author | Gregory Mierzwinski <gmierz2@outlook.com> |
Thu, 01 Aug 2019 20:36:00 +0000 | |
changeset 486816 | e067cbbbe4d4ee6764cc4343ce43a22dc24412bc |
parent 486815 | 54d0d836b0970a9db8af7844326fdc0d72845d64 |
child 486817 | d2a56641f494f2573f1643325869e70a6dbc8c05 |
push id | 36407 |
push user | ncsoregi@mozilla.com |
push date | Thu, 08 Aug 2019 09:33:10 +0000 |
treeherder | mozilla-central@a28a338396c3 [default view] [failures only] |
perfherder | [talos] [build metrics] [platform microbench] (compared to previous push) |
reviewers | perftest-reviewers, ahal, rwood |
bugs | 1567954 |
milestone | 70.0a1 |
first release with | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
last release without | nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
|
--- a/testing/config/mozbase_requirements.txt +++ b/testing/config/mozbase_requirements.txt @@ -6,15 +6,16 @@ ../mozbase/mozdevice ../mozbase/mozfile ../mozbase/mozhttpd ../mozbase/mozinfo ../mozbase/mozinstall ../mozbase/mozleak ../mozbase/mozlog ../mozbase/moznetwork +../mozbase/mozpower ../mozbase/mozprocess ../mozbase/mozprofile ../mozbase/mozproxy ../mozbase/mozrunner ../mozbase/mozscreenshot ../mozbase/moztest ../mozbase/mozversion
--- a/testing/config/mozbase_source_requirements.txt +++ b/testing/config/mozbase_source_requirements.txt @@ -6,15 +6,16 @@ --editable ../mozbase/mozdevice --editable ../mozbase/mozfile --editable ../mozbase/mozhttpd --editable ../mozbase/mozinfo --editable ../mozbase/mozinstall --editable ../mozbase/mozleak --editable ../mozbase/mozlog --editable ../mozbase/moznetwork +--editable ../mozbase/mozpower --editable ../mozbase/mozprocess --editable ../mozbase/mozprofile --editable ../mozbase/mozproxy --editable ../mozbase/mozrunner --editable ../mozbase/mozscreenshot --editable ../mozbase/moztest --editable ../mozbase/mozversion
--- a/testing/mozbase/moz.build +++ b/testing/mozbase/moz.build @@ -11,16 +11,17 @@ PYTHON_UNITTEST_MANIFESTS += [ 'mozdevice/tests/manifest.ini', 'mozfile/tests/manifest.ini', 'mozhttpd/tests/manifest.ini', 'mozinfo/tests/manifest.ini', 'mozinstall/tests/manifest.ini', 'mozleak/tests/manifest.ini', 'mozlog/tests/manifest.ini', 'moznetwork/tests/manifest.ini', + 'mozpower/tests/manifest.ini', 'mozprocess/tests/manifest.ini', 'mozprofile/tests/manifest.ini', 'mozproxy/tests/manifest.ini', 'mozrunner/tests/manifest.ini', 'mozsystemmonitor/tests/manifest.ini', 'moztest/tests/manifest.ini', 'mozversion/tests/manifest.ini', ] @@ -32,16 +33,17 @@ python_modules = [ 'mozdevice', 'mozfile', 'mozhttpd', 'mozinfo', 'mozinstall', 'mozleak', 'mozlog', 'moznetwork', + 'mozpower', 'mozprocess', 'mozprofile', 'mozproxy', 'mozrunner', 'mozscreenshot', 'mozsystemmonitor', 'moztest', 'mozversion',
new file mode 100644 --- /dev/null +++ b/testing/mozbase/mozpower/mozpower/mozpowerutils.py @@ -0,0 +1,24 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import absolute_import, unicode_literals + + +def get_logger(logger_name): + """Returns the logger that should be used based on logger_name. + Defaults to the logging logger if mozlog cannot be imported. + + :returns: mozlog or logging logger object + """ + logger = None + try: + import mozlog + logger = mozlog.get_default_logger(logger_name) + except ImportError: + pass + + if logger is None: + import logging + logging.basicConfig() + logger = logging.getLogger(logger_name) + return logger
new file mode 100644 --- /dev/null +++ b/testing/mozbase/mozpower/mozpower/powerbase.py @@ -0,0 +1,121 @@ +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this +# file, You can obtain one at http://mozilla.org/MPL/2.0/. +from __future__ import absolute_import, unicode_literals + +import os + +from .mozpowerutils import get_logger + + +class IPGExecutableMissingError(Exception): + """IPGExecutableMissingError is raised when we cannot find + the executable for Intel Power Gadget at the expected location. + """ + pass + + +class PlatformUnsupportedError(Exception): + """PlatformUnsupportedError is raised when we cannot find + an expected IPG path for the OS being tested. + """ + pass + + +class PowerBase(object): + """PowerBase provides an interface for power measurement objects + that depend on the os and cpu. When using this class as a base class + the `initialize_power_measurements`, `finalize_power_measurements`, + and `get_perfherder_data` functions must be implemented, otherwise + a NotImplementedError will be raised. + + PowerBase should only be used as the base class for other + classes and should not be instantiated directly. To enforce this + restriction calling PowerBase's constructor will raise a + NonImplementedError exception. + + :: + + from mozpower.powerbase import PowerBase + + try: + pb = PowerBase() + except NotImplementedError: + print "PowerBase cannot be instantiated." + + """ + def __init__(self, logger_name='mozpower', os=None, cpu=None): + """Initializes the PowerBase object. + + :param str logger_name: logging logger name. Defaults to 'mozpower'. + :param str os: operating system being tested. Defaults to None. + :param str cpu: cpu type being tested (either intel or arm64). Defaults to None. + :raises: * NotImplementedError + """ + if self.__class__ == PowerBase: + raise NotImplementedError + + self._logger_name = logger_name + self._logger = get_logger(logger_name) + self._os = os + self._cpu = cpu + self._ipg_path = self.get_ipg_path() + + @property + def ipg_path(self): + return self._ipg_path + + @property + def logger_name(self): + return self._logger_name + + def initialize_power_measurements(self): + """Starts power measurement gathering, must be implemented by subclass. + + :raises: * NotImplementedError + """ + raise NotImplementedError + + def finalize_power_measurements(self, test_name='power-testing', **kwargs): + """Stops power measurement gathering, must be implemented by subclass. + + :raises: * NotImplementedError + """ + raise NotImplementedError + + def get_perfherder_data(self): + """Returns the perfherder data output produced from the tests, must + be implemented by subclass. + + :raises: * NotImplementedError + """ + raise NotImplementedError + + def get_ipg_path(self): + """Returns the path to where we expect to find Intel Power Gadget + depending on the OS being tested. Raises a PlatformUnsupportedError + if the OS being tested is unsupported, and raises a IPGExecutableMissingError + if the Intel Power Gadget executable cannot be found at the expected + location. + + :returns: str + :raises: * IPGExecutableMissingError + * PlatformUnsupportedError + """ + if self._cpu != "intel": + return None + + if self._os == "darwin": + exe_path = "/Applications/Intel Power Gadget/PowerLog" + else: + raise PlatformUnsupportedError( + "%s platform currently not supported for Intel Power Gadget measurements" % + self._os + ) + if not os.path.exists(exe_path): + raise IPGExecutableMissingError( + "Intel Power Gadget is not installed, or cannot be found at the location %s" % + exe_path + ) + + return exe_path
new file mode 100644 --- /dev/null +++ b/testing/mozbase/mozpower/setup.cfg @@ -0,0 +1,2 @@ +[bdist_wheel] +universal = 1
new file mode 100644 --- /dev/null +++ b/testing/mozbase/mozpower/setup.py @@ -0,0 +1,34 @@ + +# This Source Code Form is subject to the terms of the Mozilla Public +# License, v. 2.0. If a copy of the MPL was not distributed with this file, +# You can obtain one at http://mozilla.org/MPL/2.0/. + +from __future__ import absolute_import + +from setuptools import setup + +PACKAGE_NAME = 'mozpower' +PACKAGE_VERSION = '1.0.0' + +deps = ['mozlog >= 3.0', 'mozdevice >= 3.0.2'] + +setup(name=PACKAGE_NAME, + version=PACKAGE_VERSION, + description="Mozilla-authored power usage measurement tools", + long_description="see https://firefox-source-docs.mozilla.org/mozbase/index.html", + classifiers=['Programming Language :: Python :: 2.7', + 'Programming Language :: Python :: 3.5'], + # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + keywords='', + author='Mozilla Performance Test Engineering Team', + author_email='tools@lists.mozilla.org', + url='https://wiki.mozilla.org/Auto-tools/Projects/Mozbase', + license='MPL', + packages=['mozpower'], + include_package_data=True, + zip_safe=False, + install_requires=deps, + entry_points=""" + # -*- Entry points: -*- + """, + )
new file mode 100644 --- /dev/null +++ b/testing/mozbase/mozpower/tests/conftest.py @@ -0,0 +1,15 @@ +from __future__ import absolute_import, print_function + +import pytest + +from mozpower.powerbase import PowerBase + + +@pytest.fixture(scope='function') +def powermeasurer(): + """Returns a testing subclass of the PowerBase class + for testing. + """ + class PowerMeasurer(PowerBase): + pass + return PowerMeasurer()
new file mode 100644 --- /dev/null +++ b/testing/mozbase/mozpower/tests/manifest.ini @@ -0,0 +1,3 @@ +[DEFAULT] +subsuite = mozbase +[test_powerbase.py] \ No newline at end of file
new file mode 100644 --- /dev/null +++ b/testing/mozbase/mozpower/tests/test_powerbase.py @@ -0,0 +1,94 @@ +#!/usr/bin/env python + +from __future__ import absolute_import + +import mock +import mozunit +import pytest + +from mozpower.powerbase import ( + PowerBase, + IPGExecutableMissingError, + PlatformUnsupportedError +) + + +def test_powerbase_intialization(): + """Tests that the PowerBase class correctly raises + a NotImplementedError when attempting to instantiate + it directly. + """ + with pytest.raises(NotImplementedError): + PowerBase() + + +def test_powerbase_missing_methods(powermeasurer): + """Tests that trying to call PowerBase methods + without an implementation in the subclass raises + the NotImplementedError. + """ + with pytest.raises(NotImplementedError): + powermeasurer.initialize_power_measurements() + + with pytest.raises(NotImplementedError): + powermeasurer.finalize_power_measurements() + + with pytest.raises(NotImplementedError): + powermeasurer.get_perfherder_data() + + +def test_powerbase_get_ipg_path_mac(powermeasurer): + """Tests that getting the IPG path returns the expected results. + """ + powermeasurer._os = 'darwin' + powermeasurer._cpu = 'not-intel' + + def os_side_effect(arg): + """Used to get around the os.path.exists check in + get_ipg_path which raises an IPGExecutableMissingError + otherwise. + """ + return True + + with mock.patch('os.path.exists', return_value=True) as m: + m.side_effect = os_side_effect + + # None is returned when a non-intel based machine is + # tested. + ipg_path = powermeasurer.get_ipg_path() + assert ipg_path is None + + # Check the path returned for mac intel-based machines. + powermeasurer._cpu = 'intel' + ipg_path = powermeasurer.get_ipg_path() + assert ipg_path == "/Applications/Intel Power Gadget/PowerLog" + + +def test_powerbase_get_ipg_path_errors(powermeasurer): + """Tests that the appropriate error is output when calling + get_ipg_path with invalid/unsupported _os and _cpu entries. + """ + + powermeasurer._cpu = 'intel' + powermeasurer._os = 'Not-An-OS' + + def os_side_effect(arg): + """Used to force the error IPGExecutableMissingError to occur + (in case a machine running these tests is a mac, and has intel + power gadget installed). + """ + return False + + with pytest.raises(PlatformUnsupportedError): + powermeasurer.get_ipg_path() + + with mock.patch('os.path.exists', return_value=False) as m: + m.side_effect = os_side_effect + + powermeasurer._os = 'darwin' + with pytest.raises(IPGExecutableMissingError): + powermeasurer.get_ipg_path() + + +if __name__ == '__main__': + mozunit.main()
--- a/testing/mozbase/packages.txt +++ b/testing/mozbase/packages.txt @@ -4,16 +4,17 @@ mozdebug.pth:testing/mozbase/mozdebug mozdevice.pth:testing/mozbase/mozdevice mozfile.pth:testing/mozbase/mozfile mozhttpd.pth:testing/mozbase/mozhttpd mozinfo.pth:testing/mozbase/mozinfo mozinstall.pth:testing/mozbase/mozinstall mozleak.pth:testing/mozbase/mozleak mozlog.pth:testing/mozbase/mozlog moznetwork.pth:testing/mozbase/moznetwork +mozpower.pth:testing/mozbase/mozpower mozprocess.pth:testing/mozbase/mozprocess mozprofile.pth:testing/mozbase/mozprofile mozproxy.pth:testing/mozbase/mozproxy mozrunner.pth:testing/mozbase/mozrunner mozsystemmonitor.pth:testing/mozbase/mozsystemmonitor mozscreenshot.pth:testing/mozbase/mozscreenshot moztest.pth:testing/mozbase/moztest mozversion.pth:testing/mozbase/mozversion
--- a/testing/tools/mach_test_package_bootstrap.py +++ b/testing/tools/mach_test_package_bootstrap.py @@ -21,16 +21,17 @@ SEARCH_PATHS = [ 'mozbase/mozdevice', 'mozbase/mozfile', 'mozbase/mozhttpd', 'mozbase/mozinfo', 'mozbase/mozinstall', 'mozbase/mozleak', 'mozbase/mozlog', 'mozbase/moznetwork', + 'mozbase/mozpower', 'mozbase/mozprocess', 'mozbase/mozprofile', 'mozbase/mozrunner', 'mozbase/mozscreenshot', 'mozbase/mozsystemmonitor', 'mozbase/moztest', 'mozbase/mozversion', 'reftest',