| #!/usr/bin/python2 |
| # |
| # Copyright (c) 2012 The Chromium OS Authors. All rights reserved. |
| # Use of this source code is governed by a BSD-style license that can be |
| # found in the LICENSE file. |
| |
| """Unit tests for server/cros/dynamic_suite/host_spec.py.""" |
| |
| import mox |
| import unittest |
| |
| import common |
| |
| from autotest_lib.server.cros.dynamic_suite import host_spec |
| from autotest_lib.server.cros.dynamic_suite.fakes import FakeHost |
| |
| |
| class HostSpecTest(mox.MoxTestBase): |
| """Unit tests for dynamic_suite.host_spec module. |
| |
| @var _BOARD: fake board to reimage |
| """ |
| |
| |
| _BOARD = 'board' |
| _SPECS = [host_spec.HostSpec([_BOARD]), |
| host_spec.HostSpec([_BOARD, 'pool:bvt']), |
| host_spec.HostSpec([_BOARD], ['label1'])] |
| |
| |
| def testOrderSpecsByComplexity(self): |
| """Should return new host spec list with simpler entries later.""" |
| reordered = host_spec.order_by_complexity(self._SPECS) |
| |
| for spec in self._SPECS[1:]: |
| self.assertTrue(spec in reordered[:-1]) |
| self.assertEquals(self._SPECS[0], reordered[-1]) |
| |
| |
| def testSpecSubsets(self): |
| """Validate HostSpec subset checks.""" |
| self.assertTrue(self._SPECS[0].is_subset(self._SPECS[1])) |
| self.assertTrue(self._SPECS[0].is_subset(self._SPECS[2])) |
| self.assertFalse(self._SPECS[1].is_subset(self._SPECS[2])) |
| self.assertFalse(self._SPECS[2].is_subset(self._SPECS[1])) |
| self.assertFalse(self._SPECS[1].is_subset(self._SPECS[0])) |
| self.assertFalse(self._SPECS[2].is_subset(self._SPECS[0])) |
| |
| |
| def testTrivialSpec(self): |
| """Validate that HostSpecs are correctly marked as trivial.""" |
| self.assertTrue(self._SPECS[0].is_trivial) |
| self.assertTrue(self._SPECS[1].is_trivial) |
| self.assertFalse(self._SPECS[2].is_trivial) |
| |
| |
| class HostGroupTest(mox.MoxTestBase): |
| """Unit tests for dynamic_suite.host_spec.HostGroup derived classes. |
| """ |
| |
| |
| def testCanConstructExplicit(self): |
| """Should be able to make an ExplicitHostGroup.""" |
| host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')] |
| hosts_per_spec = {host_spec.HostSpec(['l1']): host_list[:1], |
| host_spec.HostSpec(['l2']): host_list[1:]} |
| group = host_spec.ExplicitHostGroup(hosts_per_spec) |
| for host in host_list: |
| self.assertTrue(host.hostname in group.as_args()['hosts']) |
| |
| |
| def testExplicitEnforcesHostUniqueness(self): |
| """Should fail to make ExplicitHostGroup with duplicate hosts.""" |
| host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')] |
| hosts_per_spec = {host_spec.HostSpec(['l1']): host_list[:1], |
| host_spec.HostSpec(['l2']): host_list} |
| self.assertRaises(ValueError, |
| host_spec.ExplicitHostGroup, hosts_per_spec) |
| |
| |
| def testCanConstructByMetahostsWithDependencies(self): |
| """Should be able to make a HostGroup from labels.""" |
| labels = ['meta_host', 'dep1', 'dep2'] |
| num = 3 |
| group = host_spec.MetaHostGroup(labels, num) |
| args = group.as_args() |
| self.assertEquals(labels[:1] * num, args['meta_hosts']) |
| self.assertEquals(labels[1:], args['dependencies']) |
| |
| |
| def testExplicitCanTrackSuccess(self): |
| """Track success/failure in an ExplicitHostGroup.""" |
| host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')] |
| specs = [host_spec.HostSpec(['l1']), host_spec.HostSpec(['l2'])] |
| hosts_per_spec = {specs[0]: host_list[:1], specs[1]: host_list[1:]} |
| group = host_spec.ExplicitHostGroup(hosts_per_spec) |
| |
| # Reimage just the one host that satisfies specs[0]. |
| group.mark_host_success(host_list[0].hostname) |
| self.assertTrue(group.enough_hosts_succeeded()) |
| self.assertTrue(specs[1] in group.doomed_specs) |
| |
| # Reimage some host that satisfies specs[1]. |
| group.mark_host_success(host_list[2].hostname) |
| self.assertTrue(group.enough_hosts_succeeded()) |
| self.assertFalse(group.doomed_specs) |
| |
| |
| def testExplicitCanTrackSuccessWithSupersets(self): |
| """Track success/failure in an ExplicitHostGroup with supersets.""" |
| host_list = [FakeHost('h1'), FakeHost('h2'), FakeHost('h3')] |
| specs = [host_spec.HostSpec(['l1']), |
| host_spec.HostSpec(['l2']), |
| host_spec.HostSpec(['l2', 'l1'])] |
| hosts_per_spec = {specs[0]: host_list[:1], |
| specs[1]: host_list[1:2], |
| specs[2]: host_list[2:]} |
| group = host_spec.ExplicitHostGroup(hosts_per_spec) |
| |
| # Reimage just the one host that satisfies specs[2]. |
| # Because satisfying specs[2] statisfies all the specs, we should have |
| # no doomed specs. |
| group.mark_host_success(host_list[2].hostname) |
| self.assertTrue(group.enough_hosts_succeeded()) |
| self.assertFalse(group.doomed_specs) |
| |
| |
| def testExplicitCanTrackUnsatisfiedSpecs(self): |
| """Track unsatisfiable HostSpecs in ExplicitHostGroup.""" |
| group = host_spec.ExplicitHostGroup() |
| satisfiable_spec = host_spec.HostSpec(['l2']) |
| unsatisfiable_spec = host_spec.HostSpec(['l1'], ['e1']) |
| group.add_host_for_spec(unsatisfiable_spec, None) |
| group.add_host_for_spec(satisfiable_spec, FakeHost('h1')) |
| self.assertTrue(unsatisfiable_spec in group.unsatisfied_specs) |
| self.assertTrue(satisfiable_spec not in group.unsatisfied_specs) |
| |
| |
| def testExplicitOneHostEnoughToSatisfySpecs(self): |
| """One host is enough to satisfy a HostSpec in ExplicitHostGroup.""" |
| satisfiable_spec = host_spec.HostSpec(['l1']) |
| group = host_spec.ExplicitHostGroup() |
| group.add_host_for_spec(satisfiable_spec, FakeHost('h1')) |
| group.add_host_for_spec(satisfiable_spec, None) |
| self.assertTrue(satisfiable_spec not in group.unsatisfied_specs) |
| |
| group = host_spec.ExplicitHostGroup() |
| group.add_host_for_spec(satisfiable_spec, None) |
| group.add_host_for_spec(satisfiable_spec, FakeHost('h1')) |
| self.assertTrue(satisfiable_spec not in group.unsatisfied_specs) |
| |
| |
| def testExplicitSubsetSpecSatisfiedIfAnyAre(self): |
| """Ensures that any satisfied spec also satisfies a subset HostSpec.""" |
| specs = [host_spec.HostSpec(['l1'], ['l3']), |
| host_spec.HostSpec(['l1'], ['l3', 'l4']), |
| host_spec.HostSpec(['l1'], ['l5', 'l4']), |
| host_spec.HostSpec(['l1'], ['l2', 'l3', 'l4'])] |
| group = host_spec.ExplicitHostGroup() |
| group.add_host_for_spec(specs[0], None) |
| group.add_host_for_spec(specs[1], FakeHost('h1')) |
| group.add_host_for_spec(specs[2], FakeHost('h2')) |
| group.add_host_for_spec(specs[3], None) |
| |
| self.assertTrue(specs[0] not in group.unsatisfied_specs) |
| self.assertTrue(specs[1] not in group.unsatisfied_specs) |
| self.assertTrue(specs[2] not in group.unsatisfied_specs) |
| self.assertTrue(specs[3] in group.unsatisfied_specs) |
| |
| |
| def testMetaCanTrackSuccess(self): |
| """Track success/failure in a MetaHostGroup.""" |
| labels = ['meta_host', 'dep1', 'dep2'] |
| num = 3 |
| group = host_spec.MetaHostGroup(labels, num) |
| |
| self.assertFalse(group.enough_hosts_succeeded()) |
| |
| group.mark_host_success('h1') |
| self.assertTrue(group.enough_hosts_succeeded()) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |