From 6c05197a43fffe3dcd2c10f41954f8a61aec2134 Mon Sep 17 00:00:00 2001 From: Erik Rose Date: Mon, 11 Jan 2016 13:01:25 -0500 Subject: [PATCH] Remove mock as an install requirement. 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. --- acme/setup.py | 4 +- letsencrypt-apache/setup.py | 1 + letsencrypt-auto-source/letsencrypt-auto | 30 +--------- .../letsencrypt-auto.template | 2 +- .../pieces/conditional_requirements.py | 10 ---- letsencrypt-auto-source/tests/auto_test.py | 56 +++++++++++++----- .../tests/fake-letsencrypt/dist/.DS_Store | Bin 0 -> 6148 bytes .../dist/letsencrypt-99.9.9.tar.gz | Bin 0 -> 899 bytes .../tests/fake-letsencrypt/letsencrypt.py | 8 +++ .../tests/fake-letsencrypt/setup.py | 12 ++++ letsencrypt-nginx/setup.py | 1 + letshelp-letsencrypt/setup.py | 1 + setup.cfg | 2 + setup.py | 4 +- tox.ini | 31 +++++----- 15 files changed, 83 insertions(+), 79 deletions(-) create mode 100644 letsencrypt-auto-source/tests/fake-letsencrypt/dist/.DS_Store create mode 100644 letsencrypt-auto-source/tests/fake-letsencrypt/dist/letsencrypt-99.9.9.tar.gz create mode 100755 letsencrypt-auto-source/tests/fake-letsencrypt/letsencrypt.py create mode 100644 letsencrypt-auto-source/tests/fake-letsencrypt/setup.py diff --git a/acme/setup.py b/acme/setup.py index af66c143e07..7b532f28dda 100644 --- a/acme/setup.py +++ b/acme/setup.py @@ -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): @@ -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, diff --git a/letsencrypt-apache/setup.py b/letsencrypt-apache/setup.py index 58008e1e412..bfcce143b46 100644 --- a/letsencrypt-apache/setup.py +++ b/letsencrypt-apache/setup.py @@ -62,4 +62,5 @@ 'apache = letsencrypt_apache.configurator:ApacheConfigurator', ], }, + test_suite='letsencrypt_apache', ) diff --git a/letsencrypt-auto-source/letsencrypt-auto b/letsencrypt-auto-source/letsencrypt-auto index 3ae18285344..7000d302710 100755 --- a/letsencrypt-auto-source/letsencrypt-auto +++ b/letsencrypt-auto-source/letsencrypt-auto @@ -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 @@ -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 @@ -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 diff --git a/letsencrypt-auto-source/letsencrypt-auto.template b/letsencrypt-auto-source/letsencrypt-auto.template index b1852079a9c..0181d5b699e 100755 --- a/letsencrypt-auto-source/letsencrypt-auto.template +++ b/letsencrypt-auto-source/letsencrypt-auto.template @@ -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 diff --git a/letsencrypt-auto-source/pieces/conditional_requirements.py b/letsencrypt-auto-source/pieces/conditional_requirements.py index 5194a103b26..d81f03c6a6e 100644 --- a/letsencrypt-auto-source/pieces/conditional_requirements.py +++ b/letsencrypt-auto-source/pieces/conditional_requirements.py @@ -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 """ diff --git a/letsencrypt-auto-source/tests/auto_test.py b/letsencrypt-auto-source/tests/auto_test.py index 6b6f388d4ca..4fa4b4e27d5 100644 --- a/letsencrypt-auto-source/tests/auto_test.py +++ b/letsencrypt-auto-source/tests/auto_test.py @@ -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. @@ -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', @@ -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 = {'': 'letsencrypt/', - '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) @@ -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: diff --git a/letsencrypt-auto-source/tests/fake-letsencrypt/dist/.DS_Store b/letsencrypt-auto-source/tests/fake-letsencrypt/dist/.DS_Store new file mode 100644 index 0000000000000000000000000000000000000000..5008ddfcf53c02e82d7eee2e57c38e5672ef89f6 GIT binary patch literal 6148 zcmeH~Jr2S!425mzP>H1@V-^m;4Wg<&0T*E43hX&L&p$$qDprKhvt+--jT7}7np#A3 zem<@ulZcFPQ@L2!n>{z**++&mCkOWA81W14cNZlEfg7;MkzE(HCqgga^y>{tEnwC%0;vJ&^%eQ zLs35+`xjp>T02w>EAZ0 z`qy*|^j`=4A)_gah?@?1n22TRLzkzq5VOI~J2>;*I2`u6k#^^DjMgIuEBbF6rVaY9 zIsULbg8r-ePo{gg#=8H1+ty@+)XK8=qu#2$d;NakNC~y?sk|m$tY~CdRAx&8zpQx7>mOrE;nFWw}fR_h+jC^z#jGUKK1nhb{wqEFQgV7DxKsz4+Uwc-)ztIZ(5d->0h@Y|F6;i zXAu{SMe{TuZ;}2#FB`ejrqUBQWp}L}nK#sB~S00000000000000000000 Z0000000000006)f= 2 and argv[1] == '--version': + stderr.write('letsencrypt 99.9.9\n') diff --git a/letsencrypt-auto-source/tests/fake-letsencrypt/setup.py b/letsencrypt-auto-source/tests/fake-letsencrypt/setup.py new file mode 100644 index 00000000000..e5f7fde350e --- /dev/null +++ b/letsencrypt-auto-source/tests/fake-letsencrypt/setup.py @@ -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'] + } +) diff --git a/letsencrypt-nginx/setup.py b/letsencrypt-nginx/setup.py index 1d42fe48897..e4336f701ea 100644 --- a/letsencrypt-nginx/setup.py +++ b/letsencrypt-nginx/setup.py @@ -62,4 +62,5 @@ 'nginx = letsencrypt_nginx.configurator:NginxConfigurator', ], }, + test_suite='letsencrypt_nginx', ) diff --git a/letshelp-letsencrypt/setup.py b/letshelp-letsencrypt/setup.py index d487e556d4f..316868fa850 100644 --- a/letshelp-letsencrypt/setup.py +++ b/letshelp-letsencrypt/setup.py @@ -55,4 +55,5 @@ 'letshelp-letsencrypt-apache = letshelp_letsencrypt.apache:main', ], }, + test_suite='letshelp_letsencrypt', ) diff --git a/setup.cfg b/setup.cfg index ca4c1b1ca9a..4c9007edb6e 100644 --- a/setup.cfg +++ b/setup.cfg @@ -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 \ No newline at end of file diff --git a/setup.py b/setup.py index bf146f3f6d2..8604f511955 100644 --- a/setup.py +++ b/setup.py @@ -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 = [ @@ -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', diff --git a/tox.ini b/tox.ini index eb43683935d..81f96225908 100644 --- a/tox.ini +++ b/tox.ini @@ -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} @@ -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