summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJames Henstridge <james@jamesh.id.au>2008-12-03 13:16:06 +0900
committerJames Henstridge <james@jamesh.id.au>2008-12-03 13:16:06 +0900
commiteb732c5e47928a69c849bbd46166feb419be3a13 (patch)
treec5279c07679422e86352820e2dfb6b6f96506f0d
parent5236b637444ec37b5fb1c37e8eace7442acf00de (diff)
downloadtestresources-eb732c5e47928a69c849bbd46166feb419be3a13.tar.gz
Use _getGraph() to calculate the resource switching costs again. This
prevents duplicate calculation in sortTests().
-rw-r--r--lib/testresources/__init__.py41
-rw-r--r--lib/testresources/tests/test_optimising_test_suite.py32
2 files changed, 29 insertions, 44 deletions
diff --git a/lib/testresources/__init__.py b/lib/testresources/__init__.py
index 80b3e9a..0228421 100644
--- a/lib/testresources/__init__.py
+++ b/lib/testresources/__init__.py
@@ -121,6 +121,7 @@ class OptimisingTestSuite(unittest.TestSuite):
# actual tests and there can never be more.
resource_set_tests = split_by_resources(self._tests)
+ graph = self._getGraph(resource_set_tests.keys())
no_resources = frozenset()
# Recursive visit-all-nodes all-permutations.
def cost(from_set, resource_sets):
@@ -130,14 +131,13 @@ class OptimisingTestSuite(unittest.TestSuite):
"""
if not resource_sets:
# tear down last resources
- return self.cost_of_switching(from_set, no_resources), []
+ return graph[from_set][no_resources], []
costs = []
for to_set in resource_sets:
child_cost, child_order = cost(
to_set, resource_sets - set([to_set]))
- costs.append(
- (self.cost_of_switching(from_set, to_set) + child_cost,
- [to_set] + child_order))
+ costs.append((graph[from_set][to_set] + child_cost,
+ [to_set] + child_order))
return min(costs)
_, order = cost(no_resources,
set(resource_set_tests) - set([no_resources]))
@@ -145,30 +145,21 @@ class OptimisingTestSuite(unittest.TestSuite):
self._tests = sum(
(resource_set_tests[resource_set] for resource_set in order), [])
- def _getGraph(self, tests_with_resources):
+ def _getGraph(self, resource_sets):
"""Build a graph of the resource-using nodes.
- :return: A graph in the format the Dijkstra implementation requires,
- with start node 'start' (not reachable by anything)
+ :return: A complete directed graph of the switching costs
+ between each resource combination.
"""
- # build a mesh graph where a node is a test, and and the number of
- # resources to change to another test is the cost to travel straight
- # to that node.
- graph = dict((test, {}) for test in tests_with_resources)
- graph['start'] = {}
- while tests_with_resources:
- test = tests_with_resources.pop()
- test_resources = set(resource for name, resource in test.resources)
- for othertest in tests_with_resources:
- othertest_resources = set(
- resource for name, resource in othertest.resources)
- cost = self.cost_of_switching(
- test_resources, othertest_resources)
- graph[test][othertest] = cost
- graph[othertest][test] = cost
- # NB: a better cost metric is needed.
- graph['start'][test] = sum(resource.setUpCost for resource in
- test_resources)
+ graph = {}
+ for from_set in resource_sets:
+ graph[from_set] = {}
+ for to_set in resource_sets:
+ if from_set is to_set:
+ graph[from_set][to_set] = 0
+ else:
+ graph[from_set][to_set] = self.cost_of_switching(
+ from_set, to_set)
return graph
diff --git a/lib/testresources/tests/test_optimising_test_suite.py b/lib/testresources/tests/test_optimising_test_suite.py
index 9b50c01..a707212 100644
--- a/lib/testresources/tests/test_optimising_test_suite.py
+++ b/lib/testresources/tests/test_optimising_test_suite.py
@@ -264,36 +264,30 @@ class TestCostGraph(testtools.TestCase):
resource.tearDownCost = tearDownCost
return resource
- def makeTestWithResources(self, resources):
- case = testresources.ResourcedTestCase('run')
- case.resources = [
- (self.getUniqueString(), resource) for resource in resources]
- return case
-
def testEmptyGraph(self):
suite = testresources.OptimisingTestSuite()
graph = suite._getGraph([])
- self.assertEqual({'start':{}}, graph)
+ self.assertEqual({}, graph)
def testSingletonGraph(self):
- case = self.makeTestWithResources([self.makeResource()])
+ resource = self.makeResource()
suite = testresources.OptimisingTestSuite()
- graph = suite._getGraph([case])
- self.assertEqual({case: {}, 'start': {case: 1}}, graph)
+ graph = suite._getGraph([frozenset()])
+ self.assertEqual({frozenset(): {frozenset(): 0}}, graph)
def testTwoCasesInGraph(self):
res1 = self.makeResource()
res2 = self.makeResource()
- a = self.makeTestWithResources([res1, res2])
- b = self.makeTestWithResources([res2])
- suite = testresources.OptimisingTestSuite()
- graph = suite._getGraph([a, b])
- self.assertEqual(
- {a: {b: suite.cost_of_switching(set([res1, res2]), set([res2]))},
- b: {a: suite.cost_of_switching(set([res2]), set([res1, res2]))},
- 'start': {a: 2, b: 1},
- }, graph)
+ set1 = frozenset([res1, res2])
+ set2 = frozenset([res2])
+ no_resources = frozenset()
+
+ suite = testresources.OptimisingTestSuite()
+ graph = suite._getGraph([no_resources, set1, set2])
+ self.assertEqual({no_resources: {no_resources: 0, set1: 2, set2: 1},
+ set1: {no_resources: 2, set1: 0, set2: 1},
+ set2: {no_resources: 1, set1: 1, set2: 0}}, graph)
class TestGraphStuff(testtools.TestCase):