summaryrefslogtreecommitdiffstats
path: root/testing/mozbase/mozpower/tests
diff options
context:
space:
mode:
Diffstat (limited to 'testing/mozbase/mozpower/tests')
-rw-r--r--testing/mozbase/mozpower/tests/conftest.py103
-rw-r--r--testing/mozbase/mozpower/tests/files/emptyfile.txt0
-rw-r--r--testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_1_.txt30
-rw-r--r--testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_2_.txt30
-rw-r--r--testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_3_.txt30
-rw-r--r--testing/mozbase/mozpower/tests/files/valueerrorfile.txt30
-rw-r--r--testing/mozbase/mozpower/tests/manifest.ini6
-rw-r--r--testing/mozbase/mozpower/tests/test_intelpowergadget.py348
-rw-r--r--testing/mozbase/mozpower/tests/test_macintelpower.py76
-rw-r--r--testing/mozbase/mozpower/tests/test_mozpower.py255
-rw-r--r--testing/mozbase/mozpower/tests/test_powerbase.py91
11 files changed, 999 insertions, 0 deletions
diff --git a/testing/mozbase/mozpower/tests/conftest.py b/testing/mozbase/mozpower/tests/conftest.py
new file mode 100644
index 0000000000..9d81b0229b
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/conftest.py
@@ -0,0 +1,103 @@
+import os
+import tempfile
+import time
+from unittest import mock
+
+import pytest
+from mozpower import MozPower
+from mozpower.intel_power_gadget import IntelPowerGadget, IPGResultsHandler
+from mozpower.macintelpower import MacIntelPower
+from mozpower.powerbase import PowerBase
+
+
+def os_side_effect(*args, **kwargs):
+ """Used as a side effect to os.path.exists when
+ checking if the Intel Power Gadget executable exists.
+ """
+ return True
+
+
+def subprocess_side_effect(*args, **kwargs):
+ """Used as a side effect when running the Intel Power
+ Gadget tool.
+ """
+ time.sleep(1)
+
+
+@pytest.fixture(scope="function")
+def powermeasurer():
+ """Returns a testing subclass of the PowerBase class
+ for testing.
+ """
+
+ class PowerMeasurer(PowerBase):
+ pass
+
+ return PowerMeasurer()
+
+
+@pytest.fixture(scope="function")
+def ipg_obj():
+ """Returns an IntelPowerGadget object with the test
+ output file path.
+ """
+ return IntelPowerGadget(
+ "ipg-path",
+ output_file_path=os.path.abspath(os.path.dirname(__file__))
+ + "/files/raptor-tp6-amazon-firefox_powerlog",
+ )
+
+
+@pytest.fixture(scope="function")
+def ipg_rh_obj():
+ """Returns an IPGResultsHandler object set up with the
+ test files and cleans up the directory after the tests
+ are complete.
+ """
+ base_path = os.path.abspath(os.path.dirname(__file__)) + "/files/"
+ tmpdir = tempfile.mkdtemp()
+
+ # Return the results handler for the test
+ yield IPGResultsHandler(
+ [
+ base_path + "raptor-tp6-amazon-firefox_powerlog_1_.txt",
+ base_path + "raptor-tp6-amazon-firefox_powerlog_2_.txt",
+ base_path + "raptor-tp6-amazon-firefox_powerlog_3_.txt",
+ ],
+ tmpdir,
+ )
+
+
+@pytest.fixture(scope="function")
+def macintelpower_obj():
+ """Returns a MacIntelPower object with subprocess.check_output
+ and os.path.exists calls patched with side effects.
+ """
+ with mock.patch("subprocess.check_output") as subprocess_mock:
+ with mock.patch("os.path.exists") as os_mock:
+ subprocess_mock.side_effect = subprocess_side_effect
+ os_mock.side_effect = os_side_effect
+
+ yield MacIntelPower(ipg_measure_duration=2)
+
+
+@pytest.fixture(scope="function")
+def mozpower_obj():
+ """Returns a MozPower object with subprocess.check_output
+ and os.path.exists calls patched with side effects.
+ """
+ with mock.patch.object(
+ MozPower, "_get_os", return_value="Darwin"
+ ) as _, mock.patch.object(
+ MozPower, "_get_processor_info", return_value="GenuineIntel"
+ ) as _, mock.patch.object(
+ MacIntelPower, "get_ipg_path", return_value="/"
+ ) as _, mock.patch(
+ "subprocess.check_output"
+ ) as subprocess_mock, mock.patch(
+ "os.path.exists"
+ ) as os_mock:
+ subprocess_mock.side_effect = subprocess_side_effect
+ os_mock.side_effect = os_side_effect
+
+ yield MozPower(ipg_measure_duration=2)
diff --git a/testing/mozbase/mozpower/tests/files/emptyfile.txt b/testing/mozbase/mozpower/tests/files/emptyfile.txt
new file mode 100644
index 0000000000..e69de29bb2
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/files/emptyfile.txt
diff --git a/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_1_.txt b/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_1_.txt
new file mode 100644
index 0000000000..d5cc3f91a5
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_1_.txt
@@ -0,0 +1,30 @@
+"System Time","RDTSC","Elapsed Time (sec)","CPU Utilization(%)","CPU Frequency_0(MHz)","Processor Power_0(Watt)","Cumulative Processor Energy_0(Joules)","Cumulative Processor Energy_0(mWh)","IA Power_0(Watt)","Cumulative IA Energy_0(Joules)","Cumulative IA Energy_0(mWh)","Package Temperature_0(C)","Package Hot_0","DRAM Power_0(Watt)","Cumulative DRAM Energy_0(Joules)","Cumulative DRAM Energy_0(mWh)","GT Power_0(Watt)","Cumulative GT Energy_0(Joules)","Cumulative GT Energy_0(mWh)","Package Power Limit_0(Watt)","GT Frequency(MHz)"
+"12:11:05:769","61075218263548"," 2.002"," 14.000"," 3400"," 23.427"," 23.460"," 6.517"," 21.019"," 21.048"," 5.847"," 75","0"," 0.877"," 0.878"," 0.244"," 0.020"," 0.020"," 0.006"," 45.000"," 0"
+"12:11:06:774","61077822279584"," 3.007"," 20.000"," 3000"," 25.014"," 48.590"," 13.497"," 22.386"," 43.538"," 12.094"," 74","0"," 1.194"," 2.078"," 0.577"," 0.029"," 0.049"," 0.014"," 45.000"," 0"
+"12:11:07:778","61080424421708"," 4.011"," 8.000"," 1300"," 9.512"," 58.140"," 16.150"," 6.904"," 50.469"," 14.019"," 65","0"," 0.836"," 2.917"," 0.810"," 0.007"," 0.057"," 0.016"," 45.000"," 0"
+"12:11:08:781","61083023535972"," 5.013"," 1.000"," 1300"," 1.786"," 59.931"," 16.647"," 0.687"," 51.158"," 14.210"," 63","0"," 0.585"," 3.504"," 0.973"," 0.000"," 0.057"," 0.016"," 45.000"," 0"
+"12:11:09:784","61085623402302"," 6.016"," 4.000"," 4000"," 5.249"," 65.195"," 18.110"," 3.743"," 54.912"," 15.253"," 75","0"," 0.660"," 4.166"," 1.157"," 0.003"," 0.059"," 0.017"," 45.000"," 0"
+"12:11:10:787","61088224087008"," 7.020"," 20.000"," 3000"," 35.118"," 100.432"," 27.898"," 31.647"," 86.666"," 24.074"," 72","0"," 1.048"," 5.218"," 1.449"," 0.016"," 0.076"," 0.021"," 45.000"," 0"
+"12:11:11:791","61090825821126"," 8.024"," 13.000"," 3000"," 25.436"," 125.965"," 34.990"," 22.228"," 108.979"," 30.272"," 71","0"," 0.868"," 6.089"," 1.691"," 0.004"," 0.080"," 0.022"," 45.000"," 0"
+"12:11:12:795","61093429020836"," 9.028"," 5.000"," 1300"," 5.266"," 131.253"," 36.459"," 3.270"," 112.263"," 31.184"," 64","0"," 0.711"," 6.802"," 1.890"," 0.000"," 0.080"," 0.022"," 45.000"," 0"
+"12:11:13:796","61096024160928"," 10.029"," 5.000"," 4000"," 11.070"," 142.338"," 39.538"," 9.613"," 121.888"," 33.858"," 78","0"," 0.650"," 7.453"," 2.070"," 0.000"," 0.080"," 0.022"," 45.000"," 0"
+"12:11:13:796","61096024279264"," 10.029"," 57.000"," 4000"," 0.000"," 142.338"," 39.538"," 0.000"," 121.888"," 33.858"," 78","0"," 0.000"," 7.453"," 2.070"," 0.000"," 0.080"," 0.022"," 45.000"," 0"
+
+"Total Elapsed Time (sec) = 10.029232"
+"Measured RDTSC Frequency (GHz) = 2.592"
+
+"Cumulative Processor Energy_0 (Joules) = 142.337524"
+"Cumulative Processor Energy_0 (mWh) = 39.538201"
+"Average Processor Power_0 (Watt) = 14.192265"
+
+"Cumulative IA Energy_0 (Joules) = 121.888000"
+"Cumulative IA Energy_0 (mWh) = 33.857778"
+"Average IA Power_0 (Watt) = 12.153273"
+
+"Cumulative DRAM Energy_0 (Joules) = 7.453308"
+"Cumulative DRAM Energy_0 (mWh) = 2.070363"
+"Average DRAM Power_0 (Watt) = 0.743158"
+
+"Cumulative GT Energy_0 (Joules) = 0.079834"
+"Cumulative GT Energy_0 (mWh) = 0.022176"
+"Average GT Power_0 (Watt) = 0.007960"
diff --git a/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_2_.txt b/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_2_.txt
new file mode 100644
index 0000000000..9157ad1fad
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_2_.txt
@@ -0,0 +1,30 @@
+"System Time","RDTSC","Elapsed Time (sec)","CPU Utilization(%)","CPU Frequency_0(MHz)","Processor Power_0(Watt)","Cumulative Processor Energy_0(Joules)","Cumulative Processor Energy_0(mWh)","IA Power_0(Watt)","Cumulative IA Energy_0(Joules)","Cumulative IA Energy_0(mWh)","Package Temperature_0(C)","Package Hot_0","DRAM Power_0(Watt)","Cumulative DRAM Energy_0(Joules)","Cumulative DRAM Energy_0(mWh)","GT Power_0(Watt)","Cumulative GT Energy_0(Joules)","Cumulative GT Energy_0(mWh)","Package Power Limit_0(Watt)","GT Frequency(MHz)"
+"12:11:15:821","61101270635674"," 2.007"," 9.000"," 4200"," 10.341"," 10.382"," 2.884"," 7.710"," 7.740"," 2.150"," 80","0"," 0.828"," 0.831"," 0.231"," 0.000"," 0.000"," 0.000"," 45.000"," 0"
+"12:11:16:823","61103869919264"," 3.010"," 4.000"," 1300"," 9.353"," 19.762"," 5.489"," 8.079"," 15.842"," 4.400"," 64","0"," 0.597"," 1.430"," 0.397"," 0.000"," 0.000"," 0.000"," 45.000"," 0"
+"12:11:17:826","61106469262970"," 4.013"," 19.000"," 2500"," 21.127"," 40.950"," 11.375"," 17.753"," 33.645"," 9.346"," 69","0"," 1.091"," 2.524"," 0.701"," 0.011"," 0.011"," 0.003"," 45.000"," 0"
+"12:11:18:827","61109063770516"," 5.014"," 11.000"," 2000"," 11.620"," 52.581"," 14.606"," 8.333"," 41.986"," 11.663"," 64","0"," 0.961"," 3.486"," 0.968"," 0.000"," 0.011"," 0.003"," 45.000"," 0"
+"12:11:19:831","61111666134444"," 6.018"," 3.000"," 1300"," 2.722"," 55.314"," 15.365"," 1.497"," 43.489"," 12.080"," 64","0"," 0.620"," 4.108"," 1.141"," 0.000"," 0.011"," 0.003"," 45.000"," 0"
+"12:11:20:835","61114266619236"," 7.021"," 14.000"," 3400"," 17.108"," 72.478"," 20.133"," 14.538"," 58.075"," 16.132"," 79","0"," 0.918"," 5.029"," 1.397"," 0.004"," 0.016"," 0.004"," 45.000"," 0"
+"12:11:21:835","61116859007218"," 8.021"," 15.000"," 3000"," 16.651"," 89.132"," 24.759"," 13.055"," 71.132"," 19.759"," 70","0"," 1.103"," 6.132"," 1.703"," 0.005"," 0.020"," 0.006"," 45.000"," 0"
+"12:11:22:836","61119453982614"," 9.023"," 4.000"," 2000"," 3.334"," 92.470"," 25.686"," 1.974"," 73.109"," 20.308"," 64","0"," 0.654"," 6.787"," 1.885"," 0.000"," 0.020"," 0.006"," 45.000"," 0"
+"12:11:23:840","61122057636318"," 10.027"," 12.000"," 3400"," 13.925"," 106.458"," 29.572"," 11.603"," 84.764"," 23.546"," 79","0"," 0.856"," 7.647"," 2.124"," 0.006"," 0.027"," 0.007"," 45.000"," 0"
+"12:11:23:840","61122057733984"," 10.027"," 66.000"," 3400"," 0.000"," 106.458"," 29.572"," 0.000"," 84.764"," 23.546"," 79","0"," 0.000"," 7.647"," 2.124"," 0.000"," 0.027"," 0.007"," 45.000"," 0"
+
+"Total Elapsed Time (sec) = 10.027134"
+"Measured RDTSC Frequency (GHz) = 2.592"
+
+"Cumulative Processor Energy_0 (Joules) = 106.457581"
+"Cumulative Processor Energy_0 (mWh) = 29.571550"
+"Average Processor Power_0 (Watt) = 10.616950"
+
+"Cumulative IA Energy_0 (Joules) = 84.764404"
+"Cumulative IA Energy_0 (mWh) = 23.545668"
+"Average IA Power_0 (Watt) = 8.453503"
+
+"Cumulative DRAM Energy_0 (Joules) = 7.647095"
+"Cumulative DRAM Energy_0 (mWh) = 2.124193"
+"Average DRAM Power_0 (Watt) = 0.762640"
+
+"Cumulative GT Energy_0 (Joules) = 0.026550"
+"Cumulative GT Energy_0 (mWh) = 0.007375"
+"Average GT Power_0 (Watt) = 0.002648"
diff --git a/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_3_.txt b/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_3_.txt
new file mode 100644
index 0000000000..a2779d93a1
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/files/raptor-tp6-amazon-firefox_powerlog_3_.txt
@@ -0,0 +1,30 @@
+"System Time","RDTSC","Elapsed Time (sec)","CPU Utilization(%)","CPU Frequency_0(MHz)","Processor Power_0(Watt)","Cumulative Processor Energy_0(Joules)","Cumulative Processor Energy_0(mWh)","IA Power_0(Watt)","Cumulative IA Energy_0(Joules)","Cumulative IA Energy_0(mWh)","Package Temperature_0(C)","Package Hot_0","DRAM Power_0(Watt)","Cumulative DRAM Energy_0(Joules)","Cumulative DRAM Energy_0(mWh)","GT Power_0(Watt)","Cumulative GT Energy_0(Joules)","Cumulative GT Energy_0(mWh)","Package Power Limit_0(Watt)","GT Frequency(MHz)"
+"12:11:25:867","61127310813944"," 2.006"," 6.000"," 2000"," 4.862"," 4.879"," 1.355"," 3.087"," 3.097"," 0.860"," 65","0"," 0.774"," 0.776"," 0.216"," 0.021"," 0.022"," 0.006"," 45.000"," 0"
+"12:11:26:867","61129903677124"," 3.006"," 2.000"," 1300"," 2.883"," 7.763"," 2.156"," 1.253"," 4.350"," 1.208"," 63","0"," 0.644"," 1.421"," 0.395"," 0.018"," 0.039"," 0.011"," 45.000"," 0"
+"12:11:27:873","61132509307964"," 4.011"," 2.000"," 1300"," 1.788"," 9.561"," 2.656"," 0.699"," 5.054"," 1.404"," 63","0"," 0.538"," 1.961"," 0.545"," 0.000"," 0.039"," 0.011"," 45.000"," 0"
+"12:11:28:877","61135111021262"," 5.015"," 0.000"," 1300"," 1.177"," 10.743"," 2.984"," 0.321"," 5.375"," 1.493"," 63","0"," 0.535"," 2.499"," 0.694"," 0.000"," 0.039"," 0.011"," 45.000"," 0"
+"12:11:29:881","61137714179976"," 6.020"," 0.000"," 1300"," 1.064"," 11.811"," 3.281"," 0.251"," 5.627"," 1.563"," 61","0"," 0.520"," 3.021"," 0.839"," 0.000"," 0.039"," 0.011"," 45.000"," 0"
+"12:11:30:881","61140307250904"," 7.020"," 0.000"," 1300"," 1.053"," 12.864"," 3.573"," 0.256"," 5.884"," 1.634"," 61","0"," 0.528"," 3.550"," 0.986"," 0.000"," 0.039"," 0.011"," 45.000"," 0"
+"12:11:31:885","61142907976768"," 8.023"," 0.000"," 1300"," 1.069"," 13.937"," 3.871"," 0.274"," 6.159"," 1.711"," 61","0"," 0.524"," 4.075"," 1.132"," 0.000"," 0.039"," 0.011"," 45.000"," 0"
+"12:11:32:886","61145503940512"," 9.025"," 0.000"," 1300"," 1.008"," 14.947"," 4.152"," 0.228"," 6.387"," 1.774"," 60","0"," 0.522"," 4.598"," 1.277"," 0.000"," 0.039"," 0.011"," 45.000"," 0"
+"12:11:33:891","61148109378824"," 10.030"," 0.000"," 1300"," 1.007"," 15.959"," 4.433"," 0.230"," 6.618"," 1.838"," 61","0"," 0.522"," 5.123"," 1.423"," 0.000"," 0.039"," 0.011"," 45.000"," 0"
+"12:11:33:892","61148109766160"," 10.030"," 27.000"," 1300"," 0.000"," 15.959"," 4.433"," 0.000"," 6.618"," 1.838"," 61","0"," 2.448"," 5.123"," 1.423"," 0.000"," 0.039"," 0.011"," 45.000"," 0"
+
+"Total Elapsed Time (sec) = 10.030310"
+"Measured RDTSC Frequency (GHz) = 2.592"
+
+"Cumulative Processor Energy_0 (Joules) = 15.958862"
+"Cumulative Processor Energy_0 (mWh) = 4.433017"
+"Average Processor Power_0 (Watt) = 1.591064"
+
+"Cumulative IA Energy_0 (Joules) = 6.618042"
+"Cumulative IA Energy_0 (mWh) = 1.838345"
+"Average IA Power_0 (Watt) = 0.659804"
+
+"Cumulative DRAM Energy_0 (Joules) = 5.122925"
+"Cumulative DRAM Energy_0 (mWh) = 1.423035"
+"Average DRAM Power_0 (Watt) = 0.510744"
+
+"Cumulative GT Energy_0 (Joules) = 0.039490"
+"Cumulative GT Energy_0 (mWh) = 0.010969"
+"Average GT Power_0 (Watt) = 0.003937"
diff --git a/testing/mozbase/mozpower/tests/files/valueerrorfile.txt b/testing/mozbase/mozpower/tests/files/valueerrorfile.txt
new file mode 100644
index 0000000000..8f2d3485eb
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/files/valueerrorfile.txt
@@ -0,0 +1,30 @@
+"System Time","RDTSC","Elapsed Time (sec)","CPU Utilization(%)","CPU Frequency_0(MHz)","Processor Power_0(Watt)","Cumulative Processor Energy_0(Joules)","Cumulative Processor Energy_0(mWh)","IA Power_0(Watt)","Cumulative IA Energy_0(Joules)","Cumulative IA Energy_0(mWh)","Package Temperature_0(C)","Package Hot_0","DRAM Power_0(Watt)","Cumulative DRAM Energy_0(Joules)","Cumulative DRAM Energy_0(mWh)","GT Power_0(Watt)","Cumulative GT Energy_0(Joules)","Cumulative GT Energy_0(mWh)","Package Power Limit_0(Watt)","GT Frequency(MHz)"
+"12:11:05:769","61075218263548"," 2.002"," 14.000"," 3400"," 23.427"," 23.460"," 6.517"," 21.019"," 21.048"," 5.847"," 75","0"," 0.877"," 0.878"," 0.244"," 0.020"," 0.020"," 0.006"," 45.000"," 0"
+"12:11:06:774","61077822279584"," 3.007"," 20.000"," 3000"," 25.014"," 48.590"," 13.497"," 22.386"," 43.538"," 12.094"," 74","0"," 1.194"," 2.078"," 0.577"," 0.029"," 0.049"," 0.014"," 45.000"," 0"
+"12:11:07:778","61080424421708"," 4.011"," 8.000"," 1300"," 9.512"," 58.140"," 16.150"," 6.904"," 50.469"," 14.019"," 65","0"," 0.836"," 2.917"," 0.810"," 0.007"," 0.057"," 0.016"," 45.000"," 0"
+"12:11:08:781","61083023535972"," 5.013"," 1.000"," 1300"," 1.786"," 59.931"," 16.647"," 0.687"," 51.158"," 14.210"," 63","0"," 0.585"," 3.504"," 0.973"," 0.000"," 0.057"," 0.016"," 45.000"," 0"
+"12:11:09:784","61085623402302"," none"," 4.000"," 4000"," 5.249"," 65.195"," 18.110"," 3.743"," 54.912"," 15.253"," 75","0"," 0.660"," 4.166"," 1.157"," 0.003"," 0.059"," 0.017"," 45.000"," 0"
+"12:11:10:787","61088224087008"," 7.020"," 20.000"," 3000"," 35.118"," 100.432"," 27.898"," 31.647"," 86.666"," 24.074"," 72","0"," 1.048"," 5.218"," 1.449"," 0.016"," 0.076"," 0.021"," 45.000"," 0"
+"12:11:11:791","61090825821126"," 8.024"," 13.000"," 3000"," 25.436"," 125.965"," 34.990"," 22.228"," 108.979"," 30.272"," 71","0"," 0.868"," 6.089"," 1.691"," 0.004"," 0.080"," 0.022"," 45.000"," 0"
+"12:11:12:795","61093429020836"," 9.028"," 5.000"," 1300"," 5.266"," 131.253"," 36.459"," 3.270"," 112.263"," 31.184"," 64","0"," 0.711"," 6.802"," 1.890"," 0.000"," 0.080"," 0.022"," 45.000"," 0"
+"12:11:13:796","61096024160928"," 10.029"," 5.000"," 4000"," 11.070"," 142.338"," 39.538"," 9.613"," 121.888"," 33.858"," 78","0"," 0.650"," 7.453"," 2.070"," 0.000"," 0.080"," 0.022"," 45.000"," 0"
+"12:11:13:796","61096024279264"," 10.029"," 57.000"," 4000"," 0.000"," 142.338"," 39.538"," 0.000"," 121.888"," 33.858"," 78","0"," 0.000"," 7.453"," 2.070"," 0.000"," 0.080"," 0.022"," 45.000"," 0"
+
+"Total Elapsed Time (sec) = 10.029232"
+"Measured RDTSC Frequency (GHz) = 2.592"
+
+"Cumulative Processor Energy_0 (Joules) = 142.337524"
+"Cumulative Processor Energy_0 (mWh) = 39.538201"
+"Average Processor Power_0 (Watt) = 14.192265"
+
+"Cumulative IA Energy_0 (Joules) = 121.888000"
+"Cumulative IA Energy_0 (mWh) = 33.857778"
+"Average IA Power_0 (Watt) = 12.153273"
+
+"Cumulative DRAM Energy_0 (Joules) = 7.453308"
+"Cumulative DRAM Energy_0 (mWh) = 2.070363"
+"Average DRAM Power_0 (Watt) = 0.743158"
+
+"Cumulative GT Energy_0 (Joules) = 0.079834"
+"Cumulative GT Energy_0 (mWh) = 0.022176"
+"Average GT Power_0 (Watt) = 0.007960"
diff --git a/testing/mozbase/mozpower/tests/manifest.ini b/testing/mozbase/mozpower/tests/manifest.ini
new file mode 100644
index 0000000000..2e825e2fa5
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/manifest.ini
@@ -0,0 +1,6 @@
+[DEFAULT]
+subsuite = mozbase
+[test_powerbase.py]
+[test_intelpowergadget.py]
+[test_macintelpower.py]
+[test_mozpower.py]
diff --git a/testing/mozbase/mozpower/tests/test_intelpowergadget.py b/testing/mozbase/mozpower/tests/test_intelpowergadget.py
new file mode 100644
index 0000000000..9be01cb720
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/test_intelpowergadget.py
@@ -0,0 +1,348 @@
+#!/usr/bin/env python
+
+import datetime
+import os
+import time
+from unittest import mock
+
+import mozunit
+import pytest
+import six
+from mozpower.intel_power_gadget import (
+ IPGEmptyFileError,
+ IPGMissingOutputFileError,
+ IPGTimeoutError,
+ IPGUnknownValueTypeError,
+)
+
+
+def thread_is_alive(thread):
+ if six.PY2:
+ return thread.isAlive()
+ return thread.is_alive()
+
+
+def test_ipg_pathsplitting(ipg_obj):
+ """Tests that the output file path and prefix was properly split.
+ This test assumes that it is in the same directory as the conftest.py file.
+ """
+ assert (
+ ipg_obj.output_dir_path == os.path.abspath(os.path.dirname(__file__)) + "/files"
+ )
+ assert ipg_obj.output_file_prefix == "raptor-tp6-amazon-firefox_powerlog"
+
+
+def test_ipg_get_output_file_path(ipg_obj):
+ """Tests that the output file path is constantly changing
+ based on the file_counter value.
+ """
+ test_path = "/test_path/"
+ test_ext = ".txt"
+ ipg_obj._file_counter = 1
+ ipg_obj._output_dir_path = test_path
+ ipg_obj._output_file_ext = test_ext
+
+ for i in range(1, 6):
+ fpath = ipg_obj._get_output_file_path()
+
+ assert fpath.startswith(test_path)
+ assert fpath.endswith(test_ext)
+ assert str(i) in fpath
+
+
+def test_ipg_start_and_stop(ipg_obj):
+ """Tests that the IPG thread can start and stop properly."""
+
+ def subprocess_side_effect(*args, **kwargs):
+ time.sleep(1)
+
+ with mock.patch("subprocess.check_output") as m:
+ m.side_effect = subprocess_side_effect
+
+ # Start recording IPG measurements
+ ipg_obj.start_ipg()
+ assert not ipg_obj._stop
+
+ # Wait a bit for thread to start, then check it
+ timeout = 10
+ start = time.time()
+ while time.time() - start < timeout and not ipg_obj._running:
+ time.sleep(1)
+
+ assert ipg_obj._running
+ assert thread_is_alive(ipg_obj._thread)
+
+ # Stop recording IPG measurements
+ ipg_obj.stop_ipg(wait_interval=1, timeout=30)
+ assert ipg_obj._stop
+ assert not ipg_obj._running
+
+
+def test_ipg_stopping_timeout(ipg_obj):
+ """Tests that an IPGTimeoutError is raised when
+ the thread is still "running" and the wait in _wait_for_ipg
+ has exceeded the timeout value.
+ """
+ with pytest.raises(IPGTimeoutError):
+ ipg_obj._running = True
+ ipg_obj._wait_for_ipg(wait_interval=1, timeout=2)
+
+
+def test_ipg_rh_combine_cumulatives(ipg_rh_obj):
+ """Tests that cumulatives are correctly combined in
+ the _combine_cumulative_rows function.
+ """
+ cumulatives_to_combine = [
+ [0, 1, 2, 3, 4, 5],
+ [0, 1, 2, 3, 4, 5],
+ [0, 1, 2, 3, 4, 5],
+ [0, 1, 2, 3, 4, 5],
+ ]
+
+ combined_cumulatives = ipg_rh_obj._combine_cumulative_rows(cumulatives_to_combine)
+
+ # Check that accumulation worked, final value must be the maximum
+ assert combined_cumulatives[-1] == max(combined_cumulatives)
+
+ # Check that the cumulative values are monotonically increasing
+ for count, val in enumerate(combined_cumulatives[:-1]):
+ assert combined_cumulatives[count + 1] - val >= 0
+
+
+def test_ipg_rh_clean_file(ipg_rh_obj):
+ """Tests that IPGResultsHandler correctly cleans the data
+ from one file.
+ """
+ file = ipg_rh_obj._output_files[0]
+ linecount = 0
+ with open(file, "r") as f:
+ for line in f:
+ linecount += 1
+
+ results, summary, clean_file = ipg_rh_obj._clean_ipg_file(file)
+
+ # Check that each measure from the csv header
+ # is in the results dict and that the clean file output
+ # exists.
+ for measure in results:
+ assert measure in ipg_rh_obj._csv_header
+ assert os.path.exists(clean_file)
+
+ clean_rows = []
+ with open(clean_file, "r") as f:
+ for line in f:
+ if line.strip():
+ clean_rows.append(line)
+
+ # Make sure that the results and summary entries
+ # have the expected lengths.
+ for measure in results:
+ # Add 6 for new lines that were removed
+ assert len(results[measure]) + len(summary) + 6 == linecount
+ # Subtract 1 for the csv header
+ assert len(results[measure]) == len(clean_rows) - 1
+
+
+def test_ipg_rh_clean_ipg_data_no_files(ipg_rh_obj):
+ """Tests that IPGResultsHandler correctly handles the case
+ when no output files exist.
+ """
+ ipg_rh_obj._output_files = []
+ clean_data = ipg_rh_obj.clean_ipg_data()
+ assert clean_data is None
+
+
+def test_ipg_rh_clean_ipg_data(ipg_rh_obj):
+ """Tests that IPGResultsHandler correctly handles cleaning
+ all known files and that the results and the merged output
+ are correct.
+ """
+ clean_data = ipg_rh_obj.clean_ipg_data()
+ clean_files = ipg_rh_obj.cleaned_files
+ merged_output_path = ipg_rh_obj.merged_output_path
+
+ # Check that the expected output exists
+ assert clean_data is not None
+ assert len(clean_files) == len(ipg_rh_obj._output_files)
+ assert os.path.exists(merged_output_path)
+
+ # Check that the merged file length and results length
+ # is correct, and that no lines were lost and no extra lines
+ # were added.
+ expected_merged_line_count = 0
+ for file in clean_files:
+ with open(file, "r") as f:
+ for count, line in enumerate(f):
+ if count == 0:
+ continue
+ if line.strip():
+ expected_merged_line_count += 1
+
+ merged_line_count = 0
+ with open(merged_output_path, "r") as f:
+ for count, line in enumerate(f):
+ if count == 0:
+ continue
+ if line.strip():
+ merged_line_count += 1
+
+ assert merged_line_count == expected_merged_line_count
+ for measure in clean_data:
+ assert len(clean_data[measure]) == merged_line_count
+
+ # Check that the clean data rows are ordered in increasing time
+ times_in_seconds = []
+ for sys_time in clean_data["System Time"]:
+ split_sys_time = sys_time.split(":")
+ hour_min_sec = ":".join(split_sys_time[:-1])
+ millis = float(split_sys_time[-1]) / 1000
+
+ timestruct = time.strptime(hour_min_sec, "%H:%M:%S")
+ times_in_seconds.append(
+ datetime.timedelta(
+ hours=timestruct.tm_hour,
+ minutes=timestruct.tm_min,
+ seconds=timestruct.tm_sec,
+ ).total_seconds()
+ + millis
+ )
+
+ for count, val in enumerate(times_in_seconds[:-1]):
+ assert times_in_seconds[count + 1] - val >= 0
+
+
+def test_ipg_rh_format_to_perfherder_with_no_results(ipg_rh_obj):
+ """Tests that formatting the data to a perfherder-like format
+ fails when clean_ipg_data was not called beforehand.
+ """
+ formatted_data = ipg_rh_obj.format_ipg_data_to_partial_perfherder(
+ 1000, ipg_rh_obj._output_file_prefix
+ )
+ assert formatted_data is None
+
+
+def test_ipg_rh_format_to_perfherder_without_cutoff(ipg_rh_obj):
+ """Tests that formatting the data to a perfherder-like format
+ works as expected.
+ """
+ ipg_rh_obj.clean_ipg_data()
+ formatted_data = ipg_rh_obj.format_ipg_data_to_partial_perfherder(
+ 1000, ipg_rh_obj._output_file_prefix
+ )
+
+ # Check that the expected entries exist
+ assert len(formatted_data.keys()) == 5
+ assert "utilization" in formatted_data and "power-usage" in formatted_data
+
+ assert (
+ formatted_data["power-usage"]["test"]
+ == ipg_rh_obj._output_file_prefix + "-cumulative"
+ )
+ assert (
+ formatted_data["utilization"]["test"]
+ == ipg_rh_obj._output_file_prefix + "-utilization"
+ )
+ assert (
+ formatted_data["frequency-gpu"]["test"]
+ == ipg_rh_obj._output_file_prefix + "-frequency-gpu"
+ )
+ assert (
+ formatted_data["frequency-cpu"]["test"]
+ == ipg_rh_obj._output_file_prefix + "-frequency-cpu"
+ )
+ assert (
+ formatted_data["power-watts"]["test"]
+ == ipg_rh_obj._output_file_prefix + "-watts"
+ )
+
+ for measure in formatted_data:
+ # Make sure that the data exists
+ assert len(formatted_data[measure]["values"]) >= 1
+
+ for valkey in formatted_data[measure]["values"]:
+ # Make sure the names were simplified
+ assert "(" not in valkey
+ assert ")" not in valkey
+
+ # Check that gpu utilization doesn't exist but cpu does
+ utilization_vals = formatted_data["utilization"]["values"]
+ assert "cpu" in utilization_vals
+ assert "gpu" not in utilization_vals
+
+ expected_fields = ["processor-cores", "processor-package", "gpu", "dram"]
+ consumption_vals = formatted_data["power-usage"]["values"]
+
+ consumption_vals_measures = list(consumption_vals.keys())
+
+ # This assertion ensures that the consumption values contain the expected
+ # fields and nothing more.
+ assert not list(set(consumption_vals_measures) - set(expected_fields))
+
+
+def test_ipg_rh_format_to_perfherder_with_cutoff(ipg_rh_obj):
+ """Tests that formatting the data to a perfherder-like format
+ works as expected.
+ """
+ ipg_rh_obj.clean_ipg_data()
+ formatted_data = ipg_rh_obj.format_ipg_data_to_partial_perfherder(
+ 2.5, ipg_rh_obj._output_file_prefix
+ )
+
+ # Check that the formatted data was cutoff at the correct point,
+ # expecting that only the first row of merged will exist.
+ utilization_vals = formatted_data["utilization"]["values"]
+ assert utilization_vals["cpu"] == 14
+
+ # Expected vals are ordered in this way: [processor, cores, dram, gpu]
+ expected_vals = [6.517, 5.847, 0.244, 0.006]
+ consumption_vals = [
+ formatted_data["power-usage"]["values"][measure]
+ for measure in formatted_data["power-usage"]["values"]
+ ]
+ assert not list(set(expected_vals) - set(consumption_vals))
+
+
+def test_ipg_rh_missingoutputfile(ipg_rh_obj):
+ """Tests that the IPGMissingOutputFileError is raised
+ when a bad file path is passed to _clean_ipg_file.
+ """
+ bad_files = ["non-existent-file"]
+ with pytest.raises(IPGMissingOutputFileError):
+ ipg_rh_obj._clean_ipg_file(bad_files[0])
+
+ ipg_rh_obj._output_files = bad_files
+ with pytest.raises(IPGMissingOutputFileError):
+ ipg_rh_obj.clean_ipg_data()
+
+
+def test_ipg_rh_emptyfile(ipg_rh_obj):
+ """Tests that the empty file error is raised when
+ a file exists, but does not contain any results in
+ it.
+ """
+ base_path = os.path.abspath(os.path.dirname(__file__)) + "/files/"
+ bad_files = [base_path + "emptyfile.txt"]
+ with pytest.raises(IPGEmptyFileError):
+ ipg_rh_obj._clean_ipg_file(bad_files[0])
+
+ ipg_rh_obj._output_files = bad_files
+ with pytest.raises(IPGEmptyFileError):
+ ipg_rh_obj.clean_ipg_data()
+
+
+def test_ipg_rh_valuetypeerrorfile(ipg_rh_obj):
+ """Tests that the IPGUnknownValueTypeError is raised
+ when a bad entry is encountered in a file that is cleaned.
+ """
+ base_path = os.path.abspath(os.path.dirname(__file__)) + "/files/"
+ bad_files = [base_path + "valueerrorfile.txt"]
+ with pytest.raises(IPGUnknownValueTypeError):
+ ipg_rh_obj._clean_ipg_file(bad_files[0])
+
+ ipg_rh_obj._output_files = bad_files
+ with pytest.raises(IPGUnknownValueTypeError):
+ ipg_rh_obj.clean_ipg_data()
+
+
+if __name__ == "__main__":
+ mozunit.main()
diff --git a/testing/mozbase/mozpower/tests/test_macintelpower.py b/testing/mozbase/mozpower/tests/test_macintelpower.py
new file mode 100644
index 0000000000..2332c94c3e
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/test_macintelpower.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+
+import time
+from unittest import mock
+
+import mozunit
+
+
+def test_macintelpower_init(macintelpower_obj):
+ """Tests that the MacIntelPower object is correctly initialized."""
+ assert macintelpower_obj.ipg_path
+ assert macintelpower_obj.ipg
+ assert macintelpower_obj._os == "darwin"
+ assert macintelpower_obj._cpu == "intel"
+
+
+def test_macintelpower_measuring(macintelpower_obj):
+ """Tests that measurement initialization and finalization works
+ for the MacIntelPower object.
+ """
+ assert not macintelpower_obj.start_time
+ assert not macintelpower_obj.ipg._running
+ assert not macintelpower_obj.ipg._output_files
+ macintelpower_obj.initialize_power_measurements()
+
+ # Check that initialization set start_time, and started the
+ # IPG measurer thread.
+
+ # Wait a bit for thread to start, then check it
+ timeout = 10
+ start = time.time()
+ while time.time() - start < timeout and not macintelpower_obj.ipg._running:
+ time.sleep(1)
+
+ assert macintelpower_obj.start_time
+ assert macintelpower_obj.ipg._running
+
+ test_data = {"power-usage": "data"}
+
+ def formatter_side_effect(*args, **kwargs):
+ return test_data
+
+ with mock.patch(
+ "mozpower.intel_power_gadget.IPGResultsHandler.clean_ipg_data"
+ ) as _:
+ with mock.patch(
+ "mozpower.intel_power_gadget.IPGResultsHandler."
+ "format_ipg_data_to_partial_perfherder"
+ ) as formatter:
+ formatter.side_effect = formatter_side_effect
+
+ macintelpower_obj.finalize_power_measurements(wait_interval=2, timeout=30)
+
+ # Check that finalization set the end_time, stopped the IPG measurement
+ # thread, added atleast one output file name, and initialized
+ # an IPGResultsHandler object
+ assert macintelpower_obj.end_time
+ assert not macintelpower_obj.ipg._running
+ assert macintelpower_obj.ipg._output_files
+ assert macintelpower_obj.ipg_results_handler
+
+ # Check that the IPGResultHandler's methods were
+ # called
+ macintelpower_obj.ipg_results_handler.clean_ipg_data.assert_called()
+ macintelpower_obj.ipg_results_handler.format_ipg_data_to_partial_perfherder.assert_called_once_with( # NOQA: E501
+ macintelpower_obj.end_time - macintelpower_obj.start_time,
+ "power-testing",
+ )
+
+ # Make sure we can get the expected perfherder data
+ # after formatting
+ assert macintelpower_obj.get_perfherder_data() == test_data
+
+
+if __name__ == "__main__":
+ mozunit.main()
diff --git a/testing/mozbase/mozpower/tests/test_mozpower.py b/testing/mozbase/mozpower/tests/test_mozpower.py
new file mode 100644
index 0000000000..fd513e836b
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/test_mozpower.py
@@ -0,0 +1,255 @@
+#!/usr/bin/env python
+
+import subprocess
+import sys
+from unittest import mock
+
+import mozunit
+import pytest
+from mozpower import MozPower
+from mozpower.mozpower import MissingProcessorInfoError, OsCpuComboMissingError
+
+
+def test_mozpower_android_init_failure():
+ """Tests that the MozPower object fails when the android
+ flag is set. Remove this test once android is implemented.
+ """
+ with pytest.raises(NotImplementedError):
+ MozPower(android=True)
+
+
+def test_mozpower_oscpu_combo_missing_error():
+ """Tests that the error OsCpuComboMissingError is raised
+ when we can't find a OS, and CPU combination (and, therefore, cannot
+ find a power measurer).
+ """
+ with mock.patch.object(
+ MozPower, "_get_os", return_value="Not-An-OS"
+ ) as _, mock.patch.object(
+ MozPower, "_get_processor_info", return_value="Not-A-Processor"
+ ) as _:
+ with pytest.raises(OsCpuComboMissingError):
+ MozPower()
+
+
+def test_mozpower_processor_info_missing_error():
+ """Tests that the error MissingProcessorInfoError is raised
+ when failures occur during processor information parsing.
+ """
+ # The builtins module name differs between python 2 and 3
+ builtins_name = "__builtin__"
+ if sys.version_info[0] == 3:
+ builtins_name = "builtins"
+
+ def os_side_effect_true(*args, **kwargs):
+ """Used as a passing side effect for os.path.exists calls."""
+ return True
+
+ def os_side_effect_false(*args, **kwargs):
+ """Used as a failing side effect for os.path.exists calls."""
+ return False
+
+ def subprocess_side_effect_fail(*args, **kwargs):
+ """Used to mock a failure in subprocess.check_output calls."""
+ raise subprocess.CalledProcessError(1, "Testing failure")
+
+ # Test failures in macos processor information parsing
+ with mock.patch.object(MozPower, "_get_os", return_value="Darwin") as _:
+
+ with mock.patch("os.path.exists") as os_mock:
+ os_mock.side_effect = os_side_effect_false
+
+ # Check that we fail properly if the processor
+ # information file doesn't exist.
+ with pytest.raises(MissingProcessorInfoError):
+ MozPower()
+
+ # Check that we fail properly when an error occurs
+ # in the subprocess call.
+ os_mock.side_effect = os_side_effect_true
+ with mock.patch("subprocess.check_output") as subprocess_mock:
+ subprocess_mock.side_effect = subprocess_side_effect_fail
+ with pytest.raises(MissingProcessorInfoError):
+ MozPower()
+
+ # Test failures in linux processor information parsing
+ with mock.patch.object(MozPower, "_get_os", return_value="Linux") as _:
+
+ with mock.patch("os.path.exists") as os_mock:
+ os_mock.side_effect = os_side_effect_false
+
+ # Check that we fail properly if the processor
+ # information file doesn't exist.
+ with pytest.raises(MissingProcessorInfoError):
+ MozPower()
+
+ # Check that we fail properly when the model cannot be found
+ # with by searching for 'model name'.
+ os_mock.side_effect = os_side_effect_true
+ with mock.patch(
+ "%s.open" % builtins_name, mock.mock_open(read_data="")
+ ) as _:
+ with pytest.raises(MissingProcessorInfoError):
+ MozPower()
+
+
+def test_mozpower_oscpu_combo(mozpower_obj):
+ """Tests that the correct class is instantiated for a given
+ OS and CPU combination (MacIntelPower in this case).
+ """
+ assert mozpower_obj.measurer.__class__.__name__ == "MacIntelPower"
+ assert (
+ mozpower_obj.measurer._os == "darwin" and mozpower_obj.measurer._cpu == "intel"
+ )
+
+
+def test_mozpower_measuring(mozpower_obj):
+ """Tests that measurers are properly called with each method."""
+ with mock.patch(
+ "mozpower.macintelpower.MacIntelPower.initialize_power_measurements"
+ ) as _, mock.patch(
+ "mozpower.macintelpower.MacIntelPower.finalize_power_measurements"
+ ) as _, mock.patch(
+ "mozpower.macintelpower.MacIntelPower.get_perfherder_data"
+ ) as _:
+ mozpower_obj.initialize_power_measurements()
+ mozpower_obj.measurer.initialize_power_measurements.assert_called()
+
+ mozpower_obj.finalize_power_measurements()
+ mozpower_obj.measurer.finalize_power_measurements.assert_called()
+
+ mozpower_obj.get_perfherder_data()
+ mozpower_obj.measurer.get_perfherder_data.assert_called()
+
+
+def test_mozpower_measuring_with_no_measurer(mozpower_obj):
+ """Tests that no errors occur when the measurer is None, and the
+ initialize, finalize, and get_perfherder_data functions are called.
+ """
+ with mock.patch(
+ "mozpower.macintelpower.MacIntelPower.initialize_power_measurements"
+ ) as _, mock.patch(
+ "mozpower.macintelpower.MacIntelPower.finalize_power_measurements"
+ ) as _, mock.patch(
+ "mozpower.macintelpower.MacIntelPower.get_perfherder_data"
+ ) as _:
+ measurer = mozpower_obj.measurer
+ mozpower_obj.measurer = None
+
+ mozpower_obj.initialize_power_measurements()
+ assert not measurer.initialize_power_measurements.called
+
+ mozpower_obj.finalize_power_measurements()
+ assert not measurer.finalize_power_measurements.called
+
+ mozpower_obj.get_perfherder_data()
+ assert not measurer.get_perfherder_data.called
+
+ mozpower_obj.get_full_perfherder_data("mozpower")
+ assert not measurer.get_perfherder_data.called
+
+
+def test_mozpower_get_full_perfherder_data(mozpower_obj):
+ """Tests that the full perfherder data blob is properly
+ produced given a partial perfherder data blob with correct
+ entries.
+ """
+ partial_perfherder = {
+ "utilization": {
+ "type": "power",
+ "test": "mozpower",
+ "unit": "%",
+ "values": {"cpu": 50, "gpu": 0},
+ },
+ "power-usage": {
+ "type": "power",
+ "test": "mozpower",
+ "unit": "mWh",
+ "values": {"cpu": 2.0, "dram": 0.1, "gpu": 4.0},
+ },
+ "frequency-cpu": {
+ "type": "power",
+ "test": "mozpower",
+ "unit": "MHz",
+ "values": {
+ "cpu-favg": 2.0,
+ "cpu-fmax": 5.0,
+ "cpu-fmin": 0.0,
+ },
+ },
+ "frequency-gpu": {
+ "type": "power",
+ "test": "mozpower",
+ "unit": "MHz",
+ "values": {"gpu-favg": 3.0, "gpu-fmax": 6.0, "gpu-fmin": 0.0},
+ },
+ }
+ utilization_vals = [0, 50]
+ power_usage_vals = [2.0, 0.1, 4.0]
+ frequency_cpu_vals = [2.0, 5.0, 0.0]
+ frequency_gpu_vals = [3.0, 6.0, 0.0]
+
+ with mock.patch("mozpower.macintelpower.MacIntelPower.get_perfherder_data") as gpd:
+ gpd.return_value = partial_perfherder
+
+ full_perfherder = mozpower_obj.get_full_perfherder_data("mozpower")
+ assert full_perfherder["framework"]["name"] == "mozpower"
+ assert len(full_perfherder["suites"]) == 4
+
+ # Check that each of the two suites were created correctly.
+ suites = full_perfherder["suites"]
+ for suite in suites:
+ assert "subtests" in suite
+
+ assert suite["type"] == "power"
+ assert suite["alertThreshold"] == 2.0
+ assert suite["lowerIsBetter"]
+
+ all_vals = []
+ for subtest in suite["subtests"]:
+ assert "value" in subtest
+
+ # Check that the subtest names were created correctly
+ if "utilization" in suite["name"]:
+ assert "utilization" in subtest["name"]
+ elif "power-usage" in suite["name"]:
+ assert "power-usage" in subtest["name"]
+ elif "frequency-cpu" in suite["name"]:
+ assert "frequency-cpu" in subtest["name"]
+ elif "frequency-gpu" in suite["name"]:
+ assert "frequency-gpu" in subtest["name"]
+ else:
+ assert False, "Unknown subtest name %s" % subtest["name"]
+
+ all_vals.append(subtest["value"])
+
+ if "utilization" in suite["name"]:
+ assert len(all_vals) == 2
+ assert suite["unit"] == "%"
+ assert suite["name"] == "mozpower-utilization"
+ assert not list(set(all_vals) - set(utilization_vals))
+ assert suite["value"] == float(25)
+ elif "power-usage" in suite["name"]:
+ assert len(all_vals) == 3
+ assert suite["unit"] == "mWh"
+ assert suite["name"] == "mozpower-power-usage"
+ assert not list(set(all_vals) - set(power_usage_vals))
+ assert suite["value"] == float(6.1)
+ elif "frequency-cpu" in suite["name"]:
+ assert len(all_vals) == 3
+ assert suite["unit"] == "MHz"
+ assert suite["name"] == "mozpower-frequency-cpu"
+ assert not list(set(all_vals) - set(frequency_cpu_vals))
+ assert suite["value"] == float(2.0)
+ elif "frequency-gpu" in suite["name"]:
+ assert len(all_vals) == 3
+ assert suite["unit"] == "MHz"
+ assert suite["name"] == "mozpower-frequency-gpu"
+ assert not list(set(all_vals) - set(frequency_gpu_vals))
+ assert suite["value"] == float(3.0)
+ else:
+ assert False, "Unknown suite name %s" % suite["name"]
+
+
+if __name__ == "__main__":
+ mozunit.main()
diff --git a/testing/mozbase/mozpower/tests/test_powerbase.py b/testing/mozbase/mozpower/tests/test_powerbase.py
new file mode 100644
index 0000000000..46de941457
--- /dev/null
+++ b/testing/mozbase/mozpower/tests/test_powerbase.py
@@ -0,0 +1,91 @@
+#!/usr/bin/env python
+
+from unittest import mock
+
+import mozunit
+import pytest
+from mozpower.powerbase import (
+ IPGExecutableMissingError,
+ PlatformUnsupportedError,
+ PowerBase,
+)
+
+
+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()