1a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)# Copyright 2014 The Chromium Authors. All rights reserved.
2a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)# Use of this source code is governed by a BSD-style license that can be
3a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)# found in the LICENSE file.
4a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
5a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import logging
6a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import os
7a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)import unittest
8a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
9116680a4aac90f2aa7413d9095a592090648e557Ben Murdochfrom telemetry import benchmark
10a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from telemetry.core import util
11a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from telemetry.core.platform import mac_platform_backend
12cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)from telemetry.core.platform import platform_backend
13a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)from telemetry.core.platform.power_monitor import powermetrics_power_monitor
14a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
15a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
16a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)class PowerMetricsPowerMonitorTest(unittest.TestCase):
17116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  @benchmark.Enabled('mac')
18a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def testCanMonitorPowerUsage(self):
19a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    backend = mac_platform_backend.MacPlatformBackend()
20a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    power_monitor = powermetrics_power_monitor.PowerMetricsPowerMonitor(backend)
21a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    mavericks_or_later = (
22cedac228d2dd51db4b79ea1e72c7f249408ee061Torne (Richard Coles)        backend.GetOSVersionName() >= platform_backend.MAVERICKS)
23a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    # Should always be able to monitor power usage on OS Version >= 10.9 .
24c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    self.assertEqual(power_monitor.CanMonitorPower(), mavericks_or_later,
25a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        "Error checking powermetrics availability: '%s'" % '|'.join(os.uname()))
26a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
27116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  @benchmark.Enabled('mac')
28effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch  def testParseEmptyPowerMetricsOutput(self):
29effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    # Important to handle zero length powermetrics outout - crbug.com/353250 .
30effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch    self.assertIsNone(powermetrics_power_monitor.PowerMetricsPowerMonitor.
31effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch        ParsePowerMetricsOutput(''))
32effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch
33116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch  @benchmark.Enabled('mac')
34a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)  def testParsePowerMetricsOutput(self):
35a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    def getOutput(output_file):
365c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      test_data_path = os.path.join(util.GetUnittestDataDir(), output_file)
375c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu      with open(test_data_path, 'r') as f:
385c02ac1a9c1b504631c0a3d2b6e737b5d738bae1Bo Liu        process_output = f.read()
39a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return (powermetrics_power_monitor.PowerMetricsPowerMonitor.
40a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)          ParsePowerMetricsOutput(process_output))
41a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
42a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    power_monitor = powermetrics_power_monitor.PowerMetricsPowerMonitor(
43a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)        mac_platform_backend.MacPlatformBackend())
44c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch    if not power_monitor.CanMonitorPower():
45a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      logging.warning('Test not supported on this platform.')
46a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      return
47a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
48116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    # Not supported on Mac at this time.
49116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch    self.assertFalse(power_monitor.CanMeasurePerApplicationPower())
50116680a4aac90f2aa7413d9095a592090648e557Ben Murdoch
51a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    # Supported hardware reports power samples and energy consumption.
52a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result = getOutput('powermetrics_output.output')
53a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
54a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self.assertTrue(result['energy_consumption_mwh'] > 0)
55a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
56a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    # Verify that all component entries exist in output.
57a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    component_utilization = result['component_utilization']
58a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    for k in ['whole_package', 'gpu'] + ['cpu%d' % x for x in range(8)]:
59c5cede9ae108bb15f6b7a8aea21c7e1fefa2834cBen Murdoch      self.assertTrue(component_utilization[k]['average_frequency_hz'] > 0)
60a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)      self.assertTrue(component_utilization[k]['idle_percent'] > 0)
61a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)
62a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    # Unsupported hardware doesn't.
63a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    result = getOutput('powermetrics_output_unsupported_hardware.output')
64a1401311d1ab56c4ed0a474bd38c108f75cb0cd9Torne (Richard Coles)    self.assertNotIn('energy_consumption_mwh', result)
65