# Lint as: python2, python3 # # Copyright 2007 Google Inc. All Rights Reserved. """Runs profilers on a machine when no autotest job is running. This is used to profile a task when the task is running on a machine that is not running through autotest. """ from __future__ import absolute_import from __future__ import division from __future__ import print_function __author__ = 'cranger@google.com (Colby Ranger)' import platform import common from autotest_lib.client.common_lib import barrier import six # Client control file snippet used to synchronize profiler start & stop. _RUNTEST_PATTERN = ("job.run_test('profiler_sync', timeout_sync=%r,\n" " timeout_start=%r, timeout_stop=%r,\n" " hostid='%s', masterid='%s', all_ids=%r)") _PROF_MASTER = platform.node() _PORT = 11920 def _encode_args(profiler, args, dargs): parts = [repr(profiler)] parts += [repr(arg) for arg in args] parts += ["%s=%r" % darg for darg in six.iteritems(dargs)] return ", ".join(parts) def generate_test(machines, hostname, profilers, timeout_start, timeout_stop, timeout_sync=180): """ Generate a control file that enables profilers and starts profiler_sync. @param machines: sequence of all the hostnames involved in the barrier synchronization @param hostname: hostname of the machine running the generated control file @param profilers: a sequence of 3 items tuples where the first item is a string (the profiler name), second argument is a tuple with the non keyword arguments to give to the profiler when being added with "job.profilers.add()" in the control file, third item is a dictionary of the keyword arguments to give it @param timeout_start: how many seconds to wait in profiler_sync for the profilers to start (None means no timeout) @param timeout_stop: how many seconds to wait in profiler_sync for the profilers to stop (None means no timeout) @param timeout_sync: how many seconds to wait in profiler_sync for other machines to reach the start of the profiler_sync (None means no timeout) """ control_file = [] for profiler in profilers: control_file.append("job.profilers.add(%s)" % _encode_args(*profiler)) profiler_sync_call = (_RUNTEST_PATTERN % (timeout_sync, timeout_start, timeout_stop, hostname, _PROF_MASTER, machines)) control_file.append(profiler_sync_call) for profiler in reversed(profilers): control_file.append("job.profilers.delete('%s')" % profiler[0]) return "\n".join(control_file) def wait_for_profilers(machines, timeout=300): sb = barrier.barrier(_PROF_MASTER, "sync_profilers", timeout, port=_PORT) sb.rendezvous_servers(_PROF_MASTER, *machines) def start_profilers(machines, timeout=120): sb = barrier.barrier(_PROF_MASTER, "start_profilers", timeout, port=_PORT) sb.rendezvous_servers(_PROF_MASTER, *machines) def stop_profilers(machines, timeout=120): sb = barrier.barrier(_PROF_MASTER, "stop_profilers", timeout, port=_PORT) sb.rendezvous_servers(_PROF_MASTER, *machines) def finish_profilers(machines, timeout=120): sb = barrier.barrier(_PROF_MASTER, "finish_profilers", timeout, port=_PORT) sb.rendezvous_servers(_PROF_MASTER, *machines)