1dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang# Copyright (c) 2012 The Chromium OS Authors. All rights reserved. 2dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang# Use of this source code is governed by a BSD-style license that can be 3dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang# found in the LICENSE file. 4dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang# 5dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 6dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang"""This module contains unit tests for the classes in the validators module.""" 7dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 8efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwangimport glob 9dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwangimport os.path 10dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwangimport unittest 11dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 12dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwangimport common_unittest_utils 13dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwangimport common_util 14dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwangimport test_conf as conf 1510016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwangimport validators 16dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 17f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwangfrom common_unittest_utils import create_mocked_devices, parse_tests_data 182c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwangfrom firmware_constants import AXIS, GV, MTB, PLATFORM, VAL 19b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwangfrom firmware_log import MetricNameProps 20ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwangfrom geometry.elements import Point 213f245993196c7cead8716ff09633a6ad49e8b006Joseph Hwangfrom touch_device import TouchDevice 22dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwangfrom validators import (CountPacketsValidator, 23dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang CountTrackingIDValidator, 24e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang DiscardInitialSecondsValidator, 25dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang DrumrollValidator, 26a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang HysteresisValidator, 27dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang LinearityValidator, 2860a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang MtbSanityValidator, 29dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang NoGapValidator, 30cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang NoLevelJumpValidator, 31dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang NoReversedMotionValidator, 32dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang PhysicalClickValidator, 33dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang PinchValidator, 34dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang RangeValidator, 350d074428ab1b7cc71afd30ce1cfc863e13793fffCharlie Mooney ReportRateValidator, 36dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang StationaryFingerValidator, 3787321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang StationaryTapValidator, 38dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang) 39dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 40dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 41efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwangunittest_path_lumpy = os.path.join(os.getcwd(), 'tests/logs/lumpy') 423f245993196c7cead8716ff09633a6ad49e8b006Joseph Hwangmocked_device = create_mocked_devices() 433f245993196c7cead8716ff09633a6ad49e8b006Joseph Hwang 44f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang# Make short aliases for supported platforms 45f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwangalex = mocked_device[PLATFORM.ALEX] 46f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwanglumpy = mocked_device[PLATFORM.LUMPY] 47f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwanglink = mocked_device[PLATFORM.LINK] 48f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang# Some tests do not care what device is used. 49f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwangdontcare = 'dontcare' 50f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang 513f245993196c7cead8716ff09633a6ad49e8b006Joseph Hwang 52e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass CountTrackingIDValidatorTest(unittest.TestCase): 53dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Unit tests for CountTrackingIDValidator class.""" 54dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 55dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def _test_count_tracking_id(self, filename, criteria, device): 56dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang packets = parse_tests_data(filename) 57dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang validator = CountTrackingIDValidator(criteria, device=device) 587981beea4b6dfdff43ca61e17b51ba295a342702Joseph Hwang vlog = validator.check(packets) 59ecc254fc00e6b3504d4f7d87abad937cf73a267dJoseph Hwang return vlog.score 60dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 61dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_two_finger_id_change(self): 62dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Two two fingers id change. 63dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 64dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue 7867: Cyapa : Two finger scroll, tracking ids change 65dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 66dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'two_finger_id_change.dat' 67f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_count_tracking_id(filename, '== 2', lumpy) 68dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.assertTrue(score == 0) 69dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 70dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_one_finger_fast_swipe_id_split(self): 71dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """One finger fast swipe resulting in IDs split. 72dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 73dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue: 7869: Lumpy: Tracking ID reassigned during quick-2F-swipe 74dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 75dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'one_finger_fast_swipe_id_split.dat' 76f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_count_tracking_id(filename, '== 1', lumpy) 77dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.assertTrue(score == 0) 78dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 79dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_two_fingers_fast_flick_id_split(self): 80dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Two figners fast flick resulting in IDs split. 81dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 82dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue: 7869: Lumpy: Tracking ID reassigned during quick-2F-swipe 83dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 84dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'two_finger_fast_flick_id_split.dat' 85f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_count_tracking_id(filename, '== 2', lumpy) 86dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.assertTrue(score == 0) 87dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 88dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 89e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass DrumrollValidatorTest(unittest.TestCase): 90dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Unit tests for DrumrollValidator class.""" 91dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 92dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def setUp(self): 93dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.criteria = conf.drumroll_criteria 94dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 95dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def _test_drumroll(self, filename, criteria, device): 96dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang packets = parse_tests_data(filename) 97dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang validator = DrumrollValidator(criteria, device=device) 987981beea4b6dfdff43ca61e17b51ba295a342702Joseph Hwang vlog = validator.check(packets) 99ecc254fc00e6b3504d4f7d87abad937cf73a267dJoseph Hwang return vlog.score 100dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 101313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang def _get_drumroll_metrics(self, filename, criteria, device): 102efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang packets = parse_tests_data(filename, gesture_dir=unittest_path_lumpy) 103313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang validator = DrumrollValidator(criteria, device=device) 104313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang metrics = validator.check(packets).metrics 105313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang return metrics 106313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 107dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_drumroll_lumpy(self): 108dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Should catch the drumroll on lumpy. 109dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 110dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue 7809: Lumpy: Drumroll bug in firmware 111edb699f26760c240b23230b450135470a8e44a34Joseph Hwang Max distance: 52.02 px 112dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 113dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'drumroll_lumpy.dat' 114f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_drumroll(filename, self.criteria, lumpy) 115dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.assertTrue(score == 0) 116dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 117dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_drumroll_lumpy_1(self): 118dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Should catch the drumroll on lumpy. 119dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 120dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue 7809: Lumpy: Drumroll bug in firmware 121edb699f26760c240b23230b450135470a8e44a34Joseph Hwang Max distance: 43.57 px 122dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 123dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'drumroll_lumpy_1.dat' 124f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_drumroll(filename, self.criteria, lumpy) 125edb699f26760c240b23230b450135470a8e44a34Joseph Hwang self.assertTrue(score <= 0.15) 126dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 127dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_no_drumroll_link(self): 128dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Should pass (score == 1) when there is no drumroll. 129dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 130dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue 7809: Lumpy: Drumroll bug in firmware 131edb699f26760c240b23230b450135470a8e44a34Joseph Hwang Max distance: 2.92 px 132dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 133dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'no_drumroll_link.dat' 134f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_drumroll(filename, self.criteria, link) 135dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.assertTrue(score == 1) 136dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 137313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang def test_drumroll_metrics(self): 138313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang """Test the drumroll metrics.""" 139313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang expected_max_values = { 140313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang '20130506_030025-fw_11.27-robot_sim/' 141313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 'drumroll.fast-lumpy-fw_11.27-manual-20130528_044804.dat': 142313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 2.29402908535, 143313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 144313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang '20130506_030025-fw_11.27-robot_sim/' 145313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 'drumroll.fast-lumpy-fw_11.27-manual-20130528_044820.dat': 146313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 0.719567771497, 147313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 148313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang '20130506_031746-fw_11.27-robot_sim/' 149313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 'drumroll.fast-lumpy-fw_11.27-manual-20130528_044728.dat': 150313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 0.833491481592, 151313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 152313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang '20130506_032458-fw_11.23-robot_sim/' 153313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 'drumroll.fast-lumpy-fw_11.23-manual-20130528_044856.dat': 154313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 1.18368539364, 155313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 156313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang '20130506_032458-fw_11.23-robot_sim/' 157313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 'drumroll.fast-lumpy-fw_11.23-manual-20130528_044907.dat': 158313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 0.851161282019, 159313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 160313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang '20130506_032659-fw_11.23-robot_sim/' 161313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 'drumroll.fast-lumpy-fw_11.23-manual-20130528_044933.dat': 162313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 2.64245519251, 163313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 164313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang '20130506_032659-fw_11.23-robot_sim/' 165313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 'drumroll.fast-lumpy-fw_11.23-manual-20130528_044947.dat': 166313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 0.910624022916, 167313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang } 168313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang criteria = self.criteria 169313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang for filename, expected_max_value in expected_max_values.items(): 170f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang metrics = self._get_drumroll_metrics(filename, criteria, lumpy) 171313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang actual_max_value = max([m.value for m in metrics]) 172313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang self.assertAlmostEqual(expected_max_value, actual_max_value) 173313de5edc48d6af3b8891e69114ddf7d79c8516cJoseph Hwang 174dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 175e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass LinearityValidatorTest(unittest.TestCase): 176dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Unit tests for LinearityValidator class.""" 177dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 178dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def setUp(self): 17910016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang self.validator = LinearityValidator(conf.linearity_criteria, 180907efec59a199502d5508af023cd0668dcaffa1aJoseph Hwang device=lumpy, finger=0) 18110016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang self.validator.init_check() 18210016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang 18310016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang def test_simple_linear_regression0(self): 18410016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang """A perfect y-t line from bottom left to top right""" 18510016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang list_y = [20, 40, 60, 80, 100, 120, 140, 160] 18610016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang list_t = [i * 0.1 for i in range(len(list_y))] 18710016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang (max_err_px, rms_err_px) = self.validator._calc_errors_single_axis( 18810016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang list_t, list_y) 18910016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang self.assertAlmostEqual(max_err_px, 0) 19010016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang self.assertAlmostEqual(rms_err_px, 0) 19110016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang 192eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang def test_simple_linear_regression0b(self): 193eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang """An imperfect y-t line from bottom left to top right with 194eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang the first and the last entries as outliers. 195eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 196eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang In this test case: 197eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang begin segment = [1,] 198eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang end segment = [188, 190] 199eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang middle segment = [20, 40, 60, 80, 100, 120, 140, 160] 200eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 201eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang the simple linear regression line is calculated based on the 202eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang middle segment, and is 203eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang y = 20 * t 204eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang the error = [1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10] 205eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang """ 206eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang list_y = [1, 20, 40, 60, 80, 100, 120, 140, 160, 188, 190] 207eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang list_t = range(len(list_y)) 208eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 209eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang expected_errs_dict = { 210eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang VAL.WHOLE: [1, 0, 0, 0, 0, 0, 0, 0, 0, 8, 10], 211eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang VAL.BEGIN: [1, ], 212eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang VAL.END: [8, 10], 213eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang VAL.BOTH_ENDS: [1, 8, 10], 214eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang } 215eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 216eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang for segment_flag, expected_errs in expected_errs_dict.items(): 217eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang self.validator._segments= segment_flag 218eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang (max_err, rms_err) = self.validator._calc_errors_single_axis(list_t, 219eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang list_y) 220eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang expected_max_err = max(expected_errs) 221eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang expected_rms_err = (sum([i ** 2 for i in expected_errs]) / 222eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang len(expected_errs)) ** 0.5 223eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang self.assertAlmostEqual(max_err, expected_max_err) 224eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang self.assertAlmostEqual(rms_err, expected_rms_err) 225eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 226eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang def test_log_details_and_metrics(self): 227eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang """Test the axes in _log_details_and_metrics""" 228eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang # gesture_dir: tests/data/linearity 229eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang gesture_dir = 'linearity' 230eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang filenames_axes = { 231eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 'two_finger_tracking.right_to_left.slow-lumpy-fw_11.27-robot-' 232eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang '20130227_204458.dat': [AXIS.X], 233eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 'one_finger_to_edge.center_to_top.slow-lumpy-fw_11.27-robot-' 234eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang '20130227_203228.dat': [AXIS.Y], 235eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 'two_finger_tracking.bottom_left_to_top_right.normal-lumpy-' 236eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 'fw_11.27-robot-20130227_204902.dat': [AXIS.X, AXIS.Y], 237eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang } 238eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang for filename, expected_axes in filenames_axes.items(): 239eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang packets = parse_tests_data(filename, gesture_dir=gesture_dir) 240eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang # get the direction of the gesture 241eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang direction = [filename.split('-')[0].split('.')[1]] 242eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang self.validator.check(packets, direction) 243eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang actual_axes = sorted(self.validator.list_coords.keys()) 244eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang self.assertEqual(actual_axes, expected_axes) 245eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang 246eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang def _test_simple_linear_regression1(self): 24710016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang """A y-t line taken from a real example. 24810016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang 24910016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang Refer to the "Numerical example" in the wiki page: 25010016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang http://en.wikipedia.org/wiki/Simple_linear_regression 25110016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang """ 25210016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang list_t = [1.47, 1.50, 1.52, 1.55, 1.57, 1.60, 1.63, 1.65, 1.68, 1.70, 25310016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang 1.73, 1.75, 1.78, 1.80, 1.83] 25410016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang list_y = [52.21, 53.12, 54.48, 55.84, 57.20, 58.57, 59.93, 61.29, 25510016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang 63.11, 64.47, 66.28, 68.10, 69.92, 72.19, 74.46] 25610016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang expected_max_err = 1.3938545467809007 25710016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang expected_rms_err = 0.70666155991311708 25810016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang (max_err, rms_err) = self.validator._calc_errors_single_axis( 25910016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang list_t, list_y) 26010016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang self.assertAlmostEqual(max_err, expected_max_err) 26110016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang self.assertAlmostEqual(rms_err, expected_rms_err) 26210016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang 26310016f7a7ffb74c3c03ac548575ac74bd1a9a222Joseph Hwang 264e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass NoGapValidatorTest(unittest.TestCase): 265dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Unit tests for NoGapValidator class.""" 266a121b27b9145326852c5fe66e98df189c4b0fd90Joseph Hwang GAPS_SUBDIR = 'gaps' 267dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 268dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def setUp(self): 269dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.criteria = conf.no_gap_criteria 270dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 271dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def _test_no_gap(self, filename, criteria, device, slot): 272a121b27b9145326852c5fe66e98df189c4b0fd90Joseph Hwang file_subpath = os.path.join(self.GAPS_SUBDIR, filename) 273a121b27b9145326852c5fe66e98df189c4b0fd90Joseph Hwang packets = parse_tests_data(file_subpath) 274dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang validator = NoGapValidator(criteria, device=device, slot=slot) 2757981beea4b6dfdff43ca61e17b51ba295a342702Joseph Hwang vlog = validator.check(packets) 276ecc254fc00e6b3504d4f7d87abad937cf73a267dJoseph Hwang return vlog.score 277dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 278dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_two_finger_scroll_gaps(self): 279dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Test that there are gaps in the two finger scroll gesture. 280dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 281dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue 7552: Cyapa : two finger scroll motion produces gaps in tracking 282dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 283dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'two_finger_gaps.horizontal.dat' 284f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score0 = self._test_no_gap(filename, self.criteria, lumpy, 0) 285f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score1 = self._test_no_gap(filename, self.criteria, lumpy, 1) 286dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.assertTrue(score0 <= 0.1) 287dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.assertTrue(score1 <= 0.1) 288dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 289dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_gap_new_finger_arriving_or_departing(self): 290dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Test gap when new finger arriving or departing. 291dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 292dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue: 8005: Cyapa : gaps appear when new finger arrives or departs 293dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 294dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'gap_new_finger_arriving_or_departing.dat' 295f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_no_gap(filename, self.criteria, lumpy, 0) 296a121b27b9145326852c5fe66e98df189c4b0fd90Joseph Hwang self.assertTrue(score <= 0.3) 297dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 298dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_one_stationary_finger_2nd_finger_moving_gaps(self): 299dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Test one stationary finger resulting in 2nd finger moving gaps.""" 300dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'one_stationary_finger_2nd_finger_moving_gaps.dat' 301f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_no_gap(filename, self.criteria, lumpy, 1) 302dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang self.assertTrue(score <= 0.1) 303dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 304dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_resting_finger_2nd_finger_moving_gaps(self): 305dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Test resting finger resulting in 2nd finger moving gaps. 306dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 307dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue 7648: Cyapa : Resting finger plus one finger move generates a gap 308dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 309dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'resting_finger_2nd_finger_moving_gaps.dat' 310f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang score = self._test_no_gap(filename, self.criteria, lumpy, 1) 311a121b27b9145326852c5fe66e98df189c4b0fd90Joseph Hwang self.assertTrue(score <= 0.3) 312dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 313dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 314e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass PhysicalClickValidatorTest(unittest.TestCase): 315efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang """Unit tests for PhysicalClickValidator class.""" 316efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 317efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang def setUp(self): 318f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang self.device = lumpy 319efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang self.criteria = '== 1' 320b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang self.mnprops = MetricNameProps() 321efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 322efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang def _test_physical_clicks(self, gesture_dir, files, expected_score): 323efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang gesture_path = os.path.join(unittest_path_lumpy, gesture_dir) 324efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang for filename, fingers in files.items(): 325efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang packets = parse_tests_data(os.path.join(gesture_path, filename)) 326efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang validator = PhysicalClickValidator(self.criteria, 327efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang fingers=fingers, 328efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang device=self.device) 329efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang vlog = validator.check(packets) 330efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang actual_score = vlog.score 331efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang self.assertTrue(actual_score == expected_score) 332efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 333efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang def test_physical_clicks_success(self): 334efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang """All physcial click files in the gesture_dir should pass.""" 335efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang gesture_dir = '20130506_030025-fw_11.27-robot_sim' 336efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang gesture_path = os.path.join(unittest_path_lumpy, gesture_dir) 337efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 338efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang # Get all 1f physical click files. 339efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang file_prefix = 'one_finger_physical_click' 340efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang fingers = 1 341efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang files1 = [(filepath, fingers) for filepath in glob.glob( 342efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang os.path.join(gesture_path, file_prefix + '*.dat'))] 343efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 344efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang # Get all 2f physical click files. 345efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang file_prefix = 'two_fingers_physical_click' 346efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang fingers = 2 347efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang files2 = [(filepath, fingers) for filepath in glob.glob( 348efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang os.path.join(gesture_path, file_prefix + '*.dat'))] 349efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 350efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang # files is a dictionary of {filename: fingers} 351efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang files = dict(files1 + files2) 352efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang expected_score = 1.0 353efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang self._test_physical_clicks(gesture_dir, files, expected_score) 354efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 355efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang def test_physical_clicks_failure(self): 356efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang """All physcial click files specified below should fail.""" 357efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang gesture_dir = '20130506_032458-fw_11.23-robot_sim' 358efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang # files is a dictionary of {filename: fingers} 359efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang files = { 360efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 'one_finger_physical_click.bottom_side-lumpy-fw_11.23-complete-' 361efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang '20130614_065744.dat': 1, 362efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 'one_finger_physical_click.center-lumpy-fw_11.23-complete-' 363efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang '20130614_065727.dat': 1, 364efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 'two_fingers_physical_click-lumpy-fw_11.23-complete-' 365efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang '20130614_065757.dat': 2, 366efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang } 367efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang expected_score = 0.0 368efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang self._test_physical_clicks(gesture_dir, files, expected_score) 369efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 370b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang def test_physical_clicks_by_finger_IDs(self): 371b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang """Test that some physical clicks may come with or without correct 372b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang finger IDs. 373b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang """ 374b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # files is a dictionary of { 375b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # filename: (number_fingers, (actual clicks, expected clicks))} 376b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang files = { 377b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # An incorrect case with 1 finger: the event sequence comprises 378b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value 284 379b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value -1 380b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 1 381b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 0 382b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # In this case, the BTN_LEFT occurs when there is no finger. 383b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang '1f_click_incorrect_behind_tid.dat': (1, (0, 1)), 384b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang 385b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # A correct case with 1 finger: the event sequence comprises 386b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value 284 387b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 1 388b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value -1 389b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 0 390b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # In this case, the BTN_LEFT occurs when there is no finger. 391b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang '1f_click.dat': (1, (1, 1)), 392b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang 393b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # An incorrect case with 2 fingers: the event sequence comprises 394b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value 18 395b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 1 396b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 0 397b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value 19 398b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value -1 399b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value -1 400b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # In this case, the BTN_LEFT occurs when there is only 1 finger. 401b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang '2f_clicks_incorrect_before_2nd_tid.dat': (2, (0, 1)), 402b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang 403b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # An incorrect case with 2 fingers: the event sequence comprises 404b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value 18 405b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value 19 406b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value -1 407b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value -1 408b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 1 409b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 0 410b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # In this case, the BTN_LEFT occurs when there is only 1 finger. 411b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang '2f_clicks_incorrect_behind_2_tids.dat': (2, (0, 1)), 412b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang 413b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # A correct case with 2 fingers: the event sequence comprises 414b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value 18 415b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value 19 416b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 1 417b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value -1 418b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: ABS_MT_TRACKING_ID, value -1 419b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # Event: BTN_LEFT, value 0 420b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang # In this case, the BTN_LEFT occurs when there is only 1 finger. 421b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang '2f_clicks.dat': (2, (1, 1)), 422b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang } 423b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang for filename, (fingers, expected_value) in files.items(): 424b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang packets = parse_tests_data(filename) 425b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang validator = PhysicalClickValidator(self.criteria, fingers=fingers, 426b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang device=dontcare) 427b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang vlog = validator.check(packets) 428b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang metric_name = self.mnprops.CLICK_CHECK_TIDS.format(fingers) 429b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang for metric in vlog.metrics: 430b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang if metric.name == metric_name: 431b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang self.assertEqual(metric.value, expected_value) 432b6bba8d9db954b5adbfb2eb60a220948028b4b6fJoseph Hwang 433efc137d383c3fac280e1df3b657097cd6a94e392Joseph Hwang 434e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass RangeValidatorTest(unittest.TestCase): 43551b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang """Unit tests for RangeValidator class.""" 43651b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 43751b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang def setUp(self): 438f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang self.device = lumpy 43951b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 44051b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang def _test_range(self, filename, expected_short_of_range_px): 44151b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang filepath = os.path.join(unittest_path_lumpy, filename) 44251b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang packets = parse_tests_data(filepath) 44351b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang validator = RangeValidator(conf.range_criteria, device=self.device) 44451b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 44551b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang # Extract the gesture variation from the filename 44651b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang variation = (filename.split('/')[-1].split('.')[1],) 44751b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 44851b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang # Determine the axis based on the direction in the gesture variation 44951b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang axis = (self.device.axis_x if validator.is_horizontal(variation) 45051b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang else self.device.axis_y if validator.is_vertical(variation) 45151b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang else None) 45251b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang self.assertTrue(axis is not None) 45351b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 45451b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang # Convert from pixels to mms. 45551b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang expected_short_of_range_mm = self.device.pixel_to_mm_single_axis( 45651b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang expected_short_of_range_px, axis) 45751b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 45851b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang vlog = validator.check(packets, variation) 45951b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 46051b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang # There is only one metric in the metrics list. 46151b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang self.assertEqual(len(vlog.metrics), 1) 46251b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang actual_short_of_range_mm = vlog.metrics[0].value 46351b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang self.assertEqual(actual_short_of_range_mm, expected_short_of_range_mm) 46451b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 46551b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang def test_range(self): 46651b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang """All physical click files specified below should fail.""" 46751b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang # files_px is a dictionary of {filename: short_of_range_px} 46851b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang files_px = { 46951b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang '20130506_030025-fw_11.27-robot_sim/' 47051b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 'one_finger_to_edge.center_to_left.slow-lumpy-fw_11.27-' 47151b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 'robot_sim-20130506_031554.dat': 0, 47251b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 47351b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang '20130506_030025-fw_11.27-robot_sim/' 47451b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 'one_finger_to_edge.center_to_left.slow-lumpy-fw_11.27-' 47551b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 'robot_sim-20130506_031608.dat': 0, 47651b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 47751b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang '20130506_032458-fw_11.23-robot_sim/' 47851b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 'one_finger_to_edge.center_to_left.slow-lumpy-fw_11.23-' 47951b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 'robot_sim-20130506_032538.dat': 1, 48051b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 48151b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang '20130506_032458-fw_11.23-robot_sim/' 48251b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 'one_finger_to_edge.center_to_left.slow-lumpy-fw_11.23-' 48351b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 'robot_sim-20130506_032549.dat': 1, 48451b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang } 48551b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 48651b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang for filename, short_of_range_px in files_px.items(): 48751b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang self._test_range(filename, short_of_range_px) 48851b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 48951b95395336cc1e887d17acab137fcd450b7bfdcJoseph Hwang 490e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass StationaryFingerValidatorTest(unittest.TestCase): 491eb2c422de0873a741d68699d9f91d1ad351b9addJoseph Hwang """Unit tests for StationaryFingerValidator class.""" 492dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 493dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def setUp(self): 494e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwang self.criteria = conf.stationary_finger_criteria 495dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 49687321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang def _get_max_distance(self, filename, criteria, device): 497dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang packets = parse_tests_data(filename) 498dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang validator = StationaryFingerValidator(criteria, device=device) 4997981beea4b6dfdff43ca61e17b51ba295a342702Joseph Hwang vlog = validator.check(packets) 50087321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang return vlog.metrics[0].value 501dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 502dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_stationary_finger_shift(self): 503dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Test that the stationary shift due to 2nd finger tapping. 504dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 505dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue 7442: Cyapa : Second finger tap events influence stationary finger 506dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang position 507dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 508dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = 'stationary_finger_shift_with_2nd_finger_tap.dat' 50987321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang max_distance = self._get_max_distance(filename, self.criteria, lumpy) 51087321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang self.assertAlmostEqual(max_distance, 5.464430436926) 511dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 512dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang def test_stationary_strongly_affected_by_2nd_moving_finger(self): 513dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """Test stationary finger strongly affected by 2nd moving finger with 514dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang gaps. 515dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 516dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang Issue 5812: [Cypress] reported positions of stationary finger strongly 517dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang affected by nearby moving finger 518dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang """ 519dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang filename = ('stationary_finger_strongly_affected_by_2nd_moving_finger_' 520dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 'with_gaps.dat') 52187321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang max_distance = self._get_max_distance(filename, self.criteria, lumpy) 52287321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang self.assertAlmostEqual(max_distance, 4.670861210146) 52387321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang 52487321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang 52587321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwangclass StationaryTapValidatorTest(unittest.TestCase): 52687321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang """Unit tests for StationaryTapValidator class.""" 52787321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang 52887321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang def setUp(self): 52987321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang self.criteria = conf.stationary_tap_criteria 53087321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang 53187321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang def test_stationary_tap(self): 53287321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang filenames = {'1f_click.dat': 1.718284027744, 53387321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang '1f_clickb.dat': 0.577590781705} 53487321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang for filename, expected_max_distance in filenames.items(): 53587321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang packets = parse_tests_data(filename) 53687321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang validator = StationaryTapValidator(self.criteria, device=lumpy) 53787321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang vlog = validator.check(packets) 53887321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang actual_max_distance = vlog.metrics[0].value 53987321559af7db87fcf4fbe5a1eb80564aecccb71Joseph Hwang self.assertAlmostEqual(actual_max_distance, expected_max_distance) 540dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 541dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang 542e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass NoLevelJumpValidatorTest(unittest.TestCase): 543cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang """Unit tests for NoLevelJumpValidator class.""" 544cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 545cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang def setUp(self): 546cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang self.criteria = conf.no_level_jump_criteria 547cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang self.gesture_dir = 'drag_edge_thumb' 548cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 549cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang def _get_score(self, filename, device): 550cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang validator = NoLevelJumpValidator(self.criteria, device=device, 551cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang slots=[0,]) 552cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang packets = parse_tests_data(filename, gesture_dir=self.gesture_dir) 553cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang vlog = validator.check(packets) 554ecc254fc00e6b3504d4f7d87abad937cf73a267dJoseph Hwang score = vlog.score 555cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang return score 556cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 557cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang def test_level_jumps(self): 558cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang """Test files with level jumps.""" 559cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang filenames = [ 560cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.horizontal.dat', 561cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.horizontal_2.dat', 562cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.horizontal_3.no_points.dat', 563cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.vertical.dat', 564cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.vertical_2.dat', 565cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.diagonal.dat', 566cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang ] 567cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang for filename in filenames: 568f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang self.assertTrue(self._get_score(filename, lumpy) <= 0.6) 569cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 570cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang def test_no_level_jumps(self): 571cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang """Test files without level jumps.""" 572cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang filenames = [ 573cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.horizontal.curvy.dat', 574cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.horizontal_2.curvy.dat', 575cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.vertical.curvy.dat', 576cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 'drag_edge_thumb.vertical_2.curvy.dat', 577cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang ] 578cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang for filename in filenames: 579f16a39fd38ddaec0707d9ea3b1f7c3a2a0bb090fJoseph Hwang self.assertTrue(self._get_score(filename, lumpy) == 1.0) 580cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 581cc906c0b5cc5849ecfb86052dac08ad90b7d3c06Joseph Hwang 582e41b3cfce09ec790d909107c9da6726e51b13c89Joseph Hwangclass ReportRateValidatorTest(unittest.TestCase): 5830d074428ab1b7cc71afd30ce1cfc863e13793fffCharlie Mooney """Unit tests for ReportRateValidator class.""" 5847b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang def setUp(self): 5853e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang self.criteria = '>= 60' 5867b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang 5877b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang def _get_score(self, filename, device): 588ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang validator = ReportRateValidator(self.criteria, device=device, 589ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang chop_off_pauses=False) 5907b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang packets = parse_tests_data(filename) 5917b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang vlog = validator.check(packets) 592ecc254fc00e6b3504d4f7d87abad937cf73a267dJoseph Hwang score = vlog.score 5937b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang return score 5947b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang 5953e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang def test_report_rate_scores(self): 5963e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang """Test the score of the report rate.""" 5977b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang filename = '2f_scroll_diagonal.dat' 5987b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang self.assertTrue(self._get_score(filename, device=lumpy) <= 0.5) 5997b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang 6007b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang filename = 'one_finger_with_slot_0.dat' 6017b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang self.assertTrue(self._get_score(filename, device=lumpy) >= 0.9) 6027b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang 6037b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang filename = 'two_close_fingers_merging_changed_ids_gaps.dat' 6047b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang self.assertTrue(self._get_score(filename, device=lumpy) <= 0.5) 6057b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang 606f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang def test_report_rate_without_slot(self): 607f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang """Test report rate without specifying any slot.""" 608f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang filename_report_rate_pair = [ 609f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang ('2f_scroll_diagonal.dat', 40.31), 610f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang ('one_finger_with_slot_0.dat', 148.65), 611f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang ('two_close_fingers_merging_changed_ids_gaps.dat', 53.12), 612f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang ] 613f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang for filename, expected_report_rate in filename_report_rate_pair: 614ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang validator = ReportRateValidator(self.criteria, device=dontcare, 615ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang chop_off_pauses=False) 616f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang validator.check(parse_tests_data(filename)) 617f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang actual_report_rate = round(validator.report_rate, 2) 618f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang self.assertAlmostEqual(actual_report_rate, expected_report_rate) 619f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang 620f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang def test_report_rate_with_slot(self): 621f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang """Test report rate with slot=1""" 622f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang # Compute actual_report_rate 623f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang filename = ('stationary_finger_strongly_affected_by_2nd_moving_finger_' 624f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang 'with_gaps.dat') 625f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang validator = ReportRateValidator(self.criteria, device=dontcare, 626ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang finger=1, chop_off_pauses=False) 627f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang validator.check(parse_tests_data(filename)) 628f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang actual_report_rate = validator.report_rate 629f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang # Compute expected_report_rate 630f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang first_syn_time = 2597.682925 63111a616bf5acd3a0f41a30f37b06c549380881b8eJoseph Hwang last_syn_time = 2604.543335 63211a616bf5acd3a0f41a30f37b06c549380881b8eJoseph Hwang num_packets = 592 - 1 633f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang expected_report_rate = num_packets / (last_syn_time - first_syn_time) 634f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang self.assertAlmostEqual(actual_report_rate, expected_report_rate) 635f745c17c4bbf5f42a00813ef954762b5b8cb122cJoseph Hwang 6363e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang def _test_report_rate_metrics(self, filename, expected_values): 637330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang packets = parse_tests_data(filename) 638ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang validator = ReportRateValidator(self.criteria, device=lumpy, 639ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang chop_off_pauses=False) 6403e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang vlog = validator.check(packets) 6413e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang 642330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang # Verify that there are 3 metrics 643330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang number_metrics = 3 644330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang self.assertEqual(len(vlog.metrics), number_metrics) 645330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang 6463e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang # Verify the values of the 3 metrics. 6473e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang for i in range(number_metrics): 648ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang actual_value = vlog.metrics[i].value 649ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang if isinstance(actual_value, tuple): 650ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang self.assertEqual(actual_value, expected_values[i]) 651ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang else: 652ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang self.assertAlmostEqual(actual_value, expected_values[i]) 6533e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang 654330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang def test_report_rate_metrics(self): 6553e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang """Test the metrics of the report rates.""" 6563e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang # files is a dictionary of 657330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang # {filename: ((# long_intervals, # all intervals), 658330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang # ave_interval, max_interval)} 6593e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang files = { 660330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang '2f_scroll_diagonal.dat': 661330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang ((33, 33), 24.8057272727954, 26.26600000075996), 662330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang 'one_finger_with_slot_0.dat': 663330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang ((1, 12), 6.727166666678386, 20.411999998032115), 664330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang 'two_close_fingers_merging_changed_ids_gaps.dat': 665330dcded15b07bf1869bd5d4cbf2bccbc6a14537Joseph Hwang ((13, 58), 18.82680942272318, 40.936946868896484), 6663e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang } 6673e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang 6683e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang for filename, values in files.items(): 6693e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang self._test_report_rate_metrics(filename, values) 6703e04edbe5538f3f84423bc26c4a882d343e966a4Joseph Hwang 671ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang def _test_chop_off_both_ends(self, xy_pairs, distance, expected_middle): 672ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang """Verify if the actual middle is equal to the expected middle.""" 673ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang points = [Point(*xy) for xy in xy_pairs] 674ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang validator = ReportRateValidator(self.criteria, device=dontcare) 675ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang actual_middle = validator._chop_off_both_ends(points, distance) 676ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang self.assertEqual(actual_middle, expected_middle) 677ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang 678ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang def test_chop_off_both_ends0(self): 679ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang """Test chop_off_both_ends() with distinct distances.""" 680ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang xy_pairs = [ 681ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang # pauses 682ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang (100, 20), (100, 21), (101, 22), (102, 24), (103, 26), 683ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang # moving segment 684ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang (120, 30), (122, 29), (123, 32), (123, 33), (126, 35), 685ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang (126, 32), (142, 29), (148, 30), (159, 31), (162, 30), 686ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang (170, 32), (183, 32), (194, 32), (205, 32), (208, 32), 687ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang # pauses 688ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang (230, 30), (231, 31), (232, 30), (231, 30), (230, 30), 689ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang ] 690ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang 691ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang distance = 20 692ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_begin_index = 5 693ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_end_index = 19 694ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_middle = [expected_begin_index, expected_end_index] 695ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang self._test_chop_off_both_ends(xy_pairs, distance, expected_middle) 696ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang 697ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang distance = 0 698ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_begin_index = 0 699ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_end_index = len(xy_pairs) - 1 700ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_middle = [expected_begin_index, expected_end_index] 701ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang self._test_chop_off_both_ends(xy_pairs, distance, expected_middle) 702ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang 703ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang def test_chop_off_both_ends1(self): 704ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang """Test chop_off_both_ends() with some corner cases""" 705ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang distance = 20 706ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang xy_pairs = [(120, 50), (120, 50)] 707ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_middle = None 708ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang self._test_chop_off_both_ends(xy_pairs, distance, expected_middle) 709ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang 710ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang xy_pairs = [(120, 50), (150, 52), (200, 51)] 711ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_middle = [1, 1] 712ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang self._test_chop_off_both_ends(xy_pairs, distance, expected_middle) 713ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang 714ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang xy_pairs = [(120, 50), (120, 51), (200, 52), (200, 51)] 715ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang expected_middle = None 716ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang self._test_chop_off_both_ends(xy_pairs, distance, expected_middle) 717ceed19b0caa1913b4ca7a91b7b27d654e214bc09Joseph Hwang 7187b345e2cd5b68035db50f0a0706292cde45d9cf5Joseph Hwang 719a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwangclass HysteresisValidatorTest(unittest.TestCase): 720a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang """Unit tests for HysteresisValidator class.""" 721a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang 722a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang def setUp(self): 723a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang self.criteria = conf.hysteresis_criteria 724a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang 725a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang def test_hysteresis(self): 726a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang """Test that the hysteresis causes an initial jump.""" 727a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang filenames = {'center_to_right_normal_link.dat': 4.6043458, 728a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang 'center_to_right_slow_link.dat': 16.8671278} 729a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang 730a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang for filename, expected_value in filenames.items(): 731a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang packets = parse_tests_data(filename) 732a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang validator = HysteresisValidator(self.criteria, device=link) 733a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang vlog = validator.check(packets) 734a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang self.assertAlmostEqual(vlog.metrics[0].value, expected_value) 735a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang 73625ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang def test_click_data(self): 73725ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang """Test that the validator handles None distances well. 73825ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang 73925ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang In this test, distance1 = None and distance2 = None. 74025ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang This results in ratio = infinity. There should be no error incurred. 74125ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang """ 74225ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang packets = parse_tests_data('2f_clicks_test_hysteresis.dat') 74325ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang validator = HysteresisValidator(self.criteria, device=link) 74425ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang vlog = validator.check(packets) 74525ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang self.assertEqual(vlog.metrics[0].value, float('infinity')) 74625ead0eae720b5e7c627e50ad214de514287aac4Joseph Hwang 747a44a9531f8dbd9c61d1f940397a816d628d4b369Joseph Hwang 74860a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwangclass MtbSanityValidatorTest(unittest.TestCase): 74960a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang """Unit tests for MtbSanityValidator class.""" 75060a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang 75160a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang def setUp(self): 75260a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang import fake_input_device 75360a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang self.fake_device_info = fake_input_device.FakeInputDevice() 75460a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang 75560a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang def _get_number_errors(self, filename): 75660a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang packets = parse_tests_data(filename) 75760a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang validator = MtbSanityValidator(device=link, 75860a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang device_info=self.fake_device_info) 75960a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang vlog = validator.check(packets) 76060a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang number_errors, _ = vlog.metrics[1].value 76160a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang return number_errors 76260a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang 76360a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang def test_sanity_found_errors(self): 76460a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang """Test that the tracking id is set to -1 before being assigned a 76560a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang positive value. 76660a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang """ 76760a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang filenames = ['finger_crossing.top_right_to_bottom_left.slow.dat', 76860a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang 'two_finger_tap.vertical.dat'] 76960a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang for filename in filenames: 77060a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang number_errors = self._get_number_errors(filename) 77160a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang self.assertTrue(number_errors > 0) 77260a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang 77360a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang def test_sanity_pass(self): 77460a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang """Test that the MTB format is correct.""" 77560a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang filenames = ['2f_scroll_diagonal.dat', 77660a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang 'drumroll_lumpy.dat'] 77760a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang for filename in filenames: 77860a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang number_errors = self._get_number_errors(filename) 77960a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang self.assertTrue(number_errors == 0) 78060a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang 78160a345dd2a6a7c27407153b6c9734d2b63a88c01Joseph Hwang 782e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huangclass DiscardInitialSecondsValidatorTest(unittest.TestCase): 783e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang """Unit tests for DiscardInitialSecondsValidator class.""" 784e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 785e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang def setUp(self): 786e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang import fake_input_device 787e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang self.fake_device_info = fake_input_device.FakeInputDevice() 788e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 789e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang def _get_score(self, filename, criteria_str): 790e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang packets = parse_tests_data(filename) 791e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang validator = DiscardInitialSecondsValidator( 792e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang validator=CountTrackingIDValidator(criteria_str, device=link), 793e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang device=link) 794e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang vlog = validator.check(packets) 795e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang return vlog.score 796e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 797e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang def test_single_finger_hold(self): 798e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang """Test that the state machine reads one finger if 799e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang only one finger was held for over a second.""" 800e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 801e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang filename = 'one_finger_long_hold.dat' 802e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang score = self._get_score(filename, '== 1') 803e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang self.assertTrue(score == 1) 804e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 805e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang def test_double_finger_hold(self): 806e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang """Test that the state machine reads two fingers if 807e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang two fingers were held for over a second.""" 808e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 809e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang filename = 'two_finger_long_hold.dat' 810e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang score = self._get_score(filename, '== 2') 811e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang self.assertTrue(score == 1) 812e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 813e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang def test_double_tap_single_hold(self): 814e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang """Test that the validator discards the initial double tap and only 815e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang validates on the single finger long hold at the end. 816e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang """ 817e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 818e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang filename = 'two_finger_tap_one_finger_hold.dat' 819e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang score = self._get_score(filename, '== 1') 820e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang self.assertTrue(score == 1) 821e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 8222c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang def test_discard_initial_seconds(self): 8232c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang """Test that discard_initial_seconds() cuts at the proper packet. 8242c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang 8252c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang Note: to print the final_state_packet, use the following statements: 8262c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang import mtb 8272c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang print mtb.make_pretty_packet(final_state_packet) 8282c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang """ 8292c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang packets = parse_tests_data('noise_stationary_extended.dat') 8302c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang validator = DiscardInitialSecondsValidator( 8312c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang validator=CountTrackingIDValidator('== 1', device=link), 8322c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang device=link) 8332c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang validator.init_check(packets) 8346a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang packets = validator._discard_initial_seconds(packets, 1) 8352c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang final_state_packet = packets[0] 8362c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang 8372c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(len(final_state_packet) == 11) 8382c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang # Assert the correctness of the 1st finger data in the order of 8392c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang # SLOT, TRACKING_ID, POSITION_X, POSITION_Y, PRESSURE 8402c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[0][MTB.EV_VALUE] == 2) 8412c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[1][MTB.EV_VALUE] == 2427) 8422c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[2][MTB.EV_VALUE] == 670) 8432c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[3][MTB.EV_VALUE] == 361) 8442c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[4][MTB.EV_VALUE] == 26) 8452c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang # Assert the correctness of the 2nd finger data in the order of 8462c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang # SLOT, TRACKING_ID, POSITION_X, POSITION_Y, PRESSURE 8472c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[5][MTB.EV_VALUE] == 3) 8482c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[6][MTB.EV_VALUE] == 2426) 8492c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[7][MTB.EV_VALUE] == 670) 8502c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[8][MTB.EV_VALUE] == 368) 8512c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[9][MTB.EV_VALUE] == 21) 8522c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang # EVENT TIME 8532c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang self.assertTrue(final_state_packet[0][MTB.EV_TIME] == 1412021965.723953) 8542c04d55557525b8b3dd654d64d1792f57792a91aJoseph Hwang 8556a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang def test_get_snapshot_after_discarding_init_packets(self): 8566a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang """Test that get_snapshot() handles non-ready packet properly 8576a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang after discard_initial_seconds(). A non-ready packet is one that 8586a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang the attributes such as X, Y, and Z are not all ready. 8596a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang """ 8606a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang packets = parse_tests_data('non_ready_events_in_final_state_packet.dat') 8616a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang validator = DiscardInitialSecondsValidator( 8626a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang validator=CountTrackingIDValidator('== 1', device=link), 8636a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang device=link) 8646a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang validator.init_check(packets) 8656a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang packets = validator._discard_initial_seconds(packets, 1) 8666a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang final_state_packet = packets[0] 8676a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang 8686a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang self.assertTrue(len(final_state_packet) == 4) 8696a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang # Assert the correctness of the finger data in the order of 8706a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang # SLOT, TRACKING_ID, and POSITION_Y 8716a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang self.assertTrue(final_state_packet[0][MTB.EV_VALUE] == 0) 8726a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang self.assertTrue(final_state_packet[1][MTB.EV_VALUE] == 102) 8736a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang self.assertTrue(final_state_packet[2][MTB.EV_VALUE] == 1316) 8746a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang # EVENT TIME 8756a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang self.assertTrue(final_state_packet[0][MTB.EV_TIME] == 1412888977.716634) 8766a4fc49cc298c65dc1ba48b1d7705caae9d611b1Joseph Hwang 877208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang def test_noise_line_with_all_fingers_left(self): 878208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang """In this test case, all fingers left. The final_state_packet is [].""" 879208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang packets=parse_tests_data('noise_line.dat') 880208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang validator = DiscardInitialSecondsValidator(ReportRateValidator('>= 60')) 881208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang validator.init_check(packets) 882208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang packets = validator._discard_initial_seconds(packets, 1) 883208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang validator.validator.init_check(packets) 884208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang list_syn_time = validator.validator.packets.get_list_syn_time([]) 885208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang self.assertEqual(len(packets), 84) 886208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang self.assertEqual(len(list_syn_time), 84) 887208b022eac67988d5bb35a387115c3a76f9b9413Joseph Hwang 888e99ec990bb01ce483eaabd8f0881e02e265ec686Mindy Huang 889dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwangif __name__ == '__main__': 890dc2e4066a4aa7939517db57feb854691717ff8eeJoseph Hwang unittest.main() 891