[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/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)