Home | History | Annotate | Download | only in dynamic_suite
      1 #!/usr/bin/python
      2 #
      3 # Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      4 # Use of this source code is governed by a BSD-style license that can be
      5 # found in the LICENSE file.
      6 
      7 """Unit tests for server/cros/dynamic_suite/host_spec.py."""
      8 
      9 import mox
     10 import unittest
     11 
     12 import common
     13 
     14 from autotest_lib.server.cros.dynamic_suite import host_spec
     15 from autotest_lib.server.cros.dynamic_suite.fakes import FakeHost
     16 
     17 
     18 class HostSpecTest(mox.MoxTestBase):
     19     """Unit tests for dynamic_suite.host_spec module.
     20 
     21     @var _BOARD: fake board to reimage
     22     """
     23 
     24 
     25     _BOARD = 'board'
     26     _SPECS = [host_spec.HostSpec([_BOARD]),
     27               host_spec.HostSpec([_BOARD, 'pool:bvt']),
     28               host_spec.HostSpec([_BOARD], ['label1'])]
     29 
     30 
     31     def testOrderSpecsByComplexity(self):
     32         """Should return new host spec list with simpler entries later."""
     33         reordered = host_spec.order_by_complexity(self._SPECS)
     34 
     35         for spec in self._SPECS[1:]:
     36             self.assertTrue(spec in reordered[:-1])
     37         self.assertEquals(self._SPECS[0], reordered[-1])
     38 
     39 
     40     def testSpecSubsets(self):
     41         """Validate HostSpec subset checks."""
     42         self.assertTrue(self._SPECS[0].is_subset(self._SPECS[1]))
     43         self.assertTrue(self._SPECS[0].is_subset(self._SPECS[2]))
     44         self.assertFalse(self._SPECS[1].is_subset(self._SPECS[2]))
     45         self.assertFalse(self._SPECS[2].is_subset(self._SPECS[1]))
     46         self.assertFalse(self._SPECS[1].is_subset(self._SPECS[0]))
     47         self.assertFalse(self._SPECS[2].is_subset(self._SPECS[0]))
     48 
     49 
     50     def testTrivialSpec(self):
     51         """Validate that HostSpecs are correctly marked as trivial."""
     52         self.assertTrue(self._SPECS[0].is_trivial)
     53         self.assertTrue(self._SPECS[1].is_trivial)
     54         self.assertFalse(self._SPECS[2].is_trivial)
     55 
     56 
     57 class HostGroupTest(mox.MoxTestBase):
     58     """Unit tests for dynamic_suite.host_spec.HostGroup derived classes.
     59     """
     60 
     61 
     62     def testCanConstructExplicit(self):
     63         """Should be able to make an ExplicitHostGroup."""
     64         host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')]
     65         hosts_per_spec = {host_spec.HostSpec(['l1']): host_list[:1],
     66                           host_spec.HostSpec(['l2']): host_list[1:]}
     67         group = host_spec.ExplicitHostGroup(hosts_per_spec)
     68         for host in host_list:
     69             self.assertTrue(host.hostname in group.as_args()['hosts'])
     70 
     71 
     72     def testExplicitEnforcesHostUniqueness(self):
     73         """Should fail to make ExplicitHostGroup with duplicate hosts."""
     74         host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')]
     75         hosts_per_spec = {host_spec.HostSpec(['l1']): host_list[:1],
     76                           host_spec.HostSpec(['l2']): host_list}
     77         self.assertRaises(ValueError,
     78                           host_spec.ExplicitHostGroup, hosts_per_spec)
     79 
     80 
     81     def testCanConstructByMetahostsWithDependencies(self):
     82         """Should be able to make a HostGroup from labels."""
     83         labels = ['meta_host', 'dep1', 'dep2']
     84         num = 3
     85         group = host_spec.MetaHostGroup(labels, num)
     86         args = group.as_args()
     87         self.assertEquals(labels[:1] * num, args['meta_hosts'])
     88         self.assertEquals(labels[1:], args['dependencies'])
     89 
     90 
     91     def testExplicitCanTrackSuccess(self):
     92         """Track success/failure in an ExplicitHostGroup."""
     93         host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')]
     94         specs = [host_spec.HostSpec(['l1']), host_spec.HostSpec(['l2'])]
     95         hosts_per_spec = {specs[0]: host_list[:1], specs[1]: host_list[1:]}
     96         group = host_spec.ExplicitHostGroup(hosts_per_spec)
     97 
     98         # Reimage just the one host that satisfies specs[0].
     99         group.mark_host_success(host_list[0].hostname)
    100         self.assertTrue(group.enough_hosts_succeeded())
    101         self.assertTrue(specs[1] in group.doomed_specs)
    102 
    103         # Reimage some host that satisfies specs[1].
    104         group.mark_host_success(host_list[2].hostname)
    105         self.assertTrue(group.enough_hosts_succeeded())
    106         self.assertFalse(group.doomed_specs)
    107 
    108 
    109     def testExplicitCanTrackSuccessWithSupersets(self):
    110         """Track success/failure in an ExplicitHostGroup with supersets."""
    111         host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')]
    112         specs = [host_spec.HostSpec(['l1']),
    113                  host_spec.HostSpec(['l2']),
    114                  host_spec.HostSpec(['l2', 'l1'])]
    115         hosts_per_spec = {specs[0]: host_list[:1],
    116                           specs[1]: host_list[1:2],
    117                           specs[2]: host_list[2:]}
    118         group = host_spec.ExplicitHostGroup(hosts_per_spec)
    119 
    120         # Reimage just the one host that satisfies specs[2].
    121         # Because satisfying specs[2] statisfies all the specs, we should have
    122         # no doomed specs.
    123         group.mark_host_success(host_list[2].hostname)
    124         self.assertTrue(group.enough_hosts_succeeded())
    125         self.assertFalse(group.doomed_specs)
    126 
    127 
    128     def testExplicitCanTrackUnsatisfiedSpecs(self):
    129         """Track unsatisfiable HostSpecs in ExplicitHostGroup."""
    130         group = host_spec.ExplicitHostGroup()
    131         satisfiable_spec = host_spec.HostSpec(['l2'])
    132         unsatisfiable_spec = host_spec.HostSpec(['l1'], ['e1'])
    133         group.add_host_for_spec(unsatisfiable_spec, None)
    134         group.add_host_for_spec(satisfiable_spec, FakeHost('h1'))
    135         self.assertTrue(unsatisfiable_spec in group.unsatisfied_specs)
    136         self.assertTrue(satisfiable_spec not in group.unsatisfied_specs)
    137 
    138 
    139     def testExplicitOneHostEnoughToSatisfySpecs(self):
    140         """One host is enough to satisfy a HostSpec in ExplicitHostGroup."""
    141         satisfiable_spec = host_spec.HostSpec(['l1'])
    142         group = host_spec.ExplicitHostGroup()
    143         group.add_host_for_spec(satisfiable_spec, FakeHost('h1'))
    144         group.add_host_for_spec(satisfiable_spec, None)
    145         self.assertTrue(satisfiable_spec not in group.unsatisfied_specs)
    146 
    147         group = host_spec.ExplicitHostGroup()
    148         group.add_host_for_spec(satisfiable_spec, None)
    149         group.add_host_for_spec(satisfiable_spec, FakeHost('h1'))
    150         self.assertTrue(satisfiable_spec not in group.unsatisfied_specs)
    151 
    152 
    153     def testExplicitSubsetSpecSatisfiedIfAnyAre(self):
    154         """Ensures that any satisfied spec also satisfies a subset HostSpec."""
    155         specs = [host_spec.HostSpec(['l1'], ['l3']),
    156                  host_spec.HostSpec(['l1'], ['l3', 'l4']),
    157                  host_spec.HostSpec(['l1'], ['l5', 'l4']),
    158                  host_spec.HostSpec(['l1'], ['l2', 'l3', 'l4'])]
    159         group = host_spec.ExplicitHostGroup()
    160         group.add_host_for_spec(specs[0], None)
    161         group.add_host_for_spec(specs[1], FakeHost('h1'))
    162         group.add_host_for_spec(specs[2], FakeHost('h2'))
    163         group.add_host_for_spec(specs[3], None)
    164 
    165         self.assertTrue(specs[0] not in group.unsatisfied_specs)
    166         self.assertTrue(specs[1] not in group.unsatisfied_specs)
    167         self.assertTrue(specs[2] not in group.unsatisfied_specs)
    168         self.assertTrue(specs[3] in group.unsatisfied_specs)
    169 
    170 
    171     def testMetaCanTrackSuccess(self):
    172         """Track success/failure in a MetaHostGroup."""
    173         labels = ['meta_host', 'dep1', 'dep2']
    174         num = 3
    175         group = host_spec.MetaHostGroup(labels, num)
    176 
    177         self.assertFalse(group.enough_hosts_succeeded())
    178 
    179         group.mark_host_success('h1')
    180         self.assertTrue(group.enough_hosts_succeeded())
    181 
    182 
    183 if __name__ == '__main__':
    184     unittest.main()
    185