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:
@@ -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
|
||||
|
||||
153
pecan/tests/scaffold_builder.py
Normal file
153
pecan/tests/scaffold_builder.py
Normal 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()
|
||||
@@ -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)
|
||||
|
||||
20
setup.py
20
setup.py
@@ -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
26
tox.ini
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user