diff options
Diffstat (limited to 'crosperf/machine_image_manager_unittest.py')
-rwxr-xr-x | crosperf/machine_image_manager_unittest.py | 524 |
1 files changed, 277 insertions, 247 deletions
diff --git a/crosperf/machine_image_manager_unittest.py b/crosperf/machine_image_manager_unittest.py index fbbca7b6..1ea63b1c 100755 --- a/crosperf/machine_image_manager_unittest.py +++ b/crosperf/machine_image_manager_unittest.py @@ -1,12 +1,11 @@ #!/usr/bin/env python3 # -*- coding: utf-8 -*- -# Copyright 2015 The Chromium OS Authors. All rights reserved. +# Copyright 2015 The ChromiumOS Authors # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Unit tests for the MachineImageManager class.""" -from __future__ import print_function import random import unittest @@ -15,251 +14,282 @@ from machine_image_manager import MachineImageManager class MockLabel(object): - """Class for generating a mock Label.""" + """Class for generating a mock Label.""" - def __init__(self, name, remotes=None): - self.name = name - self.remote = remotes + def __init__(self, name, remotes=None): + self.name = name + self.remote = remotes - def __hash__(self): - """Provide hash function for label. + def __hash__(self): + """Provide hash function for label. - This is required because Label object is used inside a dict as key. - """ - return hash(self.name) + This is required because Label object is used inside a dict as key. + """ + return hash(self.name) - def __eq__(self, other): - """Provide eq function for label. + def __eq__(self, other): + """Provide eq function for label. - This is required because Label object is used inside a dict as key. - """ - return isinstance(other, MockLabel) and other.name == self.name + This is required because Label object is used inside a dict as key. + """ + return isinstance(other, MockLabel) and other.name == self.name class MockDut(object): - """Class for creating a mock Device-Under-Test (DUT).""" + """Class for creating a mock Device-Under-Test (DUT).""" - def __init__(self, name, label=None): - self.name = name - self.label_ = label + def __init__(self, name, label=None): + self.name = name + self.label_ = label class MachineImageManagerTester(unittest.TestCase): - """Class for testing MachineImageManager.""" - - def gen_duts_by_name(self, *names): - duts = [] - for n in names: - duts.append(MockDut(n)) - return duts - - def create_labels_and_duts_from_pattern(self, pattern): - labels = [] - duts = [] - for i, r in enumerate(pattern): - l = MockLabel('l{}'.format(i), []) - for j, v in enumerate(r.split()): - if v == '.': - l.remote.append('m{}'.format(j)) - if i == 0: - duts.append(MockDut('m{}'.format(j))) - labels.append(l) - return labels, duts - - def check_matrix_against_pattern(self, matrix, pattern): - for i, s in enumerate(pattern): - for j, v in enumerate(s.split()): - self.assertTrue(v == '.' and matrix[i][j] == ' ' or v == matrix[i][j]) - - def pattern_based_test(self, inp, output): - labels, duts = self.create_labels_and_duts_from_pattern(inp) - mim = MachineImageManager(labels, duts) - self.assertTrue(mim.compute_initial_allocation()) - self.check_matrix_against_pattern(mim.matrix_, output) - return mim - - def test_single_dut(self): - labels = [MockLabel('l1'), MockLabel('l2'), MockLabel('l3')] - dut = MockDut('m1') - mim = MachineImageManager(labels, [dut]) - mim.compute_initial_allocation() - self.assertTrue(mim.matrix_ == [['Y'], ['Y'], ['Y']]) - - def test_single_label(self): - labels = [MockLabel('l1')] - duts = self.gen_duts_by_name('m1', 'm2', 'm3') - mim = MachineImageManager(labels, duts) - mim.compute_initial_allocation() - self.assertTrue(mim.matrix_ == [['Y', 'Y', 'Y']]) - - def test_case1(self): - labels = [ - MockLabel('l1', ['m1', 'm2']), - MockLabel('l2', ['m2', 'm3']), - MockLabel('l3', ['m1']) - ] - duts = [MockDut('m1'), MockDut('m2'), MockDut('m3')] - mim = MachineImageManager(labels, duts) - self.assertTrue( - mim.matrix_ == [[' ', ' ', 'X'], ['X', ' ', ' '], [' ', 'X', 'X']]) - mim.compute_initial_allocation() - self.assertTrue( - mim.matrix_ == [[' ', 'Y', 'X'], ['X', ' ', 'Y'], ['Y', 'X', 'X']]) - - def test_case2(self): - labels = [ - MockLabel('l1', ['m1', 'm2']), - MockLabel('l2', ['m2', 'm3']), - MockLabel('l3', ['m1']) - ] - duts = [MockDut('m1'), MockDut('m2'), MockDut('m3')] - mim = MachineImageManager(labels, duts) - self.assertTrue( - mim.matrix_ == [[' ', ' ', 'X'], ['X', ' ', ' '], [' ', 'X', 'X']]) - mim.compute_initial_allocation() - self.assertTrue( - mim.matrix_ == [[' ', 'Y', 'X'], ['X', ' ', 'Y'], ['Y', 'X', 'X']]) - - def test_case3(self): - labels = [ - MockLabel('l1', ['m1', 'm2']), - MockLabel('l2', ['m2', 'm3']), - MockLabel('l3', ['m1']) - ] - duts = [MockDut('m1', labels[0]), MockDut('m2'), MockDut('m3')] - mim = MachineImageManager(labels, duts) - mim.compute_initial_allocation() - self.assertTrue( - mim.matrix_ == [[' ', 'Y', 'X'], ['X', ' ', 'Y'], ['Y', 'X', 'X']]) - - def test_case4(self): - labels = [ - MockLabel('l1', ['m1', 'm2']), - MockLabel('l2', ['m2', 'm3']), - MockLabel('l3', ['m1']) - ] - duts = [MockDut('m1'), MockDut('m2', labels[0]), MockDut('m3')] - mim = MachineImageManager(labels, duts) - mim.compute_initial_allocation() - self.assertTrue( - mim.matrix_ == [[' ', 'Y', 'X'], ['X', ' ', 'Y'], ['Y', 'X', 'X']]) - - def test_case5(self): - labels = [ - MockLabel('l1', ['m3']), - MockLabel('l2', ['m3']), - MockLabel('l3', ['m1']) - ] - duts = self.gen_duts_by_name('m1', 'm2', 'm3') - mim = MachineImageManager(labels, duts) - self.assertTrue(mim.compute_initial_allocation()) - self.assertTrue( - mim.matrix_ == [['X', 'X', 'Y'], ['X', 'X', 'Y'], ['Y', 'X', 'X']]) - - def test_2x2_with_allocation(self): - labels = [MockLabel('l0'), MockLabel('l1')] - duts = [MockDut('m0'), MockDut('m1')] - mim = MachineImageManager(labels, duts) - self.assertTrue(mim.compute_initial_allocation()) - self.assertTrue(mim.allocate(duts[0]) == labels[0]) - self.assertTrue(mim.allocate(duts[0]) == labels[1]) - self.assertTrue(mim.allocate(duts[0]) is None) - self.assertTrue(mim.matrix_[0][0] == '_') - self.assertTrue(mim.matrix_[1][0] == '_') - self.assertTrue(mim.allocate(duts[1]) == labels[1]) - - def test_10x10_general(self): - """Gen 10x10 matrix.""" - n = 10 - labels = [] - duts = [] - for i in range(n): - labels.append(MockLabel('l{}'.format(i))) - duts.append(MockDut('m{}'.format(i))) - mim = MachineImageManager(labels, duts) - self.assertTrue(mim.compute_initial_allocation()) - for i in range(n): - for j in range(n): - if i == j: - self.assertTrue(mim.matrix_[i][j] == 'Y') - else: - self.assertTrue(mim.matrix_[i][j] == ' ') - self.assertTrue(mim.allocate(duts[3]).name == 'l3') - - def test_random_generated(self): - n = 10 - labels = [] - duts = [] - for i in range(10): - # generate 3-5 machines that is compatible with this label - l = MockLabel('l{}'.format(i), []) - r = random.random() - for _ in range(4): - t = int(r * 10) % n - r *= 10 - l.remote.append('m{}'.format(t)) - labels.append(l) - duts.append(MockDut('m{}'.format(i))) - mim = MachineImageManager(labels, duts) - self.assertTrue(mim.compute_initial_allocation()) - - def test_10x10_fully_random(self): - inp = [ - 'X . . . X X . X X .', 'X X . X . X . X X .', - 'X X X . . X . X . X', 'X . X X . . X X . X', - 'X X X X . . . X . .', 'X X . X . X . . X .', - '. X . X . X X X . .', '. X . X X . X X . .', - 'X X . . . X X X . .', '. X X X X . . . . X' - ] - output = [ - 'X Y . . X X . X X .', 'X X Y X . X . X X .', - 'X X X Y . X . X . X', 'X . X X Y . X X . X', - 'X X X X . Y . X . .', 'X X . X . X Y . X .', - 'Y X . X . X X X . .', '. X . X X . X X Y .', - 'X X . . . X X X . Y', '. X X X X . . Y . X' - ] - self.pattern_based_test(inp, output) - - def test_10x10_fully_random2(self): - inp = [ - 'X . X . . X . X X X', 'X X X X X X . . X .', - 'X . X X X X X . . X', 'X X X . X . X X . .', - '. X . X . X X X X X', 'X X X X X X X . . X', - 'X . X X X X X . . X', 'X X X . X X X X . .', - 'X X X . . . X X X X', '. X X . X X X . X X' - ] - output = [ - 'X . X Y . X . X X X', 'X X X X X X Y . X .', - 'X Y X X X X X . . X', 'X X X . X Y X X . .', - '. X Y X . X X X X X', 'X X X X X X X Y . X', - 'X . X X X X X . Y X', 'X X X . X X X X . Y', - 'X X X . Y . X X X X', 'Y X X . X X X . X X' - ] - self.pattern_based_test(inp, output) - - def test_3x4_with_allocation(self): - inp = ['X X . .', '. . X .', 'X . X .'] - output = ['X X Y .', 'Y . X .', 'X Y X .'] - mim = self.pattern_based_test(inp, output) - self.assertTrue(mim.allocate(mim.duts_[2]) == mim.labels_[0]) - self.assertTrue(mim.allocate(mim.duts_[3]) == mim.labels_[2]) - self.assertTrue(mim.allocate(mim.duts_[0]) == mim.labels_[1]) - self.assertTrue(mim.allocate(mim.duts_[1]) == mim.labels_[2]) - self.assertTrue(mim.allocate(mim.duts_[3]) == mim.labels_[1]) - self.assertTrue(mim.allocate(mim.duts_[3]) == mim.labels_[0]) - self.assertTrue(mim.allocate(mim.duts_[3]) is None) - self.assertTrue(mim.allocate(mim.duts_[2]) is None) - self.assertTrue(mim.allocate(mim.duts_[1]) == mim.labels_[1]) - self.assertTrue(mim.allocate(mim.duts_[1]) is None) - self.assertTrue(mim.allocate(mim.duts_[0]) is None) - self.assertTrue(mim.label_duts_[0] == [2, 3]) - self.assertTrue(mim.label_duts_[1] == [0, 3, 1]) - self.assertTrue(mim.label_duts_[2] == [3, 1]) - self.assertListEqual(mim.allocate_log_, [(0, 2), (2, 3), (1, 0), (2, 1), - (1, 3), (0, 3), (1, 1)]) - - def test_cornercase_1(self): - """This corner case is brought up by Caroline. + """Class for testing MachineImageManager.""" + + def gen_duts_by_name(self, *names): + duts = [] + for n in names: + duts.append(MockDut(n)) + return duts + + def create_labels_and_duts_from_pattern(self, pattern): + labels = [] + duts = [] + for i, r in enumerate(pattern): + l = MockLabel("l{}".format(i), []) + for j, v in enumerate(r.split()): + if v == ".": + l.remote.append("m{}".format(j)) + if i == 0: + duts.append(MockDut("m{}".format(j))) + labels.append(l) + return labels, duts + + def check_matrix_against_pattern(self, matrix, pattern): + for i, s in enumerate(pattern): + for j, v in enumerate(s.split()): + self.assertTrue( + v == "." and matrix[i][j] == " " or v == matrix[i][j] + ) + + def pattern_based_test(self, inp, output): + labels, duts = self.create_labels_and_duts_from_pattern(inp) + mim = MachineImageManager(labels, duts) + self.assertTrue(mim.compute_initial_allocation()) + self.check_matrix_against_pattern(mim.matrix_, output) + return mim + + def test_single_dut(self): + labels = [MockLabel("l1"), MockLabel("l2"), MockLabel("l3")] + dut = MockDut("m1") + mim = MachineImageManager(labels, [dut]) + mim.compute_initial_allocation() + self.assertTrue(mim.matrix_ == [["Y"], ["Y"], ["Y"]]) + + def test_single_label(self): + labels = [MockLabel("l1")] + duts = self.gen_duts_by_name("m1", "m2", "m3") + mim = MachineImageManager(labels, duts) + mim.compute_initial_allocation() + self.assertTrue(mim.matrix_ == [["Y", "Y", "Y"]]) + + def test_case1(self): + labels = [ + MockLabel("l1", ["m1", "m2"]), + MockLabel("l2", ["m2", "m3"]), + MockLabel("l3", ["m1"]), + ] + duts = [MockDut("m1"), MockDut("m2"), MockDut("m3")] + mim = MachineImageManager(labels, duts) + self.assertTrue( + mim.matrix_ == [[" ", " ", "X"], ["X", " ", " "], [" ", "X", "X"]] + ) + mim.compute_initial_allocation() + self.assertTrue( + mim.matrix_ == [[" ", "Y", "X"], ["X", " ", "Y"], ["Y", "X", "X"]] + ) + + def test_case2(self): + labels = [ + MockLabel("l1", ["m1", "m2"]), + MockLabel("l2", ["m2", "m3"]), + MockLabel("l3", ["m1"]), + ] + duts = [MockDut("m1"), MockDut("m2"), MockDut("m3")] + mim = MachineImageManager(labels, duts) + self.assertTrue( + mim.matrix_ == [[" ", " ", "X"], ["X", " ", " "], [" ", "X", "X"]] + ) + mim.compute_initial_allocation() + self.assertTrue( + mim.matrix_ == [[" ", "Y", "X"], ["X", " ", "Y"], ["Y", "X", "X"]] + ) + + def test_case3(self): + labels = [ + MockLabel("l1", ["m1", "m2"]), + MockLabel("l2", ["m2", "m3"]), + MockLabel("l3", ["m1"]), + ] + duts = [MockDut("m1", labels[0]), MockDut("m2"), MockDut("m3")] + mim = MachineImageManager(labels, duts) + mim.compute_initial_allocation() + self.assertTrue( + mim.matrix_ == [[" ", "Y", "X"], ["X", " ", "Y"], ["Y", "X", "X"]] + ) + + def test_case4(self): + labels = [ + MockLabel("l1", ["m1", "m2"]), + MockLabel("l2", ["m2", "m3"]), + MockLabel("l3", ["m1"]), + ] + duts = [MockDut("m1"), MockDut("m2", labels[0]), MockDut("m3")] + mim = MachineImageManager(labels, duts) + mim.compute_initial_allocation() + self.assertTrue( + mim.matrix_ == [[" ", "Y", "X"], ["X", " ", "Y"], ["Y", "X", "X"]] + ) + + def test_case5(self): + labels = [ + MockLabel("l1", ["m3"]), + MockLabel("l2", ["m3"]), + MockLabel("l3", ["m1"]), + ] + duts = self.gen_duts_by_name("m1", "m2", "m3") + mim = MachineImageManager(labels, duts) + self.assertTrue(mim.compute_initial_allocation()) + self.assertTrue( + mim.matrix_ == [["X", "X", "Y"], ["X", "X", "Y"], ["Y", "X", "X"]] + ) + + def test_2x2_with_allocation(self): + labels = [MockLabel("l0"), MockLabel("l1")] + duts = [MockDut("m0"), MockDut("m1")] + mim = MachineImageManager(labels, duts) + self.assertTrue(mim.compute_initial_allocation()) + self.assertTrue(mim.allocate(duts[0]) == labels[0]) + self.assertTrue(mim.allocate(duts[0]) == labels[1]) + self.assertTrue(mim.allocate(duts[0]) is None) + self.assertTrue(mim.matrix_[0][0] == "_") + self.assertTrue(mim.matrix_[1][0] == "_") + self.assertTrue(mim.allocate(duts[1]) == labels[1]) + + def test_10x10_general(self): + """Gen 10x10 matrix.""" + n = 10 + labels = [] + duts = [] + for i in range(n): + labels.append(MockLabel("l{}".format(i))) + duts.append(MockDut("m{}".format(i))) + mim = MachineImageManager(labels, duts) + self.assertTrue(mim.compute_initial_allocation()) + for i in range(n): + for j in range(n): + if i == j: + self.assertTrue(mim.matrix_[i][j] == "Y") + else: + self.assertTrue(mim.matrix_[i][j] == " ") + self.assertTrue(mim.allocate(duts[3]).name == "l3") + + def test_random_generated(self): + n = 10 + labels = [] + duts = [] + for i in range(10): + # generate 3-5 machines that is compatible with this label + l = MockLabel("l{}".format(i), []) + r = random.random() + for _ in range(4): + t = int(r * 10) % n + r *= 10 + l.remote.append("m{}".format(t)) + labels.append(l) + duts.append(MockDut("m{}".format(i))) + mim = MachineImageManager(labels, duts) + self.assertTrue(mim.compute_initial_allocation()) + + def test_10x10_fully_random(self): + inp = [ + "X . . . X X . X X .", + "X X . X . X . X X .", + "X X X . . X . X . X", + "X . X X . . X X . X", + "X X X X . . . X . .", + "X X . X . X . . X .", + ". X . X . X X X . .", + ". X . X X . X X . .", + "X X . . . X X X . .", + ". X X X X . . . . X", + ] + output = [ + "X Y . . X X . X X .", + "X X Y X . X . X X .", + "X X X Y . X . X . X", + "X . X X Y . X X . X", + "X X X X . Y . X . .", + "X X . X . X Y . X .", + "Y X . X . X X X . .", + ". X . X X . X X Y .", + "X X . . . X X X . Y", + ". X X X X . . Y . X", + ] + self.pattern_based_test(inp, output) + + def test_10x10_fully_random2(self): + inp = [ + "X . X . . X . X X X", + "X X X X X X . . X .", + "X . X X X X X . . X", + "X X X . X . X X . .", + ". X . X . X X X X X", + "X X X X X X X . . X", + "X . X X X X X . . X", + "X X X . X X X X . .", + "X X X . . . X X X X", + ". X X . X X X . X X", + ] + output = [ + "X . X Y . X . X X X", + "X X X X X X Y . X .", + "X Y X X X X X . . X", + "X X X . X Y X X . .", + ". X Y X . X X X X X", + "X X X X X X X Y . X", + "X . X X X X X . Y X", + "X X X . X X X X . Y", + "X X X . Y . X X X X", + "Y X X . X X X . X X", + ] + self.pattern_based_test(inp, output) + + def test_3x4_with_allocation(self): + inp = ["X X . .", ". . X .", "X . X ."] + output = ["X X Y .", "Y . X .", "X Y X ."] + mim = self.pattern_based_test(inp, output) + self.assertTrue(mim.allocate(mim.duts_[2]) == mim.labels_[0]) + self.assertTrue(mim.allocate(mim.duts_[3]) == mim.labels_[2]) + self.assertTrue(mim.allocate(mim.duts_[0]) == mim.labels_[1]) + self.assertTrue(mim.allocate(mim.duts_[1]) == mim.labels_[2]) + self.assertTrue(mim.allocate(mim.duts_[3]) == mim.labels_[1]) + self.assertTrue(mim.allocate(mim.duts_[3]) == mim.labels_[0]) + self.assertTrue(mim.allocate(mim.duts_[3]) is None) + self.assertTrue(mim.allocate(mim.duts_[2]) is None) + self.assertTrue(mim.allocate(mim.duts_[1]) == mim.labels_[1]) + self.assertTrue(mim.allocate(mim.duts_[1]) is None) + self.assertTrue(mim.allocate(mim.duts_[0]) is None) + self.assertTrue(mim.label_duts_[0] == [2, 3]) + self.assertTrue(mim.label_duts_[1] == [0, 3, 1]) + self.assertTrue(mim.label_duts_[2] == [3, 1]) + self.assertListEqual( + mim.allocate_log_, + [(0, 2), (2, 3), (1, 0), (2, 1), (1, 3), (0, 3), (1, 1)], + ) + + def test_cornercase_1(self): + """This corner case is brought up by Caroline. The description is - @@ -292,18 +322,18 @@ class MachineImageManagerTester(unittest.TestCase): l1 Y X X l2 Y X X - """ + """ - inp = ['. X X', '. X X', '. X X'] - output = ['Y X X', 'Y X X', 'Y X X'] - mim = self.pattern_based_test(inp, output) - self.assertTrue(mim.allocate(mim.duts_[1]) is None) - self.assertTrue(mim.allocate(mim.duts_[2]) is None) - self.assertTrue(mim.allocate(mim.duts_[0]) == mim.labels_[0]) - self.assertTrue(mim.allocate(mim.duts_[0]) == mim.labels_[1]) - self.assertTrue(mim.allocate(mim.duts_[0]) == mim.labels_[2]) - self.assertTrue(mim.allocate(mim.duts_[0]) is None) + inp = [". X X", ". X X", ". X X"] + output = ["Y X X", "Y X X", "Y X X"] + mim = self.pattern_based_test(inp, output) + self.assertTrue(mim.allocate(mim.duts_[1]) is None) + self.assertTrue(mim.allocate(mim.duts_[2]) is None) + self.assertTrue(mim.allocate(mim.duts_[0]) == mim.labels_[0]) + self.assertTrue(mim.allocate(mim.duts_[0]) == mim.labels_[1]) + self.assertTrue(mim.allocate(mim.duts_[0]) == mim.labels_[2]) + self.assertTrue(mim.allocate(mim.duts_[0]) is None) -if __name__ == '__main__': - unittest.main() +if __name__ == "__main__": + unittest.main() |