Extract the scaffold-building tests into tox.

A lot of code was being utilized to provide a *much* slower version of what tox already provides.  This changes scaffold-building tests to run in tox across Python versions.
This commit is contained in:
Ryan Petrello
2013-03-12 15:45:37 -04:00
parent 1bf1debce6
commit 7b736524f9
5 changed files with 179 additions and 302 deletions

View File

@@ -9,9 +9,9 @@ branches:
- master
- next
install:
- pip install gunicorn
- pip install gunicorn --use-mirrors
- pip install -r requirements.txt --use-mirrors
- pip install pep8 --use-mirrors
before_script:
- pep8 --repeat --show-source --ignore=E125 --statistics --exclude *compat*,resources.py, pecan setup.py
script: python setup.py test --functional
script: python setup.py test

View File

@@ -0,0 +1,153 @@
import os
import sys
import subprocess
import urllib2
import time
if sys.version_info < (2, 7):
import unittest2 as unittest
else:
import unittest # noqa
from pecan.tests import PecanTestCase
if __name__ == '__main__':
class TestTemplateBuilds(PecanTestCase):
"""
Used to test the templated quickstart project(s).
"""
@property
def bin(self):
return os.path.dirname(sys.executable)
def poll(self, proc):
limit = 30
for i in range(limit):
proc.poll()
# Make sure it's running
if proc.returncode is None:
break
elif i == limit: # pragma: no cover
raise RuntimeError("Server process didn't start.")
time.sleep(.1)
def test_project_pecan_serve_command(self):
# Start the server
proc = subprocess.Popen([
os.path.join(self.bin, 'pecan'),
'serve',
'testing123/config.py'
])
try:
self.poll(proc)
retries = 30
while True:
retries -= 1
if retries < 0: # pragma: nocover
raise RuntimeError(
"The HTTP server has not replied within 3 seconds."
)
try:
# ...and that it's serving (valid) content...
resp = urllib2.urlopen('http://localhost:8080/')
assert resp.getcode() == 200
assert 'This is a sample Pecan project.' in resp.read()
except urllib2.URLError:
pass
else:
break
time.sleep(.1)
finally:
proc.terminate()
def test_project_pecan_shell_command(self):
# Start the server
proc = subprocess.Popen([
os.path.join(self.bin, 'pecan'),
'shell',
'testing123/config.py'
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE
)
self.poll(proc)
out, _ = proc.communicate(
'{"model" : model, "conf" : conf, "app" : app}'
)
assert 'testing123.model' in out, out
assert 'Config(' in out, out
assert 'webtest.app.TestApp' in out, out
try:
# just in case stdin doesn't close
proc.terminate()
except:
pass
class TestGunicornServeCommand(TestTemplateBuilds):
def poll_gunicorn(self, proc, port):
try:
self.poll(proc)
retries = 30
while True:
retries -= 1
if retries < 0: # pragma: nocover
raise RuntimeError(
"The gunicorn server has not replied within"
" 3 seconds."
)
try:
# ...and that it's serving (valid) content...
resp = urllib2.urlopen('http://localhost:%d/' % port)
assert resp.getcode() == 200
assert 'This is a sample Pecan project.' in resp.read()
except urllib2.URLError:
pass
else:
break
time.sleep(.1)
finally:
proc.terminate()
def test_serve_from_config(self):
# Start the server
proc = subprocess.Popen([
os.path.join(self.bin, 'gunicorn_pecan'),
'testing123/config.py'
])
self.poll_gunicorn(proc, 8080)
def test_serve_with_custom_bind(self):
# Start the server
proc = subprocess.Popen([
os.path.join(self.bin, 'gunicorn_pecan'),
'--bind=0.0.0.0:9191',
'testing123/config.py'
])
self.poll_gunicorn(proc, 9191)
# First, ensure that the `testing123` package has been installed
args = [
os.path.join(os.path.dirname(sys.executable), 'pip'),
'install',
'-U',
'-e',
'./testing123'
]
process = subprocess.Popen(args)
_, unused_err = process.communicate()
assert not process.poll()
unittest.main()

View File

@@ -2,13 +2,8 @@ import os
import sys
import tempfile
import shutil
import subprocess
import pkg_resources
import urllib2
import time
from cStringIO import StringIO
import pecan
from pecan.tests import PecanTestCase
if sys.version_info < (2, 7):
@@ -17,15 +12,6 @@ else:
import unittest # noqa
def has_internet():
try:
urllib2.urlopen('http://google.com', timeout=1)
return True
except urllib2.URLError:
pass # pragma: no cover
return False
class TestPecanScaffold(PecanTestCase):
def test_normalize_pkg_name(self):
@@ -172,267 +158,3 @@ class TestScaffoldUtils(PecanTestCase):
assert open(os.path.join(
self.scaffold_destination, 'someapp', 'bar', 'spam.txt'
), 'r').read().strip() == 'Pecan thingy'
class TestTemplateBuilds(PecanTestCase):
"""
Used to build and test the templated quickstart project(s).
"""
install_dir = tempfile.mkdtemp()
cwd = os.getcwd()
def setUp(self):
super(TestTemplateBuilds, self).setUp()
# Make a temp install location and record the cwd
self.install_scaffolded_package()
def tearDown(self):
shutil.rmtree(self.install_dir)
os.chdir(self.cwd)
def create_virtualenv(self):
# Create a new virtualenv in the temp install location
import virtualenv
virtualenv.create_environment(
self.install_dir,
site_packages=False
)
# chdir into the pecan source
os.chdir(pkg_resources.get_distribution('pecan').location)
def install_scaffolded_package(self):
self.create_virtualenv()
py_exe = os.path.join(self.install_dir, 'bin', 'python')
pecan_exe = os.path.join(self.install_dir, 'bin', 'pecan')
# env/bin/python setup.py develop (pecan)
subprocess.check_call([
py_exe,
'setup.py',
'develop'
])
# create the templated project
os.chdir(self.install_dir)
subprocess.check_call([pecan_exe, 'create', 'Testing123'])
# move into the new project directory and install
os.chdir('Testing123')
subprocess.check_call([
py_exe,
'setup.py',
'develop'
])
def install_dependency(self, name):
pip_exe = os.path.join(self.install_dir, 'bin', 'pip')
proc = subprocess.Popen([
pip_exe,
'install',
'-U',
name
])
proc.wait()
return os.path.join(
self.install_dir,
'bin',
name
)
def poll(self, proc):
limit = 30
for i in range(limit):
proc.poll()
# Make sure it's running
if proc.returncode is None:
break
elif i == limit: # pragma: no cover
raise RuntimeError("Server process didn't start.")
time.sleep(.1)
@unittest.skipUnless(has_internet(), 'Internet connectivity unavailable.')
@unittest.skipUnless(
getattr(pecan, '__run_all_tests__', False) is True,
'Skipping (slow). To run, `$ python setup.py test --functional.`'
)
def test_project_pecan_serve_command(self):
pecan_exe = os.path.join(self.install_dir, 'bin', 'pecan')
# Start the server
proc = subprocess.Popen([
pecan_exe,
'serve',
'config.py'
])
try:
self.poll(proc)
retries = 30
while True:
retries -= 1
if retries < 0: # pragma: nocover
raise RuntimeError(
"The HTTP server has not replied within 3 seconds."
)
try:
# ...and that it's serving (valid) content...
resp = urllib2.urlopen('http://localhost:8080/')
assert resp.getcode() == 200
assert 'This is a sample Pecan project.' in resp.read()
except urllib2.URLError:
pass
else:
break
time.sleep(.1)
finally:
proc.terminate()
@unittest.skipUnless(has_internet(), 'Internet connectivity unavailable.')
@unittest.skipUnless(
getattr(pecan, '__run_all_tests__', False) is True,
'Skipping (slow). To run, `$ python setup.py test --functional.`'
)
def test_project_pecan_shell_command(self):
pecan_exe = os.path.join(self.install_dir, 'bin', 'pecan')
# Start the server
proc = subprocess.Popen([
pecan_exe,
'shell',
'config.py'
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
stdin=subprocess.PIPE
)
self.poll(proc)
out, _ = proc.communicate(
'{"model" : model, "conf" : conf, "app" : app}'
)
assert 'testing123.model' in out
assert 'Config(' in out
assert 'webtest.app.TestApp' in out
try:
# just in case stdin doesn't close
proc.terminate()
except:
pass
@unittest.skipUnless(has_internet(), 'Internet connectivity unavailable.')
@unittest.skipUnless(
getattr(pecan, '__run_all_tests__', False) is True,
'Skipping (slow). To run, `$ python setup.py test --functional.`'
)
def test_project_tests_command(self):
py_exe = os.path.join(self.install_dir, 'bin', 'python')
# Run the tests
proc = subprocess.Popen([
py_exe,
'setup.py',
'test'
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
proc.wait()
assert proc.stderr.read().splitlines()[-1].strip() == 'OK'
@unittest.skipUnless(has_internet(), 'Internet connectivity unavailable.')
@unittest.skipUnless(
getattr(pecan, '__run_all_tests__', False) is True,
'Skipping (slow). To run, `$ python setup.py test --functional.`'
)
def test_project_passes_pep8(self):
# Install pep8
pep8_exe = self.install_dependency('pep8')
# Run pep8 on setup.py and the project
proc = subprocess.Popen([
pep8_exe,
'setup.py',
'testing123'
],
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
proc.wait()
# No output == good
output = proc.stdout.read()
assert output == ''
class TestGunicornServeCommand(TestTemplateBuilds):
def create_virtualenv(self):
super(TestGunicornServeCommand, self).create_virtualenv()
# Install gunicorn
self.install_dependency('gunicorn')
@property
def gunicorn_exe(self):
return os.path.join(
self.install_dir,
'bin',
'gunicorn_pecan'
)
def poll_gunicorn(self, proc, port):
try:
self.poll(proc)
retries = 30
while True:
retries -= 1
if retries < 0: # pragma: nocover
raise RuntimeError(
"The gunicorn server has not replied within 3 seconds."
)
try:
# ...and that it's serving (valid) content...
resp = urllib2.urlopen('http://localhost:%d/' % port)
assert resp.getcode() == 200
assert 'This is a sample Pecan project.' in resp.read()
except urllib2.URLError:
pass
else:
break
time.sleep(.1)
finally:
proc.terminate()
@unittest.skipUnless(has_internet(), 'Internet connectivity unavailable.')
@unittest.skipUnless(
getattr(pecan, '__run_all_tests__', False) is True,
'Skipping (slow). To run, `$ python setup.py test --functional.`'
)
def test_serve_from_config(self):
# Start the server
proc = subprocess.Popen([
self.gunicorn_exe,
'config.py'
])
self.poll_gunicorn(proc, 8080)
@unittest.skipUnless(has_internet(), 'Internet connectivity unavailable.')
@unittest.skipUnless(
getattr(pecan, '__run_all_tests__', False) is True,
'Skipping (slow). To run, `$ python setup.py test --functional.`'
)
def test_serve_with_custom_bind(self):
# Start the server
proc = subprocess.Popen([
self.gunicorn_exe,
'--bind=0.0.0.0:9191',
'config.py'
])
self.poll_gunicorn(proc, 9191)

View File

@@ -37,25 +37,6 @@ tests_require = requirements + [
if sys.version_info < (2, 7):
tests_require += ['unittest2']
class test(TestCommand):
user_options = TestCommand.user_options + [(
'functional',
None,
'Run all tests (even the really slow functional ones)'
)]
def initialize_options(self):
self.functional = None
return TestCommand.initialize_options(self)
def finalize_options(self):
if self.functional:
import pecan
setattr(pecan, '__run_all_tests__', True)
return TestCommand.finalize_options(self)
#
# call setup
#
@@ -93,7 +74,6 @@ setup(
install_requires=requirements,
tests_require=tests_require,
test_suite='pecan',
cmdclass={'test': test},
entry_points="""
[pecan.command]
serve = pecan.commands:ServeCommand

26
tox.ini
View File

@@ -1,8 +1,30 @@
[tox]
envlist = py26,py27,pep8
envlist = py26,py27,scaffolds-26,scaffolds-27,pep8
[testenv]
commands=python setup.py test --functional
commands={envpython} setup.py test -v
[testenv:scaffolds-26]
basepython = python2.6
deps = pep8
gunicorn
unittest2
changedir={envdir}/tmp
commands=pecan create testing123
{envpython} testing123/setup.py install
{envpython} testing123/setup.py test -q
pep8 --repeat --show-source testing123/setup.py testing123/testing123
{envpython} {toxinidir}/pecan/tests/scaffold_builder.py
[testenv:scaffolds-27]
basepython = python2.7
deps = {[testenv:scaffolds-26]deps}
changedir={[testenv:scaffolds-26]changedir}
commands=pecan create testing123
{envpython} testing123/setup.py install
{envpython} testing123/setup.py test -q
pep8 --repeat --show-source testing123/setup.py testing123/testing123
{envpython} {toxinidir}/pecan/tests/scaffold_builder.py
[testenv:pep8]
deps = pep8