1# Copyright (c) 2013 The Chromium OS Authors. All rights reserved. 2# Use of this source code is governed by a BSD-style license that can be 3# found in the LICENSE file. 4 5"""This module contains unit tests for firmware_summary module.""" 6 7 8import os 9import unittest 10 11import common_unittest_utils 12 13from firmware_constants import VAL 14from firmware_summary import FirmwareSummary 15 16 17# Define the relative segment weights of a validator. 18segment_weights = {VAL.BEGIN: 0.15, 19 VAL.MIDDLE: 0.7, 20 VAL.END: 0.15, 21 VAL.BOTH_ENDS: 0.15 + 0.15, 22 VAL.WHOLE: 0.15 + 0.7 + 0.15} 23 24# Define the validator score weights 25weight_rare = 1 26weight_common = 2 27weight_critical = 3 28validator_weights = {'CountPacketsValidator': weight_common, 29 'CountTrackingIDFatFingerValidator': weight_rare, 30 'CountTrackingIDNormalFingerValidator': weight_critical, 31 'DrumrollValidator': weight_rare, 32 'LinearityFatFingerValidator': weight_rare, 33 'LinearityNormalFingerValidator': weight_common, 34 'NoGapValidator': weight_common, 35 'NoLevelJumpValidator': weight_rare, 36 'NoReversedMotionValidator': weight_common, 37 'PhysicalClickValidator': weight_critical, 38 'PinchValidator': weight_common, 39 'RangeValidator': weight_common, 40 'ReportRateValidator': weight_common, 41 'StationaryFingerValidator': weight_common, 42 'StationaryTapValidator': weight_common} 43 44 45class FirmwareSummaryTest(unittest.TestCase): 46 """A base class for FirwareSummary unit tests.""" 47 @classmethod 48 def setUpClass(cls): 49 test_dir = os.path.join(os.getcwd(), 'tests') 50 log_dir = os.path.join(test_dir, 'logs', cls.log_category) 51 summary = FirmwareSummary(log_dir=log_dir, 52 validator_weights=validator_weights, 53 segment_weights=segment_weights) 54 cls.slog = summary.slog 55 cls._round_digits = 8 56 57 def _get_score(self, fw=None, gesture=None, validator=None): 58 """Score = sum / count, rounded to the 4th digit.""" 59 result= self.slog.get_result(fw=fw, gesture=gesture, 60 validators=validator) 61 average = result.stat_scores.average 62 return round(average, self._round_digits) 63 64 65class FirmwareSummaryLumpyTest(FirmwareSummaryTest): 66 """Unit tests for firmware_summary.FirmwareSummary class using Lumpy logs. 67 68 Tests were conducted with both fw 11.23 and 11.26, and in combination of 69 single and multiple iterations. 70 """ 71 @classmethod 72 def setUpClass(cls): 73 cls.log_category = 'lumpy' 74 cls.fws = ['fw_11.23', 'fw_11.27'] 75 super(FirmwareSummaryLumpyTest, cls).setUpClass() 76 77 def _test_by_gesture(self, validator, expected_scores): 78 for fw, fw_expected_scores in expected_scores.items(): 79 for gesture, expected_score in fw_expected_scores.items(): 80 actual_score = self._get_score(fw=fw, 81 gesture=gesture, 82 validator=validator) 83 self.assertAlmostEqual(actual_score, expected_score) 84 85 def test_by_gesture_CountTrackingIDNormalFingerValidator(self): 86 validator = 'CountTrackingIDNormalFingerValidator' 87 expected_scores = { 88 'fw_11.23': { 89 'one_finger_tracking': 1.0, 90 'two_finger_tracking': 1.0, 91 }, 92 'fw_11.27': { 93 'one_finger_tracking': 1.0, 94 'two_finger_tracking': 1.0, 95 } 96 } 97 self._test_by_gesture(validator, expected_scores) 98 99 def test_by_gesture_CountTrackingIDFatFingerValidator(self): 100 validator = 'CountTrackingIDFatFingerValidator' 101 expected_scores = { 102 'fw_11.23': {'drag_edge_thumb': 0.0,}, 103 'fw_11.27': {'drag_edge_thumb': 0.5,} 104 } 105 self._test_by_gesture(validator, expected_scores) 106 107 def test_by_gesture_DrumrollValidator(self): 108 validator = 'DrumrollValidator' 109 expected_scores = { 110 'fw_11.23': { 111 'drumroll': 0.75, 112 }, 113 'fw_11.27': { 114 'drumroll': 0.66666667, 115 } 116 } 117 self._test_by_gesture(validator, expected_scores) 118 119 def test_by_gesture_LinearityMiddleValidator(self): 120 validator = 'LinearityNormalFinger(Middle)Validator' 121 expected_scores = { 122 'fw_11.23': { 123 'one_finger_to_edge': 0.58086671000000001, 124 'one_finger_tracking': 0.42046572999999998, 125 'two_finger_tracking': 0.60548126000000002, 126 }, 127 'fw_11.27': { 128 'one_finger_to_edge': 0.36506074999999999, 129 'one_finger_tracking': 0.73313022999999999, 130 'two_finger_tracking': 0.70906895999999997, 131 } 132 } 133 self._test_by_gesture(validator, expected_scores) 134 135 def test_by_gesture_NoGapValidator(self): 136 validator = 'NoGapValidator' 137 expected_scores = { 138 'fw_11.23': { 139 'one_finger_to_edge': 0.16022362, 140 'one_finger_tracking': 0.11006574, 141 'two_finger_tracking': 0.09455679, 142 }, 143 'fw_11.27': { 144 'one_finger_to_edge': 0.00000000, 145 'one_finger_tracking': 0.86488696, 146 'two_finger_tracking': 0.76206434, 147 } 148 } 149 self._test_by_gesture(validator, expected_scores) 150 151 def test_by_gesture_PhysicalClickValidator(self): 152 validator = 'PhysicalClickValidator' 153 expected_scores = { 154 'fw_11.23': { 155 'one_finger_physical_click': 0.875, 156 'two_fingers_physical_click': 0.25, 157 }, 158 'fw_11.27': { 159 'one_finger_physical_click': 1.0, 160 'two_fingers_physical_click': 1.0, 161 } 162 } 163 self._test_by_gesture(validator, expected_scores) 164 165 def test_by_gesture_StationaryTapValidator(self): 166 validator = 'StationaryTapValidator' 167 expected_scores = { 168 'fw_11.23': { 169 'one_finger_physical_click': 0.1875, 170 'two_fingers_physical_click': 0.125, 171 }, 172 'fw_11.27': { 173 'one_finger_physical_click': 0.58333332999999998, 174 'two_fingers_physical_click': 0.16666666999999999, 175 } 176 } 177 self._test_by_gesture(validator, expected_scores) 178 179 def test_by_validator(self): 180 expected_scores = { 181 'fw_11.23': { 182 'CountPacketsValidator': 0.895833333333, 183 'CountTrackingIDFatFingerValidator': 0.0, 184 'CountTrackingIDNormalFingerValidator': 0.96666666999999995, 185 'DrumrollValidator': 0.75, 186 'LinearityNormalFinger(Middle)Validator': 0.54910331999999995, 187 'NoGapValidator': 0.101144302433, 188 'PhysicalClickValidator': 0.75, 189 'PinchValidator': 0.875, 190 'StationaryTapValidator': 0.16666666999999999, 191 }, 192 'fw_11.27': { 193 'CountPacketsValidator': 1.0, 194 'CountTrackingIDFatFingerValidator': 0.5, 195 'CountTrackingIDNormalFingerValidator': 0.95555555999999997, 196 'DrumrollValidator': 0.666666666667, 197 'LinearityNormalFinger(Middle)Validator': 0.66679957999999995, 198 'NoGapValidator': 0.623221473233, 199 'PhysicalClickValidator': 1.0, 200 'PinchValidator': 1.0, 201 'StationaryTapValidator': 0.44444444, 202 } 203 } 204 for fw, fw_expected_scores in expected_scores.items(): 205 for validator, expected_score in fw_expected_scores.items(): 206 actual_score = self._get_score(fw=fw, validator=validator) 207 actual_score = round(actual_score, self._round_digits) 208 self.assertAlmostEqual(actual_score, expected_score) 209 210 def test_stat_metrics(self): 211 """Test the statistics of metrics.""" 212 expected_stats_values = { 213 'fw_11.23': { 214 'CountPacketsValidator': [ 215 ('pct of incorrect cases (%)--packets', 25.00)], 216 'PhysicalClickValidator': [ 217 ('1f-click miss rate (%)', 12.50), 218 ('2f-click miss rate (%)', 75.00)], 219 'PinchValidator': [ 220 ('pct of incorrect cases (%)--pinch', 12.50)], 221 }, 222 'fw_11.27': { 223 'CountPacketsValidator': [ 224 ('pct of incorrect cases (%)--packets', 0.00)], 225 'PhysicalClickValidator': [ 226 ('1f-click miss rate (%)', 0.00), 227 ('2f-click miss rate (%)', 0.00)], 228 'PinchValidator': [ 229 ('pct of incorrect cases (%)--pinch', 0.00)], 230 }, 231 } 232 233 for fw, fw_stats_values in expected_stats_values.items(): 234 for validator, stats_metrics in fw_stats_values.items(): 235 result = self.slog.get_result(fw=fw, validators=validator) 236 for metric_name, expected_value in stats_metrics: 237 actual_value = result.stat_metrics.stats_values[metric_name] 238 self.assertAlmostEqual(actual_value, expected_value) 239 240 def test_final_weighted_average(self): 241 expected_weighted_averages = { 242 'fw_11.23': 0.68406327, 243 'fw_11.27': 0.83886367, 244 } 245 final_weighted_average = self.slog.get_final_weighted_average() 246 for fw, expected_value in expected_weighted_averages.items(): 247 actual_value = final_weighted_average[fw] 248 actual_value = round(actual_value, self._round_digits) 249 self.assertAlmostEqual(actual_value, expected_value) 250 251 252if __name__ == '__main__': 253 unittest.main() 254