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

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

I'm not sure of the exact uses Jonathan had for this API, but this does not look like what I'd have expected.

To turn on tracing with this API, it looks like I'd have to look through the entire test suite to find out where all the resource manages get instantiated and change the constructors. I'd have expected something closer to slotting in a different TestResult implementation into the test runner: something that can be done in one place and affects all resources. I'm not sure about the best way to do this though.

Second, it would be better to pass the TestResource instance and event type to the tracer rather than a formatted string. This would make it easier to do things like collect statistics about resource use and give the tracer a choice about how to format things.

Lastly, it might be worth adding a trace point before and after making/cleaning a resource. That would allow using the tracer API to calculate how much time those tasks are taking per-run and overall.

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

On Thu, 2009-06-18 at 09:50 +0000, James Henstridge wrote:
>
> I'm not sure of the exact uses Jonathan had for this API, but this
> does not look like what I'd have expected.
>
> To turn on tracing with this API, it looks like I'd have to look
> through the entire test suite to find out where all the resource
> manages get instantiated and change the constructors. I'd have
> expected something closer to slotting in a different TestResult
> implementation into the test runner: something that can be done in one
> place and affects all resources. I'm not sure about the best way to
> do this though.

Neither am I; I felt it was a good idea to get something up and running
to meet the need. Currently there are three points this could be set:
TestResource
OptimisingTestSuite
ResourcedTestCase

Of those:
- RTC is constructed by test discovery and is not positioned to set
state early enough.
- OTS can be got at more easily, but won't suffice if its not being
used.

which leaves TestResource. It can either take a parameter or use global
state. I have a very strong aversion to global state.

So while I agree with the sentiment about how to turn this on, I don't
have any better ideas that will work and be robust.

> Second, it would be better to pass the TestResource instance and event
> type to the tracer rather than a formatted string. This would make it
> easier to do things like collect statistics about resource use and
> give the tracer a choice about how to format things.
>
> Lastly, it might be worth adding a trace point before and after
> making/cleaning a resource. That would allow using the tracer API to
> calculate how much time those tasks are taking per-run and overall.

I will admit to having gone on the 'easiest' approach here; but sure I
can change it to send two parameters.

-Rob

36. By Robert Collins

Merge and simply James Henstridge's reset patch.

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

I've pushed a new commit that sends structured data and surrounds the operations.

I don't have any ideas vis-a-vis easy setup of this, so if noone else does I suggest landing it now as that could always be added later.

Revision history for this message
Jonathan Lange (jml) wrote :

In the bug report, you suggest that "we could extend the protocol more deeply and say that we'll emite to the TestResult object being used, IFF it supports an additional function[s] for recording TestResources." I think I like that approach.

However, I think you're right when you suggest that we land this now and incorporate better ideas when we actually have them.

It seems that the docstring for 'trace_function' is out of date. It says "A callable that takes strings to output." However your patch currently calls it with operation, phase & resource manager. Please update the docstring before landing the patch.

review: Approve
37. By Robert Collins

Review feedback.

38. By Robert Collins

Merge support for trace_functions in TestResource.

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'NEWS'
2--- NEWS 2009-06-17 10:23:42 +0000
3+++ NEWS 2009-06-17 12:01:49 +0000
4@@ -21,6 +21,10 @@
5
6 * Started keeping a NEWS file! (Jonathan Lange)
7
8+ * A trace_function can be supplied when constructing TestResource objects,
9+ to allow debugging of when resources are made/cleaned. (Robert Collins,
10+ #284125)
11+
12 BUG FIXES:
13
14 * Calling getResource on a dirty resource now triggers a clean and re-make
15
16=== modified file 'lib/testresources/__init__.py'
17--- lib/testresources/__init__.py 2009-06-17 10:23:42 +0000
18+++ lib/testresources/__init__.py 2009-06-17 12:01:49 +0000
19@@ -197,14 +197,22 @@
20 setUpCost = 1
21 tearDownCost = 1
22
23- def __init__(self):
24+ def __init__(self, trace_function=None):
25+ """Create a TestResource object.
26+
27+ :param trace_function: A callable that takes strings to output. This
28+ will be called with trace messages when the resource is made and
29+ cleaned.
30+ """
31 self._dirty = False
32 self._uses = 0
33 self._currentResource = None
34 self.resources = list(getattr(self.__class__, "resources", []))
35+ self._trace = trace_function or (lambda x:"")
36
37- def clean_all(self, resource):
38+ def _clean_all(self, resource):
39 """Clean the dependencies from resource, and then resource itself."""
40+ self._trace("clean: %s\n" % self)
41 self.clean(resource)
42 for name, manager in self.resources:
43 manager.finishedWith(getattr(resource, name))
44@@ -233,7 +241,7 @@
45 """
46 self._uses -= 1
47 if self._uses == 0:
48- self.clean_all(resource)
49+ self._clean_all(resource)
50 self._setResource(None)
51
52 def getResource(self):
53@@ -245,7 +253,7 @@
54 that it is no longer needed.
55 """
56 if self._uses == 0:
57- self._setResource(self.make_all())
58+ self._setResource(self._make_all())
59 elif self.isDirty():
60 self._resetResource(self._currentResource)
61 self._uses += 1
62@@ -269,8 +277,9 @@
63 finally:
64 mgr.finishedWith(res)
65
66- def make_all(self):
67+ def _make_all(self):
68 """Make the dependencies of this resource and this resource."""
69+ self._trace("make: %s\n" % self)
70 dependency_resources = {}
71 for name, resource in self.resources:
72 dependency_resources[name] = resource.getResource()
73@@ -306,8 +315,8 @@
74 return result
75
76 def _resetResource(self, old_resource):
77- self.clean_all(old_resource)
78- self._setResource(self.make_all())
79+ self._clean_all(old_resource)
80+ self._setResource(self._make_all())
81
82 def _setResource(self, new_resource):
83 """Set the current resource to a new value."""
84
85=== modified file 'lib/testresources/tests/test_test_resource.py'
86--- lib/testresources/tests/test_test_resource.py 2009-06-17 10:23:42 +0000
87+++ lib/testresources/tests/test_test_resource.py 2009-06-17 12:01:49 +0000
88@@ -44,8 +44,8 @@
89 class MockResource(testresources.TestResource):
90 """Mock resource that logs the number of make and clean calls."""
91
92- def __init__(self):
93- testresources.TestResource.__init__(self)
94+ def __init__(self, trace_function=None):
95+ testresources.TestResource.__init__(self, trace_function=trace_function)
96 self.makes = 0
97 self.cleans = 0
98
99@@ -275,3 +275,13 @@
100 self.assertEqual(1, resource_manager.makes)
101 resource = resource_manager.getResource()
102 self.assertEqual(2, resource_manager.makes)
103+
104+ def testTraceFunction(self):
105+ output = []
106+ resource_manager = MockResource(trace_function=output.append)
107+ expected = ["make: %s\n" % resource_manager]
108+ r = resource_manager.getResource()
109+ self.assertEqual(expected, output)
110+ expected.append("clean: %s\n" % resource_manager)
111+ resource_manager.finishedWith(r)
112+ self.assertEqual(expected, output)

Subscribers

People subscribed via source and target branches