Skip to content

Commit

Permalink
Remove mock as an install requirement.
Browse files Browse the repository at this point in the history
The motivation is to free us of a reliance on a rather modern version of setuptools, which caused le-auto failures for people on Wheezy and other older distros. (The alternative would have been to forcibly upgrade setuptools as the old le-auto did, but less is more.)

Mock is used only in tests, so we move it to tests_require. It will still be installed automatically when setup.py test is run. Give all packages a test_suite so this works.

The "testing" extra remains for optional packages not required for the nose tests but used in tox. However, the extra is much less useful now and is a candidate for deletion. We could roll the list of packages therein into the tox config so as not to favor any particular package.

Remove tests_require=install_requires, which I don't think does anything useful, since install requirements are implicitly installed when running setup.py test.

Fix tests to pass with mock removed. We had to stop them pulling down LE from PyPI, since the current version there (0.1.1) requires mock and explodes when `letsencrypt` is run.
  • Loading branch information
erikrose committed Jan 12, 2016
1 parent 66ca744 commit 6c05197
Show file tree
Hide file tree
Showing 15 changed files with 83 additions and 79 deletions.
4 changes: 1 addition & 3 deletions acme/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,7 @@
install_requires.extend([
# only some distros recognize stdlib argparse as already satisfying
'argparse',
'mock<1.1.0',
])
else:
install_requires.append('mock')

