1#    Copyright 2015-2016 ARM Limited
2#
3# Licensed under the Apache License, Version 2.0 (the "License");
4# you may not use this file except in compliance with the License.
5# You may obtain a copy of the License at
6#
7#     http://www.apache.org/licenses/LICENSE-2.0
8#
9# Unless required by applicable law or agreed to in writing, software
10# distributed under the License is distributed on an "AS IS" BASIS,
11# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12# See the License for the specific language governing permissions and
13# limitations under the License.
14#
15
16"""
17An example file for usage of Analyzer for thermal assertions
18"""
19from bart.common.Analyzer import Analyzer
20from trappy.stats.Topology import Topology
21import unittest
22import trappy
23
24
25class TestThermal(unittest.TestCase):
26
27    @classmethod
28    def setUpClass(cls):
29        # We can run a workload invocation script here
30        # Which then copies the required traces for analysis to
31        # the host.
32        trace_file = "update_a_trace_path_here"
33        ftrace = trappy.FTrace(trace_file, "test_run")
34
35        # Define the parameters that you intend to use in the grammar
36        config = {}
37        config["THERMAL"] = trappy.thermal.Thermal
38        config["OUT"] = trappy.cpu_power.CpuOutPower
39        config["IN"] = trappy.cpu_power.CpuInPower
40        config["PID"] = trappy.pid_controller.PIDController
41        config["GOVERNOR"] = trappy.thermal.ThermalGovernor
42        config["CONTROL_TEMP"] = 77000
43        config["SUSTAINABLE_POWER"] = 2500
44        config["EXPECTED_TEMP_QRT"] = 95
45        config["EXPECTED_STD_PCT"] = 5
46
47        # Define a Topology
48        cls.BIG = '000000f0'
49        cls.LITTLE = '0000000f'
50        cls.tz = 0
51        cls.analyzer = Analyzer(ftrace, config)
52
53    def test_temperature_quartile(self):
54        """Assert Temperature quartile"""
55
56        self.assertTrue(self.analyzer.assertStatement(
57            "numpy.percentile(THERMAL:temp, EXPECTED_TEMP_QRT) < (CONTROL_TEMP + 5000)"))
58
59    def test_average_temperature(self):
60        """Assert Average temperature"""
61
62        self.assertTrue(self.analyzer.assertStatement(
63            "numpy.mean(THERMAL:temp) < CONTROL_TEMP", select=self.tz))
64
65    def test_temp_stdev(self):
66        """Assert StdDev(temp) as % of mean"""
67
68        self.assertTrue(self.analyzer.assertStatement(
69            "(numpy.std(THERMAL:temp) * 100.0) / numpy.mean(THERMAL:temp)\
70             < EXPECTED_STD_PCT", select=self.tz))
71
72    def test_zero_load_input_power(self):
73        """Test power demand when load is zero"""
74
75        zero_load_power_big = self.analyzer.getStatement("((IN:load0 + IN:load1 + IN:load2 + IN:load3) == 0) \
76                                                     & (IN:dynamic_power > 0)", reference=True, select=self.BIG)
77        self.assertEquals(len(zero_load_power_big), 0)
78
79        zero_load_power_little = self.analyzer.getStatement("((IN:load0 + IN:load1 + IN:load2 + IN:load3) == 0) \
80                                                     & (IN:dynamic_power > 0)", reference=True, select=self.LITTLE)
81        self.assertEquals(len(zero_load_power_little), 0)
82
83    def test_sustainable_power(self):
84        """temp > control_temp, allocated_power < sustainable_power"""
85
86        self.analyzer.getStatement("(GOVERNOR:current_temperature > CONTROL_TEMP) &\
87            (PID:output > SUSTAINABLE_POWER)", reference=True, select=0)
88