| #!/usr/bin/env python3 |
| # |
| # Copyright 2019 - The Android Open Source Project |
| # |
| # Licensed under the Apache License, Version 2.0 (the 'License'); |
| # you may not use this file except in compliance with the License. |
| # You may obtain a copy of the License at |
| # |
| # http://www.apache.org/licenses/LICENSE-2.0 |
| # |
| # Unless required by applicable law or agreed to in writing, software |
| # distributed under the License is distributed on an 'AS IS' BASIS, |
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| # See the License for the specific language governing permissions and |
| # limitations under the License. |
| |
| import os |
| import statistics |
| import unittest |
| from unittest import mock |
| from unittest.mock import patch |
| |
| from acts.controllers import power_metrics |
| from acts.controllers.power_metrics import CURRENT |
| from acts.controllers.power_metrics import END_TIMESTAMP |
| from acts.controllers.power_metrics import HOUR |
| from acts.controllers.power_metrics import MILLIAMP |
| from acts.controllers.power_metrics import MINUTE |
| from acts.controllers.power_metrics import Metric |
| from acts.controllers.power_metrics import PowerMetrics |
| from acts.controllers.power_metrics import START_TIMESTAMP |
| from acts.controllers.power_metrics import TIME |
| from acts.controllers.power_metrics import WATT |
| |
| FAKE_UNIT_TYPE = 'fake_unit' |
| FAKE_UNIT = 'F' |
| |
| |
| class MeasurementTest(unittest.TestCase): |
| """Unit tests for the Measurement class.""" |
| |
| def test_init_with_valid_unit_type(self): |
| """Test that a Measurement is properly initialized given a valid unit |
| type. |
| """ |
| measurement = Metric(2, CURRENT, MILLIAMP) |
| self.assertEqual(measurement.value, 2) |
| self.assertEqual(measurement.unit, MILLIAMP) |
| |
| def test_init_with_invalid_unit_type(self): |
| """Test that __init__ raises an error if given an invalid unit type.""" |
| with self.assertRaisesRegex(TypeError, 'valid unit type'): |
| measurement = Metric(2, FAKE_UNIT_TYPE, FAKE_UNIT) |
| |
| def test_unit_conversion(self): |
| """Test that to_unit correctly converts value and unit.""" |
| ratio = 1000 |
| current_amps = Metric.amps(15) |
| current_milliamps = current_amps.to_unit(MILLIAMP) |
| self.assertEqual(current_milliamps.value / current_amps.value, ratio) |
| |
| def test_unit_conversion_with_wrong_type(self): |
| """Test that to_unit raises and error if incompatible unit type is |
| specified. |
| """ |
| current_amps = Metric.amps(3.4) |
| with self.assertRaisesRegex(TypeError, 'Incompatible units'): |
| power_watts = current_amps.to_unit(WATT) |
| |
| def test_comparison_operators(self): |
| """Test that the comparison operators work as intended.""" |
| # time_a == time_b < time_c |
| time_a = Metric.seconds(120) |
| time_b = Metric(2, TIME, MINUTE) |
| time_c = Metric(0.1, TIME, HOUR) |
| |
| self.assertEqual(time_a, time_b) |
| self.assertEqual(time_b, time_a) |
| self.assertLessEqual(time_a, time_b) |
| self.assertGreaterEqual(time_a, time_b) |
| |
| self.assertNotEqual(time_a, time_c) |
| self.assertNotEqual(time_c, time_a) |
| self.assertLess(time_a, time_c) |
| self.assertLessEqual(time_a, time_c) |
| self.assertGreater(time_c, time_a) |
| self.assertGreaterEqual(time_c, time_a) |
| |
| def test_arithmetic_operators(self): |
| """Test that the addition and subtraction operators work as intended""" |
| time_a = Metric(3, TIME, HOUR) |
| time_b = Metric(90, TIME, MINUTE) |
| |
| sum_ = time_a + time_b |
| self.assertEqual(sum_.value, 4.5) |
| self.assertEqual(sum_.unit, HOUR) |
| |
| sum_reversed = time_b + time_a |
| self.assertEqual(sum_reversed.value, 270) |
| self.assertEqual(sum_reversed.unit, MINUTE) |
| |
| diff = time_a - time_b |
| self.assertEqual(diff.value, 1.5) |
| self.assertEqual(diff.unit, HOUR) |
| |
| diff_reversed = time_b - time_a |
| self.assertEqual(diff_reversed.value, -90) |
| self.assertEqual(diff_reversed.unit, MINUTE) |
| |
| |
| class PowerMetricsTest(unittest.TestCase): |
| """Unit tests for the PowerMetrics class.""" |
| |
| SAMPLES = [0.13, 0.95, 0.32, 4.84, 2.48, 4.11, 4.85, 4.88, 4.22, 2.2] |
| RAW_DATA = list(zip(range(10), SAMPLES)) |
| VOLTAGE = 4.2 |
| |
| def setUp(self): |
| self.power_metrics = PowerMetrics(self.VOLTAGE) |
| |
| def test_import_raw_data(self): |
| """Test that power metrics can be loaded from file. Simply ensure that |
| the number of samples is correct.""" |
| |
| imported_data = power_metrics.import_raw_data( |
| os.path.join(os.path.dirname(__file__), |
| 'data/sample_monsoon_data') |
| ) |
| |
| count = 0 |
| for _, __ in imported_data: |
| count = count + 1 |
| self.assertEqual(count, 10) |
| |
| @patch('acts.controllers.power_metrics.PowerMetrics') |
| def test_split_by_test_with_timestamps(self, mock_power_metric_type): |
| """Test that given test timestamps, a power metric is generated from |
| a subset of samples corresponding to the test.""" |
| timestamps = {'sample_test': {START_TIMESTAMP: 3500, |
| END_TIMESTAMP: 8500}} |
| |
| mock_power_metric = mock.Mock() |
| mock_power_metric_type.side_effect = lambda v: mock_power_metric |
| metrics = power_metrics.generate_test_metrics(self.RAW_DATA, |
| timestamps=timestamps, |
| voltage=self.VOLTAGE) |
| |
| self.assertEqual(mock_power_metric.update_metrics.call_count, 5) |
| |
| def test_numeric_metrics(self): |
| """Test that the numeric metrics have correct values.""" |
| timestamps = {'sample_test': {START_TIMESTAMP: 0, |
| END_TIMESTAMP: 10000}} |
| metrics = power_metrics.generate_test_metrics(self.RAW_DATA, |
| timestamps=timestamps, |
| voltage=self.VOLTAGE) |
| metrics_as_dic = {m.name: m for m in metrics['sample_test']} |
| self.assertAlmostEqual(metrics_as_dic['avg_current'].value, |
| statistics.mean(self.SAMPLES) * 1000) |
| self.assertAlmostEqual(metrics_as_dic['max_current'].value, |
| max(self.SAMPLES) * 1000) |
| self.assertAlmostEqual(metrics_as_dic['min_current'].value, |
| min(self.SAMPLES) * 1000) |
| self.assertAlmostEqual( |
| metrics_as_dic['stdev_current'].value, |
| statistics.stdev(self.SAMPLES) * 1000) |
| self.assertAlmostEqual( |
| self.power_metrics.avg_power.value, |
| self.power_metrics.avg_current.value * self.VOLTAGE) |
| |
| |
| if __name__ == '__main__': |
| unittest.main() |