• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1#!/usr/bin/env python3
2#
3#   Copyright 2019 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the 'License');
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an 'AS IS' BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17import os
18import statistics
19import unittest
20from unittest import mock
21from unittest.mock import patch
22
23from acts.controllers import power_metrics
24from acts.controllers.power_metrics import CURRENT
25from acts.controllers.power_metrics import END_TIMESTAMP
26from acts.controllers.power_metrics import HOUR
27from acts.controllers.power_metrics import MILLIAMP
28from acts.controllers.power_metrics import MINUTE
29from acts.controllers.power_metrics import Metric
30from acts.controllers.power_metrics import PowerMetrics
31from acts.controllers.power_metrics import START_TIMESTAMP
32from acts.controllers.power_metrics import TIME
33from acts.controllers.power_metrics import WATT
34
35FAKE_UNIT_TYPE = 'fake_unit'
36FAKE_UNIT = 'F'
37
38
39class MeasurementTest(unittest.TestCase):
40    """Unit tests for the Measurement class."""
41
42    def test_init_with_valid_unit_type(self):
43        """Test that a Measurement is properly initialized given a valid unit
44        type.
45        """
46        measurement = Metric(2, CURRENT, MILLIAMP)
47        self.assertEqual(measurement.value, 2)
48        self.assertEqual(measurement.unit, MILLIAMP)
49
50    def test_init_with_invalid_unit_type(self):
51        """Test that __init__ raises an error if given an invalid unit type."""
52        with self.assertRaisesRegex(TypeError, 'valid unit type'):
53            measurement = Metric(2, FAKE_UNIT_TYPE, FAKE_UNIT)
54
55    def test_unit_conversion(self):
56        """Test that to_unit correctly converts value and unit."""
57        ratio = 1000
58        current_amps = Metric.amps(15)
59        current_milliamps = current_amps.to_unit(MILLIAMP)
60        self.assertEqual(current_milliamps.value / current_amps.value, ratio)
61
62    def test_unit_conversion_with_wrong_type(self):
63        """Test that to_unit raises and error if incompatible unit type is
64        specified.
65        """
66        current_amps = Metric.amps(3.4)
67        with self.assertRaisesRegex(TypeError, 'Incompatible units'):
68            power_watts = current_amps.to_unit(WATT)
69
70    def test_comparison_operators(self):
71        """Test that the comparison operators work as intended."""
72        # time_a == time_b < time_c
73        time_a = Metric.seconds(120)
74        time_b = Metric(2, TIME, MINUTE)
75        time_c = Metric(0.1, TIME, HOUR)
76
77        self.assertEqual(time_a, time_b)
78        self.assertEqual(time_b, time_a)
79        self.assertLessEqual(time_a, time_b)
80        self.assertGreaterEqual(time_a, time_b)
81
82        self.assertNotEqual(time_a, time_c)
83        self.assertNotEqual(time_c, time_a)
84        self.assertLess(time_a, time_c)
85        self.assertLessEqual(time_a, time_c)
86        self.assertGreater(time_c, time_a)
87        self.assertGreaterEqual(time_c, time_a)
88
89    def test_arithmetic_operators(self):
90        """Test that the addition and subtraction operators work as intended"""
91        time_a = Metric(3, TIME, HOUR)
92        time_b = Metric(90, TIME, MINUTE)
93
94        sum_ = time_a + time_b
95        self.assertEqual(sum_.value, 4.5)
96        self.assertEqual(sum_.unit, HOUR)
97
98        sum_reversed = time_b + time_a
99        self.assertEqual(sum_reversed.value, 270)
100        self.assertEqual(sum_reversed.unit, MINUTE)
101
102        diff = time_a - time_b
103        self.assertEqual(diff.value, 1.5)
104        self.assertEqual(diff.unit, HOUR)
105
106        diff_reversed = time_b - time_a
107        self.assertEqual(diff_reversed.value, -90)
108        self.assertEqual(diff_reversed.unit, MINUTE)
109
110
111class PowerMetricsTest(unittest.TestCase):
112    """Unit tests for the PowerMetrics class."""
113
114    SAMPLES = [0.13, 0.95, 0.32, 4.84, 2.48, 4.11, 4.85, 4.88, 4.22, 2.2]
115    RAW_DATA = list(zip(range(10), SAMPLES))
116    VOLTAGE = 4.2
117
118    def setUp(self):
119        self.power_metrics = PowerMetrics(self.VOLTAGE)
120
121    def test_import_raw_data(self):
122        """Test that power metrics can be loaded from file. Simply ensure that
123        the number of samples is correct."""
124
125        imported_data = power_metrics.import_raw_data(
126            os.path.join(os.path.dirname(__file__),
127                         'data/sample_monsoon_data')
128        )
129
130        count = 0
131        for _, __ in imported_data:
132            count = count + 1
133        self.assertEqual(count, 10)
134
135    @patch('acts.controllers.power_metrics.PowerMetrics')
136    def test_split_by_test_with_timestamps(self, mock_power_metric_type):
137        """Test that given test timestamps, a power metric is generated from
138        a subset of samples corresponding to the test."""
139        timestamps = {'sample_test': {START_TIMESTAMP: 3500,
140                                      END_TIMESTAMP: 8500}}
141
142        mock_power_metric = mock.Mock()
143        mock_power_metric_type.side_effect = lambda v: mock_power_metric
144        metrics = power_metrics.generate_test_metrics(self.RAW_DATA,
145                                                      timestamps=timestamps,
146                                                      voltage=self.VOLTAGE)
147
148        self.assertEqual(mock_power_metric.update_metrics.call_count, 5)
149
150    def test_numeric_metrics(self):
151        """Test that the numeric metrics have correct values."""
152        timestamps = {'sample_test': {START_TIMESTAMP: 0,
153                                      END_TIMESTAMP: 10000}}
154        metrics = power_metrics.generate_test_metrics(self.RAW_DATA,
155                                                      timestamps=timestamps,
156                                                      voltage=self.VOLTAGE)
157        metrics_as_dic = {m.name: m for m in metrics['sample_test']}
158        self.assertAlmostEqual(metrics_as_dic['avg_current'].value,
159                               statistics.mean(self.SAMPLES) * 1000)
160        self.assertAlmostEqual(metrics_as_dic['max_current'].value,
161                               max(self.SAMPLES) * 1000)
162        self.assertAlmostEqual(metrics_as_dic['min_current'].value,
163                               min(self.SAMPLES) * 1000)
164        self.assertAlmostEqual(
165            metrics_as_dic['stdev_current'].value,
166            statistics.stdev(self.SAMPLES) * 1000)
167        self.assertAlmostEqual(
168            self.power_metrics.avg_power.value,
169            self.power_metrics.avg_current.value * self.VOLTAGE)
170
171
172if __name__ == '__main__':
173    unittest.main()
174