1# Lint as: python2, python3 2# 3# Copyright 2007 Google Inc. All Rights Reserved. 4 5"""Runs profilers on a machine when no autotest job is running. 6 7This is used to profile a task when the task is running on a machine that is not 8running through autotest. 9""" 10 11from __future__ import absolute_import 12from __future__ import division 13from __future__ import print_function 14 15__author__ = 'cranger@google.com (Colby Ranger)' 16 17import platform 18import common 19from autotest_lib.client.common_lib import barrier 20import six 21 22# Client control file snippet used to synchronize profiler start & stop. 23_RUNTEST_PATTERN = ("job.run_test('profiler_sync', timeout_sync=%r,\n" 24 " timeout_start=%r, timeout_stop=%r,\n" 25 " hostid='%s', masterid='%s', all_ids=%r)") 26_PROF_MASTER = platform.node() 27_PORT = 11920 28 29 30def _encode_args(profiler, args, dargs): 31 parts = [repr(profiler)] 32 parts += [repr(arg) for arg in args] 33 parts += ["%s=%r" % darg for darg in six.iteritems(dargs)] 34 return ", ".join(parts) 35 36 37def generate_test(machines, hostname, profilers, timeout_start, timeout_stop, 38 timeout_sync=180): 39 """ 40 Generate a control file that enables profilers and starts profiler_sync. 41 42 @param machines: sequence of all the hostnames involved in the barrier 43 synchronization 44 @param hostname: hostname of the machine running the generated control file 45 @param profilers: a sequence of 3 items tuples where the first item is a 46 string (the profiler name), second argument is a tuple with the 47 non keyword arguments to give to the profiler when being added 48 with "job.profilers.add()" in the control file, third item is 49 a dictionary of the keyword arguments to give it 50 @param timeout_start: how many seconds to wait in profiler_sync for the 51 profilers to start (None means no timeout) 52 @param timeout_stop: how many seconds to wait in profiler_sync for the 53 profilers to stop (None means no timeout) 54 @param timeout_sync: how many seconds to wait in profiler_sync for other 55 machines to reach the start of the profiler_sync (None means no 56 timeout) 57 """ 58 control_file = [] 59 for profiler in profilers: 60 control_file.append("job.profilers.add(%s)" 61 % _encode_args(*profiler)) 62 63 profiler_sync_call = (_RUNTEST_PATTERN % 64 (timeout_sync, timeout_start, timeout_stop, 65 hostname, _PROF_MASTER, machines)) 66 control_file.append(profiler_sync_call) 67 68 for profiler in reversed(profilers): 69 control_file.append("job.profilers.delete('%s')" % profiler[0]) 70 71 return "\n".join(control_file) 72 73 74def wait_for_profilers(machines, timeout=300): 75 sb = barrier.barrier(_PROF_MASTER, "sync_profilers", 76 timeout, port=_PORT) 77 sb.rendezvous_servers(_PROF_MASTER, *machines) 78 79 80def start_profilers(machines, timeout=120): 81 sb = barrier.barrier(_PROF_MASTER, "start_profilers", 82 timeout, port=_PORT) 83 sb.rendezvous_servers(_PROF_MASTER, *machines) 84 85 86def stop_profilers(machines, timeout=120): 87 sb = barrier.barrier(_PROF_MASTER, "stop_profilers", 88 timeout, port=_PORT) 89 sb.rendezvous_servers(_PROF_MASTER, *machines) 90 91 92def finish_profilers(machines, timeout=120): 93 sb = barrier.barrier(_PROF_MASTER, "finish_profilers", 94 timeout, port=_PORT) 95 sb.rendezvous_servers(_PROF_MASTER, *machines) 96