#!/usr/bin/python # # 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()