nti.testing 4.2.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
nti/__init__.py ADDED
File without changes
@@ -0,0 +1,107 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ The ``nti.testing`` module exposes the most commonly used API from the
5
+ submodules (for example, ``nti.testing.is_true`` is just an alias for
6
+ ``nti.testing.matchers.is_true``). The submodules may contain other
7
+ functions, though, so be sure to look at their documentation.
8
+
9
+ Importing this module has side-effects when :mod:`zope.testing` is
10
+ importable:
11
+
12
+ - Add a zope.testing cleanup to ensure that transactions never
13
+ last past the boundary of a test. If a test begins a transaction
14
+ and then fails to abort or commit it, subsequent uses of the
15
+ transaction package may find that they are in a bad state,
16
+ unable to clean up resources. For example, the dreaded
17
+ ``ConnectionStateError: Cannot close a connection joined to a
18
+ transaction``.
19
+
20
+ - A zope.testing cleanup also ensures that the global transaction
21
+ manager is in its default implicit mode, at least for the
22
+ current thread.
23
+
24
+ .. versionchanged:: 3.1.0
25
+
26
+ The :mod:`mock` module, or its backwards compatibility backport for
27
+ Python 2.7, is now available as an attribute of this module, and as
28
+ the module named ``nti.testing.mock``. Thus, for compatibility with
29
+ both Python 2 and Python 3, you can write ``from nti.testing import
30
+ mock`` or ``from nti.testing.mock import Mock``, or even just
31
+ ``from nti.testing import Mock``.
32
+
33
+ .. versionchanged:: 3.1.0
34
+
35
+ Expose the most commonly used attributes of some submodules as API on this
36
+ module itself.
37
+ """
38
+
39
+ from __future__ import absolute_import
40
+ from __future__ import division
41
+ from __future__ import print_function
42
+
43
+ import transaction
44
+ import zope.testing.cleanup
45
+
46
+ from . import mock
47
+ from .mock import Mock
48
+
49
+ from .matchers import is_true
50
+ from .matchers import is_false
51
+ from .matchers import provides
52
+ from .matchers import implements
53
+ from .matchers import verifiably_provides
54
+ from .matchers import validly_provides
55
+ from .matchers import validated_by
56
+ from .matchers import not_validated_by
57
+ from .matchers import aq_inContextOf
58
+
59
+ from .time import time_monotonically_increases
60
+
61
+
62
+ __docformat__ = "restructuredtext en"
63
+
64
+ def transactionCleanUp():
65
+ """
66
+ Implement the transaction cleanup described in the module documentation.
67
+ """
68
+ try:
69
+ transaction.abort()
70
+ except transaction.interfaces.NoTransaction:
71
+ # An explicit transaction manager, with nothing
72
+ # to do. Perfect.
73
+ pass
74
+ finally:
75
+ # Note that we don't catch any other transaction errors.
76
+ # Those usually mean there's a bug in a resource manager joined
77
+ # to the transaction and it should fail the test.
78
+ transaction.manager.explicit = False
79
+
80
+
81
+ zope.testing.cleanup.addCleanUp(transactionCleanUp)
82
+
83
+ __all__ = [
84
+ # Things defined here we want to export
85
+ # if they do 'from nti.testing import *'
86
+ # This also defines what Sphinx documents for this module.
87
+ 'transactionCleanUp',
88
+ 'mock',
89
+ 'Mock',
90
+ # API Convenience exports.
91
+ # * matchers
92
+ 'is_true',
93
+ 'is_false',
94
+ 'provides',
95
+ 'implements',
96
+ 'verifiably_provides',
97
+ 'validly_provides',
98
+ 'provides',
99
+ 'validated_by',
100
+ 'not_validated_by',
101
+ 'aq_inContextOf',
102
+ # * time
103
+ 'time_monotonically_increases',
104
+ # Sub-modules that should be imported with
105
+ # * imports as well. We generally don't want anything
106
+ # imported; it's better to use direct imports.
107
+ ]
nti/testing/base.py ADDED
@@ -0,0 +1,574 @@
1
+ #!/usr/bin/env python
2
+ # -*- coding: utf-8 -*-
3
+ """
4
+ Base test classes and functions for setting up ZCA.
5
+
6
+ In some cases, you may be better off using :mod:`zope.component.testlayer`.
7
+
8
+ """
9
+
10
+ from __future__ import absolute_import
11
+ from __future__ import division
12
+ from __future__ import print_function
13
+
14
+ # stdlib imports
15
+ import gc
16
+ import os
17
+ import platform
18
+ import sys
19
+ import unittest
20
+ from unittest.mock import patch as Patch
21
+
22
+ from zope import component
23
+ from zope.component import eventtesting
24
+ from zope.component.hooks import setHooks
25
+ from zope.configuration import config
26
+ from zope.configuration import xmlconfig
27
+ from zope.dottedname import resolve as dottedname
28
+ import zope.testing.cleanup
29
+
30
+ from hamcrest import assert_that
31
+ from hamcrest import is_
32
+
33
+ from . import transactionCleanUp
34
+
35
+ logger = __import__('logging').getLogger(__name__)
36
+
37
+
38
+ _marker = object()
39
+
40
+ class AbstractConfiguringObject(object):
41
+ """
42
+ A class for executing ZCML configuration.
43
+
44
+ Other than the attributes that are documented on this class,
45
+ users are not expected to use this class or subclass it.
46
+ """
47
+
48
+ #: Class attribute naming a sequence of package objects or strings
49
+ #: naming packages. These will be configured, in order, using
50
+ #: ZCML. The ``configure.zcml`` package from each package will be
51
+ #: loaded. Instead of a package object, each item can be a tuple
52
+ #: of (filename, package); in that case, the given file (usually
53
+ #: ``meta.zcml``) will be loaded from the given package.
54
+ set_up_packages = ()
55
+
56
+ #: Class attribute naming a sequence of strings to be added as
57
+ #: features before loading the configuration. By default, this is
58
+ #: ``devmode`` and ``testmode``. (Devmode is suitable for running
59
+ #: the application, testmode is only suitable for unit tests.)
60
+ features = ('devmode', 'testmode')
61
+
62
+ #: Class attribute that is a boolean defaulting to True. When
63
+ #: true, the :mod:`zope.component.eventtesting` module will be
64
+ #: configured.
65
+ #:
66
+ #: .. note:: If there are any ``set_up_packages`` you are
67
+ #: responsible for ensuring that the :mod:`zope.component`
68
+ #: configuration is loaded.
69
+ configure_events = True
70
+
71
+ #: Instance attribute defined by :meth:`setUp` that is the :class:`~.ConfigurationMachine`
72
+ #: that was used to load configuration data (if any). This can be
73
+ #: used by individual methods to load more configuration data
74
+ #: using :meth:`configure_packages` or the methods from
75
+ #: :mod:`zope.configuration`
76
+ configuration_context = None
77
+
78
+ @staticmethod
79
+ def _doSetUp(obj):
80
+ obj._doSetUpSuper() # pylint:disable=protected-access
81
+ setHooks() # zope.component.hooks registers a zope.testing.cleanup to reset these
82
+ if obj.configure_events:
83
+ if obj.set_up_packages:
84
+ # If zope.component is being configured, we wind up with duplicates if we let
85
+ # eventtesting fully configure itself
86
+ component.provideHandler(eventtesting.events.append, (None,))
87
+ else:
88
+ eventtesting.setUp() # pragma: no cover
89
+
90
+ obj.configuration_context = obj.configure_packages(
91
+ set_up_packages=obj.set_up_packages,
92
+ features=obj.features,
93
+ context=obj.configuration_context,
94
+ package=obj.get_configuration_package())
95
+
96
+ @staticmethod
97
+ def _do_configure_packages(obj, # pylint:disable=too-many-positional-arguments
98
+ set_up_packages=(),
99
+ features=(),
100
+ context=_marker,
101
+ configure_events=True, # pylint:disable=unused-argument
102
+ package=None):
103
+ obj.configuration_context = _configure(
104
+ obj,
105
+ set_up_packages=set_up_packages,
106
+ features=features,
107
+ context=(context if context is not _marker else obj.configuration_context),
108
+ package=package)
109
+ return obj.configuration_context
110
+
111
+ @staticmethod
112
+ def _doTearDown(obj, clear_configuration_context=True, super_tear_down=None):
113
+ # always safe to clear events
114
+ eventtesting.clearEvents() # redundant with zope.testing.cleanup
115
+ # we never actually want to do this, it's not needed and can mess up other fixtures
116
+ # resetHooks()
117
+ transactionCleanUp()
118
+ if clear_configuration_context:
119
+ obj.configuration_context = None
120
+ if super_tear_down is not None:
121
+ super_tear_down()
122
+ else:
123
+ obj._doTearDownSuper() # pylint:disable=protected-access
124
+
125
+
126
+ @staticmethod
127
+ def get_configuration_package_for_class(klass):
128
+ """
129
+ Return the package that ``.`` means when configuring packages.
130
+
131
+ For test classes that exist in a subpackage called ``tests`` in
132
+ a module beginning with ``test``, this defaults to the parent
133
+ package. E.g., if *klass* is
134
+ ``nti.appserver.tests.test_app.TestApp`` then this is
135
+ ``nti.appserver``.
136
+ """
137
+ module = klass.__module__
138
+ if not module: # pragma: no cover
139
+ return None
140
+
141
+ module_parts = module.split('.')
142
+ if module_parts[-1].startswith('test') and module_parts[-2] == 'tests':
143
+ module = '.'.join(module_parts[0:-2])
144
+
145
+ package = sys.modules[module]
146
+ return package
147
+
148
+
149
+ class PatchingMixin:
150
+ """
151
+ Mixin class adding support for dynamic :mod:`unittest.mock` patches.
152
+
153
+ .. versionadded:: 4.0.0
154
+ """
155
+ def patch(self, *args, **kwargs):
156
+ """
157
+ API for subclasses. All args are passed through to :obj:`unittest.mock.patch`
158
+ which is then started and registered for cleanup.
159
+
160
+ This is intended to be used in ``setUp`` or individual test methods
161
+ when what you might need to patch is dynamic.
162
+
163
+ Returns the result of ``patch.start()``, i.e., a mock object.
164
+
165
+ .. versionadded:: 4.0.0
166
+ """
167
+ return self._install_patch(Patch(*args, **kwargs))
168
+
169
+ def _install_patch(self, patcher):
170
+ """
171
+ Starts the *patcher*, and registers a test tear down cleanup
172
+ to stop it.
173
+
174
+ Returns the result of ``patcher.start``
175
+ """
176
+ result = patcher.start()
177
+ self.addCleanup(patcher.stop)
178
+ return result
179
+
180
+
181
+ class AbstractTestBase(zope.testing.cleanup.CleanUp,
182
+ PatchingMixin,
183
+ unittest.TestCase):
184
+ """
185
+ Base class for testing. Inherits the setup and teardown functions for
186
+ :class:`zope.testing.cleanup.CleanUp`; one effect this has is to cause
187
+ the component registry to be reset after every test.
188
+
189
+ .. note:: Do not use this when you use :func:`module_setup` and
190
+ :func:`module_teardown`, as the inherited :meth:`setUp` will
191
+ undo the effects of the module setup.
192
+ """
193
+
194
+ def get_configuration_package(self):
195
+ """
196
+ See :meth:`AbstractConfiguringObject.get_configuration_package_for_class`.
197
+ """
198
+ return AbstractConfiguringObject.get_configuration_package_for_class(self.__class__)
199
+
200
+
201
+
202
+ _shared_cleanups = []
203
+
204
+ def addSharedCleanUp(func, args=(), kw=None):
205
+ """
206
+ Registers a cleanup to happen for every test, regardless of whether
207
+ the test is using shared configuration or not.
208
+ """
209
+ _shared_cleanups.append((func, args, kw or {}))
210
+ zope.testing.cleanup.addCleanUp(func, args, kw or {})
211
+
212
+ def sharedCleanup():
213
+ """
214
+ Clean up things that should be cleared for every test, even
215
+ in a shared test base.
216
+ """
217
+ for func, args, kw in _shared_cleanups:
218
+ func(*args, **kw)
219
+
220
+ class SharedTestBaseMetaclass(type):
221
+ """
222
+ A metaclass that converts the nose-specific use of ``setUpClass``
223
+ and ``tearDownClass`` into a layer that also works with zope.testrunner
224
+ (which is generally better than nose2).
225
+
226
+ This works because nose2 picks one or the other, and it chooses layers
227
+ over setUp/tearDownClass---only one of them is called. (If that changes,
228
+ it's easy to workaround.)
229
+ """
230
+
231
+ def __new__(mcs, name, bases, cdict): # pylint:disable=bad-mcs-classmethod-argument
232
+ the_type = type.__new__(mcs, name, bases, cdict)
233
+ # TODO: Based on certain features of the the_type
234
+ # like set_up_packages and features, we can probably
235
+ # cache and share layers, which will help speed up
236
+ # test runs
237
+ class layer(object):
238
+ __name__ = name
239
+ __mro__ = __bases__ = (object,)
240
+
241
+ @classmethod
242
+ def setUp(cls):
243
+ the_type.setUpClass()
244
+ @classmethod
245
+ def tearDown(cls):
246
+ the_type.tearDownClass()
247
+ @classmethod
248
+ def testSetUp(cls):
249
+ pass
250
+ @classmethod
251
+ def testTearDown(cls):
252
+ pass
253
+ the_type.layer = layer
254
+ layer.__name__ = name
255
+ return the_type
256
+
257
+ _is_pypy = platform.python_implementation() == 'PyPy'
258
+
259
+ class AbstractSharedTestBase(PatchingMixin,
260
+ unittest.TestCase,
261
+ metaclass=SharedTestBaseMetaclass,):
262
+ """
263
+ Base class for testing that can share most global data (e.g., ZCML
264
+ configuration) between unit tests. This is far more efficient, if
265
+ the global data (e.g., ZCA component registry) is otherwise
266
+ cleaned up or not mutated between tests.
267
+
268
+ Under zope.testing and nose2, this is handled by treating the class
269
+ as a *layer* through :class:`SharedTestBaseMetaclass`.
270
+
271
+ """
272
+
273
+ #: Class-level attribute that determines whether
274
+ #: we should only collect garbage when tearing down the class.
275
+ HANDLE_GC = False
276
+
277
+ @classmethod
278
+ def setUpClass(cls):
279
+ """
280
+ Subclasses must call this method. It cleans up the global state.
281
+
282
+ It also disables garbage collection until
283
+ :meth:`tearDownClass` is called if :attr:`HANDLE_GC` is True. This
284
+ way, we can collect just one generation and be sure to clean
285
+ up any weak references that were created during this run.
286
+ (Which is necessary, as ZCA heavily uses weak references, and
287
+ when that is mixed with IComponents instances that are in a
288
+ ZODB, if weak references persist and aren't cleaned, bad
289
+ things can happen. See ``nti.dataserver.site`` for details.)
290
+ This is ``False`` by default for speed; set it to true if your
291
+ TestCase will be creating new (possibly synthetic) sites/site
292
+ managers.
293
+ """
294
+
295
+ zope.testing.cleanup.cleanUp()
296
+ if cls.HANDLE_GC:
297
+ cls.__isenabled = gc.isenabled()
298
+ if not _is_pypy:
299
+ gc.disable() # PyPy GC is fast
300
+
301
+ @classmethod
302
+ def tearDownClass(cls):
303
+ """
304
+ Subclasses must call this method. It cleans up global state
305
+ and performs garbage collection if :attr:`HANDLE_GC` is true.
306
+ """
307
+ zope.testing.cleanup.cleanUp()
308
+ if cls.HANDLE_GC:
309
+ if cls.__isenabled:
310
+ gc.enable()
311
+
312
+ gc.collect(0) # collect now to clean up weak refs
313
+ gc.collect(0) # PyPy sometimes needs two cycles to get them all
314
+
315
+ assert_that(gc.garbage, is_([]))
316
+
317
+ def setUp(self):
318
+ """
319
+ Invokes :func:`sharedCleanup` for every test.
320
+ """
321
+ sharedCleanup()
322
+
323
+ def tearDown(self):
324
+ """
325
+ Invokes :func:`sharedCleanup` for every test.
326
+ """
327
+ sharedCleanup()
328
+
329
+
330
+
331
+ def _configure(self=None,
332
+ set_up_packages=(),
333
+ features=('devmode', 'testmode'),
334
+ context=None,
335
+ package=None):
336
+
337
+ features = set(features) if features is not None else set()
338
+
339
+ # This is normally created by a slug, but tests may not always
340
+ # load the slug
341
+ if os.getenv('DATASERVER_DIR_IS_BUILDOUT'): # pragma: no cover
342
+ features.add('in-buildout')
343
+
344
+
345
+ # zope.component.globalregistry conveniently adds
346
+ # a zope.testing.cleanup.CleanUp to reset the globalSiteManager
347
+ if context is None and (features or package):
348
+ context = config.ConfigurationMachine()
349
+ context.package = package
350
+ xmlconfig.registerCommonDirectives(context)
351
+
352
+ for feature in features:
353
+ context.provideFeature(feature)
354
+
355
+ if set_up_packages:
356
+ logger.debug("Configuring %s with features %s", set_up_packages, features)
357
+
358
+ for i in set_up_packages:
359
+ __traceback_info__ = (i, self)
360
+ if isinstance(i, tuple):
361
+ filename = i[0]
362
+ package = i[1]
363
+ else:
364
+ filename = 'configure.zcml'
365
+ package = i
366
+
367
+ if isinstance(package, str):
368
+ package = dottedname.resolve(package)
369
+
370
+ try:
371
+ context = xmlconfig.file(filename, package=package, context=context)
372
+ except IOError as e:
373
+ # Did we pass in a test module (__name__) and there is no
374
+ # configuration in that package? In that case, we want to
375
+ # configure the parent package for sure
376
+ module_path = getattr(package, '__file__', '')
377
+ if (module_path
378
+ and 'tests' in module_path
379
+ and os.path.join(os.path.dirname(module_path), filename) == e.filename):
380
+ parent_package_name = '.'.join(package.__name__.split('.')[:-2])
381
+ package = dottedname.resolve(parent_package_name)
382
+ context = xmlconfig.file(filename, package=package, context=context)
383
+ else: # pragma: no cover
384
+ raise
385
+
386
+ return context
387
+
388
+
389
+ class ConfiguringTestBase(AbstractConfiguringObject,
390
+ AbstractTestBase):
391
+ """
392
+ Test case that can be subclassed when ZCML configuration is desired.
393
+
394
+ Configuration is established by the class attributes documented
395
+ on :class:`AbstractConfiguringObject`.
396
+
397
+ .. note:: The ZCML configuration is executed for each test.
398
+ """
399
+
400
+ def _doSetUpSuper(self):
401
+ super().setUp()
402
+
403
+ def setUp(self):
404
+ AbstractConfiguringObject._doSetUp(self)
405
+
406
+ #: Configure additional packages. This should only be done in the ``setUp`` method
407
+ #: of a subclass. Note that this is called by ``setUp``.
408
+ configure_packages = AbstractConfiguringObject._do_configure_packages
409
+
410
+ def configure_string(self, zcml_string):
411
+ """
412
+ Execute the given ZCML string.
413
+
414
+ Tests may use this after ``setUp`` is called (this includes in the
415
+ implementation of your own ``setUp`` function).
416
+ """
417
+ self.configuration_context = xmlconfig.string(zcml_string, self.configuration_context)
418
+ return self.configuration_context
419
+
420
+ def _doTearDownSuper(self):
421
+ super().tearDown()
422
+
423
+ def tearDown(self):
424
+ self._doTearDownConfiguration()
425
+
426
+ def _doTearDownConfiguration(self):
427
+ """
428
+ Hook for subclasses to override.
429
+
430
+ This implementation calls :meth:`AbstractConfiguringObject._doTearDown`
431
+ with the default parameters. If you need to call it with a different
432
+ set of parameters, override this method to do so.
433
+
434
+ This method takes no arguments because the arguments passed to
435
+ ``_doTearDown`` are almost always static at the callsite.
436
+ """
437
+ AbstractConfiguringObject._doTearDown(
438
+ self,
439
+ )
440
+
441
+ class SharedConfiguringTestBase(AbstractConfiguringObject,
442
+ AbstractSharedTestBase):
443
+ """
444
+ Test case that can be subclassed when ZCML configuration is desired.
445
+
446
+ Configuration is established by the class attributes documented on
447
+ :class:`AbstractConfiguringObject`. (The ``configuration_context`` is also
448
+ a class attribute.)
449
+
450
+ .. note:: The ZCML configuration is only executed once, before
451
+ any tests are run.
452
+ """
453
+
454
+ @classmethod
455
+ def _doSetUpSuper(cls):
456
+ super(SharedConfiguringTestBase, cls).setUpClass()
457
+
458
+ setUpClass = classmethod(AbstractConfiguringObject._doSetUp)
459
+
460
+ #: Configure additional packages. This should only be done in the ``setUpClass``
461
+ #: method of a subclass after calling the super class. Note that this is called by
462
+ #: ``setUpClass``.
463
+ configure_packages = classmethod(AbstractConfiguringObject._do_configure_packages)
464
+
465
+ #: .. seealso:: :meth:`~.AbstractConfiguringObject.get_configuration_package_for_class`
466
+ #: .. versionadded:: 2.1.0
467
+ get_configuration_package = classmethod(
468
+ AbstractConfiguringObject.get_configuration_package_for_class
469
+ )
470
+
471
+ @classmethod
472
+ def _doTearDownSuper(cls):
473
+ super(SharedConfiguringTestBase, cls).tearDownClass()
474
+
475
+ tearDownClass = classmethod(AbstractConfiguringObject._doTearDown)
476
+
477
+ def tearDown(self):
478
+ AbstractConfiguringObject._doTearDown(
479
+ self,
480
+ clear_configuration_context=False,
481
+ super_tear_down=super().tearDown)
482
+
483
+
484
+ def module_setup(set_up_packages=(),
485
+ features=('devmode', 'testmode'),
486
+ configure_events=True):
487
+ """
488
+ A module-level fixture for configuring packages.
489
+
490
+ Either import this as ``setUpModule`` at the module level, or call
491
+ it to perform module level set up from your own function with that name.
492
+ If you use this, you must also use :func:`module_teardown`.
493
+
494
+ This is an alternative to using :class:`ConfiguringTestBase`; the
495
+ two should generally not be mixed in a module. It can also be used
496
+ with Nose's `with_setup` function.
497
+ """
498
+ zope.testing.cleanup.setUp()
499
+ setHooks()
500
+ if configure_events:
501
+ if set_up_packages:
502
+ component.provideHandler(eventtesting.events.append, (None,))
503
+ else:
504
+ eventtesting.setUp()
505
+
506
+ _configure(set_up_packages=set_up_packages, features=features)
507
+
508
+ def module_teardown():
509
+ """
510
+ Tears down the module-level fixture for configuring packages
511
+ established by :func:`module_setup`.
512
+
513
+ Either import this as ``tearDownModule`` at the module level, or
514
+ call it to perform module level tear down froum your own function
515
+ with that name.
516
+
517
+ This is an alternative to using :class:`ConfiguringTestBase`; the
518
+ two should generally not be mixed in a module.
519
+ """
520
+ eventtesting.clearEvents() # redundant with zope.testing.cleanup
521
+ # we never actually want to do this, it's not needed and can mess up other fixtures
522
+ # resetHooks()
523
+ zope.testing.cleanup.tearDown()
524
+
525
+ # The cleanup that we get by importing just zope.interface and
526
+ # zope.component has a problem: zope.component installs adapter hooks
527
+ # that cause the use of interfaces as functions to direct through the
528
+ # current site manager (as does the global component API). This
529
+ # adapter hook is a cached function of an implementation detail of the
530
+ # site manager: siteManager.adapters.adapter_hook.
531
+ #
532
+ # If no site is ever set, this caches the adapter_hook of the globalSiteManager.
533
+ #
534
+ # When the zope.component cleanup runs, it swizzles out the internals
535
+ # of the globalSiteManager by re-running __init__. However, it does
536
+ # not clear the cached adapter_hook. Thus, subsequent uses of the
537
+ # adapter hook (interface calls, or use of the global component API)
538
+ # continue to use the *old* adapter registry (which is no longer easy
539
+ # to access and inspect, especially when the C hook optimizations are
540
+ # in use) If any non-ZCML registrations are made (or the next test
541
+ # loads a subset of the ZCML the previous test did) then this
542
+ # manifests as strange adapter failures.
543
+ #
544
+ # This is obviously all implementation detail. So rather than "fix" the problem
545
+ # ourself, the solution is to import zope.site.site to ensure that the site gets
546
+ # cleaned up and the adapter_hook cache thrown away
547
+ # This problem never manifests itself in code that has already imported zope.site,
548
+ # and it seems to be an assumption that code that uses zope.component also uses zope.site
549
+ # (though we have some code that doesn't explicitly do so)
550
+
551
+ # This is detailed in test_component_broken.txt
552
+ # submitted as https://bugs.launchpad.net/zope.component/+bug/1100501
553
+ # transferred to github as https://github.com/zopefoundation/zope.component/pull/1
554
+ #import zope.site.site
555
+ # This is identified as fixed in zope.component 4.2.0
556
+
557
+
558
+ # Zope.mimetype registers hundreds and thousands of objects
559
+ # doing that for each test makes them take SO much longer
560
+ # Unfortunately, as noted above, zope.testing.cleanup.CleanUp
561
+ # installs something to reset the gsm, so it's not possible
562
+ # to simply pre-cache like the below:
563
+ # try:
564
+ # import zope.mimetype
565
+ # _configure(None, (('meta.zcml',zope.mimetype),
566
+ # ('meta.zcml',zope.component),
567
+ # zope.mimetype))
568
+ # except ImportError:
569
+ # pass
570
+
571
+ # Attempting to runaround the testing cleanup by
572
+ # using a different base doesn't quite work,
573
+ # some things are still using the old one
574
+ # globalregistry.base = BaseComponents()