aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xbuildbot_test_toolchains.py56
-rw-r--r--crosperf/benchmark_run.py3
-rwxr-xr-xcrosperf/benchmark_unittest.py7
-rwxr-xr-xcrosperf/config_unittest.py6
-rwxr-xr-xcrosperf/crosperf_test.py8
-rwxr-xr-xcrosperf/crosperf_unittest.py5
-rw-r--r--crosperf/perf_table.py6
-rw-r--r--crosperf/results_cache.py88
-rwxr-xr-xcrosperf/results_cache_unittest.py35
-rw-r--r--crosperf/schedv2.py79
-rwxr-xr-xcrosperf/schedv2_unittest.py53
-rwxr-xr-xcrosperf/settings_factory_unittest.py14
-rwxr-xr-xrun_tests.py19
13 files changed, 230 insertions, 149 deletions
diff --git a/buildbot_test_toolchains.py b/buildbot_test_toolchains.py
index 58e76b45..4cad4c7a 100755
--- a/buildbot_test_toolchains.py
+++ b/buildbot_test_toolchains.py
@@ -12,8 +12,8 @@ well as copying the images into the seven-day reports directory.
from __future__ import print_function
+import argparse
import datetime
-import optparse
import os
import re
import sys
@@ -329,33 +329,33 @@ def Main(argv):
# Common initializations
command_executer.InitCommandExecuter()
- parser = optparse.OptionParser()
- parser.add_option('--remote',
- dest='remote',
- help='Remote machines to run tests on.')
- parser.add_option('--board',
- dest='board',
- default='x86-zgb',
- help='The target board.')
- parser.add_option('--chromeos_root',
- dest='chromeos_root',
- help='The chromeos root from which to run tests.')
- parser.add_option('--weekday',
- default='',
- dest='weekday',
- help='The day of the week for which to run tests.')
- parser.add_option('--patch',
- dest='patches',
- help='The patches to use for the testing, '
- "seprate the patch numbers with ',' "
- 'for more than one patches.')
- parser.add_option('--noschedv2',
- dest='noschedv2',
- action='store_true',
- default=False,
- help='Pass --noschedv2 to crosperf.')
-
- options, _ = parser.parse_args(argv)
+ parser = argparse.ArgumentParser()
+ parser.add_argument('--remote',
+ dest='remote',
+ help='Remote machines to run tests on.')
+ parser.add_argument('--board',
+ dest='board',
+ default='x86-zgb',
+ help='The target board.')
+ parser.add_argument('--chromeos_root',
+ dest='chromeos_root',
+ help='The chromeos root from which to run tests.')
+ parser.add_argument('--weekday',
+ default='',
+ dest='weekday',
+ help='The day of the week for which to run tests.')
+ parser.add_argument('--patch',
+ dest='patches',
+ help='The patches to use for the testing, '
+ "seprate the patch numbers with ',' "
+ 'for more than one patches.')
+ parser.add_argument('--noschedv2',
+ dest='noschedv2',
+ action='store_true',
+ default=False,
+ help='Pass --noschedv2 to crosperf.')
+
+ options = parser.parse_args(argv[1:])
if not options.board:
print('Please give a board.')
return 1
diff --git a/crosperf/benchmark_run.py b/crosperf/benchmark_run.py
index 35977a63..5d161417 100644
--- a/crosperf/benchmark_run.py
+++ b/crosperf/benchmark_run.py
@@ -96,7 +96,7 @@ class BenchmarkRun(threading.Thread):
err = 'No cache hit.'
self.result = Result.CreateFromRun(
self._logger, self.log_level, self.label, self.machine, output, err,
- retval, self.benchmark.show_all_results, self.benchmark.test_name,
+ retval, self.benchmark.test_name,
self.benchmark.suite)
else:
@@ -213,7 +213,6 @@ class BenchmarkRun(threading.Thread):
self.run_completed = True
return Result.CreateFromRun(self._logger, self.log_level, self.label,
self.machine, out, err, retval,
- self.benchmark.show_all_results,
self.benchmark.test_name, self.benchmark.suite)
def SetCacheConditions(self, cache_conditions):
diff --git a/crosperf/benchmark_unittest.py b/crosperf/benchmark_unittest.py
index 32fb721e..0a90eef0 100755
--- a/crosperf/benchmark_unittest.py
+++ b/crosperf/benchmark_unittest.py
@@ -1,6 +1,9 @@
-#!/usr/bin/python
+#!/usr/bin/python2
#
# Copyright 2014 Google Inc. All Rights Reserved
+"""Unit tests for the Crosperf Benchmark class."""
+
+from __future__ import print_function
import inspect
from benchmark import Benchmark
@@ -9,6 +12,7 @@ import unittest
class BenchmarkTestCase(unittest.TestCase):
+ """Individual tests for the Benchmark class."""
def test_benchmark(self):
# Test creating a benchmark with all the fields filled out.
@@ -20,6 +24,7 @@ class BenchmarkTestCase(unittest.TestCase):
'record -e cycles', # perf_args
'telemetry_Crosperf', # suite
True) # show_all_results
+ self.assertTrue(b1.suite, 'telemetry_Crosperf')
# Test creating a benchmark field with default fields left out.
b2 = Benchmark('b2_test', # name
diff --git a/crosperf/config_unittest.py b/crosperf/config_unittest.py
index 397f2c2c..b632055e 100755
--- a/crosperf/config_unittest.py
+++ b/crosperf/config_unittest.py
@@ -1,6 +1,9 @@
-#!/usr/bin/python
+#!/usr/bin/python2
#
# Copyright 2014 Google Inc. All Rights Reserved.
+"""Unit tests for config.py"""
+
+from __future__ import print_function
import config
@@ -8,6 +11,7 @@ import unittest
class ConfigTestCase(unittest.TestCase):
+ """Class for the config unit tests."""
def test_config(self):
# Verify that config exists, that it's a dictionary, and that it's
diff --git a/crosperf/crosperf_test.py b/crosperf/crosperf_test.py
index 09aefcb6..8f929e71 100755
--- a/crosperf/crosperf_test.py
+++ b/crosperf/crosperf_test.py
@@ -1,12 +1,15 @@
-#!/usr/bin/python
+#!/usr/bin/python2
# Copyright 2011 Google Inc. All Rights Reserved.
+"""Test for crosperf."""
+
+from __future__ import print_function
import os
import tempfile
import unittest
import crosperf
-from utils.file_utils import FileUtils
+from cros_utils.file_utils import FileUtils
EXPERIMENT_FILE_1 = """
board: x86-alex
@@ -27,6 +30,7 @@ EXPERIMENT_FILE_1 = """
class CrosPerfTest(unittest.TestCase):
+ """Class to test Crosperf."""
def testDryRun(self):
filehandle, filename = tempfile.mkstemp()
diff --git a/crosperf/crosperf_unittest.py b/crosperf/crosperf_unittest.py
index 7e07ee0c..24015b37 100755
--- a/crosperf/crosperf_unittest.py
+++ b/crosperf/crosperf_unittest.py
@@ -14,8 +14,6 @@ import crosperf
import settings_factory
import experiment_file
-from help import Help
-
EXPERIMENT_FILE_1 = """
board: x86-alex
remote: chromeos-alex3
@@ -48,7 +46,8 @@ class CrosperfTest(unittest.TestCase):
'--log_dir',
dest='log_dir',
default='',
- help='The log_dir, default is under <crosperf_logs>/logs')
+ help='The log_dir, default is under '
+ '<crosperf_logs>/logs')
crosperf.SetupParserOptions(parser)
argv = ['crosperf/crosperf.py', 'temp.exp', '--rerun=True']
options, _ = parser.parse_known_args(argv)
diff --git a/crosperf/perf_table.py b/crosperf/perf_table.py
index c996719d..5a565486 100644
--- a/crosperf/perf_table.py
+++ b/crosperf/perf_table.py
@@ -1,12 +1,14 @@
# Copyright 2012 Google Inc. All Rights Reserved.
"""Parse perf report data for tabulator."""
+from __future__ import print_function
+
import os
-from utils import perf_diff
+from cros_utils import perf_diff
-def ParsePerfReport(perf_file):
+def ParsePerfReport():
"""It should return a dict."""
return {'cycles': {'foo': 10,
diff --git a/crosperf/results_cache.py b/crosperf/results_cache.py
index 2a0f1678..941e841c 100644
--- a/crosperf/results_cache.py
+++ b/crosperf/results_cache.py
@@ -4,7 +4,8 @@
# found in the LICENSE file.
"""Module to deal with result cache."""
-import getpass
+from __future__ import print_function
+
import glob
import hashlib
import os
@@ -31,7 +32,9 @@ CACHE_KEYS_FILE = 'cache_keys.txt'
class Result(object):
- """ This class manages what exactly is stored inside the cache without knowing
+ """Class for holding the results of a single test run.
+
+ This class manages what exactly is stored inside the cache without knowing
what the key of the cache is. For runs with perf, it stores perf.data,
perf.report, etc. The key generation is handled by the ResultsCache class.
"""
@@ -50,6 +53,14 @@ class Result(object):
self.perf_data_files = []
self.perf_report_files = []
self.chrome_version = ''
+ self.err = None
+ self.chroot_results_dir = ''
+ self.test_name = ''
+ self.keyvals = None
+ self.board = None
+ self.suite = None
+ self.retval = None
+ self.out = None
def CopyFilesTo(self, dest_dir, files_to_copy):
file_index = 0
@@ -83,7 +94,7 @@ class Result(object):
else:
# Otherwise get the base filename and create the correct
# path for it.
- f_dir, f_base = misc.GetRoot(f)
+ _, f_base = misc.GetRoot(f)
data_filename = os.path.join(self.chromeos_root, 'chroot/tmp',
self.temp_dir, f_base)
if data_filename.find('.json') > 0:
@@ -126,7 +137,6 @@ class Result(object):
unit in the units_dict, and replaces the old value with a list of the
old value and the units. This later gets properly parsed in the
ResultOrganizer class, for generating the reports.
-
"""
results_dict = {}
@@ -140,7 +150,7 @@ class Result(object):
results_dict[k] = new_val
return results_dict
- def GetKeyvals(self, show_all):
+ def GetKeyvals(self):
results_in_chroot = os.path.join(self.chromeos_root, 'chroot', 'tmp')
if not self.temp_dir:
self.temp_dir = tempfile.mkdtemp(dir=results_in_chroot)
@@ -150,8 +160,8 @@ class Result(object):
command = ('python generate_test_report --no-color --csv %s' %
(os.path.join('/tmp', os.path.basename(self.temp_dir))))
_, out, _ = self.ce.ChrootRunCommandWOutput(self.chromeos_root,
- command,
- print_to_console=False)
+ command,
+ print_to_console=False)
keyvals_dict = {}
tmp_dir_in_chroot = misc.GetInsideChrootPath(self.chromeos_root,
self.temp_dir)
@@ -198,7 +208,8 @@ class Result(object):
def GetDataMeasurementsFiles(self):
result = self.FindFilesInResultsDir('-name perf_measurements').splitlines()
if not result:
- result = self.FindFilesInResultsDir('-name results-chart.json').splitlines()
+ result = \
+ self.FindFilesInResultsDir('-name results-chart.json').splitlines()
return result
def GeneratePerfReportFiles(self):
@@ -262,7 +273,7 @@ class Result(object):
value = str(misc.UnitToNumber(num_events))
self.keyvals[key] = value
- def PopulateFromRun(self, out, err, retval, show_all, test, suite):
+ def PopulateFromRun(self, out, err, retval, test, suite):
self.board = self.label.board
self.out = out
self.err = err
@@ -278,13 +289,13 @@ class Result(object):
# TODO(asharif): Do something similar with perf stat.
# Grab keyvals from the directory.
- self.ProcessResults(show_all)
+ self.ProcessResults()
- def ProcessResults(self, show_all):
+ def ProcessResults(self):
# Note that this function doesn't know anything about whether there is a
# cache hit or miss. It should process results agnostic of the cache hit
# state.
- self.keyvals = self.GetKeyvals(show_all)
+ self.keyvals = self.GetKeyvals()
self.keyvals['retval'] = self.retval
# Generate report from all perf.data files.
# Now parse all perf report files and include them in keyvals.
@@ -305,7 +316,7 @@ class Result(object):
break
return chrome_version
- def PopulateFromCacheDir(self, cache_dir, show_all, test, suite):
+ def PopulateFromCacheDir(self, cache_dir, test, suite):
self.test_name = test
self.suite = suite
# Read in everything from the cache directory.
@@ -327,7 +338,7 @@ class Result(object):
self.perf_data_files = self.GetPerfDataFiles()
self.perf_report_files = self.GetPerfReportFiles()
self.chrome_version = self.GetChromeVersionFromCache(cache_dir)
- self.ProcessResults(show_all)
+ self.ProcessResults()
def CleanUp(self, rm_chroot_tmp):
if rm_chroot_tmp and self.results_dir:
@@ -398,14 +409,13 @@ class Result(object):
out,
err,
retval,
- show_all,
test,
suite='telemetry_Crosperf'):
if suite == 'telemetry':
result = TelemetryResult(logger, label, log_level, machine)
else:
result = cls(logger, label, log_level, machine)
- result.PopulateFromRun(out, err, retval, show_all, test, suite)
+ result.PopulateFromRun(out, err, retval, test, suite)
return result
@classmethod
@@ -415,7 +425,6 @@ class Result(object):
label,
machine,
cache_dir,
- show_all,
test,
suite='telemetry_Crosperf'):
if suite == 'telemetry':
@@ -423,7 +432,7 @@ class Result(object):
else:
result = cls(logger, label, log_level, machine)
try:
- result.PopulateFromCacheDir(cache_dir, show_all, test, suite)
+ result.PopulateFromCacheDir(cache_dir, test, suite)
except Exception as e:
logger.LogError('Exception while using cache: %s' % e)
@@ -432,12 +441,13 @@ class Result(object):
class TelemetryResult(Result):
+ """Class to hold the results of a single Telemetry run."""
def __init__(self, logger, label, log_level, machine, cmd_exec=None):
super(TelemetryResult, self).__init__(logger, label, log_level, machine,
cmd_exec)
- def PopulateFromRun(self, out, err, retval, show_all, test, suite):
+ def PopulateFromRun(self, out, err, retval, test, suite):
self.out = out
self.err = err
self.retval = retval
@@ -476,7 +486,9 @@ class TelemetryResult(Result):
self.keyvals[key] = value
self.keyvals['retval'] = self.retval
- def PopulateFromCacheDir(self, cache_dir):
+ def PopulateFromCacheDir(self, cache_dir, test, suite):
+ self.test_name = test
+ self.suite = suite
with open(os.path.join(cache_dir, RESULTS_FILE), 'r') as f:
self.out = pickle.load(f)
self.err = pickle.load(f)
@@ -488,6 +500,8 @@ class TelemetryResult(Result):
class CacheConditions(object):
+ """Various Cache condition values, for export."""
+
# Cache hit only if the result file exists.
CACHE_FILE_EXISTS = 0
@@ -513,12 +527,36 @@ class CacheConditions(object):
class ResultsCache(object):
- """ This class manages the key of the cached runs without worrying about what
+ """Class to handle the cache for storing/retrieving test run results.
+
+ This class manages the key of the cached runs without worrying about what
is exactly stored (value). The value generation is handled by the Results
class.
"""
CACHE_VERSION = 6
+ def __init__(self):
+ # Proper initialization happens in the Init function below.
+ self.chromeos_image = None
+ self.chromeos_root = None
+ self.test_name = None
+ self.iteration = None
+ self.test_args = None
+ self.profiler_args = None
+ self.board = None
+ self.cache_conditions = None
+ self.machine_manager = None
+ self.machine = None
+ self._logger = None
+ self.ce = None
+ self.label = None
+ self.share_cache = None
+ self.suite = None
+ self.log_level = None
+ self.show_all = None
+ self.run_local = None
+
+
def Init(self, chromeos_image, chromeos_root, test_name, iteration, test_args,
profiler_args, machine_manager, machine, board, cache_conditions,
logger_to_use, log_level, label, share_cache, suite,
@@ -535,7 +573,7 @@ class ResultsCache(object):
self.machine = machine
self._logger = logger_to_use
self.ce = command_executer.GetCommandExecuter(self._logger,
- log_level=log_level)
+ log_level=log_level)
self.label = label
self.share_cache = share_cache
self.suite = suite
@@ -639,7 +677,7 @@ class ResultsCache(object):
if self.log_level == 'verbose':
self._logger.LogOutput('Trying to read from cache dir: %s' % cache_dir)
result = Result.CreateFromCacheHit(self._logger, self.log_level, self.label,
- self.machine, cache_dir, self.show_all,
+ self.machine, cache_dir,
self.test_name, self.suite)
if not result:
return None
@@ -656,6 +694,7 @@ class ResultsCache(object):
class MockResultsCache(ResultsCache):
+ """Class for mock testing, corresponding to ResultsCache class."""
def Init(self, *args):
pass
@@ -668,8 +707,9 @@ class MockResultsCache(ResultsCache):
class MockResult(Result):
+ """Class for mock testing, corresponding to Result class."""
- def PopulateFromRun(self, out, err, retval, show_all, test, suite):
+ def PopulateFromRun(self, out, err, retval, test, suite):
self.out = out
self.err = err
self.retval = retval
diff --git a/crosperf/results_cache_unittest.py b/crosperf/results_cache_unittest.py
index a79ff862..10031734 100755
--- a/crosperf/results_cache_unittest.py
+++ b/crosperf/results_cache_unittest.py
@@ -165,8 +165,9 @@ class MockResult(Result):
def FindFilesInResultsDir(self, find_args):
return ''
- def GetKeyvals(self, show_all_results):
- if show_all_results:
+ # pylint: disable=arguments-differ
+ def GetKeyvals(self, temp=False):
+ if temp:
pass
return keyvals
@@ -417,7 +418,7 @@ class ResultTest(unittest.TestCase):
self.result.results_dir = '/tmp/test_that_resultsNmq'
# Test 1. no self.temp_dir.
- res = self.result.GetKeyvals(True)
+ res = self.result.GetKeyvals()
self.assertTrue(self.callGetNewKeyvals)
self.assertEqual(self.kv_dict, {'': 'PASS', 'telemetry_Crosperf': 'PASS'})
self.assertEqual(mock_runcmd.call_count, 1)
@@ -437,7 +438,7 @@ class ResultTest(unittest.TestCase):
'telemetry_Crosperf,PASS\n'), '']
mock_getpath.return_value = '/tmp/tmpJCajRG'
self.result.temp_dir = '/tmp/tmpJCajRG'
- res = self.result.GetKeyvals(True)
+ res = self.result.GetKeyvals()
self.assertEqual(mock_runcmd.call_count, 0)
self.assertEqual(mock_mkdtemp.call_count, 0)
self.assertEqual(mock_chrootruncmd.call_count, 1)
@@ -452,7 +453,7 @@ class ResultTest(unittest.TestCase):
# test results (which we do for Telemetry autotest runs).
reset()
self.result.suite = ''
- res = self.result.GetKeyvals(True)
+ res = self.result.GetKeyvals()
self.assertEqual(res, {'Total': 10, 'first_time': 680})
def test_get_results_dir(self):
@@ -551,7 +552,7 @@ class ResultTest(unittest.TestCase):
self.callGetPerfReportFiles = True
return []
- def FakeProcessResults(show_results):
+ def FakeProcessResults(show_results=False):
if show_results:
pass
self.callProcessResults = True
@@ -571,7 +572,7 @@ class ResultTest(unittest.TestCase):
self.result.GeneratePerfReportFiles = FakeGetPerfReportFiles
self.result.ProcessResults = FakeProcessResults
- self.result.PopulateFromRun(OUTPUT, '', 0, True, 'test',
+ self.result.PopulateFromRun(OUTPUT, '', 0, 'test',
'telemetry_Crosperf')
self.assertTrue(self.callGetResultsDir)
self.assertTrue(self.callGetPerfDataFiles)
@@ -580,7 +581,7 @@ class ResultTest(unittest.TestCase):
def test_process_results(self):
- def FakeGetKeyvals(show_all):
+ def FakeGetKeyvals(show_all=False):
if show_all:
return {'first_time': 680, 'Total': 10}
else:
@@ -595,15 +596,14 @@ class ResultTest(unittest.TestCase):
self.result.GatherPerfResults = FakeGatherPerfResults
self.result.retval = 0
- self.result.ProcessResults(True)
+ self.result.ProcessResults()
self.assertTrue(self.callGatherPerfResults)
- self.assertEqual(len(self.result.keyvals), 3)
- self.assertEqual(self.result.keyvals, {'first_time': 680,
- 'Total': 10,
+ self.assertEqual(len(self.result.keyvals), 2)
+ self.assertEqual(self.result.keyvals, {'Total': 10,
'retval': 0})
self.result.retval = 1
- self.result.ProcessResults(False)
+ self.result.ProcessResults()
self.assertEqual(len(self.result.keyvals), 2)
self.assertEqual(self.result.keyvals, {'Total': 10, 'retval': 1})
@@ -612,7 +612,8 @@ class ResultTest(unittest.TestCase):
'ChrootRunCommandWOutput')
def test_populate_from_cache_dir(self, mock_runchrootcmd, mock_getpath):
- def FakeMkdtemp(dir):
+ # pylint: disable=redefined-builtin
+ def FakeMkdtemp(dir=None):
if dir:
pass
return self.tmpdir
@@ -629,7 +630,7 @@ class ResultTest(unittest.TestCase):
save_real_mkdtemp = tempfile.mkdtemp
tempfile.mkdtemp = FakeMkdtemp
- self.result.PopulateFromCacheDir(cache_dir, True, 'sunspider',
+ self.result.PopulateFromCacheDir(cache_dir, 'sunspider',
'telemetry_Crosperf')
self.assertEqual(
self.result.keyvals,
@@ -895,7 +896,7 @@ class TelemetryResultTest(unittest.TestCase):
self.result = TelemetryResult(self.mock_logger, self.mock_label, 'average',
self.mock_cmd_exec)
self.result.ProcessResults = FakeProcessResults
- self.result.PopulateFromRun(OUTPUT, error, 3, False, 'fake_test',
+ self.result.PopulateFromRun(OUTPUT, error, 3, 'fake_test',
'telemetry_Crosperf')
self.assertTrue(self.callFakeProcessResults)
self.assertEqual(self.result.out, OUTPUT)
@@ -909,7 +910,7 @@ class TelemetryResultTest(unittest.TestCase):
current_path = os.getcwd()
cache_dir = os.path.join(current_path,
'test_cache/test_puretelemetry_input')
- self.result.PopulateFromCacheDir(cache_dir)
+ self.result.PopulateFromCacheDir(cache_dir, '', '')
self.assertEqual(self.result.out.strip(), PURE_TELEMETRY_OUTPUT.strip())
self.assertEqual(self.result.err, '')
self.assertEqual(self.result.retval, 0)
diff --git a/crosperf/schedv2.py b/crosperf/schedv2.py
index 3a31d93c..7e5bd8c9 100644
--- a/crosperf/schedv2.py
+++ b/crosperf/schedv2.py
@@ -1,7 +1,10 @@
# Copyright 2015 Google Inc. All Rights Reserved.
+"""Module to optimize the scheduling of benchmark_run tasks."""
+
+
+from __future__ import print_function
-import math
import sys
import test_flag
import traceback
@@ -24,7 +27,7 @@ class DutWorker(Thread):
self._stat_num_br_run = 0
self._stat_num_reimage = 0
self._stat_annotation = ''
- self._logger = logger.GetLogger(self._sched._experiment.log_dir)
+ self._logger = logger.GetLogger(self._sched.get_experiment().log_dir)
self.daemon = True
self._terminated = False
self._active_br = None
@@ -52,7 +55,7 @@ class DutWorker(Thread):
try:
self._stat_annotation = 'finishing cached {}'.format(br)
br.run()
- except:
+ except RuntimeError:
traceback.print_exc(file=sys.stdout)
br = self._sched.get_cached_benchmark_run()
@@ -106,11 +109,13 @@ class DutWorker(Thread):
try:
# Note, only 1 reimage at any given time, this is guaranteed in
# ImageMachine, so no sync needed below.
- retval = self._sched._experiment.machine_manager.ImageMachine(self._dut,
- label)
+ retval = self._sched.get_experiment().machine_manager.ImageMachine(
+ self._dut,
+ label)
+
if retval:
return 1
- except:
+ except RuntimeError:
return 1
self._dut.label = label
@@ -137,7 +142,7 @@ class DutWorker(Thread):
self._active_br = br
br.run()
finally:
- self._sched._experiment.BenchmarkRunFinished(br)
+ self._sched.get_experiment().BenchmarkRunFinished(br)
with self._active_br_lock:
self._active_br = None
@@ -153,18 +158,18 @@ class DutWorker(Thread):
rv, checksum, _ = command_executer.GetCommandExecuter().\
CrosRunCommandWOutput(
'cat ' + checksum_file,
- chromeos_root=self._sched._labels[0].chromeos_root,
+ chromeos_root=self._sched.get_labels(0).chromeos_root,
machine=self._dut.name,
print_to_console=False)
if rv == 0:
checksum = checksum.strip()
- for l in self._sched._labels:
+ for l in self._sched.get_labels():
if l.checksum == checksum:
self._logger.LogOutput("Dut '{}' is pre-installed with '{}'".format(
self._dut.name, l))
self._dut.label = l
return
- except:
+ except RuntimeError:
traceback.print_exc(file=sys.stdout)
self._dut.label = None
@@ -196,7 +201,7 @@ class BenchmarkRunCacheReader(Thread):
super(BenchmarkRunCacheReader, self).__init__()
self._schedv2 = schedv2
self._br_list = br_list
- self._logger = self._schedv2._logger
+ self._logger = self._schedv2.get_logger()
def run(self):
for br in self._br_list:
@@ -204,11 +209,11 @@ class BenchmarkRunCacheReader(Thread):
br.ReadCache()
if br.cache_hit:
self._logger.LogOutput('Cache hit - {}'.format(br))
- with self._schedv2._lock_on('_cached_br_list'):
- self._schedv2._cached_br_list.append(br)
+ with self._schedv2.lock_on('_cached_br_list'):
+ self._schedv2.get_cached_run_list().append(br)
else:
self._logger.LogOutput('Cache not hit - {}'.format(br))
- except:
+ except RuntimeError:
traceback.print_exc(file=sys.stderr)
@@ -221,11 +226,12 @@ class Schedv2(object):
# Create shortcuts to nested data structure. "_duts" points to a list of
# locked machines. _labels points to a list of all labels.
- self._duts = self._experiment.machine_manager._all_machines
+ self._duts = self._experiment.machine_manager.GetMachines()
self._labels = self._experiment.labels
# Bookkeeping for synchronization.
self._workers_lock = Lock()
+ # pylint: disable=unnecessary-lambda
self._lock_map = defaultdict(lambda: Lock())
# Test mode flag
@@ -256,14 +262,15 @@ class Schedv2(object):
def run_sched(self):
"""Start all dut worker threads and return immediately."""
- [w.start() for w in self._active_workers]
+ _ = [w.start() for w in self._active_workers]
def _read_br_cache(self):
"""Use multi-threading to read cache for all benchmarkruns.
We do this by firstly creating a few threads, and then assign each
thread a segment of all brs. Each thread will check cache status for
- each br and put those with cache into '_cached_br_list'."""
+ each br and put those with cache into '_cached_br_list'.
+ """
self._cached_br_list = []
n_benchmarkruns = len(self._experiment.benchmark_runs)
@@ -290,7 +297,7 @@ class Schedv2(object):
(n_threads - 1) * benchmarkruns_per_thread:])
# Assert: aggregation of benchmarkrun_segments equals to benchmark_runs.
- assert (sum([len(x) for x in benchmarkrun_segments]) == n_benchmarkruns)
+ assert sum([len(x) for x in benchmarkrun_segments]) == n_benchmarkruns
# Create and start all readers.
cache_readers = [
@@ -309,14 +316,31 @@ class Schedv2(object):
'Total {} cache hit out of {} benchmark_runs.'.format(
len(self._cached_br_list), n_benchmarkruns))
+ def get_cached_run_list(self):
+ return self._cached_br_list
+
+ def get_label_map(self):
+ return self._label_brl_map
+
+ def get_experiment(self):
+ return self._experiment
+
+ def get_labels(self, i=None):
+ if i == None:
+ return self._labels
+ return self._labels[i]
+
+ def get_logger(self):
+ return self._logger
+
def get_cached_benchmark_run(self):
"""Get a benchmark_run with 'cache hit'.
- return:
+ Returns:
The benchmark that has cache hit, if any. Otherwise none.
"""
- with self._lock_on('_cached_br_list'):
+ with self.lock_on('_cached_br_list'):
if self._cached_br_list:
return self._cached_br_list.pop()
return None
@@ -324,7 +348,7 @@ class Schedv2(object):
def get_benchmark_run(self, dut):
"""Get a benchmark_run (br) object for a certain dut.
- Arguments:
+ Args:
dut: the dut for which a br is returned.
Returns:
@@ -343,7 +367,7 @@ class Schedv2(object):
# If br list for the dut's label is empty (that means all brs for this
# label have been done), return None.
- with self._lock_on(dut.label):
+ with self.lock_on(dut.label):
brl = self._label_brl_map[dut.label]
if not brl:
return None
@@ -358,7 +382,7 @@ class Schedv2(object):
The dut_worker calling this method is responsible for reimage the dut to
this label.
- Arguments:
+ Args:
dut: the new label that is to be reimaged onto the dut.
Returns:
@@ -373,8 +397,9 @@ class Schedv2(object):
def dut_worker_finished(self, dut_worker):
"""Notify schedv2 that the dut_worker thread finished.
- Arguemnts:
- dut_worker: the thread that is about to end."""
+ Args:
+ dut_worker: the thread that is about to end.
+ """
self._logger.LogOutput('{} finished.'.format(dut_worker))
with self._workers_lock:
@@ -384,8 +409,8 @@ class Schedv2(object):
def is_complete(self):
return len(self._active_workers) == 0
- def _lock_on(self, object):
- return self._lock_map[object]
+ def lock_on(self, my_object):
+ return self._lock_map[my_object]
def terminate(self):
"""Mark flag so we stop providing br/reimages.
diff --git a/crosperf/schedv2_unittest.py b/crosperf/schedv2_unittest.py
index 29ffcb41..8ad96631 100755
--- a/crosperf/schedv2_unittest.py
+++ b/crosperf/schedv2_unittest.py
@@ -1,21 +1,18 @@
-#!/usr/bin/python
+#!/usr/bin/python2
# Copyright 2015 Google Inc. All Rights Reserved.
+"""This contains the unit tests for the new Crosperf task scheduler."""
+
+from __future__ import print_function
import mock
import unittest
import StringIO
import benchmark_run
-import machine_manager
-import schedv2
import test_flag
-from benchmark_run import MockBenchmarkRun
from experiment_factory import ExperimentFactory
from experiment_file import ExperimentFile
-from experiment_runner import ExperimentRunner
-from machine_manager import MockCrosMachine
-from cros_utils import command_executer
from cros_utils.command_executer import CommandExecuter
from experiment_runner_unittest import FakeLogger
from schedv2 import Schedv2
@@ -62,6 +59,10 @@ image2 {{
class Schedv2Test(unittest.TestCase):
+ """Class for setting up and running the unit tests."""
+
+ def setUp(self):
+ self.exp = None
mock_logger = FakeLogger()
mock_cmd_exec = mock.Mock(spec=CommandExecuter)
@@ -83,7 +84,8 @@ class Schedv2Test(unittest.TestCase):
self.exp = self._make_fake_experiment(EXPERIMENT_FILE_1)
self.exp.log_level = 'verbose'
- schedv2 = Schedv2(self.exp)
+ my_schedv2 = Schedv2(self.exp)
+ self.assertFalse(my_schedv2.is_complete())
self.assertIn('chromeos-daisy1.cros', self.exp.remote)
self.assertIn('chromeos-daisy2.cros', self.exp.remote)
self.assertIn('chromeos-daisy3.cros', self.exp.remote)
@@ -91,15 +93,14 @@ class Schedv2Test(unittest.TestCase):
self.assertIn('chromeos-daisy5.cros', self.exp.remote)
def test_unreachable_remote(self):
- """Test unreachable remotes are removed from experiment remote and
- label.remote."""
+ """Test unreachable remotes are removed from experiment and label."""
def MockIsReachable(cm):
return (cm.name != 'chromeos-daisy3.cros' and
cm.name != 'chromeos-daisy5.cros')
with mock.patch('machine_manager.MockCrosMachine.IsReachable',
- new=MockIsReachable) as f:
+ new=MockIsReachable):
self.exp = self._make_fake_experiment(EXPERIMENT_FILE_1)
self.assertIn('chromeos-daisy1.cros', self.exp.remote)
self.assertIn('chromeos-daisy2.cros', self.exp.remote)
@@ -120,7 +121,8 @@ class Schedv2Test(unittest.TestCase):
self.exp = self._make_fake_experiment(EXPERIMENT_FILE_WITH_FORMAT.format(
kraken_iterations=9))
- schedv2 = Schedv2(self.exp)
+ my_schedv2 = Schedv2(self.exp)
+ self.assertFalse(my_schedv2.is_complete())
# We have 9 * 2 == 18 brs, we use 5 threads, each reading 4, 4, 4,
# 4, 2 brs respectively.
# Assert that BenchmarkRunCacheReader() is called 5 times.
@@ -141,7 +143,8 @@ class Schedv2Test(unittest.TestCase):
self.exp = self._make_fake_experiment(EXPERIMENT_FILE_WITH_FORMAT.format(
kraken_iterations=8))
- schedv2 = Schedv2(self.exp)
+ my_schedv2 = Schedv2(self.exp)
+ self.assertFalse(my_schedv2.is_complete())
# We have 8 * 2 == 16 brs, we use 4 threads, each reading 4 brs.
self.assertEquals(reader.call_count, 4)
self.assertEquals(len(reader.call_args_list[0][0][1]), 4)
@@ -155,7 +158,8 @@ class Schedv2Test(unittest.TestCase):
self.exp = self._make_fake_experiment(EXPERIMENT_FILE_WITH_FORMAT.format(
kraken_iterations=3))
- schedv2 = Schedv2(self.exp)
+ my_schedv2 = Schedv2(self.exp)
+ self.assertFalse(my_schedv2.is_complete())
# We have 3 * 2 == 6 brs, we use 2 threads.
self.assertEquals(reader.call_count, 2)
self.assertEquals(len(reader.call_args_list[0][0][1]), 3)
@@ -167,7 +171,8 @@ class Schedv2Test(unittest.TestCase):
self.exp = self._make_fake_experiment(EXPERIMENT_FILE_WITH_FORMAT.format(
kraken_iterations=1))
- schedv2 = Schedv2(self.exp)
+ my_schedv2 = Schedv2(self.exp)
+ self.assertFalse(my_schedv2.is_complete())
# We have 1 * 2 == 2 br, so only 1 instance.
self.assertEquals(reader.call_count, 1)
self.assertEquals(len(reader.call_args_list[0][0][1]), 2)
@@ -179,15 +184,16 @@ class Schedv2Test(unittest.TestCase):
br.cache_hit = (br.label.name == 'image2')
with mock.patch('benchmark_run.MockBenchmarkRun.ReadCache',
- new=MockReadCache) as f:
+ new=MockReadCache):
# We have 2 * 30 brs, half of which are put into _cached_br_list.
self.exp = self._make_fake_experiment(EXPERIMENT_FILE_WITH_FORMAT.format(
kraken_iterations=30))
- schedv2 = Schedv2(self.exp)
- self.assertEquals(len(schedv2._cached_br_list), 30)
+ my_schedv2 = Schedv2(self.exp)
+ self.assertEquals(len(my_schedv2.get_cached_run_list()), 30)
# The non-cache-hit brs are put into Schedv2._label_brl_map.
self.assertEquals(
- reduce(lambda a, x: a + len(x[1]), schedv2._label_brl_map.iteritems(),
+ reduce(lambda a, x: a + len(x[1]),
+ my_schedv2.get_label_map().iteritems(),
0), 30)
def test_nocachehit(self):
@@ -197,15 +203,16 @@ class Schedv2Test(unittest.TestCase):
br.cache_hit = False
with mock.patch('benchmark_run.MockBenchmarkRun.ReadCache',
- new=MockReadCache) as f:
+ new=MockReadCache):
# We have 2 * 30 brs, none of which are put into _cached_br_list.
self.exp = self._make_fake_experiment(EXPERIMENT_FILE_WITH_FORMAT.format(
kraken_iterations=30))
- schedv2 = Schedv2(self.exp)
- self.assertEquals(len(schedv2._cached_br_list), 0)
+ my_schedv2 = Schedv2(self.exp)
+ self.assertEquals(len(my_schedv2.get_cached_run_list()), 0)
# The non-cache-hit brs are put into Schedv2._label_brl_map.
self.assertEquals(
- reduce(lambda a, x: a + len(x[1]), schedv2._label_brl_map.iteritems(),
+ reduce(lambda a, x: a + len(x[1]),
+ my_schedv2.get_label_map().iteritems(),
0), 60)
diff --git a/crosperf/settings_factory_unittest.py b/crosperf/settings_factory_unittest.py
index 5538e8cc..5df5fd68 100755
--- a/crosperf/settings_factory_unittest.py
+++ b/crosperf/settings_factory_unittest.py
@@ -1,20 +1,17 @@
-#!/usr/bin/python
+#!/usr/bin/python2
#
# Copyright 2014 Google Inc. All Rights Reserved.
"""Unittest for crosperf."""
-import os
-import mock
+from __future__ import print_function
+
import unittest
import settings_factory
-import settings
-
-from cros_utils import command_executer
-from cros_utils import logger
class BenchmarkSettingsTest(unittest.TestCase):
+ """Class to test benchmark settings."""
def test_init(self):
res = settings_factory.BenchmarkSettings('b_settings')
@@ -27,6 +24,7 @@ class BenchmarkSettingsTest(unittest.TestCase):
class LabelSettingsTest(unittest.TestCase):
+ """Class to test label settings."""
def test_init(self):
res = settings_factory.LabelSettings('l_settings')
@@ -42,6 +40,7 @@ class LabelSettingsTest(unittest.TestCase):
class GlobalSettingsTest(unittest.TestCase):
+ """Class to test global settings."""
def test_init(self):
res = settings_factory.GlobalSettings('g_settings')
@@ -71,6 +70,7 @@ class GlobalSettingsTest(unittest.TestCase):
class SettingsFactoryTest(unittest.TestCase):
+ """Class to test SettingsFactory."""
def test_get_settings(self):
self.assertRaises(Exception, settings_factory.SettingsFactory.GetSettings,
diff --git a/run_tests.py b/run_tests.py
index 11bbb8c3..c755278e 100755
--- a/run_tests.py
+++ b/run_tests.py
@@ -1,4 +1,4 @@
-#!/usr/bin/python
+#!/usr/bin/python2
#
# Copyright 2010 Google Inc. All Rights Reserved.
"""Script to wrap run_remote_tests.sh script.
@@ -6,23 +6,18 @@
This script calls run_remote_tests.sh with standard tests.
"""
-__author__ = 'asharif@google.com (Ahmad Sharif)'
+from __future__ import print_function
-import optparse
-import os
-import re
-import sys
+__author__ = 'asharif@google.com (Ahmad Sharif)'
-from utils import command_executer
-from utils import logger
-import build_chromeos
+import sys
-def Main(argv):
+def Main():
"""The main function."""
- print 'This script is deprecated. Use crosperf for running tests.'
+ print('This script is deprecated. Use crosperf for running tests.')
return 1
if __name__ == '__main__':
- sys.exit(Main(sys.argv))
+ sys.exit(Main())