|
@@ -0,0 +1,686 @@
|
|
|
+# HG changeset patch
|
|
|
+# User Ricky Stewart <rstewart@mozilla.com>
|
|
|
+# Date 1603737293 0
|
|
|
+# Node ID 994ae8e4833c90447d91f0e26a718573cff5a514
|
|
|
+# Parent 40f5ebdbbd79fd9cb5c0e55081ac16e9e5ca9522
|
|
|
+Bug 1654103: Standardize on Black for Python code in `mozilla-central`.
|
|
|
+
|
|
|
+
|
|
|
+Allow-list all Python code in tree for use with the black linter, and re-format all code in-tree accordingly.
|
|
|
+
|
|
|
+To produce this patch I did all of the following:
|
|
|
+
|
|
|
+1. Make changes to tools/lint/black.yml to remove include: stanza and update list of source extensions.
|
|
|
+
|
|
|
+2. Run ./mach lint --linter black --fix
|
|
|
+
|
|
|
+3. Make some ad-hoc manual updates to python/mozbuild/mozbuild/test/configure/test_configure.py -- it has some hard-coded line numbers that the reformat breaks.
|
|
|
+
|
|
|
+4. Make some ad-hoc manual updates to `testing/marionette/client/setup.py`, `testing/marionette/harness/setup.py`, and `testing/firefox-ui/harness/setup.py`, which have hard-coded regexes that break after the reformat.
|
|
|
+
|
|
|
+5. Add a set of exclusions to black.yml. These will be deleted in a follow-up bug (1672023).
|
|
|
+
|
|
|
+# ignore-this-changeset
|
|
|
+
|
|
|
+Differential Revision: https://phabricator.services.mozilla.com/D94045
|
|
|
+
|
|
|
+diff --git a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
|
|
|
+--- a/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
|
|
|
++++ b/testing/mozbase/mozsystemmonitor/mozsystemmonitor/resourcemonitor.py
|
|
|
+@@ -12,27 +12,46 @@ import warnings
|
|
|
+
|
|
|
+ from collections import (
|
|
|
+ OrderedDict,
|
|
|
+ namedtuple,
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+ class PsutilStub(object):
|
|
|
+-
|
|
|
+ def __init__(self):
|
|
|
+- self.sswap = namedtuple('sswap', ['total', 'used', 'free', 'percent', 'sin',
|
|
|
+- 'sout'])
|
|
|
+- self.sdiskio = namedtuple('sdiskio', ['read_count', 'write_count',
|
|
|
+- 'read_bytes', 'write_bytes',
|
|
|
+- 'read_time', 'write_time'])
|
|
|
+- self.pcputimes = namedtuple('pcputimes', ['user', 'system'])
|
|
|
++ self.sswap = namedtuple(
|
|
|
++ "sswap", ["total", "used", "free", "percent", "sin", "sout"]
|
|
|
++ )
|
|
|
++ self.sdiskio = namedtuple(
|
|
|
++ "sdiskio",
|
|
|
++ [
|
|
|
++ "read_count",
|
|
|
++ "write_count",
|
|
|
++ "read_bytes",
|
|
|
++ "write_bytes",
|
|
|
++ "read_time",
|
|
|
++ "write_time",
|
|
|
++ ],
|
|
|
++ )
|
|
|
++ self.pcputimes = namedtuple("pcputimes", ["user", "system"])
|
|
|
+ self.svmem = namedtuple(
|
|
|
+- 'svmem', ['total', 'available', 'percent', 'used', 'free',
|
|
|
+- 'active', 'inactive', 'buffers', 'cached'])
|
|
|
++ "svmem",
|
|
|
++ [
|
|
|
++ "total",
|
|
|
++ "available",
|
|
|
++ "percent",
|
|
|
++ "used",
|
|
|
++ "free",
|
|
|
++ "active",
|
|
|
++ "inactive",
|
|
|
++ "buffers",
|
|
|
++ "cached",
|
|
|
++ ],
|
|
|
++ )
|
|
|
+
|
|
|
+ def cpu_percent(self, a, b):
|
|
|
+ return [0]
|
|
|
+
|
|
|
+ def cpu_times(self, percpu):
|
|
|
+ if percpu:
|
|
|
+ return [self.pcputimes(0, 0)]
|
|
|
+ else:
|
|
|
+@@ -46,16 +65,17 @@ class PsutilStub(object):
|
|
|
+
|
|
|
+ def virtual_memory(self):
|
|
|
+ return self.svmem(0, 0, 0, 0, 0, 0, 0, 0, 0)
|
|
|
+
|
|
|
+
|
|
|
+ # psutil will raise NotImplementedError if the platform is not supported.
|
|
|
+ try:
|
|
|
+ import psutil
|
|
|
++
|
|
|
+ have_psutil = True
|
|
|
+ except Exception:
|
|
|
+ try:
|
|
|
+ # The PsutilStub should get us time intervals, at least
|
|
|
+ psutil = PsutilStub()
|
|
|
+ except Exception:
|
|
|
+ psutil = None
|
|
|
+
|
|
|
+@@ -108,18 +128,18 @@ def _collect(pipe, poll_interval):
|
|
|
+ # We should ideally use a monotonic clock. However, Python 2.7 doesn't
|
|
|
+ # make a monotonic clock available on all platforms. Python 3.3 does!
|
|
|
+ last_time = time.time()
|
|
|
+ io_last = get_disk_io_counters()
|
|
|
+ cpu_last = psutil.cpu_times(True)
|
|
|
+ swap_last = psutil.swap_memory()
|
|
|
+ psutil.cpu_percent(None, True)
|
|
|
+
|
|
|
+- sin_index = swap_last._fields.index('sin')
|
|
|
+- sout_index = swap_last._fields.index('sout')
|
|
|
++ sin_index = swap_last._fields.index("sin")
|
|
|
++ sout_index = swap_last._fields.index("sout")
|
|
|
+
|
|
|
+ sleep_interval = poll_interval
|
|
|
+
|
|
|
+ while not _poll(pipe, poll_interval=sleep_interval):
|
|
|
+ io = get_disk_io_counters()
|
|
|
+ cpu_times = psutil.cpu_times(True)
|
|
|
+ cpu_percent = psutil.cpu_percent(None, True)
|
|
|
+ virt_mem = psutil.virtual_memory()
|
|
|
+@@ -128,44 +148,53 @@ def _collect(pipe, poll_interval):
|
|
|
+
|
|
|
+ # TODO Does this wrap? At 32 bits? At 64 bits?
|
|
|
+ # TODO Consider patching "delta" API to upstream.
|
|
|
+ io_diff = [v - io_last[i] for i, v in enumerate(io)]
|
|
|
+ io_last = io
|
|
|
+
|
|
|
+ cpu_diff = []
|
|
|
+ for core, values in enumerate(cpu_times):
|
|
|
+- cpu_diff.append([v - cpu_last[core][i] for i, v in
|
|
|
+- enumerate(values)])
|
|
|
++ cpu_diff.append([v - cpu_last[core][i] for i, v in enumerate(values)])
|
|
|
+
|
|
|
+ cpu_last = cpu_times
|
|
|
+
|
|
|
+ swap_entry = list(swap_mem)
|
|
|
+ swap_entry[sin_index] = swap_mem.sin - swap_last.sin
|
|
|
+ swap_entry[sout_index] = swap_mem.sout - swap_last.sout
|
|
|
+ swap_last = swap_mem
|
|
|
+
|
|
|
+- data.append((last_time, measured_end_time, io_diff, cpu_diff,
|
|
|
+- cpu_percent, list(virt_mem), swap_entry))
|
|
|
++ data.append(
|
|
|
++ (
|
|
|
++ last_time,
|
|
|
++ measured_end_time,
|
|
|
++ io_diff,
|
|
|
++ cpu_diff,
|
|
|
++ cpu_percent,
|
|
|
++ list(virt_mem),
|
|
|
++ swap_entry,
|
|
|
++ )
|
|
|
++ )
|
|
|
+
|
|
|
+ collection_overhead = time.time() - last_time - poll_interval
|
|
|
+ last_time = measured_end_time
|
|
|
+ sleep_interval = max(0, poll_interval - collection_overhead)
|
|
|
+
|
|
|
+ for entry in data:
|
|
|
+ pipe.send(entry)
|
|
|
+
|
|
|
+- pipe.send(('done', None, None, None, None, None, None))
|
|
|
++ pipe.send(("done", None, None, None, None, None, None))
|
|
|
+ pipe.close()
|
|
|
+ sys.exit(0)
|
|
|
+
|
|
|
+
|
|
|
+-SystemResourceUsage = namedtuple('SystemResourceUsage',
|
|
|
+- ['start', 'end',
|
|
|
+- 'cpu_times', 'cpu_percent', 'io', 'virt', 'swap'])
|
|
|
++SystemResourceUsage = namedtuple(
|
|
|
++ "SystemResourceUsage",
|
|
|
++ ["start", "end", "cpu_times", "cpu_percent", "io", "virt", "swap"],
|
|
|
++)
|
|
|
+
|
|
|
+
|
|
|
+ class SystemResourceMonitor(object):
|
|
|
+ """Measures system resources.
|
|
|
+
|
|
|
+ Each instance measures system resources from the time it is started
|
|
|
+ until it is finished. It does this on a separate process so it doesn't
|
|
|
+ impact execution of the main Python process.
|
|
|
+@@ -258,37 +287,38 @@ class SystemResourceMonitor(object):
|
|
|
+ # failures invoking one of these functions.
|
|
|
+ try:
|
|
|
+ cpu_percent = psutil.cpu_percent(0.0, True)
|
|
|
+ cpu_times = psutil.cpu_times(False)
|
|
|
+ io = get_disk_io_counters()
|
|
|
+ virt = psutil.virtual_memory()
|
|
|
+ swap = psutil.swap_memory()
|
|
|
+ except Exception as e:
|
|
|
+- warnings.warn('psutil failed to run: %s' % e)
|
|
|
++ warnings.warn("psutil failed to run: %s" % e)
|
|
|
+ return
|
|
|
+
|
|
|
+ self._cpu_cores = len(cpu_percent)
|
|
|
+ self._cpu_times_type = type(cpu_times)
|
|
|
+ self._cpu_times_len = len(cpu_times)
|
|
|
+ self._io_type = type(io)
|
|
|
+ self._io_len = len(io)
|
|
|
+ self._virt_type = type(virt)
|
|
|
+ self._virt_len = len(virt)
|
|
|
+ self._swap_type = type(swap)
|
|
|
+ self._swap_len = len(swap)
|
|
|
+
|
|
|
+ self._pipe, child_pipe = multiprocessing.Pipe(True)
|
|
|
+
|
|
|
+- self._process = multiprocessing.Process(target=_collect,
|
|
|
+- args=(child_pipe, poll_interval))
|
|
|
++ self._process = multiprocessing.Process(
|
|
|
++ target=_collect, args=(child_pipe, poll_interval)
|
|
|
++ )
|
|
|
+
|
|
|
+ def __del__(self):
|
|
|
+ if self._running:
|
|
|
+- self._pipe.send(('terminate',))
|
|
|
++ self._pipe.send(("terminate",))
|
|
|
+ self._process.join()
|
|
|
+
|
|
|
+ # Methods to control monitoring.
|
|
|
+
|
|
|
+ def start(self):
|
|
|
+ """Start measuring system-wide CPU resource utilization.
|
|
|
+
|
|
|
+ You should only call this once per instance.
|
|
|
+@@ -310,49 +340,59 @@ class SystemResourceMonitor(object):
|
|
|
+ if not self._process:
|
|
|
+ self._stopped = True
|
|
|
+ return
|
|
|
+
|
|
|
+ assert self._running
|
|
|
+ assert not self._stopped
|
|
|
+
|
|
|
+ try:
|
|
|
+- self._pipe.send(('terminate',))
|
|
|
++ self._pipe.send(("terminate",))
|
|
|
+ except Exception:
|
|
|
+ pass
|
|
|
+ self._running = False
|
|
|
+ self._stopped = True
|
|
|
+
|
|
|
+ self.measurements = []
|
|
|
+
|
|
|
+ # The child process will send each data sample over the pipe
|
|
|
+ # as a separate data structure. When it has finished sending
|
|
|
+ # samples, it sends a special "done" message to indicate it
|
|
|
+ # is finished.
|
|
|
+
|
|
|
+ while _poll(self._pipe, poll_interval=0.1):
|
|
|
+ try:
|
|
|
+- start_time, end_time, io_diff, cpu_diff, cpu_percent, virt_mem, \
|
|
|
+- swap_mem = self._pipe.recv()
|
|
|
++ (
|
|
|
++ start_time,
|
|
|
++ end_time,
|
|
|
++ io_diff,
|
|
|
++ cpu_diff,
|
|
|
++ cpu_percent,
|
|
|
++ virt_mem,
|
|
|
++ swap_mem,
|
|
|
++ ) = self._pipe.recv()
|
|
|
+ except Exception:
|
|
|
+ # Let's assume we're done here
|
|
|
+ break
|
|
|
+
|
|
|
+ # There should be nothing after the "done" message so
|
|
|
+ # terminate.
|
|
|
+- if start_time == 'done':
|
|
|
++ if start_time == "done":
|
|
|
+ break
|
|
|
+
|
|
|
+ io = self._io_type(*io_diff)
|
|
|
+ virt = self._virt_type(*virt_mem)
|
|
|
+ swap = self._swap_type(*swap_mem)
|
|
|
+ cpu_times = [self._cpu_times_type(*v) for v in cpu_diff]
|
|
|
+
|
|
|
+- self.measurements.append(SystemResourceUsage(start_time, end_time,
|
|
|
+- cpu_times, cpu_percent, io, virt, swap))
|
|
|
++ self.measurements.append(
|
|
|
++ SystemResourceUsage(
|
|
|
++ start_time, end_time, cpu_times, cpu_percent, io, virt, swap
|
|
|
++ )
|
|
|
++ )
|
|
|
+
|
|
|
+ # We establish a timeout so we don't hang forever if the child
|
|
|
+ # process has crashed.
|
|
|
+ self._process.join(10)
|
|
|
+ if self._process.is_alive():
|
|
|
+ self._process.terminate()
|
|
|
+ self._process.join(10)
|
|
|
+
|
|
|
+@@ -447,25 +487,24 @@ class SystemResourceMonitor(object):
|
|
|
+
|
|
|
+ for t, name in self.events:
|
|
|
+ if name == start_event:
|
|
|
+ start_time = t
|
|
|
+ elif name == end_event:
|
|
|
+ end_time = t
|
|
|
+
|
|
|
+ if start_time is None:
|
|
|
+- raise Exception('Could not find start event: %s' % start_event)
|
|
|
++ raise Exception("Could not find start event: %s" % start_event)
|
|
|
+
|
|
|
+ if end_time is None:
|
|
|
+- raise Exception('Could not find end event: %s' % end_event)
|
|
|
++ raise Exception("Could not find end event: %s" % end_event)
|
|
|
+
|
|
|
+ return self.range_usage(start_time, end_time)
|
|
|
+
|
|
|
+- def aggregate_cpu_percent(self, start=None, end=None, phase=None,
|
|
|
+- per_cpu=True):
|
|
|
++ def aggregate_cpu_percent(self, start=None, end=None, phase=None, per_cpu=True):
|
|
|
+ """Obtain the aggregate CPU percent usage for a range.
|
|
|
+
|
|
|
+ Returns a list of floats representing average CPU usage percentage per
|
|
|
+ core if per_cpu is True (the default). If per_cpu is False, return a
|
|
|
+ single percentage value.
|
|
|
+
|
|
|
+ By default this will return data for the entire instrumented interval.
|
|
|
+ If phase is defined, data for a named phase will be returned. If start
|
|
|
+@@ -489,18 +528,17 @@ class SystemResourceMonitor(object):
|
|
|
+
|
|
|
+ if per_cpu:
|
|
|
+ return [sum(x) / samples for x in cpu]
|
|
|
+
|
|
|
+ cores = [sum(x) for x in cpu]
|
|
|
+
|
|
|
+ return sum(cores) / len(cpu) / samples
|
|
|
+
|
|
|
+- def aggregate_cpu_times(self, start=None, end=None, phase=None,
|
|
|
+- per_cpu=True):
|
|
|
++ def aggregate_cpu_times(self, start=None, end=None, phase=None, per_cpu=True):
|
|
|
+ """Obtain the aggregate CPU times for a range.
|
|
|
+
|
|
|
+ If per_cpu is True (the default), this returns a list of named tuples.
|
|
|
+ Each tuple is as if it were returned by psutil.cpu_times(). If per_cpu
|
|
|
+ is False, this returns a single named tuple of the aforementioned type.
|
|
|
+ """
|
|
|
+ empty = [0 for i in range(0, self._cpu_times_len)]
|
|
|
+ cpu = [list(empty) for i in range(0, self._cpu_cores)]
|
|
|
+@@ -628,74 +666,76 @@ class SystemResourceMonitor(object):
|
|
|
+ virt_fields=list(self._virt_type._fields),
|
|
|
+ swap_fields=list(self._swap_type._fields),
|
|
|
+ samples=[],
|
|
|
+ phases=[],
|
|
|
+ system={},
|
|
|
+ )
|
|
|
+
|
|
|
+ def populate_derived(e):
|
|
|
+- if e['cpu_percent_cores']:
|
|
|
+- e['cpu_percent_mean'] = sum(e['cpu_percent_cores']) / \
|
|
|
+- len(e['cpu_percent_cores'])
|
|
|
++ if e["cpu_percent_cores"]:
|
|
|
++ e["cpu_percent_mean"] = sum(e["cpu_percent_cores"]) / len(
|
|
|
++ e["cpu_percent_cores"]
|
|
|
++ )
|
|
|
+ else:
|
|
|
+- e['cpu_percent_mean'] = None
|
|
|
++ e["cpu_percent_mean"] = None
|
|
|
+
|
|
|
+- if e['cpu_times']:
|
|
|
+- e['cpu_times_sum'] = [0.0] * self._cpu_times_len
|
|
|
++ if e["cpu_times"]:
|
|
|
++ e["cpu_times_sum"] = [0.0] * self._cpu_times_len
|
|
|
+ for i in range(0, self._cpu_times_len):
|
|
|
+- e['cpu_times_sum'][i] = sum(core[i] for core in e['cpu_times'])
|
|
|
++ e["cpu_times_sum"][i] = sum(core[i] for core in e["cpu_times"])
|
|
|
+
|
|
|
+- e['cpu_times_total'] = sum(e['cpu_times_sum'])
|
|
|
++ e["cpu_times_total"] = sum(e["cpu_times_sum"])
|
|
|
+
|
|
|
+ def phase_entry(name, start, end):
|
|
|
+ e = dict(
|
|
|
+ name=name,
|
|
|
+ start=start,
|
|
|
+ end=end,
|
|
|
+ duration=end - start,
|
|
|
+ cpu_percent_cores=self.aggregate_cpu_percent(phase=name),
|
|
|
+- cpu_times=[list(c) for c in
|
|
|
+- self.aggregate_cpu_times(phase=name)],
|
|
|
++ cpu_times=[list(c) for c in self.aggregate_cpu_times(phase=name)],
|
|
|
+ io=list(self.aggregate_io(phase=name)),
|
|
|
+ )
|
|
|
+ populate_derived(e)
|
|
|
+ return e
|
|
|
+
|
|
|
+ for m in self.measurements:
|
|
|
+ e = dict(
|
|
|
+ start=m.start,
|
|
|
+ end=m.end,
|
|
|
+ io=list(m.io),
|
|
|
+ virt=list(m.virt),
|
|
|
+ swap=list(m.swap),
|
|
|
+ cpu_percent_cores=list(m.cpu_percent),
|
|
|
+- cpu_times=list(list(cpu) for cpu in m.cpu_times)
|
|
|
++ cpu_times=list(list(cpu) for cpu in m.cpu_times),
|
|
|
+ )
|
|
|
+
|
|
|
+ populate_derived(e)
|
|
|
+- o['samples'].append(e)
|
|
|
++ o["samples"].append(e)
|
|
|
+
|
|
|
+- if o['samples']:
|
|
|
+- o['start'] = o['samples'][0]['start']
|
|
|
+- o['end'] = o['samples'][-1]['end']
|
|
|
+- o['duration'] = o['end'] - o['start']
|
|
|
+- o['overall'] = phase_entry(None, o['start'], o['end'])
|
|
|
++ if o["samples"]:
|
|
|
++ o["start"] = o["samples"][0]["start"]
|
|
|
++ o["end"] = o["samples"][-1]["end"]
|
|
|
++ o["duration"] = o["end"] - o["start"]
|
|
|
++ o["overall"] = phase_entry(None, o["start"], o["end"])
|
|
|
+ else:
|
|
|
+- o['start'] = None
|
|
|
+- o['end'] = None
|
|
|
+- o['duration'] = None
|
|
|
+- o['overall'] = None
|
|
|
++ o["start"] = None
|
|
|
++ o["end"] = None
|
|
|
++ o["duration"] = None
|
|
|
++ o["overall"] = None
|
|
|
+
|
|
|
+- o['events'] = [list(ev) for ev in self.events]
|
|
|
++ o["events"] = [list(ev) for ev in self.events]
|
|
|
+
|
|
|
+ for phase, v in self.phases.items():
|
|
|
+- o['phases'].append(phase_entry(phase, v[0], v[1]))
|
|
|
++ o["phases"].append(phase_entry(phase, v[0], v[1]))
|
|
|
+
|
|
|
+ if have_psutil:
|
|
|
+- o['system'].update(dict(
|
|
|
+- cpu_logical_count=psutil.cpu_count(logical=True),
|
|
|
+- cpu_physical_count=psutil.cpu_count(logical=False),
|
|
|
+- swap_total=psutil.swap_memory()[0],
|
|
|
+- vmem_total=psutil.virtual_memory()[0],
|
|
|
+- ))
|
|
|
++ o["system"].update(
|
|
|
++ dict(
|
|
|
++ cpu_logical_count=psutil.cpu_count(logical=True),
|
|
|
++ cpu_physical_count=psutil.cpu_count(logical=False),
|
|
|
++ swap_total=psutil.swap_memory()[0],
|
|
|
++ vmem_total=psutil.virtual_memory()[0],
|
|
|
++ )
|
|
|
++ )
|
|
|
+
|
|
|
+ return o
|
|
|
+diff --git a/testing/mozbase/mozsystemmonitor/setup.py b/testing/mozbase/mozsystemmonitor/setup.py
|
|
|
+--- a/testing/mozbase/mozsystemmonitor/setup.py
|
|
|
++++ b/testing/mozbase/mozsystemmonitor/setup.py
|
|
|
+@@ -3,32 +3,34 @@
|
|
|
+ # file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
|
+
|
|
|
+ from __future__ import absolute_import
|
|
|
+
|
|
|
+ import os
|
|
|
+
|
|
|
+ from setuptools import setup
|
|
|
+
|
|
|
+-PACKAGE_VERSION = '1.0.0'
|
|
|
++PACKAGE_VERSION = "1.0.0"
|
|
|
+
|
|
|
+ try:
|
|
|
+ pwd = os.path.dirname(os.path.abspath(__file__))
|
|
|
+- description = open(os.path.join(pwd, 'README.rst')).read()
|
|
|
++ description = open(os.path.join(pwd, "README.rst")).read()
|
|
|
+ except Exception:
|
|
|
+- description = ''
|
|
|
++ description = ""
|
|
|
+
|
|
|
+ setup(
|
|
|
+- name='mozsystemmonitor',
|
|
|
+- description='Monitor system resource usage.',
|
|
|
++ name="mozsystemmonitor",
|
|
|
++ description="Monitor system resource usage.",
|
|
|
+ long_description="see https://firefox-source-docs.mozilla.org/mozbase/index.html",
|
|
|
+- classifiers=['Programming Language :: Python :: 2.7',
|
|
|
+- 'Programming Language :: Python :: 3.5'],
|
|
|
++ classifiers=[
|
|
|
++ "Programming Language :: Python :: 2.7",
|
|
|
++ "Programming Language :: Python :: 3.5",
|
|
|
++ ],
|
|
|
+ # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers
|
|
|
+- license='MPL 2.0',
|
|
|
+- keywords='mozilla',
|
|
|
+- author='Mozilla Automation and Tools Team',
|
|
|
+- author_email='tools@lists.mozilla.org',
|
|
|
+- url='https://wiki.mozilla.org/Auto-tools/Projects/Mozbase',
|
|
|
+- packages=['mozsystemmonitor'],
|
|
|
++ license="MPL 2.0",
|
|
|
++ keywords="mozilla",
|
|
|
++ author="Mozilla Automation and Tools Team",
|
|
|
++ author_email="tools@lists.mozilla.org",
|
|
|
++ url="https://wiki.mozilla.org/Auto-tools/Projects/Mozbase",
|
|
|
++ packages=["mozsystemmonitor"],
|
|
|
+ version=PACKAGE_VERSION,
|
|
|
+- install_requires=['psutil >= 3.1.1'],
|
|
|
++ install_requires=["psutil >= 3.1.1"],
|
|
|
+ )
|
|
|
+diff --git a/testing/mozbase/mozsystemmonitor/tests/test_resource_monitor.py b/testing/mozbase/mozsystemmonitor/tests/test_resource_monitor.py
|
|
|
+--- a/testing/mozbase/mozsystemmonitor/tests/test_resource_monitor.py
|
|
|
++++ b/testing/mozbase/mozsystemmonitor/tests/test_resource_monitor.py
|
|
|
+@@ -17,19 +17,18 @@ except ImportError:
|
|
|
+ psutil = None
|
|
|
+
|
|
|
+ from mozsystemmonitor.resourcemonitor import (
|
|
|
+ SystemResourceMonitor,
|
|
|
+ SystemResourceUsage,
|
|
|
+ )
|
|
|
+
|
|
|
+
|
|
|
+-@unittest.skipIf(psutil is None, 'Resource monitor requires psutil.')
|
|
|
++@unittest.skipIf(psutil is None, "Resource monitor requires psutil.")
|
|
|
+ class TestResourceMonitor(unittest.TestCase):
|
|
|
+-
|
|
|
+ def test_basic(self):
|
|
|
+ monitor = SystemResourceMonitor(poll_interval=0.5)
|
|
|
+
|
|
|
+ monitor.start()
|
|
|
+ time.sleep(3)
|
|
|
+
|
|
|
+ monitor.stop()
|
|
|
+
|
|
|
+@@ -47,30 +46,30 @@ class TestResourceMonitor(unittest.TestC
|
|
|
+ self.assertEqual(len(data), 0)
|
|
|
+
|
|
|
+ def test_phases(self):
|
|
|
+ monitor = SystemResourceMonitor(poll_interval=0.25)
|
|
|
+
|
|
|
+ monitor.start()
|
|
|
+ time.sleep(1)
|
|
|
+
|
|
|
+- with monitor.phase('phase1'):
|
|
|
++ with monitor.phase("phase1"):
|
|
|
+ time.sleep(1)
|
|
|
+
|
|
|
+- with monitor.phase('phase2'):
|
|
|
++ with monitor.phase("phase2"):
|
|
|
+ time.sleep(1)
|
|
|
+
|
|
|
+ monitor.stop()
|
|
|
+
|
|
|
+ self.assertEqual(len(monitor.phases), 2)
|
|
|
+- self.assertEqual(['phase2', 'phase1'], list(monitor.phases.keys()))
|
|
|
++ self.assertEqual(["phase2", "phase1"], list(monitor.phases.keys()))
|
|
|
+
|
|
|
+ all = list(monitor.range_usage())
|
|
|
+- data1 = list(monitor.phase_usage('phase1'))
|
|
|
+- data2 = list(monitor.phase_usage('phase2'))
|
|
|
++ data1 = list(monitor.phase_usage("phase1"))
|
|
|
++ data2 = list(monitor.phase_usage("phase2"))
|
|
|
+
|
|
|
+ self.assertGreater(len(all), len(data1))
|
|
|
+ self.assertGreater(len(data1), len(data2))
|
|
|
+
|
|
|
+ # This could fail if time.time() takes more than 0.1s. It really
|
|
|
+ # shouldn't.
|
|
|
+ self.assertAlmostEqual(data1[-1].end, data2[-1].end, delta=0.25)
|
|
|
+
|
|
|
+@@ -82,32 +81,32 @@ class TestResourceMonitor(unittest.TestC
|
|
|
+
|
|
|
+ def test_events(self):
|
|
|
+ monitor = SystemResourceMonitor(poll_interval=0.25)
|
|
|
+
|
|
|
+ monitor.start()
|
|
|
+ time.sleep(0.5)
|
|
|
+
|
|
|
+ t0 = time.time()
|
|
|
+- monitor.record_event('t0')
|
|
|
++ monitor.record_event("t0")
|
|
|
+ time.sleep(2)
|
|
|
+
|
|
|
+- monitor.record_event('t1')
|
|
|
++ monitor.record_event("t1")
|
|
|
+ time.sleep(0.5)
|
|
|
+ monitor.stop()
|
|
|
+
|
|
|
+ events = monitor.events
|
|
|
+ self.assertEqual(len(events), 2)
|
|
|
+
|
|
|
+ event = events[0]
|
|
|
+
|
|
|
+- self.assertEqual(event[1], 't0')
|
|
|
++ self.assertEqual(event[1], "t0")
|
|
|
+ self.assertAlmostEqual(event[0], t0, delta=0.25)
|
|
|
+
|
|
|
+- data = list(monitor.between_events_usage('t0', 't1'))
|
|
|
++ data = list(monitor.between_events_usage("t0", "t1"))
|
|
|
+ self.assertGreater(len(data), 0)
|
|
|
+
|
|
|
+ def test_aggregate_cpu(self):
|
|
|
+ monitor = SystemResourceMonitor(poll_interval=0.25)
|
|
|
+
|
|
|
+ monitor.start()
|
|
|
+ time.sleep(1)
|
|
|
+ monitor.stop()
|
|
|
+@@ -119,34 +118,34 @@ class TestResourceMonitor(unittest.TestC
|
|
|
+ self.assertIsInstance(v, float)
|
|
|
+
|
|
|
+ value = monitor.aggregate_cpu_percent(per_cpu=False)
|
|
|
+ self.assertIsInstance(value, float)
|
|
|
+
|
|
|
+ values = monitor.aggregate_cpu_times()
|
|
|
+ self.assertIsInstance(values, list)
|
|
|
+ self.assertGreater(len(values), 0)
|
|
|
+- self.assertTrue(hasattr(values[0], 'user'))
|
|
|
++ self.assertTrue(hasattr(values[0], "user"))
|
|
|
+
|
|
|
+ t = type(values[0])
|
|
|
+
|
|
|
+ value = monitor.aggregate_cpu_times(per_cpu=False)
|
|
|
+ self.assertIsInstance(value, t)
|
|
|
+
|
|
|
+ def test_aggregate_io(self):
|
|
|
+ monitor = SystemResourceMonitor(poll_interval=0.25)
|
|
|
+
|
|
|
+ # There's really no easy way to ensure I/O occurs. For all we know
|
|
|
+ # reads and writes will all be serviced by the page cache.
|
|
|
+ monitor.start()
|
|
|
+ time.sleep(1.0)
|
|
|
+ monitor.stop()
|
|
|
+
|
|
|
+ values = monitor.aggregate_io()
|
|
|
+- self.assertTrue(hasattr(values, 'read_count'))
|
|
|
++ self.assertTrue(hasattr(values, "read_count"))
|
|
|
+
|
|
|
+ def test_memory(self):
|
|
|
+ monitor = SystemResourceMonitor(poll_interval=0.25)
|
|
|
+
|
|
|
+ monitor.start()
|
|
|
+ time.sleep(1.0)
|
|
|
+ monitor.stop()
|
|
|
+
|
|
|
+@@ -156,34 +155,34 @@ class TestResourceMonitor(unittest.TestC
|
|
|
+ v = monitor.max_memory_percent()
|
|
|
+ self.assertIsInstance(v, float)
|
|
|
+
|
|
|
+ def test_as_dict(self):
|
|
|
+ monitor = SystemResourceMonitor(poll_interval=0.25)
|
|
|
+
|
|
|
+ monitor.start()
|
|
|
+ time.sleep(0.1)
|
|
|
+- monitor.begin_phase('phase1')
|
|
|
+- monitor.record_event('foo')
|
|
|
++ monitor.begin_phase("phase1")
|
|
|
++ monitor.record_event("foo")
|
|
|
+ time.sleep(0.1)
|
|
|
+- monitor.begin_phase('phase2')
|
|
|
+- monitor.record_event('bar')
|
|
|
++ monitor.begin_phase("phase2")
|
|
|
++ monitor.record_event("bar")
|
|
|
+ time.sleep(0.2)
|
|
|
+- monitor.finish_phase('phase1')
|
|
|
++ monitor.finish_phase("phase1")
|
|
|
+ time.sleep(0.2)
|
|
|
+- monitor.finish_phase('phase2')
|
|
|
++ monitor.finish_phase("phase2")
|
|
|
+ time.sleep(0.4)
|
|
|
+ monitor.stop()
|
|
|
+
|
|
|
+ d = monitor.as_dict()
|
|
|
+
|
|
|
+- self.assertEqual(d['version'], 2)
|
|
|
+- self.assertEqual(len(d['events']), 2)
|
|
|
+- self.assertEqual(len(d['phases']), 2)
|
|
|
+- self.assertIn('system', d)
|
|
|
+- self.assertIsInstance(d['system'], dict)
|
|
|
+- self.assertIsInstance(d['overall'], dict)
|
|
|
+- self.assertIn('duration', d['overall'])
|
|
|
+- self.assertIn('cpu_times', d['overall'])
|
|
|
++ self.assertEqual(d["version"], 2)
|
|
|
++ self.assertEqual(len(d["events"]), 2)
|
|
|
++ self.assertEqual(len(d["phases"]), 2)
|
|
|
++ self.assertIn("system", d)
|
|
|
++ self.assertIsInstance(d["system"], dict)
|
|
|
++ self.assertIsInstance(d["overall"], dict)
|
|
|
++ self.assertIn("duration", d["overall"])
|
|
|
++ self.assertIn("cpu_times", d["overall"])
|
|
|
+
|
|
|
+
|
|
|
+-if __name__ == '__main__':
|
|
|
++if __name__ == "__main__":
|
|
|
+ mozunit.main()
|