From 3838a4d70aaee73f681e81344821955af1a1a627 Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Wed, 17 Jun 2009 22:01:49 +1000 Subject: Allow tracing of TestResource activity by passing a trace_function to TestResource, fixing bug 284125. --- NEWS | 4 ++++ lib/testresources/__init__.py | 11 ++++++++++- lib/testresources/tests/test_test_resource.py | 14 ++++++++++++-- 3 files changed, 26 insertions(+), 3 deletions(-) diff --git a/NEWS b/NEWS index 004e376..260b7d9 100644 --- a/NEWS +++ b/NEWS @@ -21,6 +21,10 @@ IN DEVELOPMENT * Started keeping a NEWS file! (Jonathan Lange) + * A trace_function can be supplied when constructing TestResource objects, + to allow debugging of when resources are made/cleaned. (Robert Collins, + #284125) + BUG FIXES: * Calling getResource on a dirty resource now triggers a clean and re-make diff --git a/lib/testresources/__init__.py b/lib/testresources/__init__.py index 4bc7ef4..adccecd 100644 --- a/lib/testresources/__init__.py +++ b/lib/testresources/__init__.py @@ -197,14 +197,22 @@ class TestResource(object): setUpCost = 1 tearDownCost = 1 - def __init__(self): + def __init__(self, trace_function=None): + """Create a TestResource object. + + :param trace_function: A callable that takes strings to output. This + will be called with trace messages when the resource is made and + cleaned. + """ self._dirty = False self._uses = 0 self._currentResource = None self.resources = list(getattr(self.__class__, "resources", [])) + self._trace = trace_function or (lambda x:"") def _clean_all(self, resource): """Clean the dependencies from resource, and then resource itself.""" + self._trace("clean: %s\n" % self) self.clean(resource) for name, manager in self.resources: manager.finishedWith(getattr(resource, name)) @@ -271,6 +279,7 @@ class TestResource(object): def _make_all(self): """Make the dependencies of this resource and this resource.""" + self._trace("make: %s\n" % self) dependency_resources = {} for name, resource in self.resources: dependency_resources[name] = resource.getResource() diff --git a/lib/testresources/tests/test_test_resource.py b/lib/testresources/tests/test_test_resource.py index a11c987..83abfbe 100644 --- a/lib/testresources/tests/test_test_resource.py +++ b/lib/testresources/tests/test_test_resource.py @@ -44,8 +44,8 @@ class MockResourceInstance(object): class MockResource(testresources.TestResource): """Mock resource that logs the number of make and clean calls.""" - def __init__(self): - testresources.TestResource.__init__(self) + def __init__(self, trace_function=None): + testresources.TestResource.__init__(self, trace_function=trace_function) self.makes = 0 self.cleans = 0 @@ -275,3 +275,13 @@ class TestTestResource(testtools.TestCase): self.assertEqual(1, resource_manager.makes) resource = resource_manager.getResource() self.assertEqual(2, resource_manager.makes) + + def testTraceFunction(self): + output = [] + resource_manager = MockResource(trace_function=output.append) + expected = ["make: %s\n" % resource_manager] + r = resource_manager.getResource() + self.assertEqual(expected, output) + expected.append("clean: %s\n" % resource_manager) + resource_manager.finishedWith(r) + self.assertEqual(expected, output) -- cgit v1.2.1 From 6c40fbcb817b9c9ab49585184db6f3209c32a702 Mon Sep 17 00:00:00 2001 From: Robert Collins Date: Thu, 18 Jun 2009 20:59:14 +1000 Subject: Review feedback - make the trace happen around make and clean not just before, and pass structed info not a formatted string. --- lib/testresources/__init__.py | 8 +++++--- lib/testresources/tests/test_test_resource.py | 10 +++++++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/lib/testresources/__init__.py b/lib/testresources/__init__.py index adccecd..dc373dd 100644 --- a/lib/testresources/__init__.py +++ b/lib/testresources/__init__.py @@ -208,14 +208,15 @@ class TestResource(object): self._uses = 0 self._currentResource = None self.resources = list(getattr(self.__class__, "resources", [])) - self._trace = trace_function or (lambda x:"") + self._trace = trace_function or (lambda x,y,z:"") def _clean_all(self, resource): """Clean the dependencies from resource, and then resource itself.""" - self._trace("clean: %s\n" % self) + self._trace("clean", "start", self) self.clean(resource) for name, manager in self.resources: manager.finishedWith(getattr(resource, name)) + self._trace("clean", "stop", self) def clean(self, resource): """Override this to class method to hook into resource removal.""" @@ -279,13 +280,14 @@ class TestResource(object): def _make_all(self): """Make the dependencies of this resource and this resource.""" - self._trace("make: %s\n" % self) + self._trace("make", "start", self) dependency_resources = {} for name, resource in self.resources: dependency_resources[name] = resource.getResource() result = self.make(dependency_resources) for name, value in dependency_resources.items(): setattr(result, name, value) + self._trace("make", "stop", self) return result def make(self, dependency_resources): diff --git a/lib/testresources/tests/test_test_resource.py b/lib/testresources/tests/test_test_resource.py index 83abfbe..392f891 100644 --- a/lib/testresources/tests/test_test_resource.py +++ b/lib/testresources/tests/test_test_resource.py @@ -278,10 +278,14 @@ class TestTestResource(testtools.TestCase): def testTraceFunction(self): output = [] - resource_manager = MockResource(trace_function=output.append) - expected = ["make: %s\n" % resource_manager] + def trace(operation, phase, mgr): + output.append((operation, phase, mgr)) + resource_manager = MockResource(trace_function=trace) + expected = [("make", "start", resource_manager), + ("make", "stop", resource_manager)] r = resource_manager.getResource() self.assertEqual(expected, output) - expected.append("clean: %s\n" % resource_manager) + expected.extend([("clean", "start", resource_manager), + ("clean", "stop", resource_manager)]) resource_manager.finishedWith(r) self.assertEqual(expected, output) -- cgit v1.2.1