diff options
author | Jonathan Abrahams <jonathan@mongodb.com> | 2018-09-22 15:46:43 -0400 |
---|---|---|
committer | Max Hirschhorn <max.hirschhorn@mongodb.com> | 2018-09-22 15:46:43 -0400 |
commit | 4131e8e403ad527ae82dd5632404762889fdd385 (patch) | |
tree | 3e7152cc70edff4f6a52147d6273fc33f6a427db | |
parent | 819d93b87660999e7778881646cc6bb8c0feffa9 (diff) | |
download | mongo-4131e8e403ad527ae82dd5632404762889fdd385.tar.gz |
SERVER-36078 Integrate adb resource monitor into mongoebench test suite for Android
(cherry picked from commit 5c647106e67bed997d649699fc929e5b41a0a759)
10 files changed, 87 insertions, 16 deletions
diff --git a/buildscripts/mobile/adb_monitor.py b/buildscripts/mobile/adb_monitor.py index f9922e6cec4..26966d4a218 100644 --- a/buildscripts/mobile/adb_monitor.py +++ b/buildscripts/mobile/adb_monitor.py @@ -31,9 +31,10 @@ LOGGER = logging.getLogger(__name__) class Adb(object): """Class to abstract calls to adb.""" - def __init__(self, adb_binary="adb"): + def __init__(self, adb_binary="adb", logger=LOGGER): """Initialize the Adb object.""" self._cmd = None + self.logger = logger self.adb_path = distutils.spawn.find_executable(adb_binary) if not self.adb_path: raise EnvironmentError( @@ -137,9 +138,9 @@ class Adb(object): with open(self._tempfile) as fh: buff = fh.read() os.remove(self._tempfile) - LOGGER.debug("systrace_stop: %s", buff) + self.logger.debug("systrace_stop: %s", buff) if "Wrote trace" not in buff: - LOGGER.error("CPU file not saved: %s", buff) + self.logger.error("CPU file not saved: %s", buff) if os.path.isfile(output_file): os.remove(output_file) @@ -150,12 +151,14 @@ class AdbControl(object): # pylint: disable=too-many-instance-attributes _JOIN_TIMEOUT = 24 * 60 * 60 # 24 hours (a long time to have the monitor run for) def __init__( # pylint: disable=too-many-arguments - self, adb, battery_file=None, memory_file=None, cpu_file=None, append_file=False, - num_samples=0, collection_time_secs=0, sample_interval_ms=0): + self, adb, logger=LOGGER, battery_file=None, memory_file=None, cpu_file=None, + append_file=False, num_samples=0, collection_time_secs=0, sample_interval_ms=0): """Initialize AdbControl object.""" self.adb = adb + self.logger = logger + output_files = [battery_file, memory_file, cpu_file] if not any(output_files): raise ValueError("There are no collection sample files selected.") @@ -234,7 +237,7 @@ class AdbControl(object): # pylint: disable=too-many-instance-attributes for thread in self.all_threads: thread.join(self._JOIN_TIMEOUT) - LOGGER.info("Collections stopped.") + self.logger.info("Collections stopped.") # If any of the monitor threads encountered an error, then reraise the exception in the # main thread. @@ -246,11 +249,12 @@ class AdbControl(object): # pylint: disable=too-many-instance-attributes class AdbResourceMonitor(threading.Thread): """Thread to collect information about a specific resource using adb.""" - def __init__(self, output_file, should_stop): + def __init__(self, output_file, should_stop, logger=LOGGER): """Initialize the AdbResourceMonitor object.""" threading.Thread.__init__(self, name="AdbResourceMonitor {}".format(output_file)) self._output_file = output_file self._should_stop = should_stop + self.logger = logger self.exception = None def run(self): @@ -258,7 +262,7 @@ class AdbResourceMonitor(threading.Thread): try: self._do_monitoring() except Exception as err: # pylint: disable=broad-except - LOGGER.error("%s: Encountered an error: %s", self._output_file, err) + self.logger.error("%s: Encountered an error: %s", self._output_file, err) self.exception = err self._should_stop.set() @@ -283,19 +287,20 @@ class AdbSampleBasedResourceMonitor(AdbResourceMonitor): if self._num_samples > 0 and collected_samples >= self._num_samples: break if collected_samples > 0: - LOGGER.debug("%s: Sleeping %d ms.", self._output_file, self._sample_interval_ms) + self.logger.debug("%s: Sleeping %d ms.", self._output_file, + self._sample_interval_ms) self._should_stop.wait(self._sample_interval_ms / 1000.0) collected_samples += 1 self._take_sample(collected_samples) total_time_ms = (time.time() - now) * 1000 - LOGGER.info("%s: Stopping monitoring, %d samples collected in %d ms.", self._output_file, - collected_samples, total_time_ms) + self.logger.info("%s: Stopping monitoring, %d samples collected in %d ms.", + self._output_file, collected_samples, total_time_ms) def _take_sample(self, collected_samples): """Collect sample.""" - LOGGER.debug("%s: Collecting sample %d of %d", self._output_file, collected_samples, - self._num_samples) + self.logger.debug("%s: Collecting sample %d of %d", self._output_file, collected_samples, + self._num_samples) self.adb_cmd(output_file=self._output_file, append_file=True) @@ -310,12 +315,12 @@ class AdbContinuousResourceMonitor(AdbResourceMonitor): def _do_monitoring(self): """Monitor function.""" - LOGGER.debug("%s: Starting monitoring.", self._output_file) + self.logger.debug("%s: Starting monitoring.", self._output_file) now = time.time() self._adb_start_cmd(output_file=self._output_file) self._should_stop.wait() total_time_ms = (time.time() - now) * 1000 - LOGGER.info("%s: Stopping monitoring after %d ms.", self._output_file, total_time_ms) + self.logger.info("%s: Stopping monitoring after %d ms.", self._output_file, total_time_ms) self._adb_stop_cmd(output_file=self._output_file) diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_aggregation.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_aggregation.yml index 7bf04ee2343..6db291dcde1 100644 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_aggregation.yml +++ b/buildscripts/resmokeconfig/suites/benchrun_embedded_aggregation.yml @@ -6,4 +6,5 @@ selector: executor: hooks: + - class: CollectEmbeddedResources - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_commands.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_commands.yml index 9b4d3735212..c44747998c6 100644 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_commands.yml +++ b/buildscripts/resmokeconfig/suites/benchrun_embedded_commands.yml @@ -6,4 +6,5 @@ selector: executor: hooks: + - class: CollectEmbeddedResources - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_insert.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_insert.yml index a45103979a3..55350189472 100644 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_insert.yml +++ b/buildscripts/resmokeconfig/suites/benchrun_embedded_insert.yml @@ -6,4 +6,5 @@ selector: executor: hooks: + - class: CollectEmbeddedResources - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_misc.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_misc.yml index 0bf510f0eea..56896e5b6e1 100644 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_misc.yml +++ b/buildscripts/resmokeconfig/suites/benchrun_embedded_misc.yml @@ -15,4 +15,5 @@ selector: executor: hooks: + - class: CollectEmbeddedResources - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_mixed_and_multi.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_mixed_and_multi.yml index e022c8588f1..cd0deb1d09f 100644 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_mixed_and_multi.yml +++ b/buildscripts/resmokeconfig/suites/benchrun_embedded_mixed_and_multi.yml @@ -7,4 +7,5 @@ selector: executor: hooks: + - class: CollectEmbeddedResources - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_queries.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_queries.yml index 5c4e1ed1fe6..9ba8ef7db43 100644 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_queries.yml +++ b/buildscripts/resmokeconfig/suites/benchrun_embedded_queries.yml @@ -2,8 +2,9 @@ test_kind: benchrun_embedded_test selector: roots: - - benchrun_embedded/**/queries*.json + - benchrun_embedded/testcases/**/queries*.json executor: hooks: + - class: CollectEmbeddedResources - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_remove.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_remove.yml index 1c04043cc49..f625a2e874b 100644 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_remove.yml +++ b/buildscripts/resmokeconfig/suites/benchrun_embedded_remove.yml @@ -6,4 +6,5 @@ selector: executor: hooks: + - class: CollectEmbeddedResources - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokeconfig/suites/benchrun_embedded_update.yml b/buildscripts/resmokeconfig/suites/benchrun_embedded_update.yml index 8a85ca03226..a9ad8734a1b 100644 --- a/buildscripts/resmokeconfig/suites/benchrun_embedded_update.yml +++ b/buildscripts/resmokeconfig/suites/benchrun_embedded_update.yml @@ -6,4 +6,5 @@ selector: executor: hooks: + - class: CollectEmbeddedResources - class: CombineBenchrunEmbeddedResults diff --git a/buildscripts/resmokelib/testing/hooks/collect_embedded_resources.py b/buildscripts/resmokelib/testing/hooks/collect_embedded_resources.py new file mode 100644 index 00000000000..f6ddffc3963 --- /dev/null +++ b/buildscripts/resmokelib/testing/hooks/collect_embedded_resources.py @@ -0,0 +1,58 @@ +"""Module for generating and collecting embedded resource results.""" + +from __future__ import absolute_import + +import os + +from buildscripts.mobile import adb_monitor +from buildscripts.resmokelib import config as _config +from buildscripts.resmokelib.testing.hooks import interface + + +class CollectEmbeddedResources(interface.Hook): # pylint: disable=too-many-instance-attributes + """CollectEmbeddedResources class. + + CollectEmbeddedResources starts and stops the resource monitoring for each test. + """ + + DESCRIPTION = "Embedded resources" + + def __init__(self, hook_logger, fixture, sample_interval_ms=500, threads=1): + """Initialize CollectEmbeddedResources.""" + interface.Hook.__init__(self, hook_logger, fixture, CollectEmbeddedResources.DESCRIPTION) + self.hook_logger = hook_logger + self.adb = None + self.adb_control = None + if _config.BENCHRUN_DEVICE == "Android": + self.report_root = _config.BENCHRUN_REPORT_ROOT + self.sample_interval_ms = sample_interval_ms + self.threads = threads + self.battery_file = "battery.csv" + self.cpu_file = "cpu.json" + self.memory_file = "memory.csv" + self.adb = adb_monitor.Adb(logger=hook_logger) + + def before_test(self, test, test_report): + """Start ADB monitoring.""" + if self.adb: + battery_file = self._report_path(test, "battery.csv") + cpu_file = self._report_path(test, "cpu.json") + memory_file = self._report_path(test, "memory.csv") + self.adb_control = adb_monitor.AdbControl( + self.adb, logger=self.hook_logger, battery_file=battery_file, cpu_file=cpu_file, + memory_file=memory_file, sample_interval_ms=self.sample_interval_ms) + self.hook_logger.info("Starting ADB monitoring for test %s", test.short_name()) + self.hook_logger.info("ADB resource files: %s %s %s", battery_file, cpu_file, + memory_file) + self.adb_control.start() + + def after_test(self, test, test_report): + """Stop ADB monitoring.""" + if self.adb_control: + self.hook_logger.info("Stopping ADB monitoring for test %s", test.short_name()) + self.adb_control.stop() + + def _report_path(self, test, report_name): + """Return the report path. Reports are stored in <report_root>/<testname>/thread<num>/.""" + return os.path.join(self.report_root, test.short_name(), "thread{}".format(self.threads), + report_name) |