aboutsummaryrefslogtreecommitdiff
path: root/crosperf/machine_image_manager_unittest.py
diff options
context:
space:
mode:
Diffstat (limited to 'crosperf/machine_image_manager_unittest.py')
-rwxr-xr-xcrosperf/machine_image_manager_unittest.py524
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()