[Zope-dev] zope.component test isolation

Wolfgang Schnerring ws at gocept.com
Sat Mar 26 04:11:37 EDT 2011


Hello,

* Martin Aspeli <optilude+lists at gmail.com> [2011-03-25 13:58]:
> plone.testing (which is Plone non-specific and will shortly be BSD
> licensed) allows for stacking of ZCA registries.
> [...]
> Again, plone.testing is the result of hours and hours of finding weird
> problems, so I'd recommend you don't discard the knowledge there. I
> think a best case scenario would be for plone.testing.zca to just be a
> delegate for something more robust in zope.component.testing.

I wasn't aware plone.testing had something for the ZCA, before I read
that in this thread yesterday. I'm glad to hear that, and I certainly
don't want to discard anything. But from reading the code and what you
wrote, I get the impression that plone.testing does not yet solve the
issue completely, precisely because of the two points I brought up and
that continue below:

> On 25 March 2011 13:17, Jim Fulton <jim at zope.com> wrote:
> > On Fri, Mar 25, 2011 at 4:24 AM, Wolfgang Schnerring <ws at gocept.com> wrote:
> > > we realized that just squeezing in a new registry and bending its
> > > bases to the previously active one is not enough for full isolation,
> > > since this does not cover *deleting* registrations
> >
> > Is deleting registrations important?  This seems like an odd use case.
> > If it's needed, I would suggest starting with a baseline (e.g. stack)
> > that doesn't include the component you want to test deleting, then
> > adding in setup.

I've wanted to specifically nuke registrations sometimes, the pattern
being, load the package's configure.zcml in the layer, and then delete
something (to demonstrate some error handling behaviour).

I agree that this use case is rare, but I'm not sure it is rare enough
that we should ignore it. I need to think about this some more,
though.

> > > 2. zope.component has two entry points, the global site registry and
> > > the current registry (getGlobalSiteManager and getSiteManager).
> > > The current registry can be anything, or more precisely, you can call
> > > getSiteManager.sethook(callable) and provide a callable that returns
> > > the current registry.
> > >
> > > I think to provide test support for zope.component (i. e. generally,
> > > at the "library level"), we need to support both entry points.
> >
> > Why? Why would someone care about anything other than the current
> > effective configuration.

Because that's the API that zope.component offers, it conceptually
deals with *two* registries: the one you get from getSiteManager and
the one you get from getGlobalSiteManager.

I agree that it is unlikely that client code will *read* registrations
using getGlobalSiteManager -- since most everyone uses
zope.component.getUtility etc. (which in turn uses getSiteManager).
But *writing* is a different matter. Just one example:
zope.component.provideUtility etc. uses getGlobalSiteManager, while
the ZCML directives use getSiteManager.

At least as long as zope.component.provide* uses getGlobalSiteManager
instead of getSiteManager, I maintain that test infrastructure needs to
1. wrap the global registry
2. wrap whatever getSiteManager currently returns
(Otherwise we might be able get away with not doing (1), but I think
we'll always need to do (2).)

plone.testing has it the other way around, doing (1) but not (2), as
Martin says himself...

> > > The global one is not hard, but the getSiteManager one gets
> > > nasty really fast, because of course we have to rely on bending
> > > getSiteManager to return the current "test registry"
> 
> I don't think you need to do that. plone.testing doesn't, for sure, it
> just changes the variable that getSiteManager() looks at.

... and I'm quite sure that's wrong, becasue it doesn't deal with the
issue of getSiteManager at the level of zope.component, but at the
level of some specific implementations (zope.site and
five.localsitemanager, to be precise). When I'm using, say, Pyramid
(which also uses getSiteManager.sethook), this won't help me at all.

And to do this on the level of zope.component, I'm quite sure we are
going to need to override getSiteManager.

> > > but anyone could at any time call getSiteManager.sethook to
> > > change it!
> > 
> > Seriously?  Nobody calls that but deep infrastructure code.
>
> Agree with Jim. Are you going to stop people monkey patching
> getSiteManager() too? ;-)

My point is: Ensuring that test setup always and everywhere happens
precisely so that the code that calls sethook (for example the setup
of zope.site) is called *before* the envisioned test infrastructure
code comes along to bend getSiteManager to do its will seems very
fragile to me, if it's doable at all.

Wolfgang

-- 
Wolfgang Schnerring · ws at gocept.com
gocept gmbh & co. kg · forsterstraße 29 · 06112 halle (saale) · germany
http://gocept.com · tel +49 345 1229889 0 · fax +49 345 1229889 1
Zope and Plone consulting and development


More information about the Zope-Dev mailing list