Re: [Zope-dev] zope.component test isolation
Hi, it seems to me this has stalled somewhat, so I wanted to ask what people's conclusions are. * Wolfgang Schnerring w...@gocept.com [2011-03-26 13:41]: * Martin Aspeli optilude+li...@gmail.com [2011-03-26 11:22]: On 26 March 2011 08:11, Wolfgang Schnerring w...@gocept.com wrote: I don't think a fixture of package foo's configuration except component X and Y is all that useful. Whether the the unregister use case is useful remains debatable, but I personally don't care all *that* much for it, so if the consensus is that it's overkill I'll go along I guess. I do care quite a bit for proper getSiteManager() support... We do definitely need to allow the global site manager to be stacked (which you can achieve with __bases__ as in plone.testing, unregistration notwithstanding). But once you do that, the rest is pretty easy. The local site manager will always have the global as one of its (nested) __bases__. I'm sorry, but no, it isn't that easy. When the only local site consumer is zope.site, well, maybe. But please think of this in terms of zope.component *only*. Its API is getSiteManager.sethook(callable), and AFAICT the contract is that the return value of callable must provide IComponents (briefly: get* and register*). Nowhere does it say that you have to delegate back to the global registry, and neither it should. To bring up Pyramid once again, they explicitly don't, because they want to allow several applications (thus, several registries) coexisting in the same process. And since we can't assume this delegation, I think there is no other way to properly do the stacking than to bend getSiteManager. ... as described here, though. And I wonder if I'm missing something, because to do that properly looks like quite the can of worms to me. So, how can we proceed here? Should I (and Thomas) try to get a proof-of-concept implementation of this based on plone.testing? Or should we think about what it takes to merge most of plone.testing's ZCA support into zope.component itself first? Wolfgang ___ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] zope.component test isolation
Hi, On 4 April 2011 17:30, Wolfgang Schnerring w...@gocept.com wrote: So, how can we proceed here? Should I (and Thomas) try to get a proof-of-concept implementation of this based on plone.testing? Or should we think about what it takes to merge most of plone.testing's ZCA support into zope.component itself first? I think either approach is valuable, and not necessarily mutually exclusive. I do care about the plone.testing API, which is used in production, so bear that in mind. Martin ___ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] zope.component test isolation
Hello, * Martin Aspeli optilude+li...@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 j...@zope.com wrote: On Fri, Mar 25, 2011 at 4:24 AM, Wolfgang Schnerring w...@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 · w...@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 ___ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists -
Re: [Zope-dev] zope.component test isolation (was: Zope test layers, pytest, and test isolation)
Hi Jim, On 25 March 2011 14:12, Jim Fulton j...@zope.com wrote: Agree. There is a problem in that provideAdapter() and friends don't use getSiteManager() - the always use the global site manager. And there are parts of zope.component that use module level variables directly, ignoring hooks. These are meant to work this way. If you want to do local configuration, you should explictly select the relevent registry/manager or call getSiteManager and use the result. I sortof understand, but it makes it impossible to let people use provideAdapter() co in test setup and still retain some kind of layered test setup, without the kind of hacks we do in plone.testing. -- but anyone could at any time call getSiteManager.sethook to change it! Seriously? Nobody calls that but deep infrastructure code. People do call zope.site.hooks.setHooks() sometimes, though, e.g. upon traversal. This was never meant to be an application-level feature. I find the notion that people would call these dureing traversal to be disturbing. Are you sure you're not confusing this with setSite? Sorry, I meant setSite() above yes. Although sometimes people call setHooks() and then setSite(site) in test setup, because setSite() doesn't work until setHooks() has been called once. I think this may sometimes just be cargo-cult, though. Martin ___ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] zope.component test isolation
Hi, On 26 March 2011 08:11, Wolfgang Schnerring w...@gocept.com wrote: Hello, * Martin Aspeli optilude+li...@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: It certainly doesn't solve the unregister (non-?)use case. It has the advantage of being in use in the wild today, though. :-) On 25 March 2011 13:17, Jim Fulton j...@zope.com wrote: On Fri, Mar 25, 2011 at 4:24 AM, Wolfgang Schnerring w...@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. It would be better to explicitly register what you need. I think you either need to consider a package's ZCML-loaded configuration as an atomic part of test setup, or you need to break it down into individual registrations. In the first case, your test fixture is package foo's configuration is loaded, which is of course valid. In the second case, your fixture is the following components, some of which happen to be in package foo, are registered. I don't think a fixture of package foo's configuration except component X and Y is all that useful. Of course, there may be cases where an unregister is needed, but this is probably something you should solve locally. For example, you can explicitly unregister the component at the beginning of your test and reinstate it at the end of your test, or indeed in layer setup and tear-down. Automating this with stacking is not a great win. Please also take my word for it when I say that copying the whole registry is non-trivial and would rely on brittle ZCA internals. I tried. :) 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... We do definitely need to allow the global site manager to be stacked (which you can achieve with __bases__ as in plone.testing, unregistration notwithstanding). But once you do that, the rest is pretty easy. The local site manager will always have the global as one of its (nested) __bases__. My preference would be: - We replace the three separate module-level references to the global site manager with a single object - This object is a holder for a registry reference
Re: [Zope-dev] zope.component test isolation
Hello, * Martin Aspeli optilude+li...@gmail.com [2011-03-26 11:22]: On 26 March 2011 08:11, Wolfgang Schnerring w...@gocept.com wrote: * Martin Aspeli optilude+li...@gmail.com [2011-03-25 13:58]: Please also take my word for it when I say that copying the whole registry is non-trivial and would rely on brittle ZCA internals. I tried. :) I tried, too, and yup, in the end you'd have to write C to do it properly (because the AdapterLookupBase or something in zope.interface is written in C and would need to gain __deepcopy__ support). But it didn't seem unfeasible, and, when it was all said and done in Python, not very ugly either. I appreciate that you've already fought (and won!) against the whole persistence story (which hadn't even been on my radar so far), and I guess copying would necessitate reopening that can of worms. 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 think you either need to consider a package's ZCML-loaded configuration as an atomic part of test setup, or you need to break it down into individual registrations. In the first case, your test fixture is package foo's configuration is loaded, which is of course valid. In the second case, your fixture is the following components, some of which happen to be in package foo, are registered. I don't think a fixture of package foo's configuration except component X and Y is all that useful. It seems I can't convey why I think that precisely this is valuable even without taking into account the desire for non-leaky abstractions (in the ZODB-analogy it would be quite strange to have to write on top, please don't delete stuff, it's not supported). And of course I know how one could work around the limitation that unregistering is not supported. That doesn't make it any less inconvenient. The other point about getSiteManager below is *much* more important than unregistration support, though: 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... We do definitely need to allow the global site manager to be stacked (which you can achieve with __bases__ as in plone.testing, unregistration notwithstanding). But once you do that, the rest is pretty easy. The local site manager will always have the global as one of its (nested) __bases__. I'm sorry, but no, it isn't that easy. When the only local site consumer is zope.site, well, maybe. But please think of this in terms of zope.component *only*. Its API is getSiteManager.sethook(callable), and AFAICT the contract is that the return value of callable must provide IComponents (briefly: get* and register*). Nowhere does it say that you have to delegate back to the global registry, and neither it should. To bring up Pyramid once again, they explicitly don't, because they want to allow several applications (thus, several registries) coexisting in the same process. And since we can't assume this delegation, I think there is no other way to properly do the stacking than to bend getSiteManager. Wolfgang -- Wolfgang Schnerring · w...@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 ___ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] zope.component test isolation (was: Zope test layers, pytest, and test isolation)
Hello Uli, I've spent quite some time thinking (and partly coding) about the same issues you mention (but didn't feel ready to talk about it here, yet), so I'm glad that maybe we can start thinking about them together I think your email addresses two quite different topics, so I'll split my reply. First up: test support for zope.component. Second part: about the concept of test layers. * Uli Fouquet u...@gnufix.de [2011-03-24 01:05]: Right now we have a problem with pytest integration when it comes to ZCA setups [...] all tests share the same global ZCA registrations and changes to the registrations in one test will affect other tests run thereafter. We have a lack of test isolation. Exactly. This issue has bitten me too in various places, and as far as I know there are no solutions for it, yet. What I envision to solve this issue is that test support for zope.component should work the same way as with the ZODB. There, we have a *stack* of Databases (DemoStorages, to be precise) that wrap each other, where each one delegates reads downwards, but keeps writes for itself. So you might have one database for the layer that provides the baseline, and each test (in its setUp) gets its own database where it can do whatever it wants, because it is thrown away in its tearDown. In principle, quite a few of the mechanics to do the same thing with zope.component registries are already there (since a registry keeps a list of base registries it will delegate to when something can not be found in itself). And as Hanno and Godefroid mentioned, plone.testing does something in this direction already. (And, it bears repeating, in its core has no dependencies on Plone or Zope2.) But as far as I see, there are issues that plone.testing does not address: 1. I've been going over this stuff with my colleague Thomas Lotze, and 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 (one, you can only delete the registration from the precise registry it was created in, and two, in the just-bend-the-bases approach, once you delete a registration, it's gone forever). I think to provide full isolation, we need to make *copies*. And since zope.component in general supports a chain of registries, we probably need to make copies of each of them. 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. 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 -- but anyone could at any time call getSiteManager.sethook to change it! Which means we need to intercept that and a) prevent our hook from being replaced and b) inject the new registry into the test stack somehow. As far as I understand, plone.testing sidesteps these issues by only dealing with the global registry, and specially munging the two known cases in the Zope world where getSiteManager is changed (zope.site and five.something). ** I'd like to know what people think about this plan. Thomas and I have been over this quite a bit and think it's sound, not overly complicated, and (after we did some experiments) definitely doable. Please do point out stuff we missed. :-) I'd very much like to put this functionality into zope.component itself, which of course raises backwards compatibility issues galore, but any code for this definitely isn't wasted since we can always package it separately if we don't find a way to integrate it. Thomas and I taken up implementing this, but we can't devote a lot of time to it (about one session per week), so realistically I'm afraid I guess it will take a few months until we have something of substance. So if there are people who want to pitch in, that'd be great. I definitely could write up a more detailed plan and maybe even formulate smaller chunks so we could go at this with more people. Wolfgang -- Wolfgang Schnerring · w...@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 ___ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] zope.component test isolation (was: Zope test layers, pytest, and test isolation)
On Fri, Mar 25, 2011 at 4:24 AM, Wolfgang Schnerring w...@gocept.com wrote: Hello Uli, I've spent quite some time thinking (and partly coding) about the same issues you mention (but didn't feel ready to talk about it here, yet), so I'm glad that maybe we can start thinking about them together I think your email addresses two quite different topics, so I'll split my reply. First up: test support for zope.component. Second part: about the concept of test layers. * Uli Fouquet u...@gnufix.de [2011-03-24 01:05]: Right now we have a problem with pytest integration when it comes to ZCA setups [...] all tests share the same global ZCA registrations and changes to the registrations in one test will affect other tests run thereafter. We have a lack of test isolation. Exactly. This issue has bitten me too in various places, and as far as I know there are no solutions for it, yet. The classic solution is to start tests with empty registries, or, if you're using layers, with some baseline registries. What I envision to solve this issue is that test support for zope.component should work the same way as with the ZODB. There, we have a *stack* of Databases (DemoStorages, to be precise) that wrap each other, where each one delegates reads downwards, but keeps writes for itself. So you might have one database for the layer that provides the baseline, and each test (in its setUp) gets its own database where it can do whatever it wants, because it is thrown away in its tearDown. In principle, quite a few of the mechanics to do the same thing with zope.component registries are already there (since a registry keeps a list of base registries it will delegate to when something can not be found in itself). And as Hanno and Godefroid mentioned, plone.testing does something in this direction already. (And, it bears repeating, in its core has no dependencies on Plone or Zope2.) I like the idea of stacking registries. But as far as I see, there are issues that plone.testing does not address: 1. I've been going over this stuff with my colleague Thomas Lotze, and 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 (one, you can only delete the registration from the precise registry it was created in, and two, in the just-bend-the-bases approach, once you delete a registration, it's gone forever). I think to provide full isolation, we need to make *copies*. And since zope.component in general supports a chain of registries, we probably need to make copies of each of them. 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. 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. 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 But as you point out, there's a hook for that. -- but anyone could at any time call getSiteManager.sethook to change it! Seriously? Nobody calls that but deep infrastructure code. Which means we need to intercept that and a) prevent our hook from being replaced and b) inject the new registry into the test stack somehow. I think you're making this more complicated than it needs to be. As far as I understand, plone.testing sidesteps these issues by only dealing with the global registry, and specially munging the two known cases in the Zope world where getSiteManager is changed (zope.site and five.something). ** I'd like to know what people think about this plan. Thomas and I have been over this quite a bit and think it's sound, not overly complicated, and (after we did some experiments) definitely doable. Please do point out stuff we missed. :-) I think a stack-based approach is very appealing. I think anything more complex is likely to cause more problems than it solves. I'd very much like to put this functionality into zope.component itself, which of course raises backwards compatibility issues galore, Not sure why this would have to be backward incompatible, but I'm unconvinced that the complexity comes close to being justified by the benefit. but any code for this definitely isn't wasted since we can always package it separately if we
Re: [Zope-dev] zope.component test isolation (was: Zope test layers, pytest, and test isolation)
Hi, On 25 March 2011 13:17, Jim Fulton j...@zope.com wrote: On Fri, Mar 25, 2011 at 4:24 AM, Wolfgang Schnerring w...@gocept.com wrote: Hello Uli, I've spent quite some time thinking (and partly coding) about the same issues you mention (but didn't feel ready to talk about it here, yet), so I'm glad that maybe we can start thinking about them together I think your email addresses two quite different topics, so I'll split my reply. First up: test support for zope.component. Second part: about the concept of test layers. * Uli Fouquet u...@gnufix.de [2011-03-24 01:05]: Right now we have a problem with pytest integration when it comes to ZCA setups [...] all tests share the same global ZCA registrations and changes to the registrations in one test will affect other tests run thereafter. We have a lack of test isolation. Exactly. This issue has bitten me too in various places, and as far as I know there are no solutions for it, yet. The classic solution is to start tests with empty registries, or, if you're using layers, with some baseline registries. plone.testing (which is Plone non-specific and will shortly be BSD licensed) allows for stacking of ZCA registries. It has to do some ugly hacking to achieve this, since zope.component stores handles to the global registry in *three* different modules and update them in weird ways depending on the registry hooking, but it's well tested and robust now. See http://dev.plone.org/plone/browser/plone.testing/trunk/src/plone/testing/zca.py and http://dev.plone.org/plone/browser/plone.testing/trunk/src/plone/testing/zca.txt. What I envision to solve this issue is that test support for zope.component should work the same way as with the ZODB. There, we have a *stack* of Databases (DemoStorages, to be precise) that wrap each other, where each one delegates reads downwards, but keeps writes for itself. So you might have one database for the layer that provides the baseline, and each test (in its setUp) gets its own database where it can do whatever it wants, because it is thrown away in its tearDown. In principle, quite a few of the mechanics to do the same thing with zope.component registries are already there (since a registry keeps a list of base registries it will delegate to when something can not be found in itself). And as Hanno and Godefroid mentioned, plone.testing does something in this direction already. (And, it bears repeating, in its core has no dependencies on Plone or Zope2.) I like the idea of stacking registries. plone.testing implements this. If we could fix zope.component to make the implementation less ugly, that'd be a big win. But as far as I see, there are issues that plone.testing does not address: 1. I've been going over this stuff with my colleague Thomas Lotze, and 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 (one, you can only delete the registration from the precise registry it was created in, and two, in the just-bend-the-bases approach, once you delete a registration, it's gone forever). Correct, although this is in practice extremely rare. I'd say it's much better to control setup more carefully and not have to undo in a child layer. I think to provide full isolation, we need to make *copies*. And since zope.component in general supports a chain of registries, we probably need to make copies of each of them. Copying is very hard. It was my first attempt in plone.testing and didn't work out well. You need to support pickling of registries for local/persistent component registries. I cannot begin to tell you how many weird pickling errors I found and had to work around. 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. +1 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. Agree. There is a problem in that provideAdapter() and friends don't use getSiteManager() - the always use the global site manager. And there are parts of zope.component that use module level variables directly, ignoring hooks. 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 But as you point
Re: [Zope-dev] zope.component test isolation (was: Zope test layers, pytest, and test isolation)
On Fri, Mar 25, 2011 at 9:58 AM, Martin Aspeli optilude+li...@gmail.com wrote: On 25 March 2011 13:17, Jim Fulton j...@zope.com wrote: On Fri, Mar 25, 2011 at 4:24 AM, Wolfgang Schnerring w...@gocept.com wrote: ... 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. Agree. There is a problem in that provideAdapter() and friends don't use getSiteManager() - the always use the global site manager. And there are parts of zope.component that use module level variables directly, ignoring hooks. These are meant to work this way. If you want to do local configuration, you should explictly select the relevent registry/manager or call getSiteManager and use the result. -- but anyone could at any time call getSiteManager.sethook to change it! Seriously? Nobody calls that but deep infrastructure code. People do call zope.site.hooks.setHooks() sometimes, though, e.g. upon traversal. This was never meant to be an application-level feature. I find the notion that people would call these dureing traversal to be disturbing. Are you sure you're not confusing this with setSite? Jim -- Jim Fulton http://www.linkedin.com/in/jimfulton ___ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )
Re: [Zope-dev] zope.component test isolation
-BEGIN PGP SIGNED MESSAGE- Hash: SHA1 On 03/25/2011 09:58 AM, Martin Aspeli wrote: I would suggest a good starting point would be to see if you can make plone.testing.zca clean. It should be pretty obvious what is currently a hack. If you got there, you effectively have stacking of component registries. plone.testing would be simpler, and zope.component.testing would be able to provide a simple way to stack configuration by layer without a plone.testing dependency. If you ignore the delete use case (which I think is a non-use case), I think this is quite achievable in a sprint, say. +1 to this approach. Tres. - -- === Tres Seaver +1 540-429-0999 tsea...@palladion.com Palladion Software Excellence by Designhttp://palladion.com -BEGIN PGP SIGNATURE- Version: GnuPG v1.4.10 (GNU/Linux) Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/ iEYEARECAAYFAk2MpBsACgkQ+gerLs4ltQ7QQACgycVfipd/FvF6J8swGRJpZ2M9 SzcAniu9uvBS58WDcgxTxxllY+q8UmNX =Ljpu -END PGP SIGNATURE- ___ Zope-Dev maillist - Zope-Dev@zope.org https://mail.zope.org/mailman/listinfo/zope-dev ** No cross posts or HTML encoding! ** (Related lists - https://mail.zope.org/mailman/listinfo/zope-announce https://mail.zope.org/mailman/listinfo/zope )