blob: f206f6cd53c88ea07d5b7f9297f54cf355223716 [file] [log] [blame]
Derek Beckett63e1c442020-08-11 14:49:47 -07001# Lint as: python2, python3
2from __future__ import absolute_import
3from __future__ import division
4from __future__ import print_function
mbligh15971eb2009-12-29 02:55:23 +00005import itertools
jadmanski91cd58c2008-12-02 15:34:53 +00006import common
Derek Beckett63e1c442020-08-11 14:49:47 -07007import six
jadmanski91cd58c2008-12-02 15:34:53 +00008
jadmanski043e1132008-11-19 17:10:32 +00009
mbligh15971eb2009-12-29 02:55:23 +000010def _get_unpassable_types(arg):
jadmanski043e1132008-11-19 17:10:32 +000011 """ Given an argument, returns a set of types contained in arg that are
12 unpassable. If arg is an atomic type (e.g. int) it either returns an
13 empty set (if the type is passable) or a singleton of the type (if the
14 type is not passable). """
Derek Beckett63e1c442020-08-11 14:49:47 -070015 if isinstance(arg, (six.string_types, int, int)):
jadmanski043e1132008-11-19 17:10:32 +000016 return set()
17 elif isinstance(arg, (list, tuple, set, frozenset, dict)):
18 if isinstance(arg, dict):
19 # keys and values must both be passable
Derek Beckett63e1c442020-08-11 14:49:47 -070020 parts = itertools.chain(six.iterkeys(arg), six.itervalues(arg))
jadmanski043e1132008-11-19 17:10:32 +000021 else:
22 # for all other containers we just iterate
23 parts = iter(arg)
24 types = set()
25 for part in parts:
mbligh15971eb2009-12-29 02:55:23 +000026 types |= _get_unpassable_types(part)
jadmanski043e1132008-11-19 17:10:32 +000027 return types
28 else:
29 return set([type(arg)])
30
31
mbligh15971eb2009-12-29 02:55:23 +000032def _validate_args(args):
jadmanski043e1132008-11-19 17:10:32 +000033 """ Validates arguments. Lists and dictionaries are valid argument types,
34 so you can pass *args and **dargs in directly, rather than having to
35 iterate over them yourself. """
mbligh15971eb2009-12-29 02:55:23 +000036 unpassable_types = _get_unpassable_types(args)
jadmanski043e1132008-11-19 17:10:32 +000037 if unpassable_types:
38 msg = "arguments of type '%s' cannot be passed to remote profilers"
39 msg %= ", ".join(t.__name__ for t in unpassable_types)
40 raise TypeError(msg)
41
42
43class profiler_proxy(object):
44 """ This is a server-side class that acts as a proxy to a real client-side
45 profiler class."""
46
mbligh15971eb2009-12-29 02:55:23 +000047 def __init__(self, profiler_name):
jadmanski043e1132008-11-19 17:10:32 +000048 self.name = profiler_name
jadmanski043e1132008-11-19 17:10:32 +000049
jadmanski91cd58c2008-12-02 15:34:53 +000050 # does the profiler support rebooting?
51 profiler_module = common.setup_modules.import_module(
52 profiler_name, "autotest_lib.client.profilers.%s" % profiler_name)
53 profiler_class = getattr(profiler_module, profiler_name)
54 self.supports_reboot = profiler_class.supports_reboot
55
jadmanski043e1132008-11-19 17:10:32 +000056
jadmanski043e1132008-11-19 17:10:32 +000057 def initialize(self, *args, **dargs):
mbligh15971eb2009-12-29 02:55:23 +000058 _validate_args(args)
59 _validate_args(dargs)
mblighb3c0c912008-11-27 00:32:45 +000060 self.args, self.dargs = args, dargs
61
62
63 def setup(self, *args, **dargs):
64 assert self.args == args and self.dargs == dargs
65 # the actual setup happens lazily at start()
66
67
jadmanski4f909252008-12-01 20:47:10 +000068 def start(self, test, host=None):
mbligh15971eb2009-12-29 02:55:23 +000069 raise NotImplementedError('start not implemented')
jadmanski043e1132008-11-19 17:10:32 +000070
71
jadmanski4f909252008-12-01 20:47:10 +000072 def stop(self, test, host=None):
mbligh15971eb2009-12-29 02:55:23 +000073 raise NotImplementedError('stop not implemented')
jadmanski043e1132008-11-19 17:10:32 +000074
75
jadmanski4f909252008-12-01 20:47:10 +000076 def report(self, test, host=None, wait_on_client=True):
mbligh15971eb2009-12-29 02:55:23 +000077 raise NotImplementedError('report not implemented')