aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorcmtice <cmtice@google.com>2014-06-04 14:19:19 -0700
committerchrome-internal-fetch <chrome-internal-fetch@google.com>2014-06-05 04:15:51 +0000
commit1505b6ac10710044361cd65c7890014cb43e9930 (patch)
tree63ca8b4ca971be84d7a7603b977c698477ac1f9a
parent2a370f7af34f6b126e80ef55891b9bff6a2858bb (diff)
downloadtoolchain-utils-1505b6ac10710044361cd65c7890014cb43e9930.tar.gz
Update and expand machine_manager_unittest.
Expand machine_manager_unittest.py to test all functions in machine_manager.py. Modify MachineManager class to optionally take a command_executer and logger as arguments; also to make command executer and logger class member attributes (rather than external objects), to simplify testing. BUG=None TEST=Ran unittest to make sure it works; ran all the other unittests; ran several 'real' crosperf runs to verify that the changes didn't break crosperf. Change-Id: I29798457cb1f7572cb339722b572b9d95b21b989 Reviewed-on: https://chrome-internal-review.googlesource.com/165256 Reviewed-by: Yunlian Jiang <yunlian@google.com> Commit-Queue: Caroline Tice <cmtice@google.com> Tested-by: Caroline Tice <cmtice@google.com>
-rw-r--r--crosperf/label.py11
-rw-r--r--crosperf/machine_manager.py109
-rwxr-xr-xcrosperf/machine_manager_unittest.py789
3 files changed, 855 insertions, 54 deletions
diff --git a/crosperf/label.py b/crosperf/label.py
index 91f6e97e..78fc1314 100644
--- a/crosperf/label.py
+++ b/crosperf/label.py
@@ -82,3 +82,14 @@ class MockLabel(object):
self.chromeos_root = chromeos_root
self.image_args = image_args
self.chrome_src = chrome_src
+ self.image_type = self._GetImageType(chromeos_image)
+
+ def _GetImageType(self, chromeos_image):
+ image_type = None
+ if chromeos_image.find("xbuddy://") < 0:
+ image_type = "local"
+ elif chromeos_image.find("trybot") >= 0:
+ image_type = "trybot"
+ else:
+ image_type = "official"
+ return image_type
diff --git a/crosperf/machine_manager.py b/crosperf/machine_manager.py
index 43efdc8f..dede640d 100644
--- a/crosperf/machine_manager.py
+++ b/crosperf/machine_manager.py
@@ -14,6 +14,7 @@ import sys
import threading
import time
+
from utils import command_executer
from utils import logger
from utils.file_utils import FileUtils
@@ -26,7 +27,7 @@ class NonMatchingMachines(Exception):
pass
class CrosMachine(object):
- def __init__(self, name, chromeos_root, log_level):
+ def __init__(self, name, chromeos_root, log_level, cmd_exec=None):
self.name = name
self.image = None
self.checksum = None
@@ -35,6 +36,8 @@ class CrosMachine(object):
self.test_run = None
self.chromeos_root = chromeos_root
self.log_level = log_level
+ self.ce = cmd_exec or command_executer.GetCommandExecuter(
+ log_level=self.log_level)
self.SetUpChecksumInfo()
def SetUpChecksumInfo(self):
@@ -49,11 +52,10 @@ class CrosMachine(object):
self.machine_id_checksum = self._GetMD5Checksum(self.machine_id)
def IsReachable(self):
- ce = command_executer.GetCommandExecuter(log_level=self.log_level)
command = "ls"
- ret = ce.CrosRunCommand(command,
- machine=self.name,
- chromeos_root=self.chromeos_root)
+ ret = self.ce.CrosRunCommand(command,
+ machine=self.name,
+ chromeos_root=self.chromeos_root)
if ret:
return False
return True
@@ -92,26 +94,26 @@ class CrosMachine(object):
def _GetMemoryInfo(self):
#TODO yunlian: when the machine in rebooting, it will not return
#meminfo, the assert does not catch it either
- ce = command_executer.GetCommandExecuter(log_level=self.log_level)
command = "cat /proc/meminfo"
- ret, self.meminfo, _ = ce.CrosRunCommand(
- command, return_output=True,
- machine=self.name, username="root", chromeos_root=self.chromeos_root)
+ ret, self.meminfo, _ = self.ce.CrosRunCommand(command, return_output=True,
+ machine=self.name,
+ username="root",
+ chromeos_root=self.chromeos_root)
assert ret == 0, "Could not get meminfo from machine: %s" % self.name
if ret == 0:
self._ParseMemoryInfo()
#cpuinfo format is different across architecture
#need to find a better way to parse it.
- def _ParseCPUInfo(self,cpuinfo):
+ def _ParseCPUInfo(self, cpuinfo):
return 0
def _GetCPUInfo(self):
- ce = command_executer.GetCommandExecuter(log_level=self.log_level)
command = "cat /proc/cpuinfo"
- ret, self.cpuinfo, _ = ce.CrosRunCommand(
- command, return_output=True,
- machine=self.name, username="root", chromeos_root=self.chromeos_root)
+ ret, self.cpuinfo, _ = self.ce.CrosRunCommand(command, return_output=True,
+ machine=self.name,
+ username="root",
+ chromeos_root=self.chromeos_root)
assert ret == 0, "Could not get cpuinfo from machine: %s" % self.name
if ret == 0:
self._ParseCPUInfo(self.cpuinfo)
@@ -131,20 +133,19 @@ class CrosMachine(object):
return ""
def _GetMachineID(self):
- ce = command_executer.GetCommandExecuter(log_level=self.log_level)
command = "dump_vpd_log --full --stdout"
- ret, if_out, _ = ce.CrosRunCommand(
- command, return_output=True,
- machine=self.name, chromeos_root=self.chromeos_root)
+ ret, if_out, _ = self.ce.CrosRunCommand(command, return_output=True,
+ machine=self.name,
+ chromeos_root=self.chromeos_root)
b = if_out.splitlines()
a = [l for l in b if "Product" in l]
if len(a):
self.machine_id = a[0]
return
command = "ifconfig"
- ret, if_out, _ = ce.CrosRunCommand(
- command, return_output=True,
- machine=self.name, chromeos_root=self.chromeos_root)
+ ret, if_out, _ = self.ce.CrosRunCommand(command, return_output=True,
+ machine=self.name,
+ chromeos_root=self.chromeos_root)
b = if_out.splitlines()
a = [l for l in b if "HWaddr" in l]
if len(a):
@@ -167,7 +168,8 @@ class CrosMachine(object):
class MachineManager(object):
- def __init__(self, chromeos_root, acquire_timeout, log_level):
+ def __init__(self, chromeos_root, acquire_timeout, log_level, cmd_exec=None,
+ lgr=None):
self._lock = threading.RLock()
self._all_machines = []
self._machines = []
@@ -178,6 +180,9 @@ class MachineManager(object):
self.machine_checksum_string = {}
self.acquire_timeout = acquire_timeout
self.log_level = log_level
+ self.ce = cmd_exec or command_executer.GetCommandExecuter(
+ log_level=self.log_level)
+ self.logger = lgr or logger.GetLogger()
if os.path.isdir(lock_machine.Machine.LOCKS_DIR):
self.no_lock = False
@@ -210,28 +215,28 @@ class MachineManager(object):
# Currently can't image two machines at once.
# So have to serialized on this lock.
+ save_ce_log_level = self.ce.log_level
if self.log_level != "verbose":
- ce = command_executer.GetCommandExecuter(log_level="average")
- else:
- ce = command_executer.GetCommandExecuter()
+ self.ce.log_level = "average"
+
with self.image_lock:
if self.log_level != "verbose":
- logger.GetLogger().LogOutput("Pushing image onto machine.")
- logger.GetLogger().LogOutput("CMD : python %s "
+ self.logger.LogOutput("Pushing image onto machine.")
+ self.logger.LogOutput("CMD : python %s "
% " ".join(image_chromeos_args))
- retval = ce.RunCommand(" ".join(["python"] + image_chromeos_args))
+ retval = self.ce.RunCommand(" ".join(["python"] + image_chromeos_args))
if retval:
- cmd ="reboot && exit"
+ cmd = "reboot && exit"
if self.log_level != "verbose":
- logger.GetLogger().LogOutput("reboot & exit.")
- ce.CrosRunCommand(cmd, machine=machine.name,
- chromeos_root=self.chromeos_root)
+ self.logger.LogOutput("reboot & exit.")
+ self.ce.CrosRunCommand(cmd, machine=machine.name,
+ chromeos_root=self.chromeos_root)
time.sleep(60)
if self.log_level != "verbose":
- logger.GetLogger().LogOutput("Pushing image onto machine.")
- logger.GetLogger().LogOutput("CMD : python %s "
+ self.logger.LogOutput("Pushing image onto machine.")
+ self.logger.LogOutput("CMD : python %s "
% " ".join(image_chromeos_args))
- retval = ce.RunCommand(" ".join(["python"] + image_chromeos_args))
+ retval = self.ce.RunCommand(" ".join(["python"] + image_chromeos_args))
if retval:
raise Exception("Could not image machine: '%s'." % machine.name)
else:
@@ -239,6 +244,7 @@ class MachineManager(object):
machine.checksum = checksum
machine.image = label.chromeos_image
+ self.ce.log_level = save_ce_log_level
return retval
def ComputeCommonCheckSum(self, label):
@@ -265,30 +271,30 @@ class MachineManager(object):
locked = lock_machine.Machine(cros_machine.name).Lock(True, sys.argv[0])
if locked:
self._machines.append(cros_machine)
- ce = command_executer.GetCommandExecuter(log_level=self.log_level)
command = "cat %s" % CHECKSUM_FILE
- ret, out, _ = ce.CrosRunCommand(
+ ret, out, _ = self.ce.CrosRunCommand(
command, return_output=True, chromeos_root=self.chromeos_root,
machine=cros_machine.name)
if ret == 0:
cros_machine.checksum = out.strip()
else:
- logger.GetLogger().LogOutput("Couldn't lock: %s" % cros_machine.name)
+ self.logger.LogOutput("Couldn't lock: %s" % cros_machine.name)
# This is called from single threaded mode.
def AddMachine(self, machine_name):
with self._lock:
for m in self._all_machines:
assert m.name != machine_name, "Tried to double-add %s" % machine_name
- if self.log_level != "verbose":
- logger.GetLogger().LogOutput("Setting up remote access to %s"
- % machine_name)
- logger.GetLogger().LogOutput("Checking machine characteristics for %s"
- % machine_name)
+ if self.log_level != "verbose":
+ self.logger.LogOutput("Setting up remote access to %s"
+ % machine_name)
+ self.logger.LogOutput("Checking machine characteristics for %s"
+ % machine_name)
cm = CrosMachine(machine_name, self.chromeos_root, self.log_level)
if cm.machine_checksum:
self._all_machines.append(cm)
+
def AreAllMachineSame(self, label):
checksums = [m.machine_checksum for m in self.GetMachines(label)]
return len(set(checksums)) == 1
@@ -300,12 +306,11 @@ class MachineManager(object):
if m.name != machine_name]
res = lock_machine.Machine(machine_name).Unlock(True)
if not res:
- logger.GetLogger().LogError("Could not unlock machine: '%s'."
- % m.name)
+ self.logger.LogError("Could not unlock machine: '%s'."
+ % m.name)
def ForceSameImageToAllMachines(self, label):
machines = self.GetMachines(label)
- chromeos_image = label.chromeos_image
for m in machines:
self.ImageMachine(m, label)
m.SetUpChecksumInfo()
@@ -330,7 +335,7 @@ class MachineManager(object):
if not self.AreAllMachineSame(label):
if not throw:
# Log fatal message, which calls sys.exit. Default behavior.
- logger.GetLogger().LogFatal("-- not all the machines are identical")
+ self.logger.LogFatal("-- not all the machines are identical")
else:
# Raise an exception, which can be caught and handled by calling
# function.
@@ -346,9 +351,9 @@ class MachineManager(object):
machine_names = []
for machine in machines:
machine_names.append(machine.name)
- logger.GetLogger().LogFatal("Could not acquire any of the "
- "following machines: '%s'"
- % ", ".join(machine_names))
+ self.logger.LogFatal("Could not acquire any of the "
+ "following machines: '%s'"
+ % ", ".join(machine_names))
### for m in self._machines:
### if (m.locked and time.time() - m.released_time < 10 and
@@ -407,8 +412,8 @@ class MachineManager(object):
if not self.no_lock:
res = lock_machine.Machine(m.name).Unlock(True)
if not res:
- logger.GetLogger().LogError("Could not unlock machine: '%s'."
- % m.name)
+ self.logger.LogError("Could not unlock machine: '%s'."
+ % m.name)
def __str__(self):
with self._lock:
diff --git a/crosperf/machine_manager_unittest.py b/crosperf/machine_manager_unittest.py
index 059ce20a..4ce1d7f2 100755
--- a/crosperf/machine_manager_unittest.py
+++ b/crosperf/machine_manager_unittest.py
@@ -3,11 +3,21 @@
# Copyright 2012 Google Inc. All Rights Reserved.
"""Unittest for machine_manager."""
+import os.path
+import time
+import hashlib
+
+import mock
import unittest
import label
import machine_manager
+import image_checksummer
+from benchmark import Benchmark
+from benchmark_run import MockBenchmarkRun
+from utils import command_executer
+from utils import logger
class MyMachineManager(machine_manager.MachineManager):
@@ -30,16 +40,61 @@ class MyMachineManager(machine_manager.MachineManager):
CHROMEOS_ROOT = "/tmp/chromeos-root"
MACHINE_NAMES = ["lumpy1", "lumpy2", "lumpy3", "daisy1", "daisy2"]
-LABEL_LUMPY = label.MockLabel("lumpy", "image", CHROMEOS_ROOT, "lumpy",
+LABEL_LUMPY = label.MockLabel("lumpy", "lumpy_chromeos_image", CHROMEOS_ROOT, "lumpy",
["lumpy1", "lumpy2", "lumpy3", "lumpy4"],
"", "", False, "")
-LABEL_MIX = label.MockLabel("mix", "image", CHROMEOS_ROOT, "mix",
+LABEL_MIX = label.MockLabel("mix", "chromeos_image", CHROMEOS_ROOT, "mix",
["daisy1", "daisy2", "lumpy3", "lumpy4"],
"", "", False, "")
class MachineManagerTest(unittest.TestCase):
+ mock_cmd_exec = mock.Mock(spec=command_executer.CommandExecuter)
+
+ mock_logger = mock.Mock(spec=logger.Logger)
+
+ mock_lumpy1 = mock.Mock(spec=machine_manager.CrosMachine)
+ mock_lumpy2 = mock.Mock(spec=machine_manager.CrosMachine)
+ mock_lumpy3 = mock.Mock(spec=machine_manager.CrosMachine)
+ mock_daisy1 = mock.Mock(spec=machine_manager.CrosMachine)
+ mock_daisy2 = mock.Mock(spec=machine_manager.CrosMachine)
+
+ @mock.patch.object (os.path, 'isdir')
+ def setUp(self, mock_isdir):
+
+ mock_isdir.return_value = True
+ self.mm = machine_manager.MachineManager("/usr/local/chromeos", 0,
+ "average", self.mock_cmd_exec,
+ self.mock_logger)
+
+ self.mock_lumpy1.name = 'lumpy1'
+ self.mock_lumpy2.name = 'lumpy2'
+ self.mock_lumpy3.name = 'lumpy3'
+ self.mock_daisy1.name = 'daisy1'
+ self.mock_daisy2.name = 'daisy2'
+ self.mock_lumpy1.machine_checksum = 'lumpy123'
+ self.mock_lumpy2.machine_checksum = 'lumpy123'
+ self.mock_lumpy3.machine_checksum = 'lumpy123'
+ self.mock_daisy1.machine_checksum = 'daisy12'
+ self.mock_daisy2.machine_checksum = 'daisy12'
+ self.mock_lumpy1.checksum_string = 'lumpy_checksum_str'
+ self.mock_lumpy2.checksum_string = 'lumpy_checksum_str'
+ self.mock_lumpy3.checksum_string = 'lumpy_checksum_str'
+ self.mock_daisy1.checksum_string = 'daisy_checksum_str'
+ self.mock_daisy2.checksum_string = 'daisy_checksum_str'
+ self.mock_lumpy1.cpuinfo = "lumpy_cpu_info"
+ self.mock_lumpy2.cpuinfo = "lumpy_cpu_info"
+ self.mock_lumpy3.cpuinfo = "lumpy_cpu_info"
+ self.mock_daisy1.cpuinfo = "daisy_cpu_info"
+ self.mock_daisy2.cpuinfo = "daisy_cpu_info"
+ self.mm._all_machines.append(self.mock_daisy1)
+ self.mm._all_machines.append(self.mock_daisy2)
+ self.mm._all_machines.append(self.mock_lumpy1)
+ self.mm._all_machines.append(self.mock_lumpy2)
+ self.mm._all_machines.append(self.mock_lumpy3)
+
+
def testAreAllMachineSame(self):
manager = MyMachineManager(CHROMEOS_ROOT)
for m in MACHINE_NAMES:
@@ -64,5 +119,735 @@ class MachineManagerTest(unittest.TestCase):
names = [m.name for m in manager.GetAvailableMachines(LABEL_LUMPY)]
self.assertEqual(names, ["lumpy1", "lumpy3"])
+ @mock.patch.object(time, 'sleep')
+ @mock.patch.object(command_executer.CommandExecuter, 'RunCommand')
+ @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand')
+ @mock.patch.object(image_checksummer.ImageChecksummer, 'Checksum')
+ def test_image_machine(self, mock_checksummer, mock_run_croscmd,
+ mock_run_cmd, mock_sleep):
+
+ def FakeMD5Checksum(input_str):
+ return "machine_fake_md5_checksum"
+
+ self.fake_logger_count = 0
+ self.fake_logger_msgs = []
+
+ def FakeLogOutput(msg):
+ self.fake_logger_count += 1
+ self.fake_logger_msgs.append(msg)
+
+ def ResetValues():
+ self.fake_logger_count = 0
+ self.fake_logger_msgs = []
+ mock_run_cmd.reset_mock()
+ mock_run_croscmd.reset_mock()
+ mock_checksummer.reset_mock()
+ mock_sleep.reset_mock()
+ machine.checksum = "fake_md5_checksum"
+ self.mm.checksum = None
+ self.mm.num_reimages = 0
+
+ self.mock_cmd_exec.CrosRunCommand = mock_run_croscmd
+ self.mock_cmd_exec.RunCommand = mock_run_cmd
+
+ self.mm.logger.LogOutput = FakeLogOutput
+ machine = self.mock_lumpy1
+ machine._GetMD5Checksum = FakeMD5Checksum
+ machine.checksum = "fake_md5_checksum"
+ mock_checksummer.return_value = "fake_md5_checksum"
+ self.mock_cmd_exec.log_level = "verbose"
+
+ # Test 1: label.image_type == "local"
+ LABEL_LUMPY.image_type = "local"
+ self.mm.ImageMachine(machine, LABEL_LUMPY)
+ self.assertEqual(mock_run_cmd.call_count, 0)
+ self.assertEqual(mock_run_croscmd.call_count, 0)
+ self.assertEqual(mock_checksummer.call_count, 1)
+
+ #Test 2: label.image_type == "trybot"
+ ResetValues()
+ LABEL_LUMPY.image_type = "trybot"
+ mock_run_cmd.return_value = 0
+ self.mm.ImageMachine(machine, LABEL_LUMPY)
+ self.assertEqual(mock_run_cmd.call_count, 1)
+ self.assertEqual(mock_run_croscmd.call_count, 0)
+ self.assertEqual(mock_checksummer.call_count, 0)
+ image_call_args_str = mock_run_cmd.call_args[0][0]
+ image_call_args = image_call_args_str.split(' ')
+ self.assertEqual(image_call_args[0], 'python')
+ self.assertEqual(image_call_args[1].split('/')[-1], 'image_chromeos.pyc')
+ image_call_args = image_call_args[2:]
+ self.assertEqual(image_call_args,
+ [ '--chromeos_root=/tmp/chromeos-root',
+ '--image=lumpy_chromeos_image',
+ '--image_args=', '--remote=lumpy1',
+ '--logging_level=average', '--board=lumpy'])
+
+ # Test 3: label.image_type is neither local nor trybot; retval from
+ # RunCommand is 1, i.e. image_chromeos fails...
+ ResetValues()
+ LABEL_LUMPY.image_type = "other"
+ mock_run_cmd.return_value = 1
+ try:
+ self.mm.ImageMachine(machine, LABEL_LUMPY)
+ except:
+ self.assertEqual(mock_checksummer.call_count, 0)
+ self.assertEqual(mock_run_cmd.call_count, 2)
+ self.assertEqual(mock_run_croscmd.call_count, 1)
+ self.assertEqual(mock_sleep.call_count, 1)
+ image_call_args_str = mock_run_cmd.call_args[0][0]
+ image_call_args = image_call_args_str.split(' ')
+ self.assertEqual(image_call_args[0], 'python')
+ self.assertEqual(image_call_args[1].split('/')[-1], 'image_chromeos.pyc')
+ image_call_args = image_call_args[2:]
+ self.assertEqual(image_call_args,
+ [ '--chromeos_root=/tmp/chromeos-root',
+ '--image=lumpy_chromeos_image',
+ '--image_args=', '--remote=lumpy1',
+ '--logging_level=average', '--board=lumpy'])
+ self.assertEqual(mock_run_croscmd.call_args[0][0], 'reboot && exit')
+
+ # Test 4: Everything works properly. Trybot image type.
+ ResetValues()
+ LABEL_LUMPY.image_type = 'trybot'
+ mock_run_cmd.return_value = 0
+ self.mm.ImageMachine(machine, LABEL_LUMPY)
+ self.assertEqual(mock_checksummer.call_count, 0)
+ self.assertEqual(mock_run_cmd.call_count, 1)
+ self.assertEqual(mock_run_croscmd.call_count, 0)
+ self.assertEqual(mock_sleep.call_count, 0)
+ image_call_args_str = mock_run_cmd.call_args[0][0]
+ image_call_args = image_call_args_str.split(' ')
+ self.assertEqual(image_call_args[0], 'python')
+ self.assertEqual(image_call_args[1].split('/')[-1], 'image_chromeos.pyc')
+ image_call_args = image_call_args[2:]
+ self.assertEqual(image_call_args,
+ [ '--chromeos_root=/tmp/chromeos-root',
+ '--image=lumpy_chromeos_image',
+ '--image_args=', '--remote=lumpy1',
+ '--logging_level=average', '--board=lumpy'])
+
+
+ def test_compute_common_checksum(self):
+
+ self.mm.machine_checksum = {}
+ self.mm.ComputeCommonCheckSum(LABEL_LUMPY)
+ self.assertEqual(self.mm.machine_checksum['lumpy'], 'lumpy123')
+ self.assertEqual(len(self.mm.machine_checksum), 1)
+
+ self.mm.machine_checksum = {}
+ self.mm.ComputeCommonCheckSum(LABEL_MIX)
+ self.assertEqual(len(self.mm.machine_checksum), 1)
+ self.assertEqual(self.mm.machine_checksum['mix'], 'daisy12')
+
+
+ def test_compute_common_checksum_string(self):
+ self.mm.machine_checksum_string = {}
+ self.mm.ComputeCommonCheckSumString(LABEL_LUMPY)
+ self.assertEqual(len(self.mm.machine_checksum_string), 1)
+ self.assertEqual(self.mm.machine_checksum_string['lumpy'],
+ 'lumpy_checksum_str')
+
+ self.mm.machine_checksum_string = {}
+ self.mm.ComputeCommonCheckSumString(LABEL_MIX)
+ self.assertEqual(len(self.mm.machine_checksum_string), 1)
+ self.assertEqual(self.mm.machine_checksum_string['mix'],
+ 'daisy_checksum_str')
+
+
+ @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand')
+ def test_try_to_lock_machine(self, mock_cros_runcmd):
+
+ self.assertRaises(self.mm._TryToLockMachine, None)
+
+ mock_cros_runcmd.return_value = [0, "false_lock_checksum", ""]
+ self.mock_cmd_exec.CrosRunCommand = mock_cros_runcmd
+ self.mm._machines = []
+ self.mm._TryToLockMachine(self.mock_lumpy1)
+ self.assertEqual(len(self.mm._machines), 1)
+ self.assertEqual(self.mm._machines[0], self.mock_lumpy1)
+ self.assertEqual(self.mock_lumpy1.checksum, "false_lock_checksum")
+ self.assertEqual(mock_cros_runcmd.call_count, 1)
+ cmd_str = mock_cros_runcmd.call_args[0][0]
+ self.assertEqual(cmd_str, 'cat /usr/local/osimage_checksum_file')
+ args_dict = mock_cros_runcmd.call_args[1]
+ self.assertEqual(len(args_dict), 3)
+ self.assertEqual(args_dict['machine'], self.mock_lumpy1.name)
+ self.assertEqual(args_dict['chromeos_root'], '/usr/local/chromeos')
+ self.assertTrue(args_dict['return_output'])
+
+
+ @mock.patch.object(machine_manager, 'CrosMachine')
+ def test_add_machine(self, mock_machine):
+
+ mock_machine.machine_checksum = 'daisy123'
+ self.assertEqual (len(self.mm._all_machines), 5)
+ self.mm.AddMachine('daisy3')
+ self.assertEqual (len(self.mm._all_machines), 6)
+
+ self.assertRaises(Exception, self.mm.AddMachine, 'lumpy1')
+
+
+ def test_are_all_machines_same(self):
+ result = self.mm.AreAllMachineSame(LABEL_LUMPY)
+ self.assertTrue(result)
+
+ result = self.mm.AreAllMachineSame(LABEL_MIX)
+ self.assertFalse(result)
+
+
+ def test_remove_machine(self):
+ self.mm._machines = self.mm._all_machines
+ self.assertTrue(self.mock_lumpy2 in self.mm._machines)
+ self.mm.RemoveMachine(self.mock_lumpy2.name)
+ self.assertFalse(self.mock_lumpy2 in self.mm._machines)
+
+
+ def test_force_same_image_to_all_machines(self):
+ self.image_log = []
+
+ def FakeImageMachine(machine, label_arg):
+ image = label_arg.chromeos_image
+ self.image_log.append("Pushed %s onto %s" % (image, machine.name))
+
+ def FakeSetUpChecksumInfo():
+ pass
+
+ self.mm.ImageMachine = FakeImageMachine
+ self.mock_lumpy1.SetUpChecksumInfo = FakeSetUpChecksumInfo
+ self.mock_lumpy2.SetUpChecksumInfo = FakeSetUpChecksumInfo
+ self.mock_lumpy3.SetUpChecksumInfo = FakeSetUpChecksumInfo
+
+ self.mm.ForceSameImageToAllMachines(LABEL_LUMPY)
+ self.assertEqual(len(self.image_log), 3)
+ self.assertEqual(self.image_log[0],
+ 'Pushed lumpy_chromeos_image onto lumpy1')
+ self.assertEqual(self.image_log[1],
+ 'Pushed lumpy_chromeos_image onto lumpy2')
+ self.assertEqual(self.image_log[2],
+ 'Pushed lumpy_chromeos_image onto lumpy3')
+
+
+
+ @mock.patch.object(image_checksummer.ImageChecksummer, 'Checksum')
+ @mock.patch.object(hashlib,'md5')
+ def test_acquire_machine(self, mock_md5, mock_checksum):
+
+ self.msgs = []
+ self.log_fatal_msgs = []
+
+ def FakeLock(machine):
+ self.msgs.append("Tried to lock %s" % machine.name)
+
+ def FakeLogFatal(msg):
+ self.log_fatal_msgs.append(msg)
+
+ self.mm._TryToLockMachine = FakeLock
+ self.mm.logger.LogFatal = FakeLogFatal
+
+ mock_md5.return_value = "123456"
+ mock_checksum.return_value = "fake_md5_checksum"
+
+ self.mm._machines = self.mm._all_machines
+ self.mock_lumpy1.locked = True
+ self.mock_lumpy2.locked = True
+ self.mock_lumpy3.locked = False
+ self.mock_lumpy3.checksum = "fake_md5_checksum"
+ self.mock_daisy1.locked = True
+ self.mock_daisy2.locked = False
+ self.mock_daisy2.checksum = "fake_md5_checksum"
+
+ # Test 1. Basic test. Acquire lumpy3.
+ m = self.mm.AcquireMachine(LABEL_LUMPY.chromeos_image, LABEL_LUMPY, True)
+ self.assertEqual(m, self.mock_lumpy3)
+ self.assertTrue(self.mock_lumpy3.locked)
+ self.assertEqual(mock_checksum.call_count, 1)
+ self.assertEqual(mock_md5.call_count, 0)
+ self.assertEqual(self.msgs, ['Tried to lock lumpy1',
+ 'Tried to lock lumpy2',
+ 'Tried to lock lumpy3'])
+
+ # Test: Not all machines are the same, throw = True
+ self.assertRaises (machine_manager.NonMatchingMachines,
+ self.mm.AcquireMachine,
+ LABEL_MIX.chromeos_image, LABEL_MIX, True)
+
+ # Test 3. Not all machines are the same, throw = False
+ self.assertEqual(len(self.log_fatal_msgs), 0)
+ m = self.mm.AcquireMachine(LABEL_MIX.chromeos_image, LABEL_MIX, False)
+ self.assertEqual(len(self.log_fatal_msgs), 1)
+ self.assertEqual(self.log_fatal_msgs[0],
+ '-- not all the machines are identical')
+
+ # Test the second return statment (machine is unlocked, has no checksum)
+ save_locked = self.mock_lumpy1.locked
+ self.mock_lumpy1.locked = False
+ self.mock_lumpy1.checksum = None
+ m = self.mm.AcquireMachine(LABEL_LUMPY.chromeos_image, LABEL_LUMPY, True)
+ self.assertEqual(m, self.mock_lumpy1)
+ self.assertTrue(self.mock_lumpy1.locked)
+
+ # Test the third return statement:
+ # - machine is unlocked
+ # - checksums don't match
+ # - current time minus release time is > 20.
+ self.mock_lumpy1.locked = False
+ self.mock_lumpy1.checksum = "123"
+ self.mock_lumpy1.released_time = 0
+ m = self.mm.AcquireMachine(LABEL_LUMPY.chromeos_image, LABEL_LUMPY, True)
+ self.assertEqual(m, self.mock_lumpy1)
+ self.assertTrue(self.mock_lumpy1.locked)
+
+ # Test all machines are already locked.
+ m = self.mm.AcquireMachine(LABEL_LUMPY.chromeos_image, LABEL_LUMPY, True)
+ self.assertIsNone(m)
+
+ # Restore values of mock_lumpy1, so other tests succeed.
+ self.mock_lumpy1.locked = save_locked
+ self.mock_lumpy1.checksum = "123"
+
+
+ def test_get_available_machines(self):
+ self.mm._machines = self.mm._all_machines
+
+ machine_list = self.mm.GetAvailableMachines()
+ self.assertEqual(machine_list, self.mm._all_machines)
+
+ machine_list = self.mm.GetAvailableMachines(LABEL_MIX)
+ self.assertEqual(machine_list, [self.mock_daisy1, self.mock_daisy2,
+ self.mock_lumpy3])
+
+ machine_list = self.mm.GetAvailableMachines(LABEL_LUMPY)
+ self.assertEqual(machine_list, [self.mock_lumpy1, self.mock_lumpy2,
+ self.mock_lumpy3])
+
+
+ def test_get_machines(self):
+ machine_list = self.mm.GetMachines()
+ self.assertEqual(machine_list, self.mm._all_machines)
+
+ machine_list = self.mm.GetMachines(LABEL_MIX)
+ self.assertEqual(machine_list, [self.mock_daisy1, self.mock_daisy2,
+ self.mock_lumpy3])
+
+ machine_list = self.mm.GetMachines(LABEL_LUMPY)
+ self.assertEqual(machine_list, [self.mock_lumpy1, self.mock_lumpy2,
+ self.mock_lumpy3])
+
+
+ def test_release_machines(self):
+
+ self.mm._machines = [self.mock_lumpy1, self.mock_daisy2]
+
+ self.mock_lumpy1.locked = True
+ self.mock_daisy2.locked = True
+
+ self.assertTrue(self.mock_lumpy1.locked)
+ self.mm.ReleaseMachine(self.mock_lumpy1)
+ self.assertFalse(self.mock_lumpy1.locked)
+ self.assertEqual(self.mock_lumpy1.status, "Available")
+
+ self.assertTrue(self.mock_daisy2.locked)
+ self.mm.ReleaseMachine(self.mock_daisy2)
+ self.assertFalse(self.mock_daisy2.locked)
+ self.assertEqual(self.mock_daisy2.status, "Available")
+
+ # Test double-relase...
+ self.assertRaises(AssertionError, self.mm.ReleaseMachine, self.mock_lumpy1)
+
+
+ def test_cleanup(self):
+ self.mock_logger.reset_mock()
+ self.mm.Cleanup()
+ self.assertEqual(self.mock_logger.call_count, 0)
+
+
+ OUTPUT_STR = 'Machine Status:\nMachine Thread Lock Status Checksum \nlumpy1 test run True PENDING 123 \n\nlumpy3 test run False PENDING 123 \n\ndaisy2 test run True PENDING 678 '
+
+
+ def test_as_string(self):
+
+ mock_logger = mock.Mock(spec=logger.Logger)
+
+ bench = Benchmark("page_cycler.netsim.top_10", # name
+ "page_cycler.netsim.top_10", # test_name
+ "", # test_args
+ 1, # iteratins
+ False, # rm_chroot_tmp
+ "", # perf_args
+ suite="telemetry_Crosperf") # suite
+
+ test_run = MockBenchmarkRun("test run",
+ bench,
+ LABEL_LUMPY,
+ 1,
+ [],
+ self.mm,
+ mock_logger,
+ "verbose",
+ "")
+
+ self.mm._machines = [self.mock_lumpy1, self.mock_lumpy2, self.mock_lumpy3,
+ self.mock_daisy1, self.mock_daisy2]
+
+ self.mock_lumpy1.test_run = test_run
+ self.mock_lumpy2.test_run = test_run
+ self.mock_lumpy3.test_run = test_run
+ self.mock_daisy1.test_run = test_run
+ self.mock_daisy2.test_run = test_run
+
+ self.mock_lumpy1.locked = True
+ self.mock_lumpy2.locked = False
+ self.mock_lumpy3.locked = False
+ self.mock_daisy1.locked = False
+ self.mock_daisy2.locked = True
+
+ self.mock_lumpy1.checksum = "123"
+ self.mock_lumpy3.checksum = "123"
+ self.mock_daisy2.checksum = "678"
+
+ output = self.mm.AsString()
+ self.assertEqual(output, self.OUTPUT_STR)
+
+
+ def test_get_all_cpu_info(self):
+ info = self.mm.GetAllCPUInfo([LABEL_LUMPY, LABEL_MIX])
+ self.assertEqual(info,
+ 'lumpy\n-------------------\nlumpy_cpu_info\n\n\nmix\n-'
+ '------------------\ndaisy_cpu_info\n\n\n')
+
+
+
+MEMINFO_STRING = """MemTotal: 3990332 kB
+MemFree: 2608396 kB
+Buffers: 147168 kB
+Cached: 811560 kB
+SwapCached: 0 kB
+Active: 503480 kB
+Inactive: 628572 kB
+Active(anon): 174532 kB
+Inactive(anon): 88576 kB
+Active(file): 328948 kB
+Inactive(file): 539996 kB
+Unevictable: 0 kB
+Mlocked: 0 kB
+SwapTotal: 5845212 kB
+SwapFree: 5845212 kB
+Dirty: 9384 kB
+Writeback: 0 kB
+AnonPages: 173408 kB
+Mapped: 146268 kB
+Shmem: 89676 kB
+Slab: 188260 kB
+SReclaimable: 169208 kB
+SUnreclaim: 19052 kB
+KernelStack: 2032 kB
+PageTables: 7120 kB
+NFS_Unstable: 0 kB
+Bounce: 0 kB
+WritebackTmp: 0 kB
+CommitLimit: 7840376 kB
+Committed_AS: 1082032 kB
+VmallocTotal: 34359738367 kB
+VmallocUsed: 364980 kB
+VmallocChunk: 34359369407 kB
+DirectMap4k: 45824 kB
+DirectMap2M: 4096000 kB
+"""
+
+CPUINFO_STRING = """processor: 0
+vendor_id: GenuineIntel
+cpu family: 6
+model: 42
+model name: Intel(R) Celeron(R) CPU 867 @ 1.30GHz
+stepping: 7
+microcode: 0x25
+cpu MHz: 1300.000
+cache size: 2048 KB
+physical id: 0
+siblings: 2
+core id: 0
+cpu cores: 2
+apicid: 0
+initial apicid: 0
+fpu: yes
+fpu_exception: yes
+cpuid level: 13
+wp: yes
+flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave lahf_lm arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpid
+bogomips: 2594.17
+clflush size: 64
+cache_alignment: 64
+address sizes: 36 bits physical, 48 bits virtual
+power management:
+
+processor: 1
+vendor_id: GenuineIntel
+cpu family: 6
+model: 42
+model name: Intel(R) Celeron(R) CPU 867 @ 1.30GHz
+stepping: 7
+microcode: 0x25
+cpu MHz: 1300.000
+cache size: 2048 KB
+physical id: 0
+siblings: 2
+core id: 1
+cpu cores: 2
+apicid: 2
+initial apicid: 2
+fpu: yes
+fpu_exception: yes
+cpuid level: 13
+wp: yes
+flags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave lahf_lm arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpid
+bogomips: 2594.17
+clflush size: 64
+cache_alignment: 64
+address sizes: 36 bits physical, 48 bits virtual
+power management:
+"""
+
+CHECKSUM_STRING = "processor: 0vendor_id: GenuineIntelcpu family: 6model: 42model name: Intel(R) Celeron(R) CPU 867 @ 1.30GHzstepping: 7microcode: 0x25cache size: 2048 KBphysical id: 0siblings: 2core id: 0cpu cores: 2apicid: 0initial apicid: 0fpu: yesfpu_exception: yescpuid level: 13wp: yesflags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave lahf_lm arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpidclflush size: 64cache_alignment: 64address sizes: 36 bits physical, 48 bits virtualpower management:processor: 1vendor_id: GenuineIntelcpu family: 6model: 42model name: Intel(R) Celeron(R) CPU 867 @ 1.30GHzstepping: 7microcode: 0x25cache size: 2048 KBphysical id: 0siblings: 2core id: 1cpu cores: 2apicid: 2initial apicid: 2fpu: yesfpu_exception: yescpuid level: 13wp: yesflags: fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf pni pclmulqdq dtes64 monitor ds_cpl vmx est tm2 ssse3 cx16 xtpr pdcm pcid sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer xsave lahf_lm arat epb xsaveopt pln pts dts tpr_shadow vnmi flexpriority ept vpidclflush size: 64cache_alignment: 64address sizes: 36 bits physical, 48 bits virtualpower management: 4194304"
+
+DUMP_VPD_STRING = """
+"PBA_SN"="Pba.txt"
+"Product_S/N"="HT4L91SC300208"
+"serial_number"="HT4L91SC300208Z"
+"System_UUID"="12153006-1755-4f66-b410-c43758a71127"
+"shipping_country"="US"
+"initial_locale"="en-US"
+"keyboard_layout"="xkb:us::eng"
+"initial_timezone"="America/Los_Angeles"
+"MACAddress"=""
+"System_UUID"="29dd9c61-7fa1-4c83-b89a-502e7eb08afe"
+"ubind_attribute"="0c433ce7585f486730b682bb05626a12ce2d896e9b57665387f8ce2ccfdcc56d2e2f1483"
+"gbind_attribute"="7e9a851324088e269319347c6abb8d1572ec31022fa07e28998229afe8acb45c35a89b9d"
+"ActivateDate"="2013-38"
+"""
+
+
+IFCONFIG_STRING = """
+eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500
+ inet 172.17.129.247 netmask 255.255.254.0 broadcast 172.17.129.255
+ inet6 2620:0:1000:3002:143:fed4:3ff6:279d prefixlen 64 scopeid 0x0<global>
+ inet6 2620:0:1000:3002:4459:1399:1f02:9e4c prefixlen 64 scopeid 0x0<global>
+ inet6 2620:0:1000:3002:d9e4:87b:d4ec:9a0e prefixlen 64 scopeid 0x0<global>
+ inet6 2620:0:1000:3002:7d45:23f1:ea8a:9604 prefixlen 64 scopeid 0x0<global>
+ inet6 2620:0:1000:3002:250:b6ff:fe63:db65 prefixlen 64 scopeid 0x0<global>
+ inet6 fe80::250:b6ff:fe63:db65 prefixlen 64 scopeid 0x20<link>
+ ether 00:50:b6:63:db:65 txqueuelen 1000 (Ethernet)
+ RX packets 9817166 bytes 10865181708 (10.1 GiB)
+ RX errors 194 dropped 0 overruns 0 frame 194
+ TX packets 0 bytes 2265811903 (2.1 GiB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+eth1: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
+ ether e8:03:9a:9c:50:3d txqueuelen 1000 (Ethernet)
+ RX packets 0 bytes 0 (0.0 B)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 0 bytes 0 (0.0 B)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+lo: flags=73<UP,LOOPBACK,RUNNING> mtu 16436
+ inet 127.0.0.1 netmask 255.0.0.0
+ inet6 ::1 prefixlen 128 scopeid 0x10<host>
+ loop txqueuelen 0 (Local Loopback)
+ RX packets 981004 bytes 1127468524 (1.0 GiB)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 981004 bytes 1127468524 (1.0 GiB)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+
+wlan0: flags=4099<UP,BROADCAST,MULTICAST> mtu 1500
+ ether 44:6d:57:20:4a:c5 txqueuelen 1000 (Ethernet)
+ RX packets 0 bytes 0 (0.0 B)
+ RX errors 0 dropped 0 overruns 0 frame 0
+ TX packets 0 bytes 0 (0.0 B)
+ TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
+"""
+
+
+class CrosMachineTest(unittest.TestCase):
+
+ mock_cmd_exec = mock.Mock(spec=command_executer.CommandExecuter)
+
+ @mock.patch.object(machine_manager.CrosMachine, 'SetUpChecksumInfo')
+ def test_init(self, mock_setup):
+
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ self.assertEqual(mock_setup.call_count, 1)
+ self.assertEqual(cm.chromeos_root, "/usr/local/chromeos")
+ self.assertEqual(cm.log_level, "average")
+
+
+ @mock.patch.object(machine_manager.CrosMachine, 'IsReachable')
+ @mock.patch.object(machine_manager.CrosMachine, '_GetMemoryInfo')
+ @mock.patch.object(machine_manager.CrosMachine, '_GetCPUInfo')
+ @mock.patch.object(machine_manager.CrosMachine,
+ '_ComputeMachineChecksumString')
+ @mock.patch.object(machine_manager.CrosMachine, '_GetMachineID')
+ @mock.patch.object(machine_manager.CrosMachine, '_GetMD5Checksum')
+ def test_setup_checksum_info(self, mock_md5sum, mock_machineid,
+ mock_checkstring, mock_cpuinfo, mock_meminfo,
+ mock_isreachable):
+
+ # Test 1. Machine is not reachable; SetUpChecksumInfo is called via
+ # __init__.
+ mock_isreachable.return_value = False
+ mock_md5sum.return_value = "md5_checksum"
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ cm.checksum_string = "This is a checksum string."
+ cm.machine_id = "machine_id1"
+ self.assertEqual(mock_isreachable.call_count, 1)
+ self.assertIsNone(cm.machine_checksum)
+ self.assertEqual(mock_meminfo.call_count, 0)
+
+ # Test 2. Machine is reachable. Call explicitly.
+ mock_isreachable.return_value = True
+ cm.checksum_string = "This is a checksum string."
+ cm.machine_id = "machine_id1"
+ cm.SetUpChecksumInfo()
+ self.assertEqual(mock_isreachable.call_count, 2)
+ self.assertEqual(mock_meminfo.call_count, 1)
+ self.assertEqual(mock_cpuinfo.call_count, 1)
+ self.assertEqual(mock_checkstring.call_count, 1)
+ self.assertEqual(mock_machineid.call_count, 1)
+ self.assertEqual(mock_md5sum.call_count, 2)
+ self.assertEqual(cm.machine_checksum, "md5_checksum")
+ self.assertEqual(cm.machine_id_checksum, "md5_checksum")
+ self.assertEqual(mock_md5sum.call_args_list[0][0][0],
+ "This is a checksum string.")
+ self.assertEqual(mock_md5sum.call_args_list[1][0][0],
+ "machine_id1")
+
+ @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand')
+ @mock.patch.object(machine_manager.CrosMachine, "SetUpChecksumInfo")
+ def test_is_reachable(self, mock_setup, mock_run_cmd):
+
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ self.mock_cmd_exec.CrosRunCommand = mock_run_cmd
+
+ # Test 1. CrosRunCommand returns 1 (fail)
+ mock_run_cmd.return_value = 1
+ result = cm.IsReachable()
+ self.assertFalse(result)
+ self.assertEqual(mock_setup.call_count, 1)
+ self.assertEqual(mock_run_cmd.call_count, 1)
+
+ # Test 2. CrosRunCommand returns 0 (success)
+ mock_run_cmd.return_value = 0
+ result = cm.IsReachable()
+ self.assertTrue(result)
+ self.assertEqual(mock_run_cmd.call_count, 2)
+ first_args = mock_run_cmd.call_args_list[0]
+ second_args = mock_run_cmd.call_args_list[1]
+ self.assertEqual (first_args[0], second_args[0])
+ self.assertEqual (first_args[1], second_args[1])
+ self.assertEqual (len(first_args[0]), 1)
+ self.assertEqual (len(first_args[1]), 2)
+ self.assertEqual (first_args[0][0], 'ls')
+ args_dict = first_args[1]
+ self.assertEqual (args_dict['machine'], 'daisy.cros')
+ self.assertEqual (args_dict['chromeos_root'], '/usr/local/chromeos')
+
+
+ @mock.patch.object(machine_manager.CrosMachine, "SetUpChecksumInfo")
+ def test_parse_memory_info(self, mock_setup):
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ cm.meminfo = MEMINFO_STRING
+ cm._ParseMemoryInfo()
+ self.assertEqual(cm.phys_kbytes, 4194304)
+
+
+ @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand')
+ @mock.patch.object(machine_manager.CrosMachine, "SetUpChecksumInfo")
+ def test_get_memory_info(self, mock_setup, mock_run_cmd):
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ self.mock_cmd_exec.CrosRunCommand = mock_run_cmd
+ mock_run_cmd.return_value = [0, MEMINFO_STRING, ""]
+ cm._GetMemoryInfo()
+ self.assertEqual(mock_run_cmd.call_count, 1)
+ call_args = mock_run_cmd.call_args_list[0]
+ self.assertEqual(call_args[0][0], "cat /proc/meminfo")
+ args_dict = call_args[1]
+ self.assertEqual(args_dict['username'], 'root')
+ self.assertEqual(args_dict['machine'], 'daisy.cros')
+ self.assertEqual(args_dict['chromeos_root'], '/usr/local/chromeos')
+ self.assertEqual(args_dict['return_output'], True)
+ self.assertEqual(cm.meminfo, MEMINFO_STRING)
+ self.assertEqual(cm.phys_kbytes, 4194304)
+
+ mock_run_cmd.return_value = [1, MEMINFO_STRING, ""]
+ self.assertRaises (cm._GetMemoryInfo)
+
+
+ @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand')
+ @mock.patch.object(machine_manager.CrosMachine, "SetUpChecksumInfo")
+ def test_get_cpu_info(self, mock_setup, mock_run_cmd):
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ self.mock_cmd_exec.CrosRunCommand = mock_run_cmd
+ mock_run_cmd.return_value = [0, CPUINFO_STRING, ""]
+ cm._GetCPUInfo()
+ self.assertEqual(mock_run_cmd.call_count, 1)
+ call_args = mock_run_cmd.call_args_list[0]
+ self.assertEqual(call_args[0][0], "cat /proc/cpuinfo")
+ args_dict = call_args[1]
+ self.assertEqual(args_dict['username'], 'root')
+ self.assertEqual(args_dict['machine'], 'daisy.cros')
+ self.assertEqual(args_dict['chromeos_root'], '/usr/local/chromeos')
+ self.assertEqual(args_dict['return_output'], True)
+ self.assertEqual(cm.cpuinfo, CPUINFO_STRING)
+
+
+ @mock.patch.object(machine_manager.CrosMachine, "SetUpChecksumInfo")
+ def test_compute_machine_checksum_string(self, mock_setup):
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ cm.cpuinfo = CPUINFO_STRING
+ cm.meminfo = MEMINFO_STRING
+ cm._ParseMemoryInfo()
+ cm._ComputeMachineChecksumString()
+ self.assertEqual(cm.checksum_string, CHECKSUM_STRING)
+
+
+ @mock.patch.object(machine_manager.CrosMachine, "SetUpChecksumInfo")
+ def test_get_md5_checksum(self, mock_setup):
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ temp_str = "abcde"
+ checksum_str = cm._GetMD5Checksum(temp_str)
+ self.assertEqual(checksum_str, "ab56b4d92b40713acc5af89985d4b786")
+
+ temp_str = ""
+ checksum_str = cm._GetMD5Checksum(temp_str)
+ self.assertEqual(checksum_str, "")
+
+
+ @mock.patch.object(command_executer.CommandExecuter, 'CrosRunCommand')
+ @mock.patch.object(machine_manager.CrosMachine, "SetUpChecksumInfo")
+ def test_get_machine_id(self, mock_setup, mock_run_cmd):
+ cm = machine_manager.CrosMachine("daisy.cros", "/usr/local/chromeos",
+ "average", self.mock_cmd_exec)
+ self.mock_cmd_exec.CrosRunCommand = mock_run_cmd
+ mock_run_cmd.return_value = [0, DUMP_VPD_STRING, ""]
+
+ cm._GetMachineID()
+ self.assertEqual(cm.machine_id, '"Product_S/N"="HT4L91SC300208"')
+
+ mock_run_cmd.return_value = [0, IFCONFIG_STRING, ""]
+ cm._GetMachineID()
+ self.assertEqual(cm.machine_id, " ether 00:50:b6:63:db:65 txqueuelen 1000 (Ethernet)_ ether e8:03:9a:9c:50:3d txqueuelen 1000 (Ethernet)_ ether 44:6d:57:20:4a:c5 txqueuelen 1000 (Ethernet)")
+
+ mock_run_cmd.return_value = [0, "invalid hardware config", ""]
+ self.assertRaises(cm._GetMachineID)
+
+
+
if __name__ == "__main__":
unittest.main()