[Autotest] Measure autoserv run time end to end with graphite
Add a whitelist in global config to store a white list of test with run time
measurement enabled. Autoserv uses the white list to filter tests need to
have run time measured.
BUG=chromium:237811
TEST=tested with autoserv in local machine
DEPLOY=none
Change-Id: I6340f5984d47143f648aa8907e4941856a89dbbd
Reviewed-on: https://gerrit.chromium.org/gerrit/57807
Tested-by: Dan Shi <dshi@chromium.org>
Commit-Queue: Dan Shi <dshi@chromium.org>
Reviewed-by: Dan Shi <dshi@chromium.org>
diff --git a/client/cros/constants.py b/client/cros/constants.py
index 6258d0c..8ad2b8f 100644
--- a/client/cros/constants.py
+++ b/client/cros/constants.py
@@ -136,4 +136,4 @@
SHILL_XMLRPC_SERVER_READY_METHOD = 'ready'
# Bug filing
-CHROME_VERSION = 'CHROME_VERSION'
+CHROME_VERSION = 'CHROME_VERSION'
\ No newline at end of file
diff --git a/global_config.ini b/global_config.ini
index e91f7a8..e23592c 100644
--- a/global_config.ini
+++ b/global_config.ini
@@ -33,6 +33,8 @@
[AUTOSERV]
# Autotest potential install paths
client_autodir_paths: /usr/local/autotest
+# White list of tests with run time measurement enabled.
+measure_run_time_tests: desktopui_ScreenLocker,login_LoginSuccess,security_ProfilePermissions
[CLIENT]
drop_caches: False
diff --git a/server/autoserv b/server/autoserv
index 10c2875..8d2623e 100755
--- a/server/autoserv
+++ b/server/autoserv
@@ -10,10 +10,12 @@
import common
-from autotest_lib.client.common_lib.global_config import global_config
-require_atfork = global_config.get_config_value(
+from autotest_lib.client.common_lib import control_data
+from autotest_lib.client.common_lib import global_config
+require_atfork = global_config.global_config.get_config_value(
'AUTOSERV', 'require_atfork_module', type=bool, default=True)
+
try:
import atfork
atfork.monkeypatch_os_fork_functions()
@@ -31,9 +33,14 @@
print e
sys.exit(1)
+from autotest_lib.server import frontend
+from autotest_lib.server.hosts import site_host
from autotest_lib.server import server_logging_config
from autotest_lib.server import server_job, utils, autoserv_parser, autotest
+from autotest_lib.server import utils as server_utils
+
from autotest_lib.client.common_lib import pidfile, logging_manager
+from autotest_lib.site_utils.graphite import stats
def log_alarm(signum, frame):
logging.error("Received SIGALARM. Ignoring and continuing on.")
@@ -185,6 +192,14 @@
def main():
+ # White list of tests with run time measurement enabled.
+ measure_run_time_tests_names = global_config.global_config.get_config_value(
+ 'AUTOSERV', 'measure_run_time_tests', type=str)
+ if measure_run_time_tests_names:
+ measure_run_time_tests = [t.strip() for t in
+ measure_run_time_tests_names.split(',')]
+ else:
+ measure_run_time_tests = []
# grab the parser
parser = autoserv_parser.autoserv_parser
parser.parse_args()
@@ -239,6 +254,24 @@
autotest.BaseAutotest.set_install_in_tmpdir(
parser.options.install_in_tmpdir)
+ timer = None
+ try:
+ # Take the first argument as control file name, get the test name from
+ # the control file. If the test name exists in the list of tests with
+ # run time measurement enabled, start a timer to begin measurement.
+ if (len(parser.args) > 0 and parser.args[0] != '' and
+ parser.options.machines):
+ test_name = control_data.parse_control(parser.args[0]).name
+ if test_name in measure_run_time_tests:
+ machines = parser.options.machines.replace(',', ' '
+ ).strip().split()
+ afe = frontend.AFE()
+ board = server_utils.get_board_from_afe(machines[0], afe)
+ timer = stats.Timer('autoserv_run_time.%s.%s' %
+ (board, test_name))
+ timer.start()
+ except control_data.ControlVariableException as e:
+ logging.error(str(e))
exit_code = 0
try:
try:
@@ -253,6 +286,8 @@
finally:
if pid_file_manager:
pid_file_manager.close_file(exit_code)
+ if timer:
+ timer.stop()
sys.exit(exit_code)
diff --git a/server/hosts/site_host.py b/server/hosts/site_host.py
index e35b6b1..6a9d7be 100644
--- a/server/hosts/site_host.py
+++ b/server/hosts/site_host.py
@@ -21,6 +21,7 @@
from autotest_lib.client.cros import constants
from autotest_lib.server import autoserv_parser
from autotest_lib.server import autotest
+from autotest_lib.server import utils as server_utils
from autotest_lib.server.cros.dynamic_suite import constants as ds_constants
from autotest_lib.server.cros.dynamic_suite import tools, frontend_wrappers
from autotest_lib.server.cros.servo import servo
@@ -657,21 +658,6 @@
self.run('rm -rf ' + path)
- def _get_label_from_afe(self, label_prefix):
- """Retrieve a host's specific label from the AFE.
-
- Looks for a host label that has the form <label_prefix>:<value>
- and returns the "<value>" part of the label. None is returned
- if there is not a label matching the pattern
-
- @returns the label that matches the prefix or 'None'
- """
- labels = self._AFE.get_labels(name__startswith=label_prefix,
- host__hostname__in=[self.hostname])
- if labels and len(labels) == 1:
- return labels[0].name.split(label_prefix, 1)[1]
-
-
def _get_board_from_afe(self):
"""Retrieve this host's board from its labels in the AFE.
@@ -681,7 +667,7 @@
@returns board from label, or `None`.
"""
- return self._get_label_from_afe(ds_constants.BOARD_PREFIX)
+ return server_utils.get_board_from_afe(self.hostname, self._AFE)
def get_build(self):
@@ -692,7 +678,7 @@
@returns The current build or None if it could not find it or if there
were multiple build labels assigned to this host.
"""
- return self._get_label_from_afe(ds_constants.VERSION_PREFIX)
+ return server_utils.get_build_from_afe(self.hostname, self._AFE)
def _install_repair(self):
diff --git a/server/site_utils.py b/server/site_utils.py
new file mode 100644
index 0000000..d4ae343
--- /dev/null
+++ b/server/site_utils.py
@@ -0,0 +1,57 @@
+# Copyright (c) 2013 The Chromium Authors. All rights reserved.
+# Use of this source code is governed by a BSD-style license that can be
+# found in the LICENSE file.
+
+import logging
+
+from autotest_lib.server.cros.dynamic_suite import constants
+
+
+def get_label_from_afe(hostname, label_prefix, afe):
+ """Retrieve a host's specific label from the AFE.
+
+ Looks for a host label that has the form <label_prefix>:<value>
+ and returns the "<value>" part of the label. None is returned
+ if there is not a label matching the pattern
+
+ @param hostname: hostname of given DUT.
+ @param label_prefix: prefix of label to be matched, e.g., |board:|
+ @param afe: afe instance.
+ @returns the label that matches the prefix or 'None'
+
+ """
+ labels = afe.get_labels(name__startswith=label_prefix,
+ host__hostname__in=[hostname])
+ if labels and len(labels) == 1:
+ return labels[0].name.split(label_prefix, 1)[1]
+
+
+def get_board_from_afe(hostname, afe):
+ """Retrieve given host's board from its labels in the AFE.
+
+ Looks for a host label of the form "board:<board>", and
+ returns the "<board>" part of the label. `None` is returned
+ if there is not a single, unique label matching the pattern.
+
+ @param hostname: hostname of given DUT.
+ @param afe: afe instance.
+ @returns board from label, or `None`.
+
+ """
+ return get_label_from_afe(hostname, constants.BOARD_PREFIX, afe)
+
+
+def get_build_from_afe(hostname, afe):
+ """Retrieve the current build for given host from the AFE.
+
+ Looks through the host's labels in the AFE to determine its build.
+
+ @param hostname: hostname of given DUT.
+ @param afe: afe instance.
+ @returns The current build or None if it could not find it or if there
+ were multiple build labels assigned to this host.
+
+ """
+ return get_label_from_afe(hostname, constants.VERSION_PREFIX, afe)
+
+