Commit c602a525 authored by jim's avatar jim

Refactored tests to use a documented and, hopefully, sane, testing

API. This allowed the tests to be simplified somewhat.


git-svn-id: http://svn.zope.org/repos/main/zc.buildout/trunk@70237 62d5b8a3-27da-0310-9561-8e5933582275
parent 05a111b9
...@@ -262,7 +262,7 @@ buildout: ...@@ -262,7 +262,7 @@ buildout:
>>> os.chdir(sample_buildout) >>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout') >>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout), >>> print system(buildout),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Installing data-dir buildout: Installing data-dir
data-dir: Creating directory mystuff data-dir: Creating directory mystuff
...@@ -286,9 +286,9 @@ about the part we installed: ...@@ -286,9 +286,9 @@ about the part we installed:
parts = data-dir parts = data-dir
<BLANKLINE> <BLANKLINE>
[data-dir] [data-dir]
__buildout_installed__ = /tmp/sample-buildout/mystuff __buildout_installed__ = /sample-buildout/mystuff
__buildout_signature__ = recipes-c7vHV6ekIDUPy/7fjAaYjg== __buildout_signature__ = recipes-c7vHV6ekIDUPy/7fjAaYjg==
path = /tmp/sample-buildout/mystuff path = /sample-buildout/mystuff
recipe = recipes:mkdir recipe = recipes:mkdir
Note that the directory we installed is included in .installed.cfg. Note that the directory we installed is included in .installed.cfg.
...@@ -310,7 +310,7 @@ we'll see that the directory gets removed and recreated: ...@@ -310,7 +310,7 @@ we'll see that the directory gets removed and recreated:
... """) ... """)
>>> print system(buildout), >>> print system(buildout),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling data-dir buildout: Uninstalling data-dir
buildout: Installing data-dir buildout: Installing data-dir
data-dir: Creating directory mydata data-dir: Creating directory mydata
...@@ -352,7 +352,7 @@ the directory in: ...@@ -352,7 +352,7 @@ the directory in:
We'll get a user error, not a traceback. We'll get a user error, not a traceback.
>>> print system(buildout), >>> print system(buildout),
buildout: Develop: /private/tmp/tmp_I5pHasample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
data-dir: Cannot create /xxx/mydata. /xxx is not a directory. data-dir: Cannot create /xxx/mydata. /xxx is not a directory.
Error: Invalid Path Error: Invalid Path
...@@ -467,7 +467,7 @@ Now, if we run the buildout, we'll see the options with the values ...@@ -467,7 +467,7 @@ Now, if we run the buildout, we'll see the options with the values
substituted. substituted.
>>> print system(buildout), >>> print system(buildout),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling data-dir buildout: Uninstalling data-dir
buildout: Installing data-dir buildout: Installing data-dir
data-dir: Creating directory mydata data-dir: Creating directory mydata
...@@ -486,7 +486,7 @@ recipe, so it assumed it could and reinstalled mydata. If we rerun ...@@ -486,7 +486,7 @@ recipe, so it assumed it could and reinstalled mydata. If we rerun
the buildout: the buildout:
>>> print system(buildout), >>> print system(buildout),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Installing data-dir buildout: Installing data-dir
buildout: Installing debug buildout: Installing debug
File 1 mydata/file File 1 mydata/file
...@@ -561,7 +561,7 @@ customization. ...@@ -561,7 +561,7 @@ customization.
Here is a more elaborate example. Here is a more elaborate example.
>>> extensions = mkdtemp() >>> extensions = tmpdir('extensions')
>>> write(sample_buildout, 'buildout.cfg', >>> write(sample_buildout, 'buildout.cfg',
... """ ... """
...@@ -689,7 +689,7 @@ reading the configuration file. ($HOME is the value of the HOME ...@@ -689,7 +689,7 @@ reading the configuration file. ($HOME is the value of the HOME
environment variable. The '/' is replaced by the operating system file environment variable. The '/' is replaced by the operating system file
delimiter.) delimiter.)
>>> home = mkdtemp() >>> home = tmpdir('home')
>>> mkdir(home, '.buildout') >>> mkdir(home, '.buildout')
>>> write(home, '.buildout', 'default.cfg', >>> write(home, '.buildout', 'default.cfg',
... """ ... """
...@@ -784,7 +784,7 @@ Note that we used the installed buildout option to specify an ...@@ -784,7 +784,7 @@ Note that we used the installed buildout option to specify an
alternate file to store information about installed parts. alternate file to store information about installed parts.
>>> print system(buildout+' -c other.cfg debug:op1=foo -v'), >>> print system(buildout+' -c other.cfg debug:op1=foo -v'),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Installing debug buildout: Installing debug
name other name other
op1 foo op1 foo
...@@ -797,7 +797,7 @@ WARNING. ...@@ -797,7 +797,7 @@ WARNING.
Options can also be combined in the usual Unix way, as in: Options can also be combined in the usual Unix way, as in:
>>> print system(buildout+' -vcother.cfg debug:op1=foo'), >>> print system(buildout+' -vcother.cfg debug:op1=foo'),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Installing debug buildout: Installing debug
name other name other
op1 foo op1 foo
...@@ -876,21 +876,21 @@ the buildout in the usual way: ...@@ -876,21 +876,21 @@ the buildout in the usual way:
recipe = recipes:debug recipe = recipes:debug
<BLANKLINE> <BLANKLINE>
[d1] [d1]
__buildout_installed__ = /tmp/sample-buildout/d1 __buildout_installed__ = /sample-buildout/d1
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d1 path = /sample-buildout/d1
recipe = recipes:mkdir recipe = recipes:mkdir
<BLANKLINE> <BLANKLINE>
[d2] [d2]
__buildout_installed__ = /tmp/sample-buildout/d2 __buildout_installed__ = /sample-buildout/d2
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d2 path = /sample-buildout/d2
recipe = recipes:mkdir recipe = recipes:mkdir
<BLANKLINE> <BLANKLINE>
[d3] [d3]
__buildout_installed__ = /tmp/sample-buildout/d3 __buildout_installed__ = /sample-buildout/d3
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d3 path = /sample-buildout/d3
recipe = recipes:mkdir recipe = recipes:mkdir
Now we'll update our configuration file: Now we'll update our configuration file:
...@@ -960,27 +960,27 @@ The .installed.cfg is only updated for the recipes that ran: ...@@ -960,27 +960,27 @@ The .installed.cfg is only updated for the recipes that ran:
recipe = recipes:debug recipe = recipes:debug
<BLANKLINE> <BLANKLINE>
[d2] [d2]
__buildout_installed__ = /tmp/sample-buildout/d2 __buildout_installed__ = /sample-buildout/d2
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d2 path = /sample-buildout/d2
recipe = recipes:mkdir recipe = recipes:mkdir
<BLANKLINE> <BLANKLINE>
[d3] [d3]
__buildout_installed__ = /tmp/sample-buildout/data3 __buildout_installed__ = /sample-buildout/data3
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/data3 path = /sample-buildout/data3
recipe = recipes:mkdir recipe = recipes:mkdir
<BLANKLINE> <BLANKLINE>
[d4] [d4]
__buildout_installed__ = /tmp/sample-buildout/data4 __buildout_installed__ = /sample-buildout/data4
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/data4 path = /sample-buildout/data4
recipe = recipes:mkdir recipe = recipes:mkdir
<BLANKLINE> <BLANKLINE>
[d1] [d1]
__buildout_installed__ = /tmp/sample-buildout/d1 __buildout_installed__ = /sample-buildout/d1
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg== __buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d1 path = /sample-buildout/d1
recipe = recipes:mkdir recipe = recipes:mkdir
Note that the installed data for debug, d1, and d2 haven't changed, Note that the installed data for debug, d1, and d2 haven't changed,
...@@ -1028,7 +1028,7 @@ The buildout normally puts the bin, eggs, and parts directories in the ...@@ -1028,7 +1028,7 @@ The buildout normally puts the bin, eggs, and parts directories in the
directory in the directory containing the configuration file. You can directory in the directory containing the configuration file. You can
provide alternate locations, and even names for these directories. provide alternate locations, and even names for these directories.
>>> alt = mkdtemp('sample-alt') >>> alt = tmpdir('sample-alt')
>>> write(sample_buildout, 'buildout.cfg', >>> write(sample_buildout, 'buildout.cfg',
... """ ... """
...@@ -1047,11 +1047,11 @@ provide alternate locations, and even names for these directories. ...@@ -1047,11 +1047,11 @@ provide alternate locations, and even names for these directories.
... )) ... ))
>>> print system(buildout), >>> print system(buildout),
buildout: Creating directory /tmp/sample-alt/scripts buildout: Creating directory /sample-alt/scripts
buildout: Creating directory /tmp/sample-alt/work buildout: Creating directory /sample-alt/work
buildout: Creating directory /tmp/sample-alt/basket buildout: Creating directory /sample-alt/basket
buildout: Creating directory /sample-alt/developbasket buildout: Creating directory /sample-alt/developbasket
buildout: Develop: /tmp/sample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling d4 buildout: Uninstalling d4
buildout: Uninstalling d3 buildout: Uninstalling d3
buildout: Uninstalling d2 buildout: Uninstalling d2
...@@ -1068,7 +1068,8 @@ provide alternate locations, and even names for these directories. ...@@ -1068,7 +1068,8 @@ provide alternate locations, and even names for these directories.
You can also specify an alternate buildout directory: You can also specify an alternate buildout directory:
>>> alt = mkdtemp('sample-alt') >>> rmdir(alt)
>>> alt = tmpdir('sample-alt')
>>> write(sample_buildout, 'buildout.cfg', >>> write(sample_buildout, 'buildout.cfg',
... """ ... """
...@@ -1082,11 +1083,11 @@ You can also specify an alternate buildout directory: ...@@ -1082,11 +1083,11 @@ You can also specify an alternate buildout directory:
... )) ... ))
>>> print system(buildout), >>> print system(buildout),
buildout: Creating directory /tmp/sample-alt/bin buildout: Creating directory /sample-alt/bin
buildout: Creating directory /tmp/sample-alt/parts buildout: Creating directory /sample-alt/parts
buildout: Creating directory /tmp/sample-alt/eggs buildout: Creating directory /sample-alt/eggs
buildout: Creating directory /tmp/sample-alt/develop-eggs buildout: Creating directory /sample-alt/develop-eggs
buildout: Develop: /tmp/sample-buildout/recipes/setup.py buildout: Develop: /sample-buildout/recipes/setup.py
>>> ls(alt) >>> ls(alt)
- .installed.cfg - .installed.cfg
...@@ -1135,7 +1136,7 @@ configuration file. Because the verbosity is subtracted from the log ...@@ -1135,7 +1136,7 @@ configuration file. Because the verbosity is subtracted from the log
level, we get a final log level of 20, which is the INFO level. level, we get a final log level of 20, which is the INFO level.
>>> print system(buildout), >>> print system(buildout),
INFO Develop: /tmp/sample-buildout/recipes/setup.py INFO Develop: /sample-buildout/recipes/setup.py
Predefined buildout options Predefined buildout options
--------------------------- ---------------------------
...@@ -1155,16 +1156,16 @@ database is shown. ...@@ -1155,16 +1156,16 @@ database is shown.
>>> print system(buildout+' -v'), >>> print system(buildout+' -v'),
Configuration data: Configuration data:
[buildout] [buildout]
bin-directory = /tmp/sample-buildout/bin bin-directory = /sample-buildout/bin
develop-eggs-directory = /tmp/sample-buildout/develop-eggs develop-eggs-directory = /sample-buildout/develop-eggs
directory = /tmp/sample-buildout directory = /sample-buildout
eggs-directory = /tmp/sample-buildout/eggs eggs-directory = /sample-buildout/eggs
executable = /usr/local/bin/python2.3 executable = /usr/local/bin/python2.3
installed = /tmp/sample-buildout/.installed.cfg installed = /sample-buildout/.installed.cfg
log-format = %%(name)s: %%(message)s log-format = %%(name)s: %%(message)s
log-level = INFO log-level = INFO
parts = parts =
parts-directory = /tmp/sample-buildout/parts parts-directory = /sample-buildout/parts
python = buildout python = buildout
verbosity = 10 verbosity = 10
<BLANKLINE> <BLANKLINE>
...@@ -1242,7 +1243,7 @@ If zc.buildout is installed, you can use it to create a new buildout ...@@ -1242,7 +1243,7 @@ If zc.buildout is installed, you can use it to create a new buildout
with it's own local copies of zc.buildout and setuptools and with with it's own local copies of zc.buildout and setuptools and with
local buildout scripts. local buildout scripts.
>>> sample_bootstrapped = mkdtemp('sample-bootstrapped') >>> sample_bootstrapped = tmpdir('sample-bootstrapped')
>>> print system(buildout >>> print system(buildout
... +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg') ... +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
...@@ -1342,5 +1343,5 @@ We see that out extension is loaded and executed: ...@@ -1342,5 +1343,5 @@ We see that out extension is loaded and executed:
>>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')), >>> print system(os.path.join(sample_bootstrapped, 'bin', 'buildout')),
ext ['buildout'] ext ['buildout']
buildout: Develop: /tmp/tmpi0JFIIsample-bootstrapped/demo/setup.py buildout: Develop: /sample-bootstrapped/demo/setup.py
...@@ -202,11 +202,6 @@ def _call_easy_install(spec, dest, ...@@ -202,11 +202,6 @@ def _call_easy_install(spec, dest,
exit_code = os.spawnle(os.P_WAIT, executable, executable, *args) exit_code = os.spawnle(os.P_WAIT, executable, executable, *args)
assert exit_code == 0 assert exit_code == 0
# We may overwrite distributions, so clear importer
# cache.
sys.path_importer_cache.clear()
def _get_dist(requirement, env, ws, def _get_dist(requirement, env, ws,
dest, links, index, executable, always_unzip): dest, links, index, executable, always_unzip):
...@@ -235,16 +230,18 @@ def _get_dist(requirement, env, ws, ...@@ -235,16 +230,18 @@ def _get_dist(requirement, env, ws,
raise zc.buildout.UserError( raise zc.buildout.UserError(
"Couln't download a distribution for %s." "Couln't download a distribution for %s."
% requirement) % requirement)
metadata = pkg_resources.EggMetadata( should_unzip = False
zipimport.zipimporter(dist.location) if always_unzip:
) metadata = pkg_resources.EggMetadata(
if (always_unzip zipimport.zipimporter(dist.location)
or )
metadata.has_metadata('not-zip-safe') should_unzip = not (
or metadata.has_metadata('not-zip-safe')
not metadata.has_metadata('zip-safe') or
): not metadata.has_metadata('zip-safe')
)
if should_unzip:
setuptools.archive_util.unpack_archive( setuptools.archive_util.unpack_archive(
dist.location, dist.location,
os.path.join(dest, os.path.basename(dist.location) os.path.join(dest, os.path.basename(dist.location)
...@@ -274,8 +271,14 @@ def _get_dist(requirement, env, ws, ...@@ -274,8 +271,14 @@ def _get_dist(requirement, env, ws,
finally: finally:
shutil.rmtree(tmp) shutil.rmtree(tmp)
# Because we have added a new egg, we need to rescan # Because we have added a new egg, we need to rescan
# the destination directory. # the destination directory.
# We may overwrite distributions, so clear importer
# cache.
sys.path_importer_cache.clear()
env.scan([dest]) env.scan([dest])
dist = env.best_match(requirement, ws) dist = env.best_match(requirement, ws)
logger.info("Got %s", dist) logger.info("Got %s", dist)
......
...@@ -69,23 +69,19 @@ We have a link server that has a number of eggs: ...@@ -69,23 +69,19 @@ We have a link server that has a number of eggs:
>>> print get(link_server), >>> print get(link_server),
<html><body> <html><body>
<a href="demo-0.1-py2.3.egg">demo-0.1-py2.3.egg</a><br>
<a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br> <a href="demo-0.1-py2.4.egg">demo-0.1-py2.4.egg</a><br>
<a href="demo-0.2-py2.3.egg">demo-0.2-py2.3.egg</a><br>
<a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br> <a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
<a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
<a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br> <a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br>
<a href="demoneeded-1.0.tar.gz">demoneeded-1.0.tar.gz</a><br> <a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
<a href="demoneeded-1.1.tar.gz">demoneeded-1.1.tar.gz</a><br> <a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
<a href="extdemo-1.4.tar.gz">extdemo-1.4.tar.gz</a><br> <a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
<a href="index/">index/</a><br> <a href="index/">index/</a><br>
<a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
<a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br> <a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br>
</body></html> </body></html>
Let's make a directory and install the demo egg to it, using the demo: Let's make a directory and install the demo egg to it, using the demo:
>>> dest = mkdtemp('sample-install') >>> dest = tmpdir('sample-install')
>>> import zc.buildout.easy_install >>> import zc.buildout.easy_install
>>> ws = zc.buildout.easy_install.install( >>> ws = zc.buildout.easy_install.install(
... ['demo==0.2'], dest, ... ['demo==0.2'], dest,
...@@ -106,8 +102,8 @@ The working set contains the distributions we retrieved. ...@@ -106,8 +102,8 @@ The working set contains the distributions we retrieved.
And the actual eggs were added to the eggs directory. And the actual eggs were added to the eggs directory.
>>> ls(dest) >>> ls(dest)
- demo-0.2-py2.3.egg - demo-0.2-py2.4.egg
- demoneeded-1.1-py2.3.egg - demoneeded-1.1-py2.4.egg
If we ask for the demo distribution without a version restriction, If we ask for the demo distribution without a version restriction,
we'll get the newer version: we'll get the newer version:
...@@ -115,9 +111,9 @@ we'll get the newer version: ...@@ -115,9 +111,9 @@ we'll get the newer version:
>>> ws = zc.buildout.easy_install.install( >>> ws = zc.buildout.easy_install.install(
... ['demo'], dest, links=[link_server], index=link_server+'index/') ... ['demo'], dest, links=[link_server], index=link_server+'index/')
>>> ls(dest) >>> ls(dest)
- demo-0.2-py2.3.egg - demo-0.2-py2.4.egg
- demo-0.3-py2.3.egg - demo-0.3-py2.4.egg
- demoneeded-1.1-py2.3.egg - demoneeded-1.1-py2.4.egg
We can supply additional distributions. We can also supply We can supply additional distributions. We can also supply
specifications for distributions that would normally be found via specifications for distributions that would normally be found via
...@@ -134,28 +130,31 @@ dependencies. We might do this to specify a sprcific version. ...@@ -134,28 +130,31 @@ dependencies. We might do this to specify a sprcific version.
demoneeded 1.0 demoneeded 1.0
>>> ls(dest) >>> ls(dest)
- demo-0.2-py2.3.egg - demo-0.2-py2.4.egg
- demo-0.3-py2.3.egg - demo-0.3-py2.4.egg
- demoneeded-1.0-py2.3.egg - demoneeded-1.0-py2.4.egg
- demoneeded-1.1-py2.3.egg - demoneeded-1.1-py2.4.egg
- other-1.0-py2.3.egg - other-1.0-py2.4.egg
We can specify an alternate Python executable, and we can specify We can request that eggs be unzipped even if they are zip safe. This
that, when we retrieve (or create) an egg, it should be unzipped. can be useful when debugging.
>>> dest = mkdtemp('sample-install') >>> rmdir(dest)
>>> dest = tmpdir('sample-install')
>>> ws = zc.buildout.easy_install.install( >>> ws = zc.buildout.easy_install.install(
... ['demo'], dest, links=[link_server], index=link_server+'index/', ... ['demo'], dest, links=[link_server], index=link_server+'index/',
... always_unzip=True, executable= python2_3_executable) ... always_unzip=True)
>>> ls(dest) >>> ls(dest)
d demo-0.3-py2.3.egg d demo-0.3-py2.4.egg
d demoneeded-1.1-py2.3.egg d demoneeded-1.1-py2.4.egg
>>> dest = mkdtemp('sample-install')
>>> rmdir(dest)
>>> dest = tmpdir('sample-install')
>>> ws = zc.buildout.easy_install.install( >>> ws = zc.buildout.easy_install.install(
... ['demo'], dest, links=[link_server], index=link_server+'index/', ... ['demo'], dest, links=[link_server], index=link_server+'index/',
... always_unzip=True, executable=python2_4_executable) ... always_unzip=True)
>>> ls(dest) >>> ls(dest)
d demo-0.3-py2.4.egg d demo-0.3-py2.4.egg
...@@ -180,13 +179,14 @@ The scripts method can be used to generate scripts. Let's create a ...@@ -180,13 +179,14 @@ The scripts method can be used to generate scripts. Let's create a
destination directory for it to place them in: destination directory for it to place them in:
>>> import tempfile >>> import tempfile
>>> bin = mkdtemp() >>> bin = tmpdir('bin')
Now, we'll use the scripts method to generate scripts in this directory Now, we'll use the scripts method to generate scripts in this directory
from the demo egg: from the demo egg:
>>> import sys
>>> scripts = zc.buildout.easy_install.scripts( >>> scripts = zc.buildout.easy_install.scripts(
... ['demo'], ws, python2_4_executable, bin) ... ['demo'], ws, sys.executable, bin)
the four arguments we passed were: the four arguments we passed were:
...@@ -223,12 +223,12 @@ interpreter and without having to provide a '.py' suffix. ...@@ -223,12 +223,12 @@ interpreter and without having to provide a '.py' suffix.
The demo script run the entry point defined in the demo egg: The demo script run the entry point defined in the demo egg:
>>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE >>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3 #!/usr/local/bin/python2.4
<BLANKLINE> <BLANKLINE>
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg', '/sample-install/demo-0.3-py2.4.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg', '/sample-install/demoneeded-1.1-py2.4.egg',
] ]
<BLANKLINE> <BLANKLINE>
import eggrecipedemo import eggrecipedemo
...@@ -257,15 +257,15 @@ rather than passing a requirement: ...@@ -257,15 +257,15 @@ rather than passing a requirement:
>>> scripts = zc.buildout.easy_install.scripts( >>> scripts = zc.buildout.easy_install.scripts(
... [('demo', 'eggrecipedemo', 'main')], ... [('demo', 'eggrecipedemo', 'main')],
... ws, python2_4_executable, bin) ... ws, sys.executable, bin)
>>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE >>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3 #!/usr/local/bin/python2.4
<BLANKLINE> <BLANKLINE>
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg', '/sample-install/demo-0.3-py2.4.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg', '/sample-install/demoneeded-1.1-py2.4.egg',
] ]
<BLANKLINE> <BLANKLINE>
import eggrecipedemo import eggrecipedemo
...@@ -283,7 +283,7 @@ based on the working set. This generated script can also be used to ...@@ -283,7 +283,7 @@ based on the working set. This generated script can also be used to
run other scripts with the path set on the working set: run other scripts with the path set on the working set:
>>> scripts = zc.buildout.easy_install.scripts( >>> scripts = zc.buildout.easy_install.scripts(
... ['demo'], ws, python2_4_executable, bin, interpreter='py') ... ['demo'], ws, sys.executable, bin, interpreter='py')
>>> ls(bin) >>> ls(bin)
...@@ -308,8 +308,8 @@ the path set: ...@@ -308,8 +308,8 @@ the path set:
import sys import sys
<BLANKLINE> <BLANKLINE>
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/tmp5zS2Afsample-install/demo-0.3-py2.4.egg', '/sample-install/demo-0.3-py2.4.egg',
'/tmp/tmp5zS2Afsample-install/demoneeded-1.1-py2.4.egg', '/sample-install/demoneeded-1.1-py2.4.egg',
] ]
<BLANKLINE> <BLANKLINE>
_interactive = True _interactive = True
...@@ -337,9 +337,9 @@ An additional argumnet can be passed to define which scripts to install ...@@ -337,9 +337,9 @@ An additional argumnet can be passed to define which scripts to install
and to provide script names. The argument is a dictionary mapping and to provide script names. The argument is a dictionary mapping
original script names to new script names. original script names to new script names.
>>> bin = mkdtemp() >>> bin = tmpdir('bin2')
>>> scripts = zc.buildout.easy_install.scripts( >>> scripts = zc.buildout.easy_install.scripts(
... ['demo'], ws, python2_4_executable, bin, dict(demo='run')) ... ['demo'], ws, sys.executable, bin, dict(demo='run'))
>>> if sys.platform == 'win32': >>> if sys.platform == 'win32':
... scripts == [os.path.join(bin, 'run.exe'), ... scripts == [os.path.join(bin, 'run.exe'),
...@@ -360,16 +360,16 @@ We can pass a keyword argument, extra paths, to caue additional paths ...@@ -360,16 +360,16 @@ We can pass a keyword argument, extra paths, to caue additional paths
to be included in the a generated script: to be included in the a generated script:
>>> scripts = zc.buildout.easy_install.scripts( >>> scripts = zc.buildout.easy_install.scripts(
... ['demo'], ws, python2_4_executable, bin, dict(demo='run'), ... ['demo'], ws, sys.executable, bin, dict(demo='run'),
... extra_paths=['/foo/bar']) ... extra_paths=['/foo/bar'])
>>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3 #!/usr/local/bin/python2.4
<BLANKLINE> <BLANKLINE>
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg', '/sample-install/demo-0.3-py2.4.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg', '/sample-install/demoneeded-1.1-py2.4.egg',
'/foo/bar', '/foo/bar',
] ]
<BLANKLINE> <BLANKLINE>
...@@ -386,15 +386,15 @@ entry point. The value passed source string to be placed between the ...@@ -386,15 +386,15 @@ entry point. The value passed source string to be placed between the
parentheses in the call: parentheses in the call:
>>> scripts = zc.buildout.easy_install.scripts( >>> scripts = zc.buildout.easy_install.scripts(
... ['demo'], ws, python2_4_executable, bin, dict(demo='run'), ... ['demo'], ws, sys.executable, bin, dict(demo='run'),
... arguments='1, 2') ... arguments='1, 2')
>>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE >>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3 #!/usr/local/bin/python2.4
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg', '/sample-install/demo-0.3-py2.4.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg', '/sample-install/demoneeded-1.1-py2.4.egg',
] ]
<BLANKLINE> <BLANKLINE>
import eggrecipedemo import eggrecipedemo
...@@ -492,5 +492,5 @@ Now if we look in our destination directory, we see we have an extdemo egg: ...@@ -492,5 +492,5 @@ Now if we look in our destination directory, we see we have an extdemo egg:
>>> ls(dest) >>> ls(dest)
d demo-0.3-py2.4.egg d demo-0.3-py2.4.egg
d demoneeded-1.1-py2.4.egg d demoneeded-1.1-py2.4.egg
d extdemo-1.4-py2.3-unix-i686.egg d extdemo-1.4-py2.4-unix-i686.egg
...@@ -24,6 +24,10 @@ from zope.testing import doctest, renormalizing ...@@ -24,6 +24,10 @@ from zope.testing import doctest, renormalizing
import pkg_resources import pkg_resources
import zc.buildout.buildout import zc.buildout.buildout
import zc.buildout.easy_install
setuptools_location = pkg_resources.working_set.find(
pkg_resources.Requirement.parse('setuptools')).location
def cat(dir, *names): def cat(dir, *names):
path = os.path.join(dir, *names) path = os.path.join(dir, *names)
...@@ -46,10 +50,11 @@ def ls(dir, *subs): ...@@ -46,10 +50,11 @@ def ls(dir, *subs):
print '- ', print '- ',
print name print name
def mkdir(dir, *subs): def mkdir(*path):
if subs: os.mkdir(os.path.join(*path))
dir = os.path.join(dir, *subs)
os.mkdir(dir) def rmdir(*path):
shutil.rmtree(os.path.join(*path))
def write(dir, *args): def write(dir, *args):
open(os.path.join(dir, *(args[:-1])), 'w').write(args[-1]) open(os.path.join(dir, *(args[:-1])), 'w').write(args[-1])
...@@ -64,128 +69,30 @@ def system(command, input=''): ...@@ -64,128 +69,30 @@ def system(command, input=''):
def get(url): def get(url):
return urllib2.urlopen(url).read() return urllib2.urlopen(url).read()
def buildoutSetUp(test): def _runsetup(setup, executable, *args):
# we both need to make sure that HOME isn't set and be prepared if os.path.isdir(setup):
# to restore whatever it was after the test. setup = os.path.join(setup, 'setup.py')
test.globs['_oldhome'] = os.environ['HOME'] d = os.path.dirname(setup)
del os.environ['HOME'] # pop doesn't truly remove it :(
temporary_directories = []
def mkdtemp(*args):
d = tempfile.mkdtemp(*args)
temporary_directories.append(d)
return d
os.environ['buildout-testing-index-url'] = 'file://'+mkdtemp()
sample = mkdtemp('sample-buildout')
# Create a basic buildout.cfg to avoid a warning from buildout:
open(os.path.join(sample, 'buildout.cfg'), 'w').write(
"[buildout]\nparts =\n"
)
# Use the buildout bootstrap command to create a buildout
zc.buildout.buildout.Buildout(
os.path.join(sample, 'buildout.cfg'),
[('buildout', 'log-level', 'WARNING')]
).bootstrap([])
test.globs.update(dict(
__here = os.getcwd(),
sample_buildout = sample,
ls = ls,
cat = cat,
mkdir = mkdir,
write = write,
system = system,
get = get,
__temporary_directories__ = temporary_directories,
__tearDown__ = [],
mkdtemp = mkdtemp,
cd = os.chdir,
))
def buildoutTearDown(test):
os.chdir(test.globs['__here'])
for d in test.globs['__temporary_directories__']:
shutil.rmtree(d)
for f in test.globs['__tearDown__']:
f()
if test.globs.get('_oldhome') is not None:
os.environ['HOME'] = test.globs['_oldhome']
args = [zc.buildout.easy_install._safe_arg(arg)
for arg in args]
args.insert(0, '-q')
args.append(dict(os.environ, PYTHONPATH=setuptools_location))
script_template = '''\
#!%(python)s
import sys
sys.path[0:0] = %(path)r
from pkg_resources import load_entry_point
sys.exit(load_entry_point('zc.buildout', 'console_scripts', 'buildout')())
'''
def runsetup(d, executable, type='bdist_egg'):
here = os.getcwd() here = os.getcwd()
try: try:
os.chdir(d) os.chdir(d)
os.spawnle( os.spawnle(os.P_WAIT, executable, executable, setup, *args)
os.P_WAIT, executable, executable,
'setup.py', '-q', type,
{'PYTHONPATH': os.path.dirname(pkg_resources.__file__)},
)
if os.path.exists('build'): if os.path.exists('build'):
shutil.rmtree('build') shutil.rmtree('build')
finally: finally:
os.chdir(here) os.chdir(here)
def create_sample_eggs(test, executable=sys.executable): def sdist(setup, dest):
if 'sample_eggs' in test.globs: _runsetup(setup, sys.executable, 'sdist', '-d', dest, '--formats=zip')
sample = os.path.dirname(test.globs['sample_eggs'])
else:
sample = test.globs['mkdtemp']('sample-eggs')
test.globs['sample_eggs'] = os.path.join(sample, 'dist')
write(sample, 'README.txt', '')
for i in (0, 1):
write(sample, 'eggrecipedemobeeded.py', 'y=%s\n' % i)
write(
sample, 'setup.py',
"from setuptools import setup\n"
"setup(name='demoneeded', py_modules=['eggrecipedemobeeded'],"
" zip_safe=True, version='1.%s', author='bob', url='bob', "
"author_email='bob')\n"
% i
)
runsetup(sample, executable, 'sdist')
write( def bdist_egg(setup, executable, dest):
sample, 'setup.py', _runsetup(setup, executable, 'bdist_egg', '-d', dest)
"from setuptools import setup\n"
"setup(name='other', zip_safe=True, version='1.0', "
"py_modules=['eggrecipedemobeeded'])\n"
)
runsetup(sample, executable)
os.remove(os.path.join(sample, 'eggrecipedemobeeded.py'))
for i in (1, 2, 3):
write(
sample, 'eggrecipedemo.py',
'import eggrecipedemobeeded\n'
'x=%s\n'
'def main(): print x, eggrecipedemobeeded.y\n'
% i)
write(
sample, 'setup.py',
"from setuptools import setup\n"
"setup(name='demo', py_modules=['eggrecipedemo'],"
" install_requires = 'demoneeded',"
" entry_points={'console_scripts': ['demo = eggrecipedemo:main']},"
" zip_safe=True, version='0.%s')\n" % i
)
runsetup(sample, executable)
def find_python(version): def find_python(version):
e = os.environ.get('PYTHON%s' % version) e = os.environ.get('PYTHON%s' % version)
...@@ -223,77 +130,81 @@ def find_python(version): ...@@ -223,77 +130,81 @@ def find_python(version):
"of the Python %(version)s executable before running the tests." "of the Python %(version)s executable before running the tests."
) )
def multi_python(test): def buildoutSetUp(test):
p23 = find_python('2.3')
p24 = find_python('2.4')
create_sample_eggs(test, executable=p23)
create_sample_eggs(test, executable=p24)
test.globs['python2_3_executable'] = p23
test.globs['python2_4_executable'] = p24
test.globs['__tear_downs'] = __tear_downs = []
test.globs['register_teardown'] = register_teardown = __tear_downs.append
extdemo_c = """ here = os.getcwd()
#include <Python.h> register_teardown(lambda: os.chdir(here))
#include <extdemo.h>
static PyMethodDef methods[] = {{NULL}}; old_home = os.environ.get('HOME')
if old_home is not None:
del os.environ['HOME'] # pop doesn't truly remove it :(
register_teardown(lambda: os.environ.__setitem__('HOME', old_home))
PyMODINIT_FUNC base = tempfile.mkdtemp()
initextdemo(void) register_teardown(lambda: shutil.rmtree(base))
{ base = os.path.join(base, '_TEST_')
PyObject *d; os.mkdir(base)
d = Py_InitModule3("extdemo", methods, "");
PyDict_SetItemString(d, "val", PyInt_FromLong(EXTDEMO));
}
"""
extdemo_setup_py = """ tmp = tempfile.mkdtemp('buildouttests')
from distutils.core import setup, Extension register_teardown(lambda: shutil.rmtree(tmp))
zc.buildout.easy_install.default_index_url = 'file://'+tmp
os.environ['buildout-testing-index-url'] = (
zc.buildout.easy_install.default_index_url)
setup(name = "extdemo", version = "1.4", url="http://www.zope.org", def tmpdir(name):
author="Demo", author_email="demo@demo.com", path = os.path.join(base, name)
ext_modules = [Extension('extdemo', ['extdemo.c'])], mkdir(path)
) return path
"""
def add_source_dist(test): sample = tmpdir('sample-buildout')
import tarfile
tmp = tempfile.mkdtemp('test-sdist')
open(os.path.join(tmp, 'extdemo.c'), 'w').write(extdemo_c);
open(os.path.join(tmp, 'setup.py'), 'w').write(extdemo_setup_py);
open(os.path.join(tmp, 'README'), 'w').write("");
open(os.path.join(tmp, 'MANIFEST.in'), 'w').write("include *.c\n");
here = os.getcwd()
os.chdir(tmp)
status = os.spawnl(os.P_WAIT, sys.executable, sys.executable,
os.path.join(tmp, 'setup.py'), '-q', 'sdist')
os.chdir(here)
assert status == 0
if sys.platform == 'win32':
sname = 'extdemo-1.4.zip'
else:
sname = 'extdemo-1.4.tar.gz'
shutil.move( # Create a basic buildout.cfg to avoid a warning from buildout:
os.path.join(tmp, 'dist', sname), open(os.path.join(sample, 'buildout.cfg'), 'w').write(
os.path.join(test.globs['sample_eggs'], sname), "[buildout]\nparts =\n"
) )
def make_tree(test): # Use the buildout bootstrap command to create a buildout
sample_eggs = test.globs['sample_eggs'] zc.buildout.buildout.Buildout(
tree = dict( os.path.join(sample, 'buildout.cfg'),
[(n, open(os.path.join(sample_eggs, n), 'rb').read()) [('buildout', 'log-level', 'WARNING')]
for n in os.listdir(sample_eggs) ).bootstrap([])
])
tree['index'] = {} def start_server(path):
return tree port, thread = _start_server(path, name=path)
url = 'http://localhost:%s/' % port
register_teardown(lambda: stop_server(url, thread))
return url
test.globs.update(dict(
sample_buildout = sample,
ls = ls,
cat = cat,
mkdir = mkdir,
rmdir = rmdir,
tmpdir = tmpdir,
write = write,
system = system,
get = get,
cd = (lambda *path: os.chdir(os.path.join(*path))),
join = os.path.join,
sdist = sdist,
bdist_egg = bdist_egg,
start_server = start_server,
))
def buildoutTearDown(test):
for f in test.globs['__tear_downs']:
f()
class Server(BaseHTTPServer.HTTPServer): class Server(BaseHTTPServer.HTTPServer):
def __init__(self, tree, *args): def __init__(self, tree, *args):
BaseHTTPServer.HTTPServer.__init__(self, *args) BaseHTTPServer.HTTPServer.__init__(self, *args)
self.tree = tree self.tree = os.path.abspath(tree)
__run = True __run = True
def serve_forever(self): def serve_forever(self):
...@@ -313,28 +224,30 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler): ...@@ -313,28 +224,30 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
def do_GET(self): def do_GET(self):
if '__stop__' in self.path: if '__stop__' in self.path:
raise SystemExit raise SystemExit
tree = self.tree path = os.path.abspath(os.path.join(self.tree, *self.path.split('/')))
for name in self.path.split('/'): if not (
if not name: ((path == self.tree) or path.startswith(self.tree+os.path.sep))
continue and
tree = tree.get(name) os.path.exists(path)
if tree is None: ):
self.send_response(404, 'Not Found') self.send_response(404, 'Not Found')
out = '<html><body>Not Found</body></html>' #self.send_response(200)
self.send_header('Content-Length', str(len(out))) out = '<html><body>Not Found</body></html>'
self.send_header('Content-Type', 'text/html') #out = '\n'.join(self.tree, self.path, path)
self.end_headers() self.send_header('Content-Length', str(len(out)))
self.wfile.write(out) self.send_header('Content-Type', 'text/html')
return self.end_headers()
self.wfile.write(out)
return
self.send_response(200) self.send_response(200)
if isinstance(tree, dict): if os.path.isdir(path):
out = ['<html><body>\n'] out = ['<html><body>\n']
items = tree.items() names = os.listdir(path)
items.sort() names.sort()
for name, v in items: for name in names:
if isinstance(v, dict): if os.path.isdir(os.path.join(path, name)):
name += '/' name += '/'
out.append('<a href="%s">%s</a><br>\n' % (name, name)) out.append('<a href="%s">%s</a><br>\n' % (name, name))
out.append('</body></html>\n') out.append('</body></html>\n')
...@@ -342,13 +255,13 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler): ...@@ -342,13 +255,13 @@ class Handler(BaseHTTPServer.BaseHTTPRequestHandler):
self.send_header('Content-Length', str(len(out))) self.send_header('Content-Length', str(len(out)))
self.send_header('Content-Type', 'text/html') self.send_header('Content-Type', 'text/html')
else: else:
out = tree out = open(path).read()
self.send_header('Content-Length', len(out)) self.send_header('Content-Length', len(out))
if name.endswith('.egg'): if path.endswith('.egg'):
self.send_header('Content-Type', 'application/zip') self.send_header('Content-Type', 'application/zip')
elif name.endswith('.gz'): elif path.endswith('.gz'):
self.send_header('Content-Type', 'application/x-gzip') self.send_header('Content-Type', 'application/x-gzip')
elif name.endswith('.zip'): elif path.endswith('.zip'):
self.send_header('Content-Type', 'application/x-gzip') self.send_header('Content-Type', 'application/x-gzip')
else: else:
self.send_header('Content-Type', 'text/html') self.send_header('Content-Type', 'text/html')
...@@ -396,13 +309,6 @@ def stop_server(url, thread=None): ...@@ -396,13 +309,6 @@ def stop_server(url, thread=None):
if thread is not None: if thread is not None:
thread.join() # wait for thread to stop thread.join() # wait for thread to stop
def setUpServer(test, tree):
port, thread = _start_server(tree, name=test.name)
link_server = 'http://localhost:%s/' % port
test.globs['link_server'] = link_server
test.globs['__tearDown__'].append(lambda: stop_server(link_server, thread))
def wait(port, up): def wait(port, up):
addr = 'localhost', port addr = 'localhost', port
for i in range(120): for i in range(120):
...@@ -424,3 +330,51 @@ def wait(port, up): ...@@ -424,3 +330,51 @@ def wait(port, up):
raise raise
else: else:
raise SystemError("Couln't stop server") raise SystemError("Couln't stop server")
def install(project, destination):
if not isinstance(destination, basestring):
destination = os.path.join(destination.globs['sample_buildout'],
'eggs')
dist = pkg_resources.working_set.find(
pkg_resources.Requirement.parse(project))
if dist.location.endswith('.egg'):
destination = os.path.join(destination,
os.path.basename(dist.location),
)
if os.path.isdir(dist.location):
shutil.copytree(dist.location, destination)
else:
shutil.copyfile(dist.location, destination)
else:
# copy link
open(os.path.join(destination, project+'.egg-link'), 'w'
).write(dist.location)
def install_develop(project, destination):
if not isinstance(destination, basestring):
destination = os.path.join(destination.globs['sample_buildout'],
'develop-eggs')
dist = pkg_resources.working_set.find(
pkg_resources.Requirement.parse(project))
open(os.path.join(destination, project+'.egg-link'), 'w'
).write(dist.location)
def _normalize_path(match):
return '/'+match.group(1).replace(os.path.sep, '/')
normalize_path = (
re.compile(r'''[^'" \t\n\r]+%(sep)s_TEST_%(sep)s([^"' \t\n\r]+)'''
% dict(sep=os.path.sep)),
_normalize_path,
)
normalize_script = (
re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'),
'\\1- \\2\n')
normalize_egg_py = (
re.compile('-py\d[.]\d(-\S+)?.egg'),
'-pyN.N.egg',
)
Testing Support
===============
The zc.buildout.testing module provides an API that can be used when
writing recipe tests. This API is documented below. Many examples of
using this API can be found in the zc.buildout, zc.recipe.egg, and
zc.recipe.testrunner tests.
zc.buildout.testing.buildoutSetUp(test)
---------------------------------------
The buildoutSetup function can be used as a doctest setup function.
It performs adds a number of names to the test namespace:
sample_buildout
This is the name of a buildout with a basic configuration.
ls(*path)
List the contents of a directory. The directory path is provided as one or
more strings, to be joined with os.path.join.
cat(*path)
Display the contents of a file. The file path is provided as one or
more strings, to be joined with os.path.join.
On Windows, if the file doesn't exist, the function will try
adding a '-script.py' suffix. This helps to work around a
difference in script generation on windows.
mkdir(*path)
Create a directory. The directory path is provided as one or
more strings, to be joined with os.path.join.
rmdir(*path)
Remove a directory. The directory path is provided as one or
more strings, to be joined with os.path.join.
tmpdir(name)
Create a temporary directory with the given name. The directory
will be automatically removed at the end of the test. The path of
the created directory is returned.
Further, if the the normalize_path normlaizing substitution (see
below) is used, then any paths starting with this path will be
normalized to::
/name/restofpath
No two temporary directories can be created with the same name. A
directory created with tmpdir can be removed with rmdir and recreated.
Note that the sample_buildout directory is created by calling this
function.
write(*path_and_contents)
Create a file. The file path is provided as one or more strings,
to be joined with os.path.join. The last argument is the file contents.
system(command, input='')
Execute a system command with the given input passed to the
command's standard input. The output (error and regular output)
from the command is returned.
get(url)
Get a web page.
cd(*path)
Change to the given directory. The directory path is provided as one or
more strings, to be joined with os.path.join.
The directory will be reset at the end of the test.
join(*path)
A convenient reference to os.path.join.
register_teardown(func)
Register a tear-down function. The function will be called with
no arguments at the end of the test.
start_server(path)
Start a web server on the given path. The server will be shut
down at the end of the test. The server URL is returned.
sdist(setup, dest)
Create a source distribution by running the given setup file and
placing the result in the given destination directory. If the
setup argument is a directory, the thge setup.py file in that
directory is used.
bdist_egg(setup, executable, dest)
Create an egg by running the given setup file with the given
Python executable and placing the result in the given destination
directory. If the setup argument is a directory, the thge
setup.py file in that directory is used.
find_python(version)
Find a Python executable for the given version, where version is a
string like "2.4".
This function uses the following strategy to find a Python of the
given version:
- Look for an environment variable of the form PYTHON%(version)s.
- On windows, look for \Pythonm%(version)s\python
- on Unix, try running python%(version)s or just python to get the
executable
zc.buildout.testing.buildoutTearDown(test)
------------------------------------------
Tear down everything set up by zc.buildout.testing.buildoutSetUp. Any
functions passed to register_teardown are called as well.
install(project, destination)
-----------------------------
Install eggs for a given project into a destination. If the
destination is a test object, then the eggs directory of the
sample buildout (sample_buildout) defined by the test will be used.
Tests will use this to install the distributions for the packages
being tested (and their dependencies) into a sample buildout. The egg
to be used should already be loaded, by importing one of the modules
provided, before calling this function.
install_develop(project, destination)
-------------------------------------
Like install, but a develop egg is installed even if the current egg
if not a develop egg.
Output normalization
--------------------
Recipe tests often generate output that is dependent on temporary file
locations, operating system conventions or Python versions. To deal
with these dependencies, we often use
zope.testing.renormalizing.RENormalizing to normalize test output.
zope.testing.renormalizing.RENormalizing takes pairs of regular
expressions and substitutions. The zc.buildout.testing module provides
a few helpful variables that define regular-expression/substitution
pairs that you can pass to zope.testing.renormalizing.RENormalizing.
normalize_path
Converts tests paths, based on directories created with tmpdir(),
to simple paths.
normalize_script
On Unix-like systems, scripts are implemented in single files
without suffixes. On windows, scripts are implemented with 2
files, a -script.py file and a .exe file. This normalization
converts directory listings of Windows scripts to the form
generated on UNix-like systems.
normalize_egg_py
Normalize Python version and platform indicators, if specified, in
egg names.
...@@ -16,7 +16,7 @@ ...@@ -16,7 +16,7 @@
$Id$ $Id$
""" """
import os, re, shutil, sys, unittest, zipfile import os, re, shutil, sys, tempfile, unittest, zipfile
from zope.testing import doctest, renormalizing from zope.testing import doctest, renormalizing
import pkg_resources import pkg_resources
import zc.buildout.testing, zc.buildout.easy_install import zc.buildout.testing, zc.buildout.easy_install
...@@ -231,7 +231,7 @@ if os.path.exists(bootstrap_py): ...@@ -231,7 +231,7 @@ if os.path.exists(bootstrap_py):
def test_bootstrap_py(): def test_bootstrap_py():
"""Make sure the bootstrap script actually works """Make sure the bootstrap script actually works
>>> sample_buildout = mkdtemp() >>> sample_buildout = tmpdir('sample')
>>> os.chdir(sample_buildout) >>> os.chdir(sample_buildout)
>>> write('bootstrap.py', open(bootstrap_py).read()) >>> write('bootstrap.py', open(bootstrap_py).read())
>>> print system(sys.executable+' '+'bootstrap.py'), # doctest: +ELLIPSIS >>> print system(sys.executable+' '+'bootstrap.py'), # doctest: +ELLIPSIS
...@@ -362,7 +362,7 @@ We had a problem running a bootstrap with an extension. Let's make ...@@ -362,7 +362,7 @@ We had a problem running a bootstrap with an extension. Let's make
sure it is fixed. Basically, we don't load extensions when sure it is fixed. Basically, we don't load extensions when
bootstrapping. bootstrapping.
>>> d = mkdtemp('sample-bootstrap-2') >>> d = tmpdir('sample-bootstrap')
>>> write(d, 'buildout.cfg', >>> write(d, 'buildout.cfg',
... ''' ... '''
...@@ -374,72 +374,108 @@ bootstrapping. ...@@ -374,72 +374,108 @@ bootstrapping.
>>> os.chdir(d) >>> os.chdir(d)
>>> print system(os.path.join(sample_buildout, 'bin', 'buildout') >>> print system(os.path.join(sample_buildout, 'bin', 'buildout')
... + ' bootstrap'), ... + ' bootstrap'),
buildout: Creating directory /sample-bootstrap-2/bin buildout: Creating directory /sample-bootstrap/bin
buildout: Creating directory /sample-bootstrap-2/parts buildout: Creating directory /sample-bootstrap/parts
buildout: Creating directory /sample-bootstrap-2/eggs buildout: Creating directory /sample-bootstrap/eggs
buildout: Creating directory /sample-bootstrap-2/develop-eggs buildout: Creating directory /sample-bootstrap/develop-eggs
""" """
def easy_install_SetUp(test):
zc.buildout.testing.buildoutSetUp(test)
zc.buildout.testing.multi_python(test)
zc.buildout.testing.add_source_dist(test)
zc.buildout.testing.setUpServer(test, zc.buildout.testing.make_tree(test))
class PythonNormalizing(renormalizing.RENormalizing):
def _transform(self, want, got):
if '/xyzsample-install/' in want:
got = got.replace('-py2.4.egg', '-py2.3.egg')
firstg = got.split('\n')[0]
firstw = want.split('\n')[0]
if firstg.startswith('#!') and firstw.startswith('#!'):
firstg = ' '.join(firstg.split()[1:])
got = firstg + '\n' + '\n'.join(got.split('\n')[1:])
firstw = ' '.join(firstw.split()[1:])
want = firstw + '\n' + '\n'.join(want.split('\n')[1:])
for pattern, repl in self.patterns:
want = pattern.sub(repl, want)
got = pattern.sub(repl, got)
return want, got
def check_output(self, want, got, optionflags):
if got == want:
return True
want, got = self._transform(want, got)
if got == want:
return True
return doctest.OutputChecker.check_output(self, want, got, optionflags)
def output_difference(self, example, got, optionflags): def create_sample_eggs(test, executable=sys.executable):
write = test.globs['write']
want = example.want dest = test.globs['sample_eggs']
tmp = tempfile.mkdtemp()
try:
write(tmp, 'README.txt', '')
for i in (0, 1):
write(tmp, 'eggrecipedemobeeded.py', 'y=%s\n' % i)
write(
tmp, 'setup.py',
"from setuptools import setup\n"
"setup(name='demoneeded', py_modules=['eggrecipedemobeeded'],"
" zip_safe=True, version='1.%s', author='bob', url='bob', "
"author_email='bob')\n"
% i
)
zc.buildout.testing.sdist(tmp, dest)
# If want is empty, use original outputter. This is useful write(
# when setting up tests for the first time. In that case, we tmp, 'setup.py',
# generally use the differencer to display output, which we evaluate "from setuptools import setup\n"
# by hand. "setup(name='other', zip_safe=True, version='1.0', "
if not want.strip(): "py_modules=['eggrecipedemobeeded'])\n"
return doctest.OutputChecker.output_difference( )
self, example, got, optionflags) zc.buildout.testing.bdist_egg(tmp, executable, dest)
os.remove(os.path.join(tmp, 'eggrecipedemobeeded.py'))
for i in (1, 2, 3):
write(
tmp, 'eggrecipedemo.py',
'import eggrecipedemobeeded\n'
'x=%s\n'
'def main(): print x, eggrecipedemobeeded.y\n'
% i)
write(
tmp, 'setup.py',
"from setuptools import setup\n"
"setup(name='demo', py_modules=['eggrecipedemo'],"
" install_requires = 'demoneeded',"
" entry_points={'console_scripts': "
"['demo = eggrecipedemo:main']},"
" zip_safe=True, version='0.%s')\n" % i
)
zc.buildout.testing.bdist_egg(tmp, executable, dest)
finally:
shutil.rmtree(tmp)
extdemo_c = """
#include <Python.h>
#include <extdemo.h>
static PyMethodDef methods[] = {{NULL}};
PyMODINIT_FUNC
initextdemo(void)
{
PyObject *d;
d = Py_InitModule3("extdemo", methods, "");
PyDict_SetItemString(d, "val", PyInt_FromLong(EXTDEMO));
}
"""
# Dang, this isn't as easy to override as we might wish extdemo_setup_py = """
original = want from distutils.core import setup, Extension
want, got = self._transform(want, got)
# temporarily hack example with normalized want: setup(name = "extdemo", version = "1.4", url="http://www.zope.org",
example.want = want author="Demo", author_email="demo@demo.com",
result = doctest.OutputChecker.output_difference( ext_modules = [Extension('extdemo', ['extdemo.c'])],
self, example, got, optionflags) )
example.want = original """
return result def add_source_dist(test):
import tarfile
tmp = tempfile.mkdtemp('test-sdist')
write = test.globs['write']
try:
write(tmp, 'extdemo.c', extdemo_c);
write(tmp, 'setup.py', extdemo_setup_py);
write(tmp, 'README', "");
write(tmp, 'MANIFEST.in', "include *.c\n");
test.globs['sdist'](tmp, test.globs['sample_eggs'])
except:
shutil.rmtree(tmp)
def easy_install_SetUp(test):
zc.buildout.testing.buildoutSetUp(test)
sample_eggs = test.globs['tmpdir']('sample_eggs')
test.globs['sample_eggs'] = sample_eggs
os.mkdir(os.path.join(sample_eggs, 'index'))
create_sample_eggs(test)
add_source_dist(test)
test.globs['link_server'] = test.globs['start_server'](
test.globs['sample_eggs'])
egg_parse = re.compile('([0-9a-zA-Z_.]+)-([0-9a-zA-Z_.]+)-py(\d[.]\d).egg$' egg_parse = re.compile('([0-9a-zA-Z_.]+)-([0-9a-zA-Z_.]+)-py(\d[.]\d).egg$'
).match ).match
...@@ -468,7 +504,8 @@ def makeNewRelease(project, ws, dest): ...@@ -468,7 +504,8 @@ def makeNewRelease(project, ws, dest):
def updateSetup(test): def updateSetup(test):
zc.buildout.testing.buildoutSetUp(test) zc.buildout.testing.buildoutSetUp(test)
test.globs['new_releases'] = new_releases = test.globs['mkdtemp']() new_releases = test.globs['tmpdir']('new_releases')
test.globs['new_releases'] = new_releases
sample_buildout = test.globs['sample_buildout'] sample_buildout = test.globs['sample_buildout']
eggs = os.path.join(sample_buildout, 'eggs') eggs = os.path.join(sample_buildout, 'eggs')
...@@ -509,29 +546,30 @@ def updateSetup(test): ...@@ -509,29 +546,30 @@ def updateSetup(test):
os.mkdir(os.path.join(new_releases, 'zc.buildout')) os.mkdir(os.path.join(new_releases, 'zc.buildout'))
os.mkdir(os.path.join(new_releases, 'setuptools')) os.mkdir(os.path.join(new_releases, 'setuptools'))
normalize_bang = (
re.compile(re.escape('#!'+sys.executable)),
'#!/usr/local/bin/python2.4',
)
def test_suite(): def test_suite():
import zc.buildout.testselectingpython
return unittest.TestSuite(( return unittest.TestSuite((
doctest.DocFileSuite( doctest.DocFileSuite(
'buildout.txt', 'runsetup.txt', 'buildout.txt', 'runsetup.txt',
setUp=zc.buildout.testing.buildoutSetUp, setUp=zc.buildout.testing.buildoutSetUp,
tearDown=zc.buildout.testing.buildoutTearDown, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
zc.buildout.testing.normalize_path,
zc.buildout.testing.normalize_script,
zc.buildout.testing.normalize_egg_py,
(re.compile('__buildout_signature__ = recipes-\S+'), (re.compile('__buildout_signature__ = recipes-\S+'),
'__buildout_signature__ = recipes-SSSSSSSSSSS'), '__buildout_signature__ = recipes-SSSSSSSSSSS'),
(re.compile('\S+sample-(\w+)%s(\S+)' % os_path_sep),
r'/sample-\1/\2'),
(re.compile('\S+sample-(\w+)'), r'/sample-\1'),
(re.compile('executable = \S+python\S*'), (re.compile('executable = \S+python\S*'),
'executable = python'), 'executable = python'),
(re.compile('setuptools-\S+[.]egg'), 'setuptools.egg'), (re.compile('setuptools-\S+[.]egg'), 'setuptools.egg'),
(re.compile('zc.buildout(-\S+)?[.]egg(-link)?'), (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
'zc.buildout.egg'), 'zc.buildout.egg'),
(re.compile('creating \S*setup.cfg'), 'creating setup.cfg'), (re.compile('creating \S*setup.cfg'), 'creating setup.cfg'),
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'),
'\\1- \\2\n'),
(re.compile("(\w)%s(\w)" % os_path_sep), r"\1/\2"),
(re.compile('hello-1[.]0-py\d[.]\d[.]egg'),
'hello-1.0-py2.4.egg')
]) ])
), ),
...@@ -540,10 +578,10 @@ def test_suite(): ...@@ -540,10 +578,10 @@ def test_suite():
setUp=updateSetup, setUp=updateSetup,
tearDown=zc.buildout.testing.buildoutTearDown, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
(re.compile('#!\S+python\S*'), '#!python'), zc.buildout.testing.normalize_path,
(re.compile('\S+sample-(\w+)'), r'/sample-\1'), zc.buildout.testing.normalize_script,
(re.compile('-py\d[.]\d.egg'), r'-py2.3.egg'), zc.buildout.testing.normalize_egg_py,
(re.compile(r'\\+'), '/'), normalize_bang,
]) ])
), ),
...@@ -552,43 +590,29 @@ def test_suite(): ...@@ -552,43 +590,29 @@ def test_suite():
setUp=easy_install_SetUp, setUp=easy_install_SetUp,
tearDown=zc.buildout.testing.buildoutTearDown, tearDown=zc.buildout.testing.buildoutTearDown,
checker=PythonNormalizing([ checker=renormalizing.RENormalizing([
(re.compile("'" zc.buildout.testing.normalize_path,
"(\w:)?" zc.buildout.testing.normalize_script,
"[%(sep)s/]\S+sample-install[%(sep)s/]" zc.buildout.testing.normalize_egg_py,
"[%(sep)s/]?(dist" normalize_bang,
"[%(sep)s/])?"
% dict(sep=os_path_sep)),
'/sample-eggs/'),
(re.compile("([d-] ((ext)?demo(needed)?|other)"
"-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"),
'\\1V.V.egg'),
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'),
'\\1- \\2\n'),
(re.compile('(\w+-\d[.]\d[.])zip'), '\\1tar.gz'),
(re.compile('#!\S+python\S+'), '#!python'),
]), ]),
), ),
doctest.DocTestSuite( doctest.DocTestSuite(
setUp=zc.buildout.testing.buildoutSetUp, setUp=zc.buildout.testing.buildoutSetUp,
tearDown=zc.buildout.testing.buildoutTearDown, tearDown=zc.buildout.testing.buildoutTearDown,
checker=PythonNormalizing([ checker=renormalizing.RENormalizing([
zc.buildout.testing.normalize_path,
zc.buildout.testing.normalize_script,
zc.buildout.testing.normalize_egg_py,
(re.compile("buildout: Running \S*setup.py"), (re.compile("buildout: Running \S*setup.py"),
'buildout: Running setup.py'), 'buildout: Running setup.py'),
(re.compile('py_zc'), 'py-zc'), # XXX get rid of after next rel (re.compile('py_zc'), 'py-zc'), # XXX get rid of after next rel
(re.compile('setuptools-\S+-py\d.\d.egg'), (re.compile('setuptools-\S+-'),
'setuptools.egg'), 'setuptools.egg'),
(re.compile('zc.buildout-\S+-py\d.\d.egg'), (re.compile('zc.buildout-\S+-'),
'zc.buildout.egg'), 'zc.buildout.egg'),
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'),
'\\1- \\2\n'),
(re.compile('\S+sample-(\w+)'), r'/sample-\1'),
(re.compile(r'\\+'), '/'),
]), ]),
) ),
zc.buildout.testselectingpython.test_suite(),
)) ))
if __name__ == '__main__':
unittest.main(defaultTest='test_suite')
##############################################################################
#
# Copyright (c) 2006 Zope Corporation and Contributors.
# All Rights Reserved.
#
# This software is subject to the provisions of the Zope Public License,
# Version 2.0 (ZPL). A copy of the ZPL should accompany this distribution.
# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
# FOR A PARTICULAR PURPOSE.
#
##############################################################################
import os, unittest
from zope.testing import doctest
import zc.buildout.tests
import zc.buildout.testing
def test_selecting_python_via_easy_install():
"""\
We can specify an alternate Python executable.
>>> dest = tmpdir('sample-install')
>>> ws = zc.buildout.easy_install.install(
... ['demo'], dest, links=[link_server], index=link_server+'index/',
... always_unzip=True, executable= python2_3_executable)
>>> ls(dest)
d demo-0.3-py2.3.egg
d demoneeded-1.1-py2.3.egg
>>> rmdir(dest)
>>> dest = tmpdir('sample-install')
>>> ws = zc.buildout.easy_install.install(
... ['demo'], dest, links=[link_server], index=link_server+'index/',
... always_unzip=True, executable=python2_4_executable)
>>> ls(dest)
d demo-0.3-py2.4.egg
d demoneeded-1.1-py2.4.egg
"""
# XXX need to think how this will work w future versions of python
def multi_python(test):
p23 = zc.buildout.testing.find_python('2.3')
p24 = zc.buildout.testing.find_python('2.4')
sample_eggs = test.globs['tmpdir']('sample_eggs')
os.mkdir(os.path.join(sample_eggs, 'index'))
test.globs['sample_eggs'] = sample_eggs
zc.buildout.tests.create_sample_eggs(test, executable=p23)
zc.buildout.tests.create_sample_eggs(test, executable=p24)
test.globs['python2_3_executable'] = p23
test.globs['python2_4_executable'] = p24
def setup(test):
zc.buildout.testing.buildoutSetUp(test)
multi_python(test)
zc.buildout.tests.add_source_dist(test)
test.globs['link_server'] = test.globs['start_server'](
test.globs['sample_eggs'])
def test_suite():
return doctest.DocTestSuite(setUp=setup,
tearDown=zc.buildout.testing.buildoutTearDown)
...@@ -8,9 +8,9 @@ new_releases folder: ...@@ -8,9 +8,9 @@ new_releases folder:
>>> ls(new_releases) >>> ls(new_releases)
d setuptools d setuptools
- setuptools-99.99-py2.3.egg - setuptools-99.99-py2.4.egg
d zc.buildout d zc.buildout
- zc.buildout-99.99-py2.3.egg - zc.buildout-99.99-py2.4.egg
Let's update the sample buildout.cfg to look in this area: Let's update the sample buildout.cfg to look in this area:
...@@ -80,12 +80,12 @@ new versions found in new releases: ...@@ -80,12 +80,12 @@ new versions found in new releases:
Our buildout script has been updated to use the new eggs: Our buildout script has been updated to use the new eggs:
>>> cat(sample_buildout, 'bin', 'buildout') >>> cat(sample_buildout, 'bin', 'buildout')
#!/usr/local/bin/python2.3 #!/usr/local/bin/python2.4
<BLANKLINE> <BLANKLINE>
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/tmpc4avO6sample-buildout/eggs/zc.buildout-99.99-py2.3.egg', '/sample-buildout/eggs/zc.buildout-99.99-py2.4.egg',
'/tmp/tmpc4avO6sample-buildout/eggs/setuptools-99.99-py2.3.egg', '/sample-buildout/eggs/setuptools-99.99-py2.4.egg',
] ]
<BLANKLINE> <BLANKLINE>
import zc.buildout.buildout import zc.buildout.buildout
......
...@@ -51,15 +51,16 @@ interpreter ...@@ -51,15 +51,16 @@ interpreter
extra-paths extra-paths
Extra paths to include in a generates script. Extra paths to include in a generates script.
We have a link server that has a number of eggs: We have a link server that has a number of distributions:
>>> print get(link_server), >>> print get(link_server),
<html><body> <html><body>
<a href="demo-0.1-py2.3.egg">demo-0.1-py2.3.egg</a><br> <a href="demo-0.1-py2.3.egg">demo-0.1-py2.3.egg</a><br>
<a href="demo-0.2-py2.3.egg">demo-0.2-py2.3.egg</a><br> <a href="demo-0.2-py2.3.egg">demo-0.2-py2.3.egg</a><br>
<a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br> <a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
<a href="demoneeded-1.0.tar.gz">demoneeded-1.0.tar.gz</a><br> <a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
<a href="demoneeded-1.1.tar.gz">demoneeded-1.1.tar.gz</a><br> <a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
<a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
<a href="index/">index/</a><br> <a href="index/">index/</a><br>
<a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br> <a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
</body></html> </body></html>
...@@ -198,7 +199,7 @@ Then we'll get a new demo egg: ...@@ -198,7 +199,7 @@ Then we'll get a new demo egg:
>>> ls(sample_buildout, 'eggs') >>> ls(sample_buildout, 'eggs')
- demo-0.2-py2.3.egg - demo-0.2-py2.3.egg
- demo-0.3-py2.3.egg - demo-0.3-py2.3.egg
- demoneeded-1.0-py2.3.egg - demoneeded-1.1-py2.3.egg
- setuptools-0.6-py2.4.egg - setuptools-0.6-py2.4.egg
- zc.buildout-1.0-py2.4.egg - zc.buildout-1.0-py2.4.egg
...@@ -287,12 +288,12 @@ extra-paths option: ...@@ -287,12 +288,12 @@ extra-paths option:
Let's look at the script that was generated: Let's look at the script that was generated:
>>> cat(sample_buildout, 'bin', 'foo') # doctest: +NORMALIZE_WHITESPACE >>> cat(sample_buildout, 'bin', 'foo') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3 #!/usr/local/bin/python2.4
<BLANKLINE> <BLANKLINE>
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg', '/sample-buildout/eggs/demo-0.3-py2.4.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg', '/sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
'/foo/bar', '/foo/bar',
'/spam/eggs', '/spam/eggs',
] ]
...@@ -335,12 +336,12 @@ declate entry points using the entry-points option: ...@@ -335,12 +336,12 @@ declate entry points using the entry-points option:
- other - other
>>> cat(sample_buildout, 'bin', 'other') >>> cat(sample_buildout, 'bin', 'other')
#!/usr/local/bin/python2.3 #!/usr/local/bin/python2.4
<BLANKLINE> <BLANKLINE>
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/private/tmp/tmp88gKbfsample-buildout/eggs/demo-0.3-py2.3.egg', '/sample-buildout/eggs/demo-0.3-py2.4.egg',
'/private/tmp/tmp88gKbfsample-buildout/eggs/demoneeded-1.1-py2.3.egg', '/sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
'/foo/bar', '/foo/bar',
'/spam/eggs', '/spam/eggs',
] ]
......
...@@ -19,8 +19,9 @@ We have a link server: ...@@ -19,8 +19,9 @@ We have a link server:
<a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br> <a href="demo-0.2-py2.4.egg">demo-0.2-py2.4.egg</a><br>
<a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br> <a href="demo-0.3-py2.3.egg">demo-0.3-py2.3.egg</a><br>
<a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br> <a href="demo-0.3-py2.4.egg">demo-0.3-py2.4.egg</a><br>
<a href="demoneeded-1.0.tar.gz">demoneeded-1.0.tar.gz</a><br> <a href="demoneeded-1.0.zip">demoneeded-1.0.zip</a><br>
<a href="demoneeded-1.1.tar.gz">demoneeded-1.1.tar.gz</a><br> <a href="demoneeded-1.1.zip">demoneeded-1.1.zip</a><br>
<a href="extdemo-1.4.zip">extdemo-1.4.zip</a><br>
<a href="index/">index/</a><br> <a href="index/">index/</a><br>
<a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br> <a href="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
<a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br> <a href="other-1.0-py2.4.egg">other-1.0-py2.4.egg</a><br>
...@@ -81,8 +82,8 @@ And the generated scripts invoke Python 2.3: ...@@ -81,8 +82,8 @@ And the generated scripts invoke Python 2.3:
<BLANKLINE> <BLANKLINE>
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demo-0.2-py2.3.egg', '/sample-buildout/eggs/demo-0.2-py2.3.egg',
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demoneeded-1.1-py2.3.egg', '/sample-buildout/eggs/demoneeded-1.1-py2.3.egg',
] ]
<BLANKLINE> <BLANKLINE>
import eggrecipedemo import eggrecipedemo
...@@ -100,8 +101,8 @@ And the generated scripts invoke Python 2.3: ...@@ -100,8 +101,8 @@ And the generated scripts invoke Python 2.3:
import sys import sys
<BLANKLINE> <BLANKLINE>
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/tmp5zS2Afsample-buildout/eggs/demo-0.2-py2.3.egg', '/sample-buildout/eggs/demo-0.2-py2.3.egg',
'/tmp/tmp5zS2Afsample-buildout/eggs/demoneeded-1.1-py2.3.egg', '/sample-buildout/eggs/demoneeded-1.1-py2.3.egg',
] ]
<BLANKLINE> <BLANKLINE>
_interactive = True _interactive = True
...@@ -172,8 +173,8 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs: ...@@ -172,8 +173,8 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs:
<BLANKLINE> <BLANKLINE>
import sys import sys
sys.path[0:0] = [ sys.path[0:0] = [
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demo-0.2-py2.4.egg', '/sample-buildout/eggs/demo-0.2-py2.4.egg',
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demoneeded-1.1-py2.4.egg', '/sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
] ]
<BLANKLINE> <BLANKLINE>
import eggrecipedemo import eggrecipedemo
...@@ -193,8 +194,8 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs: ...@@ -193,8 +194,8 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs:
import sys import sys
<BLANKLINE> <BLANKLINE>
sys.path[0:0] = [ sys.path[0:0] = [
'/tmp/tmp5zS2Afsample-buildout/eggs/demo-0.2-py2.4.egg', '/sample-buildout/eggs/demo-0.2-py2.4.egg',
'/tmp/tmp5zS2Afsample-buildout/eggs/demoneeded-1.1-py2.4.egg', '/sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
] ]
<BLANKLINE> <BLANKLINE>
_interactive = True _interactive = True
......
...@@ -13,6 +13,8 @@ ...@@ -13,6 +13,8 @@
############################################################################## ##############################################################################
import os, re, shutil, sys import os, re, shutil, sys
import zc.buildout.tests
import zc.buildout.testselectingpython
import zc.buildout.testing import zc.buildout.testing
import unittest import unittest
...@@ -28,53 +30,26 @@ def dirname(d, level=1): ...@@ -28,53 +30,26 @@ def dirname(d, level=1):
return dirname(os.path.dirname(d), level-1) return dirname(os.path.dirname(d), level-1)
def setUp(test): def setUp(test):
zc.buildout.testing.buildoutSetUp(test) zc.buildout.tests.easy_install_SetUp(test)
open(os.path.join(test.globs['sample_buildout'], zc.buildout.testing.install_develop('zc.recipe.egg', test)
'develop-eggs', 'zc.recipe.egg.egg-link'),
'w').write(dirname(__file__, 4))
zc.buildout.testing.create_sample_eggs(test)
zc.buildout.testing.setUpServer(test, zc.buildout.testing.make_tree(test))
def setUpPython(test):
zc.buildout.testing.buildoutSetUp(test)
open(os.path.join(test.globs['sample_buildout'],
'develop-eggs', 'zc.recipe.egg.egg-link'),
'w').write(dirname(__file__, 4))
zc.buildout.testing.multi_python(test)
zc.buildout.testing.setUpServer(test, zc.buildout.testing.make_tree(test))
def setUpCustom(test):
zc.buildout.testing.buildoutSetUp(test)
open(os.path.join(test.globs['sample_buildout'],
'develop-eggs', 'zc.recipe.egg.egg-link'),
'w').write(dirname(__file__, 4))
zc.buildout.testing.create_sample_eggs(test)
zc.buildout.testing.add_source_dist(test)
zc.buildout.testing.setUpServer(test, zc.buildout.testing.make_tree(test))
def setUpSelecting(test):
zc.buildout.testselectingpython.setup(test)
zc.buildout.testing.install_develop('zc.recipe.egg', test)
def test_suite(): def test_suite():
return unittest.TestSuite(( return unittest.TestSuite((
#doctest.DocTestSuite(),
doctest.DocFileSuite( doctest.DocFileSuite(
'README.txt', 'README.txt',
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown, setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
(re.compile('(\S+[/%(sep)s]| )' zc.buildout.testing.normalize_path,
'(\\w+-)[^ \t\n%(sep)s/]+.egg' zc.buildout.testing.normalize_script,
% dict(sep=os_path_sep) zc.buildout.testing.normalize_egg_py,
), zc.buildout.tests.normalize_bang,
'\\2-VVV-egg'),
(re.compile('-py\d[.]\d.egg'), '-py2.4.egg'),
(re.compile('zc.buildout(-\S+)?[.]egg(-link)?'), (re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
'zc.buildout.egg'), 'zc.buildout.egg'),
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'), (re.compile('setuptools-[^-]+-'), 'setuptools-X-')
'\\1- \\2\n'),
(re.compile('#![^\n]+python[^\n]*\n'), '#!python\n'),
(re.compile('(\w+-\d[.]\d[.])zip'), '\\1tar.gz'),
]) ])
), ),
doctest.DocFileSuite( doctest.DocFileSuite(
...@@ -106,22 +81,18 @@ def test_suite(): ...@@ -106,22 +81,18 @@ def test_suite():
), ),
doctest.DocFileSuite( doctest.DocFileSuite(
'selecting-python.txt', 'selecting-python.txt',
setUp=setUpPython, tearDown=zc.buildout.testing.buildoutTearDown, setUp=setUpSelecting,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
(re.compile('\S+sample-(\w+)[%(sep)s/](\S+)' zc.buildout.testing.normalize_path,
% dict(sep=os_path_sep)), zc.buildout.testing.normalize_script,
r'/sample-\1/\2'),
(re.compile('\S+sample-(\w+)'), r'/sample-\1'),
(re.compile('- ([a-zA-Z_0-9.]+)(-\S+)?[.]egg(-link)?'), (re.compile('- ([a-zA-Z_0-9.]+)(-\S+)?[.]egg(-link)?'),
'\\1.egg'), '\\1.egg'),
(re.compile(r'\\\\'), '/'),
(re.compile(r'/\\'), '/'),
(re.compile('(\w+-\d[.]\d[.])zip'), '\\1tar.gz'),
]), ]),
), ),
doctest.DocFileSuite( doctest.DocFileSuite(
'custom.txt', 'custom.txt',
setUp=setUpCustom, tearDown=zc.buildout.testing.buildoutTearDown, setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
(re.compile("(d ((ext)?demo(needed)?|other)" (re.compile("(d ((ext)?demo(needed)?|other)"
"-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"), "-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"),
......
...@@ -4,7 +4,7 @@ Test-Runner Recipe ...@@ -4,7 +4,7 @@ Test-Runner Recipe
The test-runner recipe, zc.recipe.testrunner, creates a test runner The test-runner recipe, zc.recipe.testrunner, creates a test runner
for a project. for a project.
The test-runner recipe has 2 options: The test-runner recipe has 3 options:
eggs eggs
The eggs option specified a list of eggs to test given as one ore The eggs option specified a list of eggs to test given as one ore
...@@ -207,5 +207,5 @@ extra-paths option to specify them: ...@@ -207,5 +207,5 @@ extra-paths option to specify them:
<BLANKLINE> <BLANKLINE>
if __name__ == '__main__': if __name__ == '__main__':
zope.testing.testrunner.run([ zope.testing.testrunner.run([
'--test-path', '/private/tmp/tmppoToJzsample-buildout/demo', '--test-path', '/sample-buildout/demo',
]) ])
...@@ -28,37 +28,23 @@ def dirname(d, level=1): ...@@ -28,37 +28,23 @@ def dirname(d, level=1):
def setUp(test): def setUp(test):
zc.buildout.testing.buildoutSetUp(test) zc.buildout.testing.buildoutSetUp(test)
eggs = os.path.join(test.globs['sample_buildout'], 'eggs') zc.buildout.testing.install_develop('zc.recipe.testrunner', test)
open(os.path.join(eggs, 'zc.recipe.testrunner.egg-link'), zc.buildout.testing.install_develop('zc.recipe.egg', test)
'w').write(dirname(__file__, 4)) zc.buildout.testing.install('zope.testing', test)
open(os.path.join(eggs, 'zc.recipe.egg.egg-link'),
'w').write(dirname(zc.recipe.egg.__file__, 4))
testing = dirname(zope.testing.__file__, 3)
assert testing.endswith('.egg')
if os.path.isfile(testing):
shutil.copy(testing, eggs)
else:
shutil.copytree(testing, os.path.join(eggs, os.path.basename(testing)))
def tearDown(test):
zc.buildout.testing.buildoutTearDown(test)
def test_suite(): def test_suite():
return unittest.TestSuite(( return unittest.TestSuite((
#doctest.DocTestSuite(), #doctest.DocTestSuite(),
doctest.DocFileSuite( doctest.DocFileSuite(
'README.txt', 'README.txt',
setUp=setUp, tearDown=tearDown, setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([ checker=renormalizing.RENormalizing([
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'), zc.buildout.testing.normalize_path,
'\\1- \\2\n'), zc.buildout.testing.normalize_script,
zc.buildout.testing.normalize_egg_py,
(re.compile('#!\S+python\S*'), '#!python'), (re.compile('#!\S+python\S*'), '#!python'),
(re.compile('\S+sample-(\w+)'), r'/sample-\1'), (re.compile('\d[.]\d+ seconds'), '0.001 seconds'),
(re.compile('-([^-]+)-py\d[.]\d.egg'), r'-py2.3.egg'), (re.compile('zope.testing-[^-]+-'), 'zope.testing-X-'),
(re.compile(r'\\+'), '/'),
(re.compile('\d[.]\d+ seconds'), '0.001 seconds')
]) ])
), ),
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment