def testBasicSortTests(self):
        # Test every permutation of inputs, with legacy tests.
        # Cannot use equal costs because of the use of
        # a 2*optimal heuristic for sorting: with equal
        # costs the wrong sort order is < twice the optimal
        # weight, and thus can be selected.
        resource_one = testresources.TestResource()
        resource_two = testresources.TestResource()
        resource_two.setUpCost = 5
        resource_two.tearDownCost = 5
        resource_three = testresources.TestResource()

        self.case1.resources = [("_one", resource_one), ("_two", resource_two)]
        self.case2.resources = [("_two", resource_two),
                                ("_three", resource_three)]
        self.case3.resources = [("_three", resource_three)]
        # acceptable sorted orders are:
        # 1, 2, 3, 4
        # 3, 2, 1, 4

        for permutation in self._permute_four(self.cases):
            self.assertIn(self.sortTests(permutation),
                          [[self.case1, self.case2, self.case3, self.case4],
                           [self.case3, self.case2, self.case1, self.case4]],
                          "failed with permutation %s" % (permutation, ))
 def testneededResourcesClosure(self):
     # Calling neededResources on a TestResource with dependencies includes
     # the needed resources of the needed resources.
     resource = testresources.TestResource()
     dep1 = testresources.TestResource()
     dep2 = testresources.TestResource()
     resource.resources.append(("dep1", dep1))
     dep1.resources.append(("dep2", dep2))
     self.assertEqual([dep2, dep1, resource], resource.neededResources())
 def testneededResourcesDependenciesFirst(self):
     # Calling neededResources on a TestResource with dependencies puts the
     # dependencies first.
     resource = testresources.TestResource()
     dep1 = testresources.TestResource()
     dep2 = testresources.TestResource()
     resource.resources.append(("dep1", dep1))
     resource.resources.append(("dep2", dep2))
     self.assertEqual([dep1, dep2, resource], resource.neededResources())
 def testDependentResources(self):
     resource1 = testresources.TestResource()
     resource2 = testresources.TestResource()
     resource1.resources = [('foo', resource2)]
     resourced_case = self.makeResourcedTestCase(has_resource=False)
     resourced_case.resources = [('resource1', resource1)]
     resource_set_tests = split_by_resources([resourced_case])
     self.assertEqual(
         {
             frozenset(): [],
             frozenset([resource1, resource2]): [resourced_case]
         }, resource_set_tests)
    def testGlobalMinimum(self):
        # When a local minimum leads to a global non-minum, the global
        # non-minimum is still reached. We construct this by having a resource
        # that appears very cheap (it has a low setup cost) but is very
        # expensive to tear down. Then we have it be used twice: the global
        # minimum depends on only tearing it down once. To prevent it
        # accidentally being chosen twice, we make one use of it be
        # on its own, and another with a resource to boost its cost,
        # finally we put a resource which is more expensive to setup
        # than the expensive teardown is to teardown, but less expensive
        # than it + the small booster to setup.
        # valid results are - the expensive setup, then both expensive
        # teardowns, and the legacy fourth, or
        # both expensive teardowns and then the expensive setup (and the legacy
        # fourth)
        # case1 has expensive setup (one)
        # case2 has expensive teardown (two)
        # case3 has expensive teardown + boost (three)
        resource_one = testresources.TestResource()
        resource_one.setUpCost = 20
        resource_two = testresources.TestResource()
        resource_two.tearDownCost = 50
        resource_three = testresources.TestResource()
        resource_three.setUpCost = 72
        # node costs:
        #  ->1 = r1.up                    = 20
        #  ->2 = r2.up                    = 1
        #  ->3 = r2.up + r3.up            = 122
        # 1->2 = r1.down + r2.up          = 2
        # 1->3 = r1.down + r2.up + r3.up  = 93
        # 2->1 = r2.down + r1.up          = 70
        # 2->3 = r3.up                    = 72
        # 3->1 = r1.up + r2.down + r3.down= 71
        # 3->2 = r3.down                  = 1
        # 1->  = r1.down                  = 1
        # 2->  = r2.down                  = 50
        # 3->  = r3.down + r3.down        = 51
        # naive path = 2, 1, 3 = 1 + 70 + 93 + 51 = 215
        # better    = 2, 3, 1 = 1 + 72 + 71 + 1 = 145
        acceptable_orders = [
            [self.case1, self.case2, self.case3, self.case4],
            [self.case1, self.case3, self.case2, self.case4],
            [self.case2, self.case3, self.case1, self.case4],
            [self.case3, self.case2, self.case1, self.case4],
        ]

        self.case1.resources = [("_one", resource_one)]
        self.case2.resources = [("_two", resource_two)]
        self.case3.resources = [("_two", resource_two),
                                ("_three", resource_three)]
        for permutation in self._permute_four(self.cases):
            self.assertIn(self.sortTests(permutation), acceptable_orders)
    def testSortConsidersDependencies(self):
        """Tests with different dependencies are sorted together."""
        # We test this by having two resources (one and two) that share a very
        # expensive dependency (dep). So one and two have to sort together. By
        # using a cheap resource directly from several tests we can force the
        # optimise to choose between keeping the cheap resource together or
        # keeping the expensive dependency together.
        # Test1, res_one, res_common_one
        # Test2, res_two, res_common_two
        # Test3, res_common_one, res_common_two
        # In a dependency naive sort, we will have test3 between test1 and
        # test2 always. In a dependency aware sort, test1 and two will
        # always group.

        resource_one = testresources.TestResource()
        resource_two = testresources.TestResource()
        resource_one_common = testresources.TestResource()
        # make it cheaper to keep a _common resource than to switch both
        # resources (when dependencies are ignored)
        resource_one_common.setUpCost = 2
        resource_one_common.tearDownCost = 2
        resource_two_common = testresources.TestResource()
        resource_two_common.setUpCost = 2
        resource_two_common.tearDownCost = 2
        dep = testresources.TestResource()
        dep.setUpCost = 20
        dep.tearDownCost = 20
        resource_one.resources.append(("dep1", dep))
        resource_two.resources.append(("dep2", dep))

        self.case1.resources = [("withdep", resource_one),
                                ("common", resource_one_common)]
        self.case2.resources = [("withdep", resource_two),
                                ("common", resource_two_common)]
        self.case3.resources = [("_one", resource_one_common),
                                ("_two", resource_two_common)]
        self.case4.resources = []

        acceptable_orders = [
            [self.case1, self.case2, self.case3, self.case4],
            [self.case2, self.case1, self.case3, self.case4],
            [self.case3, self.case1, self.case2, self.case4],
            [self.case3, self.case2, self.case1, self.case4],
        ]

        for permutation in self._permute_four(self.cases):
            self.assertIn(self.sortTests(permutation), acceptable_orders)
    def testSortIsStableWithinGroups(self):
        """Tests with the same resources maintain their relative order."""
        resource_one = testresources.TestResource()
        resource_two = testresources.TestResource()

        self.case1.resources = [("_one", resource_one)]
        self.case2.resources = [("_one", resource_one)]
        self.case3.resources = [("_one", resource_one), ("_two", resource_two)]
        self.case4.resources = [("_one", resource_one), ("_two", resource_two)]

        for permutation in self._permute_four(self.cases):
            sorted = self.sortTests(permutation)
            self.assertEqual(
                permutation.index(self.case1) < permutation.index(self.case2),
                sorted.index(self.case1) < sorted.index(self.case2))
            self.assertEqual(
                permutation.index(self.case3) < permutation.index(self.case4),
                sorted.index(self.case3) < sorted.index(self.case4))
class TestSplitByResources(testtools.TestCase):
    """Tests for split_by_resources."""
    def makeTestCase(self):
        return unittest.TestCase('run')

    def makeResourcedTestCase(self, has_resource=True):
        case = testresources.ResourcedTestCase('run')
        if has_resource:
            case.resources = [('resource', testresources.TestResource())]
 def makeResource(self, setUpCost=1, tearDownCost=1):
     resource = testresources.TestResource()
     resource.setUpCost = setUpCost
     resource.tearDownCost = tearDownCost
     return resource
Exemplo n.º 10
0
 def testneededResourcesDefault(self):
     # Calling neededResources on a default TestResource returns the
     # resource.
     resource = testresources.TestResource()
     self.assertEqual([resource], resource.neededResources())
Exemplo n.º 11
0
 def testInitiallyNoCurrentResource(self):
     resource_manager = testresources.TestResource()
     self.assertEqual(None, resource_manager._currentResource)
Exemplo n.º 12
0
 def testInitiallyUnused(self):
     resource_manager = testresources.TestResource()
     self.assertEqual(0, resource_manager._uses)
Exemplo n.º 13
0
 def testInitiallyNotDirty(self):
     resource_manager = testresources.TestResource()
     self.assertEqual(False, resource_manager._dirty)
Exemplo n.º 14
0
 def testUnimplementedGetResource(self):
     # By default, TestResource raises NotImplementedError on getResource
     # because make is not defined initially.
     resource_manager = testresources.TestResource()
     self.assertRaises(NotImplementedError, resource_manager.getResource)
Exemplo n.º 15
0
 def testDefaultCosts(self):
     # The base TestResource costs 1 to set up and to tear down.
     resource_manager = testresources.TestResource()
     self.assertEqual(resource_manager.setUpCost, 1)
     self.assertEqual(resource_manager.tearDownCost, 1)