Commit 412c9227 authored by Jim Fulton's avatar Jim Fulton

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

API. This allowed the tests to be simplified somewhat.
parent e87c4bdf
......@@ -262,7 +262,7 @@ buildout:
>>> os.chdir(sample_buildout)
>>> buildout = os.path.join(sample_buildout, 'bin', 'buildout')
>>> print system(buildout),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Installing data-dir
data-dir: Creating directory mystuff
......@@ -286,9 +286,9 @@ about the part we installed:
parts = data-dir
<BLANKLINE>
[data-dir]
__buildout_installed__ = /tmp/sample-buildout/mystuff
__buildout_installed__ = /sample-buildout/mystuff
__buildout_signature__ = recipes-c7vHV6ekIDUPy/7fjAaYjg==
path = /tmp/sample-buildout/mystuff
path = /sample-buildout/mystuff
recipe = recipes:mkdir
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:
... """)
>>> print system(buildout),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling data-dir
buildout: Installing data-dir
data-dir: Creating directory mydata
......@@ -352,7 +352,7 @@ the directory in:
We'll get a user error, not a traceback.
>>> 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.
Error: Invalid Path
......@@ -467,7 +467,7 @@ Now, if we run the buildout, we'll see the options with the values
substituted.
>>> print system(buildout),
buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Develop: /sample-buildout/recipes/setup.py
buildout: Uninstalling data-dir
buildout: Installing data-dir
data-dir: Creating directory mydata
......@@ -486,7 +486,7 @@ recipe, so it assumed it could and reinstalled mydata. If we rerun
the 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 debug
File 1 mydata/file
......@@ -561,7 +561,7 @@ customization.
Here is a more elaborate example.
>>> extensions = mkdtemp()
>>> extensions = tmpdir('extensions')
>>> write(sample_buildout, 'buildout.cfg',
... """
......@@ -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
delimiter.)
>>> home = mkdtemp()
>>> home = tmpdir('home')
>>> mkdir(home, '.buildout')
>>> write(home, '.buildout', 'default.cfg',
... """
......@@ -784,7 +784,7 @@ Note that we used the installed buildout option to specify an
alternate file to store information about installed parts.
>>> 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
name other
op1 foo
......@@ -797,7 +797,7 @@ WARNING.
Options can also be combined in the usual Unix way, as in:
>>> 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
name other
op1 foo
......@@ -876,21 +876,21 @@ the buildout in the usual way:
recipe = recipes:debug
<BLANKLINE>
[d1]
__buildout_installed__ = /tmp/sample-buildout/d1
__buildout_installed__ = /sample-buildout/d1
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d1
path = /sample-buildout/d1
recipe = recipes:mkdir
<BLANKLINE>
[d2]
__buildout_installed__ = /tmp/sample-buildout/d2
__buildout_installed__ = /sample-buildout/d2
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d2
path = /sample-buildout/d2
recipe = recipes:mkdir
<BLANKLINE>
[d3]
__buildout_installed__ = /tmp/sample-buildout/d3
__buildout_installed__ = /sample-buildout/d3
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d3
path = /sample-buildout/d3
recipe = recipes:mkdir
Now we'll update our configuration file:
......@@ -960,27 +960,27 @@ The .installed.cfg is only updated for the recipes that ran:
recipe = recipes:debug
<BLANKLINE>
[d2]
__buildout_installed__ = /tmp/sample-buildout/d2
__buildout_installed__ = /sample-buildout/d2
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d2
path = /sample-buildout/d2
recipe = recipes:mkdir
<BLANKLINE>
[d3]
__buildout_installed__ = /tmp/sample-buildout/data3
__buildout_installed__ = /sample-buildout/data3
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/data3
path = /sample-buildout/data3
recipe = recipes:mkdir
<BLANKLINE>
[d4]
__buildout_installed__ = /tmp/sample-buildout/data4
__buildout_installed__ = /sample-buildout/data4
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/data4
path = /sample-buildout/data4
recipe = recipes:mkdir
<BLANKLINE>
[d1]
__buildout_installed__ = /tmp/sample-buildout/d1
__buildout_installed__ = /sample-buildout/d1
__buildout_signature__ = recipes-PiIFiO8ny5yNZ1S3JfT0xg==
path = /tmp/sample-buildout/d1
path = /sample-buildout/d1
recipe = recipes:mkdir
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
directory in the directory containing the configuration file. You can
provide alternate locations, and even names for these directories.
>>> alt = mkdtemp('sample-alt')
>>> alt = tmpdir('sample-alt')
>>> write(sample_buildout, 'buildout.cfg',
... """
......@@ -1047,11 +1047,11 @@ provide alternate locations, and even names for these directories.
... ))
>>> print system(buildout),
buildout: Creating directory /tmp/sample-alt/scripts
buildout: Creating directory /tmp/sample-alt/work
buildout: Creating directory /tmp/sample-alt/basket
buildout: Creating directory /sample-alt/scripts
buildout: Creating directory /sample-alt/work
buildout: Creating directory /sample-alt/basket
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 d3
buildout: Uninstalling d2
......@@ -1068,7 +1068,8 @@ provide alternate locations, and even names for these directories.
You can also specify an alternate buildout directory:
>>> alt = mkdtemp('sample-alt')
>>> rmdir(alt)
>>> alt = tmpdir('sample-alt')
>>> write(sample_buildout, 'buildout.cfg',
... """
......@@ -1082,11 +1083,11 @@ You can also specify an alternate buildout directory:
... ))
>>> print system(buildout),
buildout: Creating directory /tmp/sample-alt/bin
buildout: Creating directory /tmp/sample-alt/parts
buildout: Creating directory /tmp/sample-alt/eggs
buildout: Creating directory /tmp/sample-alt/develop-eggs
buildout: Develop: /tmp/sample-buildout/recipes/setup.py
buildout: Creating directory /sample-alt/bin
buildout: Creating directory /sample-alt/parts
buildout: Creating directory /sample-alt/eggs
buildout: Creating directory /sample-alt/develop-eggs
buildout: Develop: /sample-buildout/recipes/setup.py
>>> ls(alt)
- .installed.cfg
......@@ -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.
>>> print system(buildout),
INFO Develop: /tmp/sample-buildout/recipes/setup.py
INFO Develop: /sample-buildout/recipes/setup.py
Predefined buildout options
---------------------------
......@@ -1155,16 +1156,16 @@ database is shown.
>>> print system(buildout+' -v'),
Configuration data:
[buildout]
bin-directory = /tmp/sample-buildout/bin
develop-eggs-directory = /tmp/sample-buildout/develop-eggs
directory = /tmp/sample-buildout
eggs-directory = /tmp/sample-buildout/eggs
bin-directory = /sample-buildout/bin
develop-eggs-directory = /sample-buildout/develop-eggs
directory = /sample-buildout
eggs-directory = /sample-buildout/eggs
executable = /usr/local/bin/python2.3
installed = /tmp/sample-buildout/.installed.cfg
installed = /sample-buildout/.installed.cfg
log-format = %%(name)s: %%(message)s
log-level = INFO
parts =
parts-directory = /tmp/sample-buildout/parts
parts-directory = /sample-buildout/parts
python = buildout
verbosity = 10
<BLANKLINE>
......@@ -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
local buildout scripts.
>>> sample_bootstrapped = mkdtemp('sample-bootstrapped')
>>> sample_bootstrapped = tmpdir('sample-bootstrapped')
>>> print system(buildout
... +' -c'+os.path.join(sample_bootstrapped, 'setup.cfg')
......@@ -1342,5 +1343,5 @@ We see that out extension is loaded and executed:
>>> print system(os.path.join(sample_bootstrapped, 'bin', '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,
exit_code = os.spawnle(os.P_WAIT, executable, executable, *args)
assert exit_code == 0
# We may overwrite distributions, so clear importer
# cache.
sys.path_importer_cache.clear()
def _get_dist(requirement, env, ws,
dest, links, index, executable, always_unzip):
......@@ -236,15 +231,17 @@ def _get_dist(requirement, env, ws,
"Couln't download a distribution for %s."
% requirement)
should_unzip = False
if always_unzip:
metadata = pkg_resources.EggMetadata(
zipimport.zipimporter(dist.location)
)
if (always_unzip
or
should_unzip = not (
metadata.has_metadata('not-zip-safe')
or
not metadata.has_metadata('zip-safe')
):
)
if should_unzip:
setuptools.archive_util.unpack_archive(
dist.location,
os.path.join(dest, os.path.basename(dist.location)
......@@ -274,8 +271,14 @@ def _get_dist(requirement, env, ws,
finally:
shutil.rmtree(tmp)
# Because we have added a new egg, we need to rescan
# the destination directory.
# We may overwrite distributions, so clear importer
# cache.
sys.path_importer_cache.clear()
env.scan([dest])
dist = env.best_match(requirement, ws)
logger.info("Got %s", dist)
......
......@@ -69,23 +69,19 @@ We have a link server that has a number of eggs:
>>> print get(link_server),
<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.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.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="demoneeded-1.0.tar.gz">demoneeded-1.0.tar.gz</a><br>
<a href="demoneeded-1.1.tar.gz">demoneeded-1.1.tar.gz</a><br>
<a href="extdemo-1.4.tar.gz">extdemo-1.4.tar.gz</a><br>
<a href="demoneeded-1.0.zip">demoneeded-1.0.zip</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="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>
</body></html>
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
>>> ws = zc.buildout.easy_install.install(
... ['demo==0.2'], dest,
......@@ -106,8 +102,8 @@ The working set contains the distributions we retrieved.
And the actual eggs were added to the eggs directory.
>>> ls(dest)
- demo-0.2-py2.3.egg
- demoneeded-1.1-py2.3.egg
- demo-0.2-py2.4.egg
- demoneeded-1.1-py2.4.egg
If we ask for the demo distribution without a version restriction,
we'll get the newer version:
......@@ -115,9 +111,9 @@ we'll get the newer version:
>>> ws = zc.buildout.easy_install.install(
... ['demo'], dest, links=[link_server], index=link_server+'index/')
>>> ls(dest)
- demo-0.2-py2.3.egg
- demo-0.3-py2.3.egg
- demoneeded-1.1-py2.3.egg
- demo-0.2-py2.4.egg
- demo-0.3-py2.4.egg
- demoneeded-1.1-py2.4.egg
We can supply additional distributions. We can also supply
specifications for distributions that would normally be found via
......@@ -134,28 +130,31 @@ dependencies. We might do this to specify a sprcific version.
demoneeded 1.0
>>> ls(dest)
- demo-0.2-py2.3.egg
- demo-0.3-py2.3.egg
- demoneeded-1.0-py2.3.egg
- demoneeded-1.1-py2.3.egg
- other-1.0-py2.3.egg
- demo-0.2-py2.4.egg
- demo-0.3-py2.4.egg
- demoneeded-1.0-py2.4.egg
- demoneeded-1.1-py2.4.egg
- other-1.0-py2.4.egg
We can specify an alternate Python executable, and we can specify
that, when we retrieve (or create) an egg, it should be unzipped.
We can request that eggs be unzipped even if they are zip safe. This
can be useful when debugging.
>>> dest = mkdtemp('sample-install')
>>> 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_3_executable)
... always_unzip=True)
>>> ls(dest)
d demo-0.3-py2.3.egg
d demoneeded-1.1-py2.3.egg
d demo-0.3-py2.4.egg
d demoneeded-1.1-py2.4.egg
>>> dest = mkdtemp('sample-install')
>>> 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)
... always_unzip=True)
>>> ls(dest)
d demo-0.3-py2.4.egg
......@@ -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:
>>> import tempfile
>>> bin = mkdtemp()
>>> bin = tmpdir('bin')
Now, we'll use the scripts method to generate scripts in this directory
from the demo egg:
>>> import sys
>>> scripts = zc.buildout.easy_install.scripts(
... ['demo'], ws, python2_4_executable, bin)
... ['demo'], ws, sys.executable, bin)
the four arguments we passed were:
......@@ -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:
>>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg',
'/sample-install/demo-0.3-py2.4.egg',
'/sample-install/demoneeded-1.1-py2.4.egg',
]
<BLANKLINE>
import eggrecipedemo
......@@ -257,15 +257,15 @@ rather than passing a requirement:
>>> scripts = zc.buildout.easy_install.scripts(
... [('demo', 'eggrecipedemo', 'main')],
... ws, python2_4_executable, bin)
... ws, sys.executable, bin)
>>> cat(bin, 'demo') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg',
'/sample-install/demo-0.3-py2.4.egg',
'/sample-install/demoneeded-1.1-py2.4.egg',
]
<BLANKLINE>
import eggrecipedemo
......@@ -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:
>>> scripts = zc.buildout.easy_install.scripts(
... ['demo'], ws, python2_4_executable, bin, interpreter='py')
... ['demo'], ws, sys.executable, bin, interpreter='py')
>>> ls(bin)
......@@ -308,8 +308,8 @@ the path set:
import sys
<BLANKLINE>
sys.path[0:0] = [
'/tmp/tmp5zS2Afsample-install/demo-0.3-py2.4.egg',
'/tmp/tmp5zS2Afsample-install/demoneeded-1.1-py2.4.egg',
'/sample-install/demo-0.3-py2.4.egg',
'/sample-install/demoneeded-1.1-py2.4.egg',
]
<BLANKLINE>
_interactive = True
......@@ -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
original script names to new script names.
>>> bin = mkdtemp()
>>> bin = tmpdir('bin2')
>>> 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':
... scripts == [os.path.join(bin, 'run.exe'),
......@@ -360,16 +360,16 @@ We can pass a keyword argument, extra paths, to caue additional paths
to be included in the a generated script:
>>> 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'])
>>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg',
'/sample-install/demo-0.3-py2.4.egg',
'/sample-install/demoneeded-1.1-py2.4.egg',
'/foo/bar',
]
<BLANKLINE>
......@@ -386,15 +386,15 @@ entry point. The value passed source string to be placed between the
parentheses in the call:
>>> 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')
>>> cat(bin, 'run') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3
#!/usr/local/bin/python2.4
import sys
sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg',
'/sample-install/demo-0.3-py2.4.egg',
'/sample-install/demoneeded-1.1-py2.4.egg',
]
<BLANKLINE>
import eggrecipedemo
......@@ -492,5 +492,5 @@ Now if we look in our destination directory, we see we have an extdemo egg:
>>> ls(dest)
d demo-0.3-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
This diff is collapsed.
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.
This diff is collapsed.
##############################################################################
#
# 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:
>>> ls(new_releases)
d setuptools
- setuptools-99.99-py2.3.egg
- setuptools-99.99-py2.4.egg
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:
......@@ -80,12 +80,12 @@ new versions found in new releases:
Our buildout script has been updated to use the new eggs:
>>> cat(sample_buildout, 'bin', 'buildout')
#!/usr/local/bin/python2.3
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
'/tmp/tmpc4avO6sample-buildout/eggs/zc.buildout-99.99-py2.3.egg',
'/tmp/tmpc4avO6sample-buildout/eggs/setuptools-99.99-py2.3.egg',
'/sample-buildout/eggs/zc.buildout-99.99-py2.4.egg',
'/sample-buildout/eggs/setuptools-99.99-py2.4.egg',
]
<BLANKLINE>
import zc.buildout.buildout
......
......@@ -51,15 +51,16 @@ interpreter
extra-paths
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),
<html><body>
<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.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.1.tar.gz">demoneeded-1.1.tar.gz</a><br>
<a href="demoneeded-1.0.zip">demoneeded-1.0.zip</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="other-1.0-py2.3.egg">other-1.0-py2.3.egg</a><br>
</body></html>
......@@ -198,7 +199,7 @@ Then we'll get a new demo egg:
>>> ls(sample_buildout, 'eggs')
- demo-0.2-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
- zc.buildout-1.0-py2.4.egg
......@@ -287,12 +288,12 @@ extra-paths option:
Let's look at the script that was generated:
>>> cat(sample_buildout, 'bin', 'foo') # doctest: +NORMALIZE_WHITESPACE
#!/usr/local/bin/python2.3
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
'/tmp/xyzsample-install/demo-0.3-py2.3.egg',
'/tmp/xyzsample-install/demoneeded-1.1-py2.3.egg',
'/sample-buildout/eggs/demo-0.3-py2.4.egg',
'/sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
'/foo/bar',
'/spam/eggs',
]
......@@ -335,12 +336,12 @@ declate entry points using the entry-points option:
- other
>>> cat(sample_buildout, 'bin', 'other')
#!/usr/local/bin/python2.3
#!/usr/local/bin/python2.4
<BLANKLINE>
import sys
sys.path[0:0] = [
'/private/tmp/tmp88gKbfsample-buildout/eggs/demo-0.3-py2.3.egg',
'/private/tmp/tmp88gKbfsample-buildout/eggs/demoneeded-1.1-py2.3.egg',
'/sample-buildout/eggs/demo-0.3-py2.4.egg',
'/sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
'/foo/bar',
'/spam/eggs',
]
......
......@@ -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.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="demoneeded-1.0.tar.gz">demoneeded-1.0.tar.gz</a><br>
<a href="demoneeded-1.1.tar.gz">demoneeded-1.1.tar.gz</a><br>
<a href="demoneeded-1.0.zip">demoneeded-1.0.zip</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="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>
......@@ -81,8 +82,8 @@ And the generated scripts invoke Python 2.3:
<BLANKLINE>
import sys
sys.path[0:0] = [
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demo-0.2-py2.3.egg',
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demoneeded-1.1-py2.3.egg',
'/sample-buildout/eggs/demo-0.2-py2.3.egg',
'/sample-buildout/eggs/demoneeded-1.1-py2.3.egg',
]
<BLANKLINE>
import eggrecipedemo
......@@ -100,8 +101,8 @@ And the generated scripts invoke Python 2.3:
import sys
<BLANKLINE>
sys.path[0:0] = [
'/tmp/tmp5zS2Afsample-buildout/eggs/demo-0.2-py2.3.egg',
'/tmp/tmp5zS2Afsample-buildout/eggs/demoneeded-1.1-py2.3.egg',
'/sample-buildout/eggs/demo-0.2-py2.3.egg',
'/sample-buildout/eggs/demoneeded-1.1-py2.3.egg',
]
<BLANKLINE>
_interactive = True
......@@ -172,8 +173,8 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs:
<BLANKLINE>
import sys
sys.path[0:0] = [
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demo-0.2-py2.4.egg',
'/private/tmp/tmpOEtRO8sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
'/sample-buildout/eggs/demo-0.2-py2.4.egg',
'/sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
]
<BLANKLINE>
import eggrecipedemo
......@@ -193,8 +194,8 @@ If we change the Python version to 2.4, we'll use Python 2.4 eggs:
import sys
<BLANKLINE>
sys.path[0:0] = [
'/tmp/tmp5zS2Afsample-buildout/eggs/demo-0.2-py2.4.egg',
'/tmp/tmp5zS2Afsample-buildout/eggs/demoneeded-1.1-py2.4.egg',
'/sample-buildout/eggs/demo-0.2-py2.4.egg',
'/sample-buildout/eggs/demoneeded-1.1-py2.4.egg',
]
<BLANKLINE>
_interactive = True
......
......@@ -13,6 +13,8 @@
##############################################################################
import os, re, shutil, sys
import zc.buildout.tests
import zc.buildout.testselectingpython
import zc.buildout.testing
import unittest
......@@ -28,53 +30,26 @@ def dirname(d, level=1):
return dirname(os.path.dirname(d), level-1)
def setUp(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.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))
zc.buildout.tests.easy_install_SetUp(test)
zc.buildout.testing.install_develop('zc.recipe.egg', test)
def setUpSelecting(test):
zc.buildout.testselectingpython.setup(test)
zc.buildout.testing.install_develop('zc.recipe.egg', test)
def test_suite():
return unittest.TestSuite((
#doctest.DocTestSuite(),
doctest.DocFileSuite(
'README.txt',
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
(re.compile('(\S+[/%(sep)s]| )'
'(\\w+-)[^ \t\n%(sep)s/]+.egg'
% dict(sep=os_path_sep)
),
'\\2-VVV-egg'),
(re.compile('-py\d[.]\d.egg'), '-py2.4.egg'),
zc.buildout.testing.normalize_path,
zc.buildout.testing.normalize_script,
zc.buildout.testing.normalize_egg_py,
zc.buildout.tests.normalize_bang,
(re.compile('zc.buildout(-\S+)?[.]egg(-link)?'),
'zc.buildout.egg'),
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'),
'\\1- \\2\n'),
(re.compile('#![^\n]+python[^\n]*\n'), '#!python\n'),
(re.compile('(\w+-\d[.]\d[.])zip'), '\\1tar.gz'),
(re.compile('setuptools-[^-]+-'), 'setuptools-X-')
])
),
doctest.DocFileSuite(
......@@ -106,22 +81,18 @@ def test_suite():
),
doctest.DocFileSuite(
'selecting-python.txt',
setUp=setUpPython, tearDown=zc.buildout.testing.buildoutTearDown,
setUp=setUpSelecting,
tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
(re.compile('\S+sample-(\w+)[%(sep)s/](\S+)'
% dict(sep=os_path_sep)),
r'/sample-\1/\2'),
(re.compile('\S+sample-(\w+)'), r'/sample-\1'),
zc.buildout.testing.normalize_path,
zc.buildout.testing.normalize_script,
(re.compile('- ([a-zA-Z_0-9.]+)(-\S+)?[.]egg(-link)?'),
'\\1.egg'),
(re.compile(r'\\\\'), '/'),
(re.compile(r'/\\'), '/'),
(re.compile('(\w+-\d[.]\d[.])zip'), '\\1tar.gz'),
]),
),
doctest.DocFileSuite(
'custom.txt',
setUp=setUpCustom, tearDown=zc.buildout.testing.buildoutTearDown,
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
(re.compile("(d ((ext)?demo(needed)?|other)"
"-\d[.]\d-py)\d[.]\d(-\S+)?[.]egg"),
......
......@@ -4,7 +4,7 @@ Test-Runner Recipe
The test-runner recipe, zc.recipe.testrunner, creates a test runner
for a project.
The test-runner recipe has 2 options:
The test-runner recipe has 3 options:
eggs
The eggs option specified a list of eggs to test given as one ore
......@@ -207,5 +207,5 @@ extra-paths option to specify them:
<BLANKLINE>
if __name__ == '__main__':
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):
def setUp(test):
zc.buildout.testing.buildoutSetUp(test)
eggs = os.path.join(test.globs['sample_buildout'], 'eggs')
open(os.path.join(eggs, 'zc.recipe.testrunner.egg-link'),
'w').write(dirname(__file__, 4))
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)
zc.buildout.testing.install_develop('zc.recipe.testrunner', test)
zc.buildout.testing.install_develop('zc.recipe.egg', test)
zc.buildout.testing.install('zope.testing', test)
def test_suite():
return unittest.TestSuite((
#doctest.DocTestSuite(),
doctest.DocFileSuite(
'README.txt',
setUp=setUp, tearDown=tearDown,
setUp=setUp, tearDown=zc.buildout.testing.buildoutTearDown,
checker=renormalizing.RENormalizing([
(re.compile('(\n?)- ([a-zA-Z_.-]+)-script.py\n- \\2.exe\n'),
'\\1- \\2\n'),
zc.buildout.testing.normalize_path,
zc.buildout.testing.normalize_script,
zc.buildout.testing.normalize_egg_py,
(re.compile('#!\S+python\S*'), '#!python'),
(re.compile('\S+sample-(\w+)'), r'/sample-\1'),
(re.compile('-([^-]+)-py\d[.]\d.egg'), r'-py2.3.egg'),
(re.compile(r'\\+'), '/'),
(re.compile('\d[.]\d+ seconds'), '0.001 seconds')
(re.compile('\d[.]\d+ seconds'), '0.001 seconds'),
(re.compile('zope.testing-[^-]+-'), 'zope.testing-X-'),
])
),
......
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