# Keep in sync with conditional_requirements.py.
if sys.version_info < (2, 7, 9):
Expand Down Expand Up @@ -75,6 +72,7 @@
packages=find_packages(),
include_package_data=True,
install_requires=install_requires,
tests_require='mock<1.1.0' if sys.version_info < (2, 7) else 'mock',
extras_require={
'docs': docs_extras,
'testing': testing_extras,
Expand Down
1 change: 1 addition & 0 deletions letsencrypt-apache/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@
'apache = letsencrypt_apache.configurator:ApacheConfigurator',
],
},
test_suite='letsencrypt_apache',
)
30 changes: 1 addition & 29 deletions letsencrypt-auto-source/letsencrypt-auto
Original file line number Diff line number Diff line change
Expand Up @@ -619,16 +619,6 @@ pyasn1==0.1.9
# sha256: wxZH7baf09RlqEfqMVfTe-0flfGXYLEaR6qRwEtmYxQ
# sha256: YrCJpVvh2JSc0rx-DfC9254Cj678jDIDjMhIYq791uQ
argparse==1.4.0
# sha256: j4MIDaoknQNsvM-4rlzG_wB7iNbZN1ITca-r57Gbrbw
# sha256: uDndLZwRfHAUMMFJlWkYpCOphjtIsJyQ4wpgE-fS9E8
mock==1.0.1
"""
else:
print """
# sha256: P1c6GL6U3ohtEZHyfBaEJ-9pPo3Pzs-VsXBXey62nLs
# sha256: HiR9vsxs4FcpnrfuAZrWgxS7kxUugdmmEQ019NXsoPY
mock==1.3.0
"""
UNLIKELY_EOF
Expand Down Expand Up @@ -1606,7 +1596,7 @@ UNLIKELY_EOF
if [ "$PEEP_STATUS" != 0 ]; then
# Report error. (Otherwise, be quiet.)
echo "Had a problem while downloading and verifying Python packages:"
echo $PEEP_OUT
echo "$PEEP_OUT"
exit 1
fi
fi
Expand Down Expand Up @@ -1655,24 +1645,6 @@ from subprocess import check_call, CalledProcessError
from sys import argv, exit
from urllib2 import build_opener, HTTPHandler, HTTPSHandler, HTTPError
#test
PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY-----
MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAnwHkSuCSy3gIHawaCiIe
4ilJ5kfEmSoiu50uiimBhTESq1JG2gVqXVXFxxVgobGhahSF+/iRVp3imrTtGp1B
2heoHbELnPTTZ8E36WHKf4gkLEo0y0XgOP3oBJ9IM5q8J68x0U3Q3c+kTxd/sgww
s5NVwpjw4aAZhgDPe5u+rvthUYOD1whYUANgYvooCpV4httNv5wuDjo7SG2V797T
QTE8aG3AOhWzdsLm6E6Tl2o/dR6XKJi/RMiXIk53SzArimtAJXe/1GyADe1AgIGE
33Ja3hU3uu9lvnnkowy1VI0qvAav/mu/APahcWVYkBAvSVAhH3zGNAGZUnP2zfcP
rH7OPw/WrxLVGlX4trLnvQr1wzX7aiM2jdikcMiaExrP0JfQXPu00y3c+hjOC5S0
+E5P+e+8pqz5iC5mmvEqy2aQJ6pV7dSpYX3mcDs8pCYaVXXtCPXS1noWirCcqCMK
EHGGdJCTXXLHaWUaGQ9Gx1An1gU7Ljkkji2Al65ZwYhkFowsLfuniYKuAywRrCNu
q958HnzFpZiQZAqZYtOHaiQiaHPs/36ZN0HuOEy0zM9FEHbp4V/DEn4pNCfAmRY5
3v+3nIBhgiLdlM7cV9559aDNeutF25n1Uz2kvuSVSS94qTEmlteCPZGBQb9Rr2wn
I2OU8tPRzqKdQ6AwS9wvqscCAwEAAQ==
-----END PUBLIC KEY-----
""")
# real
PUBLIC_KEY = environ.get('LE_AUTO_PUBLIC_KEY', """-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA6MR8W/galdxnpGqBsYbq
OzQb2eyW15YFjDDEMI0ZOzt8f504obNs920lDnpPD2/KqgsfjOgw2K7xWDJIj/18
Expand Down
2 changes: 1 addition & 1 deletion letsencrypt-auto-source/letsencrypt-auto.template
Original file line number Diff line number Diff line change
Expand Up @@ -201,7 +201,7 @@ UNLIKELY_EOF
if [ "$PEEP_STATUS" != 0 ]; then
# Report error. (Otherwise, be quiet.)
echo "Had a problem while downloading and verifying Python packages:"
echo $PEEP_OUT
echo "$PEEP_OUT"
exit 1
fi
fi
Expand Down
10 changes: 0 additions & 10 deletions letsencrypt-auto-source/pieces/conditional_requirements.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,14 +26,4 @@
# sha256: wxZH7baf09RlqEfqMVfTe-0flfGXYLEaR6qRwEtmYxQ
# sha256: YrCJpVvh2JSc0rx-DfC9254Cj678jDIDjMhIYq791uQ
argparse==1.4.0
# sha256: j4MIDaoknQNsvM-4rlzG_wB7iNbZN1ITca-r57Gbrbw
# sha256: uDndLZwRfHAUMMFJlWkYpCOphjtIsJyQ4wpgE-fS9E8
mock==1.0.1
"""
else:
print """
# sha256: P1c6GL6U3ohtEZHyfBaEJ-9pPo3Pzs-VsXBXey62nLs
# sha256: HiR9vsxs4FcpnrfuAZrWgxS7kxUugdmmEQ019NXsoPY
mock==1.3.0
"""
56 changes: 40 additions & 16 deletions letsencrypt-auto-source/tests/auto_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,21 @@ def signed(content, private_key_name='signing.key'):
return out


def run_le_auto(venv_dir, base_url):
def install_le_auto(contents, venv_dir):
"""Install some given source code as the letsencrypt-auto script at the
root level of a virtualenv.
:arg contents: The contents of the built letsencrypt-auto script
:arg venv_dir: The path under which to install the script
"""
venv_le_auto_path = join(venv_dir, 'letsencrypt-auto')
with open(venv_le_auto_path, 'w') as le_auto:
le_auto.write(contents)
chmod(venv_le_auto_path, S_IRUSR | S_IXUSR)


def run_le_auto(venv_dir, base_url, **kwargs):
"""Run the prebuilt version of letsencrypt-auto, returning stdout and
stderr strings.
Expand All @@ -181,7 +195,8 @@ def run_le_auto(venv_dir, base_url):
LsIVPBuy9IcgHidUQ96hJnoPsDCWsHwX62495QKEarauyKQrJzFes0EY95orDM47
Z5o/NDiQB11m91yNB0MmPYY9QSbnOA9j7IaaC97AwRLuwXY+/R2ablTcxurWou68
iQIDAQAB
-----END PUBLIC KEY-----""")
-----END PUBLIC KEY-----""",
**kwargs)
env.update(d)
return out_and_err(
join(venv_dir, 'letsencrypt-auto') + ' --version',
Expand Down Expand Up @@ -250,40 +265,50 @@ def test_successes(self):
the next, saving code.
"""
NEW_LE_AUTO = build_le_auto(version='99.9.9')
NEW_LE_AUTO = build_le_auto(
version='99.9.9',
requirements='# sha256: 7NpInQZj4v2dvdCBUYtcBHqVlBfnUmlsKF_oSOzU9zY\n'
'letsencrypt==99.9.9')
NEW_LE_AUTO_SIG = signed(NEW_LE_AUTO)

with ephemeral_dir() as venv_dir:
# This serves a PyPI page with a higher version, a GitHub-alike
# with a corresponding le-auto script, and a matching signature.
resources = {'': '<a href="letsencrypt/">letsencrypt/</a>',
'letsencrypt/json': dumps({'releases': {'99.9.9': None}}),
resources = {'letsencrypt/json': dumps({'releases': {'99.9.9': None}}),
'v99.9.9/letsencrypt-auto': NEW_LE_AUTO,
'v99.9.9/letsencrypt-auto.sig': NEW_LE_AUTO_SIG}
with serving(resources) as base_url:
run_letsencrypt_auto = partial(
run_le_auto,
venv_dir,
base_url,
PIP_FIND_LINKS=join(tests_dir(),
'fake-letsencrypt',
'dist'))

# Test when a phase-1 upgrade is needed, there's no LE binary
# installed, and peep verifies:
copy(LE_AUTO_PATH, venv_dir)
out, err = run_le_auto(venv_dir, base_url)
install_le_auto(build_le_auto(version='50.0.0'), venv_dir)
out, err = run_letsencrypt_auto()
ok_(re.match(r'letsencrypt \d+\.\d+\.\d+',
err.strip().splitlines()[-1]))
# Make a few assertions to test the validity of the next tests:
self.assertIn('Upgrading letsencrypt-auto ', out)
self.assertIn('Creating virtual environment...', out)

# This conveniently sets us up to test the next 2 cases.
# Now we have le-auto 99.9.9 and LE 99.9.9 installed. This
# conveniently sets us up to test the next 2 cases.

# Test when neither phase-1 upgrade nor phase-2 upgrade is
# needed (probably a common case):
set_le_script_version(venv_dir, '99.9.9')
out, err = run_le_auto(venv_dir, base_url)
out, err = run_letsencrypt_auto()
self.assertNotIn('Upgrading letsencrypt-auto ', out)
self.assertNotIn('Creating virtual environment...', out)

# Test when a phase-1 upgrade is not needed but a phase-2
# upgrade is:
set_le_script_version(venv_dir, '0.0.1')
out, err = run_le_auto(venv_dir, base_url)
out, err = run_letsencrypt_auto()
self.assertNotIn('Upgrading letsencrypt-auto ', out)
self.assertIn('Creating virtual environment...', out)

Expand Down Expand Up @@ -315,13 +340,12 @@ def test_peep_failure(self):
'letsencrypt/json': dumps({'releases': {'99.9.9': None}})}
with serving(resources) as base_url:
# Build a le-auto script embedding a bad requirements file:
venv_le_auto_path = join(venv_dir, 'letsencrypt-auto')
with open(venv_le_auto_path, 'w') as le_auto:
le_auto.write(build_le_auto(
install_le_auto(
build_le_auto(
version='99.9.9',
requirements='# sha256: badbadbadbadbadbadbadbadbadbadbadbadbadbadb\n'
'configobj==5.0.6'))
chmod(venv_le_auto_path, S_IRUSR | S_IXUSR)
'configobj==5.0.6'),
venv_dir)
try:
out, err = run_le_auto(venv_dir, base_url)
except CalledProcessError as exc:
Expand Down
Binary file not shown.
Binary file not shown.
8 changes: 8 additions & 0 deletions letsencrypt-auto-source/tests/fake-letsencrypt/letsencrypt.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from sys import argv, stderr


