blob: c6261247d5eec8e85f51df3416313fb433ca3183 [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 unittest
from acts import signals
from acts.controllers import power_metrics
from acts.test_utils.instrumentation import instrumentation_proto_parser as parser
from acts.test_utils.instrumentation.config_wrapper import ConfigWrapper
from acts.test_utils.instrumentation.power.instrumentation_power_test import ACCEPTANCE_THRESHOLD
from acts.test_utils.instrumentation.power.instrumentation_power_test import InstrumentationPowerTest
import mock
# avg: 2.214, stdev: 1.358, max: 4.78, min: 0.61
AMPS = [1.64, 2.98, 1.72, 3.45, 1.31, 4.78, 3.43, 0.61, 1.19, 1.03]
RAW_DATA = list(zip(range(10), AMPS))
# timestamps that cover all samples
TIMESTAMP_LIMITS = {parser.START_TIMESTAMP: 0,
parser.END_TIMESTAMP: 10_000}
TIMESTAMPS = {'instrTest1': TIMESTAMP_LIMITS,
'instrTest2': TIMESTAMP_LIMITS}
METRICS = power_metrics.generate_test_metrics(
raw_data=RAW_DATA, voltage=4.2, timestamps=TIMESTAMPS)
class MockInstrumentationPowerTest(InstrumentationPowerTest):
"""Mock test class to initialize required attributes."""
def __init__(self):
self.log = mock.Mock()
self.metric_logger = mock.Mock()
self.current_test_name = 'test_case'
self._test_options = ConfigWrapper({ACCEPTANCE_THRESHOLD: {}})
def set_criteria(self, criteria):
"""Set the acceptance criteria for metrics validation."""
self._test_options = ConfigWrapper(
{ACCEPTANCE_THRESHOLD: criteria})
class InstrumentationPowerTestTest(unittest.TestCase):
"""Unit tests for InstrumentationPowerTest."""
def setUp(self):
self.instrumentation_power_test = MockInstrumentationPowerTest()
def test_validate_power_results_lower_and_upper_limit_accept(self):
"""Test that validate_power_results accept passing measurements
given a lower and upper limit.
"""
criteria_accept = {
'instrTest1': {
'avg_current': {
'unit_type': 'current',
'unit': 'A',
'lower_limit': 1.5,
'upper_limit': 2.5
},
'max_current': {
'unit_type': 'current',
'unit': 'mA',
'upper_limit': 5000
}
}
}
self.instrumentation_power_test.set_criteria(criteria_accept)
with self.assertRaises(signals.TestPass):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1')
def test_validate_power_results_lower_and_upper_limit_reject(self):
"""Test that validate_power_results reject failing measurements
given a lower and upper limit.
"""
criteria_reject = {
'instrTest1': {
'avg_current': {
'unit_type': 'current',
'unit': 'A',
'lower_limit': 1.5,
'upper_limit': 2
},
'max_current': {
'unit_type': 'current',
'unit': 'mA',
'upper_limit': 4000
}
}
}
self.instrumentation_power_test.set_criteria(criteria_reject)
with self.assertRaises(signals.TestFailure):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1')
def test_validate_power_results_expected_value_and_deviation_accept(self):
"""Test that validate_power_results accept passing measurements
given an expected value and percent deviation.
"""
criteria_accept = {
'instrTest1': {
'stdev_current': {
'unit_type': 'current',
'unit': 'A',
'expected_value': 1.5,
'percent_deviation': 20
}
}
}
self.instrumentation_power_test.set_criteria(criteria_accept)
with self.assertRaises(signals.TestPass):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1')
def test_validate_power_results_expected_value_and_deviation_reject(self):
"""Test that validate_power_results reject failing measurements
given an expected value and percent deviation.
"""
criteria_reject = {
'instrTest1': {
'min_current': {
'unit_type': 'current',
'unit': 'mA',
'expected_value': 500,
'percent_deviation': 10
}
}
}
self.instrumentation_power_test.set_criteria(criteria_reject)
with self.assertRaises(signals.TestFailure):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1')
def test_validate_power_results_no_such_test(self):
"""Test that validate_power_results skip validation if there are no
criteria matching the specified instrumentation test name.
"""
criteria_wrong_test = {
'instrTest2': {
'min_current': {
'unit_type': 'current',
'unit': 'A',
'expected_value': 2,
'percent_deviation': 20
}
}
}
self.instrumentation_power_test.set_criteria(criteria_wrong_test)
with self.assertRaises(signals.TestPass):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1')
def test_validate_power_results_no_such_metric(self):
"""Test that validate_power_results skip validation if the specified
metric is invalid.
"""
criteria_invalid_metric = {
'instrTest1': {
'no_such_metric': {
'unit_type': 'current',
'unit': 'A',
'lower_limit': 5,
'upper_limit': 7
}
}
}
self.instrumentation_power_test.set_criteria(criteria_invalid_metric)
with self.assertRaises(signals.TestPass):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1')
def test_validate_power_results_criteria_missing_params(self):
"""Test that validate_power_results skip validation if the specified
metric has missing parameters.
"""
criteria_missing_params = {
'instrTest1': {
'avg_current': {
'unit': 'A',
'lower_limit': 1,
'upper_limit': 2
}
}
}
self.instrumentation_power_test.set_criteria(criteria_missing_params)
with self.assertRaises(signals.TestPass):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1')
def test_validate_power_results_pass_if_all_tests_accept(self):
"""Test that validate_power_results succeeds if it accepts the results
of all instrumentation tests.
"""
criteria_multi_test_accept = {
'instrTest1': {
'avg_current': {
'unit_type': 'current',
'unit': 'A',
'lower_limit': 2
},
'stdev_current': {
'unit_type': 'current',
'unit': 'mA',
'expected_value': 1250,
'percent_deviation': 30
}
},
'instrTest2': {
'max_current': {
'unit_type': 'current',
'unit': 'A',
'upper_limit': 5
},
'avg_power': {
'unit_type': 'power',
'unit': 'W',
'upper_limit': 10
}
}
}
self.instrumentation_power_test.set_criteria(criteria_multi_test_accept)
with self.assertRaises(signals.TestPass):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1',
'instrTest2')
def test_validate_power_results_fail_if_at_least_one_test_rejects(self):
"""Test that validate_power_results fails if it rejects the results
of at least one instrumentation test.
"""
criteria_multi_test_reject = {
'instrTest1': {
'avg_current': {
'unit_type': 'current',
'unit': 'A',
'lower_limit': 2
},
'stdev_current': {
'unit_type': 'current',
'unit': 'mA',
'expected_value': 1250,
'percent_deviation': 30
}
},
'instrTest2': {
'max_current': {
'unit_type': 'current',
'unit': 'A',
'upper_limit': 5
},
'avg_power': {
'unit_type': 'power',
'unit': 'W',
'upper_limit': 8
}
}
}
self.instrumentation_power_test.set_criteria(criteria_multi_test_reject)
with self.assertRaises(signals.TestFailure):
self.instrumentation_power_test.validate_metrics(METRICS,
'instrTest1',
'instrTest2')
if __name__ == '__main__':
unittest.main()