Merge lp:~lifeless/testresources/bug-271619 into lp:~testresources-developers/testresources/trunk

Proposed by Robert Collins
Status: Merged
Merged at revision: not available
Proposed branch: lp:~lifeless/testresources/bug-271619
Merge into: lp:~testresources-developers/testresources/trunk
Diff against target: None lines
To merge this branch: bzr merge lp:~lifeless/testresources/bug-271619
Reviewer Review Type Date Requested Status
Jonathan Lange Approve
James Henstridge Pending
testresources developers Pending
Review via email: mp+7610@code.launchpad.net
To post a comment you must log in.
Revision history for this message
Jonathan Lange (jml) wrote :

I think this patch is fundamentally correct and adds a useful feature.

However, I think the docstring for `reset` should be changed so that the first line says something like, "Return a clean version of 'old_resource'". That is, it should describe what the method does.

The docstring should also provide some hints as to *why* one might want to override the method. One way to do this would be to follow-up the "By default" sentence with "If there is a faster way of resetting the resource than cleaning it and remaking it, you probably want to override this method to do that." Or something along those lines.

Thanks for the patch & for dealing with this long-dormant bug.

jml

review: Approve
Revision history for this message
Robert Collins (lifeless) wrote :

Some views on code only show the first line, and as an intentionally overridable method I think its important to keep that in there. However - "Overridable method to return a clean version of old_resource." should meet your points too.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
=== modified file 'NEWS'
--- NEWS 2009-06-17 10:23:42 +0000
+++ NEWS 2009-06-18 10:36:00 +0000
@@ -19,6 +19,11 @@
1919
20 * Expanded TODO. (Jonathan Lange)20 * Expanded TODO. (Jonathan Lange)
2121
22 * Resources can now be reset by overriding TestResource.reset, which for
23 some resources is significantly cheaper. If checking for dirtiness is
24 expensive, isDirty can also be overridden.
25 (James Henstridge, Robert Collins)
26
22 * Started keeping a NEWS file! (Jonathan Lange)27 * Started keeping a NEWS file! (Jonathan Lange)
2328
24 BUG FIXES:29 BUG FIXES:
2530
=== modified file 'lib/testresources/__init__.py'
--- lib/testresources/__init__.py 2009-06-17 10:23:42 +0000
+++ lib/testresources/__init__.py 2009-06-18 10:36:00 +0000
@@ -203,7 +203,7 @@
203 self._currentResource = None203 self._currentResource = None
204 self.resources = list(getattr(self.__class__, "resources", []))204 self.resources = list(getattr(self.__class__, "resources", []))
205205
206 def clean_all(self, resource):206 def _clean_all(self, resource):
207 """Clean the dependencies from resource, and then resource itself."""207 """Clean the dependencies from resource, and then resource itself."""
208 self.clean(resource)208 self.clean(resource)
209 for name, manager in self.resources:209 for name, manager in self.resources:
@@ -233,7 +233,7 @@
233 """233 """
234 self._uses -= 1234 self._uses -= 1
235 if self._uses == 0:235 if self._uses == 0:
236 self.clean_all(resource)236 self._clean_all(resource)
237 self._setResource(None)237 self._setResource(None)
238238
239 def getResource(self):239 def getResource(self):
@@ -245,9 +245,9 @@
245 that it is no longer needed.245 that it is no longer needed.
246 """246 """
247 if self._uses == 0:247 if self._uses == 0:
248 self._setResource(self.make_all())248 self._setResource(self._make_all())
249 elif self.isDirty():249 elif self.isDirty():
250 self._resetResource(self._currentResource)250 self._setResource(self.reset(self._currentResource))
251 self._uses += 1251 self._uses += 1
252 return self._currentResource252 return self._currentResource
253253
@@ -269,7 +269,7 @@
269 finally:269 finally:
270 mgr.finishedWith(res)270 mgr.finishedWith(res)
271271
272 def make_all(self):272 def _make_all(self):
273 """Make the dependencies of this resource and this resource."""273 """Make the dependencies of this resource and this resource."""
274 dependency_resources = {}274 dependency_resources = {}
275 for name, resource in self.resources:275 for name, resource in self.resources:
@@ -305,9 +305,23 @@
305 result.append(self)305 result.append(self)
306 return result306 return result
307307
308 def _resetResource(self, old_resource):308 def reset(self, old_resource):
309 self.clean_all(old_resource)309 """Override this to reset resources.
310 self._setResource(self.make_all())310
311 By default, the resource will be cleaned then remade if it had
312 previously been `dirtied`.
313
314 This function needs to take the dependent resource stack into
315 consideration as _make_all and _clean_all do.
316
317 :return: The new resource.
318 """
319 if self._dirty:
320 self._clean_all(old_resource)
321 resource = self._make_all()
322 else:
323 resource = old_resource
324 return resource
311325
312 def _setResource(self, new_resource):326 def _setResource(self, new_resource):
313 """Set the current resource to a new value."""327 """Set the current resource to a new value."""
314328
=== modified file 'lib/testresources/tests/test_test_resource.py'
--- lib/testresources/tests/test_test_resource.py 2009-06-17 10:23:42 +0000
+++ lib/testresources/tests/test_test_resource.py 2009-06-18 10:36:00 +0000
@@ -57,6 +57,19 @@
57 return MockResourceInstance("Boo!")57 return MockResourceInstance("Boo!")
5858
5959
60class MockResettableResource(MockResource):
61 """Mock resource that logs the number of reset calls too."""
62
63 def __init__(self):
64 MockResource.__init__(self)
65 self.resets = 0
66
67 def reset(self, resource):
68 self.resets += 1
69 resource._name += "!"
70 return resource
71
72
60class TestTestResource(testtools.TestCase):73class TestTestResource(testtools.TestCase):
6174
62 def testUnimplementedGetResource(self):75 def testUnimplementedGetResource(self):
@@ -183,6 +196,33 @@
183 resource_manager.getResource()196 resource_manager.getResource()
184 self.assertEqual(1, resource_manager.makes)197 self.assertEqual(1, resource_manager.makes)
185198
199 def testGetResourceResetsUsedResource(self):
200 resource_manager = MockResettableResource()
201 resource_manager.getResource()
202 resource = resource_manager.getResource()
203 self.assertEqual(1, resource_manager.makes)
204 resource_manager.dirtied(resource)
205 resource_manager.getResource()
206 self.assertEqual(1, resource_manager.makes)
207 self.assertEqual(1, resource_manager.resets)
208 resource_manager.finishedWith(resource)
209
210 def testUsedResourceResetBetweenUses(self):
211 resource_manager = MockResettableResource()
212 # take two refs; like happens with OptimisingTestSuite.
213 resource_manager.getResource()
214 resource = resource_manager.getResource()
215 resource_manager.dirtied(resource)
216 resource_manager.finishedWith(resource)
217 # Get again, but its been dirtied.
218 resource = resource_manager.getResource()
219 resource_manager.finishedWith(resource)
220 resource_manager.finishedWith(resource)
221 # The resource is made once, reset once and cleaned once.
222 self.assertEqual(1, resource_manager.makes)
223 self.assertEqual(1, resource_manager.resets)
224 self.assertEqual(1, resource_manager.cleans)
225
186 def testFinishedWithDecrementsUses(self):226 def testFinishedWithDecrementsUses(self):
187 resource_manager = MockResource()227 resource_manager = MockResource()
188 resource = resource_manager.getResource()228 resource = resource_manager.getResource()
@@ -237,6 +277,8 @@
237 resource_manager.finishedWith(resource)277 resource_manager.finishedWith(resource)
238 self.assertIs(resource, resource_manager._currentResource)278 self.assertIs(resource, resource_manager._currentResource)
239279
280 # The default implementation of reset() performs a make/clean if
281 # the dirty flag is set.
240 def testDirtiedSetsDirty(self):282 def testDirtiedSetsDirty(self):
241 resource_manager = MockResource()283 resource_manager = MockResource()
242 resource = resource_manager.getResource()284 resource = resource_manager.getResource()
@@ -257,15 +299,23 @@
257 resource_manager.finishedWith(resource1)299 resource_manager.finishedWith(resource1)
258 self.assertEqual(2, resource_manager.cleans)300 self.assertEqual(2, resource_manager.cleans)
259301
260 def testDirtyingResourceTriggersRemake(self):302 def testDefaultResetMethodPreservesCleanResource(self):
303 resource_manager = MockResource()
304 resource = resource_manager.getResource()
305 self.assertEqual(1, resource_manager.makes)
306 self.assertEqual(False, resource_manager._dirty)
307 resource_manager.reset(resource)
308 self.assertEqual(1, resource_manager.makes)
309 self.assertEqual(0, resource_manager.cleans)
310
311 def testDefaultResetMethodRecreatesDirtyResource(self):
261 resource_manager = MockResource()312 resource_manager = MockResource()
262 resource = resource_manager.getResource()313 resource = resource_manager.getResource()
263 self.assertEqual(1, resource_manager.makes)314 self.assertEqual(1, resource_manager.makes)
264 resource_manager.dirtied(resource)315 resource_manager.dirtied(resource)
265 resource_manager.getResource()316 resource_manager.reset(resource)
317 self.assertEqual(2, resource_manager.makes)
266 self.assertEqual(1, resource_manager.cleans)318 self.assertEqual(1, resource_manager.cleans)
267 self.assertEqual(2, resource_manager.makes)
268 self.assertEqual(False, resource_manager._dirty)
269319
270 def testDirtyingWhenUnused(self):320 def testDirtyingWhenUnused(self):
271 resource_manager = MockResource()321 resource_manager = MockResource()

Subscribers

People subscribed via source and target branches