Commit 244608ce authored by Michael Howitz's avatar Michael Howitz

``zc.buildout.testing.buildoutSetUp`` installs a new handler in the python...

``zc.buildout.testing.buildoutSetUp`` installs a new handler in the python root logging facility. This handler is now removed during tear down as it might disturb other packages reusing buildout's testing infrastructure.

parent 55c8f93b
......@@ -5,9 +5,16 @@ Change History
==================
- Better Windows compatibility in test infrastructure.
- Now the bootstrap.py has an optional --version argument,
that can be used to force zc.buildout version to use.
- ``zc.buildout.testing.buildoutSetUp`` installs a new handler in the
python root logging facility. This handler is now removed during
tear down as it might disturb other packages reusing buildout's
testing infrastructure.
1.2.1 (2009-03-18)
==================
......
......@@ -18,6 +18,7 @@ $Id$
import BaseHTTPServer
import errno
import logging
import os
import pkg_resources
import random
......@@ -210,6 +211,14 @@ def buildoutSetUp(test):
here = os.getcwd()
register_teardown(lambda: os.chdir(here))
handlers_before_set_up = logging.getLogger().handlers[:]
def restore_root_logger_handlers():
root_logger = logging.getLogger()
for handler in root_logger.handlers[:]:
root_logger.removeHandler(handler)
for handler in handlers_before_set_up:
root_logger.addHandler(handler)
register_teardown(restore_root_logger_handlers)
base = tempfile.mkdtemp('buildoutSetUp')
base = os.path.realpath(base)
......
Bug fixes in zc.buildout.testing
================================
Logging handler which did not get deleted
-----------------------------------------
The buildout testing set up runs a buildout which adds a
``logging.StreamHandler`` to the root logger. But tear down did not
remove it. This can disturb other tests of packages reusing
zc.buildout.testing.
The handers before calling set up are:
>>> import logging
>>> len(logging.getLogger().handlers)
1
>>> logging.getLogger().handlers # doctest: +ELLIPSIS
[<zope.testing.testrunner.logsupport.NullHandler instance at ...>]
After calling it, a ``logging.StreamHandler`` was added:
>>> import zc.buildout.testing
>>> import doctest
>>> test = doctest.DocTestParser().get_doctest(
... '>>> x', {}, 'foo', 'foo.py', 0)
>>> zc.buildout.testing.buildoutSetUp(test)
>>> len(logging.getLogger().handlers)
2
>>> logging.getLogger().handlers # doctest: +ELLIPSIS +NORMALIZE_WHITESPACE
[<zope.testing.testrunner.logsupport.NullHandler instance at ...>,
<logging.StreamHandler instance at ...>]
But tear down removes the new logging handler:
>>> zc.buildout.testing.buildoutTearDown(test)
>>> len(logging.getLogger().handlers)
1
>>> logging.getLogger().handlers # doctest: +ELLIPSIS
[<zope.testing.testrunner.logsupport.NullHandler instance at ...>]
......@@ -43,7 +43,7 @@ We should be able to deal with setup scripts that aren't setuptools based.
... '''
... [buildout]
... develop = foo
... parts =
... parts =
... ''')
>>> print system(join('bin', 'buildout')),
......@@ -70,7 +70,7 @@ We should be able to deal with setup scripts that aren't setuptools based.
... '''
... [buildout]
... develop = foo
... parts =
... parts =
... ''')
>>> print system(join('bin', 'buildout')+' -vv'), # doctest: +ELLIPSIS
......@@ -265,9 +265,9 @@ def show_who_requires_when_there_is_a_conflict():
requirements.
>>> make_dist_that_requires(sample_buildout, 'sampley',
... ['demoneeded ==1.0'])
... ['demoneeded ==1.0'])
>>> make_dist_that_requires(sample_buildout, 'samplez',
... ['demoneeded ==1.1'])
... ['demoneeded ==1.1'])
Now, let's create a buildout that requires y and z:
......@@ -299,7 +299,7 @@ def show_who_requires_when_there_is_a_conflict():
Here, we see that sampley required an older version of demoneeded.
What if we hadn't required sampley ourselves:
>>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
>>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
>>> make_dist_that_requires(sample_buildout, 'sampleb',
... ['sampley', 'samplea'])
>>> write('buildout.cfg',
......@@ -354,8 +354,8 @@ def show_who_requires_missing_distributions():
Fortunately, buildout will tell us who's asking for something that
we can't find.
>>> make_dist_that_requires(sample_buildout, 'sampley', ['demoneeded'])
>>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
>>> make_dist_that_requires(sample_buildout, 'sampley', ['demoneeded'])
>>> make_dist_that_requires(sample_buildout, 'samplea', ['sampleb'])
>>> make_dist_that_requires(sample_buildout, 'sampleb',
... ['sampley', 'samplea'])
>>> write('buildout.cfg',
......@@ -381,15 +381,15 @@ def show_who_requires_missing_distributions():
Getting distribution for 'demoneeded'.
Error: Couldn't find a distribution for 'demoneeded'.
"""
def test_comparing_saved_options_with_funny_characters():
"""
If an option has newlines, extra/odd spaces or a %, we need to make
sure the comparison with the saved value works correctly.
>>> mkdir(sample_buildout, 'recipes')
>>> write(sample_buildout, 'recipes', 'debug.py',
>>> write(sample_buildout, 'recipes', 'debug.py',
... '''
... class Debug:
... def __init__(self, buildout, name, options):
......@@ -399,7 +399,7 @@ def test_comparing_saved_options_with_funny_characters():
... path foo
... </filestorage>
...
... </zodb>
... </zodb>
... \"\"\"
... options['debug1'] = \"\"\"
... <zodb>
......@@ -408,7 +408,7 @@ def test_comparing_saved_options_with_funny_characters():
... path foo
... </filestorage>
...
... </zodb>
... </zodb>
... \"\"\"
... options['debug2'] = ' x '
... options['debug3'] = '42'
......@@ -468,7 +468,7 @@ a local directory that may contained unzipped eggs.
... '''
... from setuptools import setup
... setup(name='demo', py_modules=[''],
... zip_safe=False, version='1.0', author='bob', url='bob',
... zip_safe=False, version='1.0', author='bob', url='bob',
... author_email='bob')
... ''')
......@@ -480,7 +480,7 @@ Install it so it gets unzipped:
>>> d1 = tmpdir('d1')
>>> ws = zc.buildout.easy_install.install(
... ['demo'], d1, links=[join(src, 'dist')],
... ['demo'], d1, links=[join(src, 'dist')],
... )
>>> ls(d1)
......@@ -490,7 +490,7 @@ Then try to install it again:
>>> d2 = tmpdir('d2')
>>> ws = zc.buildout.easy_install.install(
... ['demo'], d2, links=[d1],
... ['demo'], d2, links=[d1],
... )
>>> ls(d2)
......@@ -524,7 +524,7 @@ We'll start by creating a faux 'python' that executable that prints a
... '''
... [buildout]
... develop = demo
... parts =
... parts =
... ''')
>>> print system(join('bin', 'buildout')),
......@@ -562,7 +562,7 @@ def create_sections_on_command_line():
[foo]
bar = 1
...
"""
def test_help():
......@@ -594,12 +594,12 @@ sure it is fixed. Basically, we don't load extensions when
bootstrapping.
>>> d = tmpdir('sample-bootstrap')
>>> write(d, 'buildout.cfg',
... '''
... [buildout]
... extensions = some_awsome_extension
... parts =
... parts =
... ''')
>>> os.chdir(d)
......@@ -616,7 +616,7 @@ bootstrapping.
def bug_92891_bootstrap_crashes_with_egg_recipe_in_buildout_section():
"""
>>> d = tmpdir('sample-bootstrap')
>>> write(d, 'buildout.cfg',
... '''
... [buildout]
......@@ -727,7 +727,7 @@ All gone
def add_setuptools_to_dependencies_when_namespace_packages():
'''
'''
Often, a package depends on setuptools soley by virtue of using
namespace packages. In this situation, package authors often forget to
declare setuptools as a dependency. This is a mistake, but,
......@@ -754,12 +754,12 @@ a devlop egg, we will also generate a warning.
... )
... """)
>>> write('foo', 'README.txt', '')
>>> write('buildout.cfg',
... """
... [buildout]
... develop = foo
... parts =
... parts =
... """)
>>> print system(join('bin', 'buildout')),
......@@ -772,7 +772,7 @@ and we will get setuptools included in the working set.
>>> handler = zope.testing.loggingsupport.InstalledHandler(
... 'zc.buildout.easy_install', level=logging.WARNING)
>>> logging.getLogger('zc.buildout.easy_install').propagate = False
>>> [dist.project_name
... for dist in zc.buildout.easy_install.working_set(
... ['foox'], sys.executable,
......@@ -797,11 +797,11 @@ On the other hand, if we have a regular egg, rather than a develop egg:
>>> ls('develop-eggs')
- zc.recipe.egg.egg-link
>>> ls('eggs') # doctest: +ELLIPSIS
- foox-0.0.0-py2.4.egg
...
We do not get a warning, but we do get setuptools included in the working set:
>>> [dist.project_name
......@@ -825,12 +825,12 @@ namespace package.
... setup(name='bar', install_requires = ['foox'])
... """)
>>> write('bar', 'README.txt', '')
>>> write('buildout.cfg',
... """
... [buildout]
... develop = foo bar
... parts =
... parts =
... """)
>>> print system(join('bin', 'buildout')),
......@@ -858,7 +858,7 @@ namespace package.
def develop_preserves_existing_setup_cfg():
"""
See "Handling custom build options for extensions in develop eggs" in
easy_install.txt. This will be very similar except that we'll have an
existing setup.cfg:
......@@ -882,7 +882,7 @@ existing setup.cfg:
>>> dest = tmpdir('dest')
>>> zc.buildout.easy_install.develop(
... extdemo, dest,
... extdemo, dest,
... {'include-dirs': os.path.join(sample_buildout, 'include')})
'/dest/extdemo.egg-link'
......@@ -961,7 +961,7 @@ Uninstall recipes need to be called when a part is removed too:
>>> write('buildout.cfg', '''
... [buildout]
... develop = recipes
... parts =
... parts =
... ''')
>>> print system(join('bin', 'buildout')),
......@@ -976,7 +976,7 @@ def extensions_installed_as_eggs_work_in_offline_mode():
'''
>>> mkdir('demo')
>>> write('demo', 'demo.py',
>>> write('demo', 'demo.py',
... """
... def ext(buildout):
... print 'ext', list(buildout)
......@@ -985,7 +985,7 @@ def extensions_installed_as_eggs_work_in_offline_mode():
>>> write('demo', 'setup.py',
... """
... from setuptools import setup
...
...
... setup(
... name = "demo",
... py_modules=['demo'],
......@@ -1006,13 +1006,13 @@ def extensions_installed_as_eggs_work_in_offline_mode():
>>> print system(join(sample_buildout, 'bin', 'buildout')),
ext ['buildout']
'''
def changes_in_svn_or_CVS_dont_affect_sig():
"""
If we have a develop recipe, it's signature shouldn't be affected to
changes in .svn or CVS directories.
......@@ -1030,13 +1030,13 @@ changes in .svn or CVS directories.
... def install(*args): return ()
... update = install
... ''')
>>> write('buildout.cfg',
... '''
... [buildout]
... develop = recipe
... parts = foo
...
...
... [foo]
... recipe = recipe
... ''')
......@@ -1082,13 +1082,13 @@ because of the missing target file.
... def install(*args): return ()
... update = install
... ''')
>>> write('buildout.cfg',
... '''
... [buildout]
... develop = recipe
... parts = foo
...
...
... [foo]
... recipe = recipe
... ''')
......@@ -1099,7 +1099,7 @@ because of the missing target file.
Installing foo.
>>> write('recipe', 'some-file', '1')
>>> os.symlink(join('recipe', 'some-file'),
>>> os.symlink(join('recipe', 'some-file'),
... join('recipe', 'another-file'))
>>> ls('recipe')
l another-file
......@@ -1241,7 +1241,7 @@ We can also select a particular recipe version:
Uninstalling foo.
Installing foo.
recipe v1
"""
def update_adds_to_uninstall_list():
......@@ -1331,7 +1331,7 @@ def log_when_there_are_not_local_distros():
>>> handler.uninstall()
>>> logger.propagate = old_propogate
"""
def internal_errors():
......@@ -1339,7 +1339,7 @@ def internal_errors():
>>> mkdir(sample_buildout, 'recipes')
>>> write(sample_buildout, 'recipes', 'mkdir.py',
>>> write(sample_buildout, 'recipes', 'mkdir.py',
... '''
... class Mkdir:
... def __init__(self, buildout, name, options):
......@@ -1385,7 +1385,7 @@ def internal_errors():
def whine_about_unused_options():
'''
>>> write('foo.py',
>>> write('foo.py',
... """
... class Foo:
...
......@@ -1654,7 +1654,7 @@ def install_source_dist_with_bad_py():
>>> print system(buildout+' setup badegg sdist'), # doctest: +ELLIPSIS
Running setup script 'badegg/setup.py'.
...
>>> dist = join('badegg', 'dist')
>>> write('buildout.cfg',
......@@ -1687,7 +1687,7 @@ def install_source_dist_with_bad_py():
>>> ls('eggs') # doctest: +ELLIPSIS
d badegg-1-py2.4.egg
...
>>> ls('bin')
- bo
- buildout
......@@ -1705,7 +1705,7 @@ def version_requirements_in_build_honored():
... """)
>>> zc.buildout.easy_install.build(
... 'extdemo ==1.4', dest,
... 'extdemo ==1.4', dest,
... {'include-dirs': os.path.join(sample_buildout, 'include')},
... links=[link_server], index=link_server+'index/',
... newest=False)
......@@ -1756,7 +1756,7 @@ def bug_105081_Specific_egg_versions_are_ignored_when_newer_eggs_are_around():
... recipe = zc.recipe.egg
... eggs = demo ==0.1
... ''' % globals())
>>> print system(buildout),
Uninstalling x.
Installing x.
......@@ -1778,7 +1778,7 @@ if sys.version_info > (2, 4):
... p.stdin.close()
... print p.stdout.read()
... print 'Exit:', bool(p.wait())
>>> call(buildout)
<BLANKLINE>
Exit: False
......@@ -1862,7 +1862,7 @@ def bug_59270_recipes_always_start_in_buildout_dir():
... setup(name='bad.test',
... entry_points={'zc.buildout': ['default=bad_recipe:Bad']},)
... ''')
>>> write('buildout.cfg',
... '''
... [buildout]
......@@ -1886,12 +1886,12 @@ def bug_59270_recipes_always_start_in_buildout_dir():
Installing b2.
/sample-buildout
/sample-buildout/bad_start
"""
def bug_61890_file_urls_dont_seem_to_work_in_find_dash_links():
"""
This bug arises from the fact that setuptools is overly restrictive
about file urls, requiring that file urls pointing at directories
must end in a slash.
......@@ -1912,7 +1912,7 @@ def bug_61890_file_urls_dont_seem_to_work_in_find_dash_links():
>>> ls(dest)
- demo-0.2-py2.4.egg
- demoneeded-1.1-py2.4.egg
"""
def bug_75607_buildout_should_not_run_if_it_creates_an_empty_buildout_cfg():
......@@ -1924,12 +1924,12 @@ def bug_75607_buildout_should_not_run_if_it_creates_an_empty_buildout_cfg():
Error: Couldn't open /sample-buildout/buildout.cfg
"""
def dealing_with_extremely_insane_dependencies():
r"""
There was a problem with analysis of dependencies taking a long
time, in part because the analysis would get repeated every time a
package was encountered in a dependency list. Now, we don't do
......@@ -1951,7 +1951,7 @@ def dealing_with_extremely_insane_dependencies():
>>> write('buildout.cfg',
... '''
... [buildout]
... develop = pack0 pack1 pack2 pack3 pack4
... develop = pack0 pack1 pack2 pack3 pack4
... parts = pack1
...
... [pack1]
......@@ -2070,7 +2070,7 @@ directory and then use the wacky extension to load the demo package
Installing demo.
Getting distribution for 'demoneeded'.
Got demoneeded 1.0.
"""
def distributions_from_local_find_links_make_it_to_download_cache():
......@@ -2096,12 +2096,12 @@ need to make it to the download cache.
>>> list(zc.buildout.easy_install.install(['foo'], 'eggs',
... links=[join('test', 'dist')])) # doctest: +ELLIPSIS
[foo 0.0.0 ...
>>> ls('cache')
- foo-0.0.0-py2.4.egg
>>> _ = zc.buildout.easy_install.download_cache(old_cache)
"""
def create_egg(name, version, dest, install_requires=None,
......@@ -2245,13 +2245,13 @@ Using different version numbers to work around zip impporter cache problems. :(
had 33a1
>>> _ = zc.buildout.easy_install.prefer_final(True)
"""
def buildout_prefer_final_option():
"""
The prefer-final buildout option can be used for override the default
preference for newer distributions.
preference for newer distributions.
The default is prefer-final = false:
......@@ -2358,7 +2358,7 @@ Distribution setup scripts can import modules in the distribution directory:
... '''
... [buildout]
... develop = foo
... parts =
... parts =
... ''')
>>> print system(join('bin', 'buildout')),
......@@ -2406,7 +2406,7 @@ honoring our version specification.
Installing foo.
Getting distribution for 'foo==1'.
Got foo 1.
"""
def pyc_and_pyo_files_have_correct_paths():
......@@ -2455,10 +2455,10 @@ def dont_mess_with_standard_dirs_with_variable_refs():
... '''
... [buildout]
... eggs-directory = ${buildout:directory}/develop-eggs
... parts =
... parts =
... ''' % globals())
>>> print system(buildout),
"""
def expand_shell_patterns_in_develop_paths():
......@@ -2529,7 +2529,7 @@ def warn_users_when_expanding_shell_patterns_yields_no_results():
######################################################################
def create_sample_eggs(test, executable=sys.executable):
write = test.globs['write']
dest = test.globs['sample_eggs']
......@@ -2652,7 +2652,7 @@ def easy_install_SetUp(test):
test.globs['sample_eggs'])
test.globs['update_extdemo'] = lambda : add_source_dist(test, 1.5)
zc.buildout.testing.install_develop('zc.recipe.egg', test)
egg_parse = re.compile('([0-9a-zA-Z_.]+)-([0-9a-zA-Z_.]+)-py(\d[.]\d).egg$'
).match
def makeNewRelease(project, ws, dest):
......@@ -2660,20 +2660,20 @@ def makeNewRelease(project, ws, dest):
eggname, oldver, pyver = egg_parse(
os.path.basename(dist.location)
).groups()
dest = os.path.join(dest, "%s-99.99-py%s.egg" % (eggname, pyver))
dest = os.path.join(dest, "%s-99.99-py%s.egg" % (eggname, pyver))
if os.path.isfile(dist.location):
shutil.copy(dist.location, dest)
zip = zipfile.ZipFile(dest, 'a')
zip.writestr(
'EGG-INFO/PKG-INFO',
zip.read('EGG-INFO/PKG-INFO').replace("Version: %s" % oldver,
zip.read('EGG-INFO/PKG-INFO').replace("Version: %s" % oldver,
"Version: 99.99")
)
zip.close()
else:
shutil.copytree(dist.location, dest)
info_path = os.path.join(dest, 'EGG-INFO', 'PKG-INFO')
info = open(info_path).read().replace("Version: %s" % oldver,
info = open(info_path).read().replace("Version: %s" % oldver,
"Version: 99.99")
open(info_path, 'w').write(info)
......@@ -2791,7 +2791,7 @@ def test_suite():
(re.compile('[-d] setuptools'), '- setuptools'),
])
),
doctest.DocFileSuite(
'easy_install.txt', 'downloadcache.txt', 'dependencylinks.txt',
'allowhosts.txt', 'unzip.txt',
......@@ -2861,7 +2861,9 @@ def test_suite():
'[Errno 17] File exists: '
),
])
),
),
doctest.DocFileSuite(
'testing_bugfix.txt'),
]
# adding bootstrap.txt doctest to the suite
......
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