blob: 1533998aa46db92e4d4a76c5f7ae15ba779e3527 [file] [log] [blame]
#!/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()