def main():
"""Act like letsencrypt --version insofar as printing the version number to
stderr."""
if len(argv) >= 2 and argv[1] == '--version':
stderr.write('letsencrypt 99.9.9\n')
12 changes: 12 additions & 0 deletions letsencrypt-auto-source/tests/fake-letsencrypt/setup.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
from setuptools import setup


setup(
name='letsencrypt',
version='99.9.9',
description='A mock version of letsencrypt that just prints its version',
py_modules=['letsencrypt'],
entry_points={
'console_scripts': ['letsencrypt = letsencrypt:main']
}
)
1 change: 1 addition & 0 deletions letsencrypt-nginx/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,4 +62,5 @@
'nginx = letsencrypt_nginx.configurator:NginxConfigurator',
],
},
test_suite='letsencrypt_nginx',
)
1 change: 1 addition & 0 deletions letshelp-letsencrypt/setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,4 +55,5 @@
'letshelp-letsencrypt-apache = letshelp_letsencrypt.apache:main',
],
},
test_suite='letshelp_letsencrypt',
)
2 changes: 2 additions & 0 deletions setup.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -9,3 +9,5 @@ nocapture=1
cover-package=letsencrypt,acme,letsencrypt_apache,letsencrypt_nginx
cover-erase=1
cover-tests=1
# More verbose output: allows to detect busy waiting loops, especially on Travis
verbosity=1
4 changes: 1 addition & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,12 +53,10 @@ def read_file(filename, encoding='utf8'):
# only some distros recognize stdlib argparse as already satisfying
'argparse',
'ConfigArgParse>=0.10.0', # python2.6 support, upstream #17
'mock<1.1.0',
])
else:
install_requires.extend([
'ConfigArgParse',
'mock',
])

dev_extras = [
Expand Down Expand Up @@ -116,13 +114,13 @@ def read_file(filename, encoding='utf8'):
include_package_data=True,

install_requires=install_requires,
tests_require='mock<1.1.0' if sys.version_info < (2, 7) else 'mock',
extras_require={
'dev': dev_extras,
'docs': docs_extras,
'testing': testing_extras,
},

tests_require=install_requires,
# to test all packages run "python setup.py test -s
# {acme,letsencrypt_apache,letsencrypt_nginx}"
test_suite='letsencrypt',
Expand Down
31 changes: 14 additions & 17 deletions tox.ini
Original file line number Diff line number Diff line change
Expand Up @@ -8,23 +8,20 @@
skipsdist = true
envlist = py26,py27,py33,py34,py35,cover,lint

# nosetest -v => more verbose output, allows to detect busy waiting
# loops, especially on Travis

[testenv]
# packages installed separately to ensure that dowstream deps problems
# packages installed separately to ensure that downstream deps problems
# are detected, c.f. #1002
commands =
pip install -e acme[testing]
nosetests -v acme
pip install -e .[testing]
nosetests -v letsencrypt
pip install -e acme
python acme/setup.py test
pip install -e .
python setup.py test
pip install -e letsencrypt-apache
nosetests -v letsencrypt_apache
python letsencrypt-apache/setup.py test
pip install -e letsencrypt-nginx
nosetests -v letsencrypt_nginx
python letsencrypt-nginx/setup.py test
pip install -e letshelp-letsencrypt
nosetests -v letshelp_letsencrypt
python letshelp-letsencrypt/setup.py test

setenv =
PYTHONPATH = {toxinidir}
Expand All @@ -33,18 +30,18 @@ setenv =

[testenv:py33]
commands =
pip install -e acme[testing]
nosetests -v acme
pip install -e acme
python acme/setup.py test

[testenv:py34]
commands =
pip install -e acme[testing]
nosetests -v acme
pip install -e acme
python acme/setup.py test

[testenv:py35]
commands =
pip install -e acme[testing]
nosetests -v acme
pip install -e acme
python acme/setup.py test

[testenv:cover]
basepython = python2.7
Expand Down

0 comments on commit 6c05197

Please sign in to comment.