2018-03-09 14:23:55 +10:00
|
|
|
#!/usr/bin/python3
|
|
|
|
|
# vim: set expandtab shiftwidth=4:
|
|
|
|
|
# -*- Mode: python; coding: utf-8; indent-tabs-mode: nil -*- */
|
|
|
|
|
#
|
|
|
|
|
# Copyright © 2018 Red Hat, Inc.
|
|
|
|
|
#
|
|
|
|
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
|
|
|
|
# copy of this software and associated documentation files (the "Software"),
|
|
|
|
|
# to deal in the Software without restriction, including without limitation
|
|
|
|
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
|
|
|
|
# and/or sell copies of the Software, and to permit persons to whom the
|
|
|
|
|
# Software is furnished to do so, subject to the following conditions:
|
|
|
|
|
#
|
|
|
|
|
# The above copyright notice and this permission notice (including the next
|
|
|
|
|
# paragraph) shall be included in all copies or substantial portions of the
|
|
|
|
|
# Software.
|
|
|
|
|
#
|
|
|
|
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
|
|
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
|
|
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
|
|
|
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
|
|
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
|
|
|
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
|
|
|
# DEALINGS IN THE SOFTWARE.
|
|
|
|
|
|
|
|
|
|
import argparse
|
|
|
|
|
import os
|
|
|
|
|
import sys
|
|
|
|
|
import unittest
|
|
|
|
|
import yaml
|
|
|
|
|
import re
|
|
|
|
|
|
|
|
|
|
from pkg_resources import parse_version
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TestYaml(unittest.TestCase):
|
|
|
|
|
filename = ''
|
|
|
|
|
|
|
|
|
|
@classmethod
|
|
|
|
|
def setUpClass(cls):
|
|
|
|
|
with open(cls.filename) as f:
|
|
|
|
|
cls.yaml = yaml.safe_load(f)
|
|
|
|
|
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
def dict_key_crosscheck(self, d, keys):
|
|
|
|
|
'''Check that each key in d is in keys, and that each key is in d'''
|
|
|
|
|
self.assertEqual(sorted(d.keys()), sorted(keys))
|
|
|
|
|
|
|
|
|
|
def libinput_events(self, filter=None):
|
|
|
|
|
'''Returns all libinput events in the recording, regardless of the
|
|
|
|
|
device'''
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
events = d['events']
|
|
|
|
|
for e in events:
|
|
|
|
|
try:
|
|
|
|
|
libinput = e['libinput']
|
|
|
|
|
except KeyError:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
for ev in libinput:
|
2018-04-19 13:48:25 +10:00
|
|
|
if (filter is None or ev['type'] == filter or
|
|
|
|
|
isinstance(filter, list) and ev['type'] in filter):
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
yield ev
|
|
|
|
|
|
2018-03-09 14:23:55 +10:00
|
|
|
def test_sections_exist(self):
|
|
|
|
|
sections = ['version', 'ndevices', 'libinput', 'system', 'devices']
|
|
|
|
|
for section in sections:
|
|
|
|
|
self.assertIn(section, self.yaml)
|
|
|
|
|
|
|
|
|
|
def test_version(self):
|
|
|
|
|
version = self.yaml['version']
|
|
|
|
|
self.assertTrue(isinstance(version, int))
|
|
|
|
|
self.assertEqual(version, 1)
|
|
|
|
|
|
|
|
|
|
def test_ndevices(self):
|
|
|
|
|
ndevices = self.yaml['ndevices']
|
|
|
|
|
self.assertTrue(isinstance(ndevices, int))
|
|
|
|
|
self.assertGreaterEqual(ndevices, 1)
|
|
|
|
|
self.assertEqual(ndevices, len(self.yaml['devices']))
|
|
|
|
|
|
|
|
|
|
def test_libinput(self):
|
|
|
|
|
libinput = self.yaml['libinput']
|
|
|
|
|
version = libinput['version']
|
|
|
|
|
self.assertTrue(isinstance(version, str))
|
2018-04-19 16:01:42 +10:00
|
|
|
self.assertGreaterEqual(parse_version(version),
|
|
|
|
|
parse_version('1.10.0'))
|
2018-03-09 14:23:55 +10:00
|
|
|
git = libinput['git']
|
|
|
|
|
self.assertTrue(isinstance(git, str))
|
|
|
|
|
self.assertNotEqual(git, 'unknown')
|
|
|
|
|
|
|
|
|
|
def test_system(self):
|
|
|
|
|
system = self.yaml['system']
|
|
|
|
|
kernel = system['kernel']
|
|
|
|
|
self.assertTrue(isinstance(kernel, str))
|
|
|
|
|
self.assertEqual(kernel, os.uname().release)
|
|
|
|
|
|
|
|
|
|
dmi = system['dmi']
|
|
|
|
|
self.assertTrue(isinstance(dmi, str))
|
|
|
|
|
with open('/sys/class/dmi/id/modalias') as f:
|
|
|
|
|
sys_dmi = f.read()[:-1] # trailing newline
|
|
|
|
|
self.assertEqual(dmi, sys_dmi)
|
|
|
|
|
|
|
|
|
|
def test_devices_sections_exist(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
self.assertIn('node', d)
|
|
|
|
|
self.assertIn('evdev', d)
|
|
|
|
|
self.assertIn('udev', d)
|
|
|
|
|
|
|
|
|
|
def test_evdev_sections_exist(self):
|
|
|
|
|
sections = ['name', 'id', 'codes', 'properties']
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
evdev = d['evdev']
|
|
|
|
|
for s in sections:
|
|
|
|
|
self.assertIn(s, evdev)
|
|
|
|
|
|
|
|
|
|
def test_evdev_name(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
evdev = d['evdev']
|
|
|
|
|
name = evdev['name']
|
|
|
|
|
self.assertTrue(isinstance(name, str))
|
|
|
|
|
self.assertGreaterEqual(len(name), 5)
|
|
|
|
|
|
|
|
|
|
def test_evdev_id(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
evdev = d['evdev']
|
|
|
|
|
id = evdev['id']
|
|
|
|
|
self.assertTrue(isinstance(id, list))
|
|
|
|
|
self.assertEqual(len(id), 4)
|
|
|
|
|
self.assertGreater(id[0], 0)
|
|
|
|
|
self.assertGreater(id[1], 0)
|
|
|
|
|
|
|
|
|
|
def test_evdev_properties(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
evdev = d['evdev']
|
|
|
|
|
properties = evdev['properties']
|
|
|
|
|
self.assertTrue(isinstance(properties, list))
|
|
|
|
|
|
|
|
|
|
def test_udev_sections_exist(self):
|
|
|
|
|
sections = ['properties']
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
udev = d['udev']
|
|
|
|
|
for s in sections:
|
|
|
|
|
self.assertIn(s, udev)
|
|
|
|
|
|
|
|
|
|
def test_udev_properties(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
udev = d['udev']
|
|
|
|
|
properties = udev['properties']
|
|
|
|
|
self.assertTrue(isinstance(properties, list))
|
|
|
|
|
self.assertGreater(len(properties), 0)
|
|
|
|
|
|
|
|
|
|
self.assertIn('ID_INPUT=1', properties)
|
|
|
|
|
for p in properties:
|
|
|
|
|
self.assertTrue(re.match('[A-Z0-9_]+=.+', p))
|
|
|
|
|
|
|
|
|
|
def test_udev_id_inputs(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
udev = d['udev']
|
|
|
|
|
properties = udev['properties']
|
|
|
|
|
id_inputs = [p for p in properties if p.startswith('ID_INPUT')]
|
|
|
|
|
# We expect ID_INPUT and ID_INPUT_something, but might get more
|
|
|
|
|
# than one of the latter
|
|
|
|
|
self.assertGreaterEqual(len(id_inputs), 2)
|
|
|
|
|
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
def test_events_have_section(self):
|
2018-03-09 14:23:55 +10:00
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
events = d['events']
|
|
|
|
|
for e in events:
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
self.assertTrue('evdev' in e or 'libinput' in e)
|
2018-03-09 14:23:55 +10:00
|
|
|
|
|
|
|
|
def test_events_evdev(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
events = d['events']
|
|
|
|
|
for e in events:
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
try:
|
|
|
|
|
evdev = e['evdev']
|
|
|
|
|
except KeyError:
|
|
|
|
|
continue
|
|
|
|
|
|
2018-03-09 14:23:55 +10:00
|
|
|
for ev in evdev:
|
|
|
|
|
self.assertEqual(len(ev), 5)
|
|
|
|
|
|
|
|
|
|
# Last event in each frame is SYN_REPORT
|
|
|
|
|
ev_syn = evdev[-1]
|
|
|
|
|
self.assertEqual(ev_syn[2], 0)
|
|
|
|
|
self.assertEqual(ev_syn[3], 0)
|
2018-04-19 14:04:09 +10:00
|
|
|
# SYN_REPORT value is 1 in case of some key repeats
|
|
|
|
|
self.assertLessEqual(ev_syn[4], 1)
|
2018-03-09 14:23:55 +10:00
|
|
|
|
|
|
|
|
def test_events_evdev_syn_report(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
events = d['events']
|
|
|
|
|
for e in events:
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
try:
|
|
|
|
|
evdev = e['evdev']
|
|
|
|
|
except KeyError:
|
|
|
|
|
continue
|
2018-03-09 14:23:55 +10:00
|
|
|
for ev in evdev[:-1]:
|
|
|
|
|
self.assertFalse(ev[2] == 0 and ev[3] == 0)
|
|
|
|
|
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
def test_events_libinput(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
events = d['events']
|
|
|
|
|
for e in events:
|
|
|
|
|
try:
|
|
|
|
|
libinput = e['libinput']
|
|
|
|
|
except KeyError:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
self.assertTrue(isinstance(libinput, list))
|
|
|
|
|
for ev in libinput:
|
|
|
|
|
self.assertTrue(isinstance(ev, dict))
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_type(self):
|
2018-04-19 13:46:12 +10:00
|
|
|
types = ['POINTER_MOTION', 'POINTER_MOTION_ABSOLUTE', 'POINTER_AXIS',
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
'POINTER_BUTTON', 'DEVICE_ADDED', 'KEYBOARD_KEY',
|
2018-04-19 13:48:25 +10:00
|
|
|
'TOUCH_DOWN', 'TOUCH_MOTION', 'TOUCH_UP', 'TOUCH_FRAME',
|
|
|
|
|
'GESTURE_SWIPE_BEGIN', 'GESTURE_SWIPE_UPDATE',
|
|
|
|
|
'GESTURE_SWIPE_END', 'GESTURE_PINCH_BEGIN',
|
|
|
|
|
'GESTURE_PINCH_UPDATE', 'GESTURE_PINCH_END',
|
2018-05-02 10:50:20 +10:00
|
|
|
'TABLET_TOOL_AXIS', 'TABLET_TOOL_PROXIMITY',
|
|
|
|
|
'TABLET_TOOL_BUTTON', 'TABLET_TOOL_TIP',
|
|
|
|
|
'TABLET_PAD_STRIP', 'TABLET_PAD_RING',
|
|
|
|
|
'TABLET_PAD_BUTTON'
|
2018-04-19 13:48:25 +10:00
|
|
|
]
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
for e in self.libinput_events():
|
|
|
|
|
self.assertIn('type', e)
|
|
|
|
|
self.assertIn(e['type'], types)
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_time(self):
|
|
|
|
|
# DEVICE_ADDED has no time
|
|
|
|
|
# first event may have 0.0 time if the first frame generates a
|
|
|
|
|
# libinput event.
|
|
|
|
|
try:
|
|
|
|
|
for e in list(self.libinput_events())[2:]:
|
|
|
|
|
self.assertIn('time', e)
|
|
|
|
|
self.assertGreater(e['time'], 0.0)
|
|
|
|
|
self.assertLess(e['time'], 60.0)
|
|
|
|
|
except IndexError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_device_added(self):
|
|
|
|
|
keys = ['type', 'seat', 'logical_seat']
|
|
|
|
|
for e in self.libinput_events('DEVICE_ADDED'):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
self.assertEqual(e['seat'], 'seat0')
|
|
|
|
|
self.assertEqual(e['logical_seat'], 'default')
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_pointer_motion(self):
|
|
|
|
|
keys = ['type', 'time', 'delta', 'unaccel']
|
|
|
|
|
for e in self.libinput_events('POINTER_MOTION'):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
delta = e['delta']
|
|
|
|
|
self.assertTrue(isinstance(delta, list))
|
|
|
|
|
self.assertEqual(len(delta), 2)
|
|
|
|
|
for d in delta:
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
unaccel = e['unaccel']
|
|
|
|
|
self.assertTrue(isinstance(unaccel, list))
|
|
|
|
|
self.assertEqual(len(unaccel), 2)
|
|
|
|
|
for d in unaccel:
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_pointer_button(self):
|
|
|
|
|
keys = ['type', 'time', 'button', 'state', 'seat_count']
|
|
|
|
|
for e in self.libinput_events('POINTER_BUTTON'):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
button = e['button']
|
|
|
|
|
self.assertGreater(button, 0x100) # BTN_0
|
|
|
|
|
self.assertLess(button, 0x160) # KEY_OK
|
|
|
|
|
state = e['state']
|
|
|
|
|
self.assertIn(state, ['pressed', 'released'])
|
|
|
|
|
scount = e['seat_count']
|
|
|
|
|
self.assertGreaterEqual(scount, 0)
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_pointer_absolute(self):
|
|
|
|
|
keys = ['type', 'time', 'point', 'transformed']
|
|
|
|
|
for e in self.libinput_events('POINTER_MOTION_ABSOLUTE'):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
point = e['point']
|
|
|
|
|
self.assertTrue(isinstance(point, list))
|
|
|
|
|
self.assertEqual(len(point), 2)
|
|
|
|
|
for p in point:
|
|
|
|
|
self.assertTrue(isinstance(p, float))
|
|
|
|
|
self.assertGreater(p, 0.0)
|
|
|
|
|
self.assertLess(p, 300.0)
|
|
|
|
|
|
|
|
|
|
transformed = e['transformed']
|
|
|
|
|
self.assertTrue(isinstance(transformed, list))
|
|
|
|
|
self.assertEqual(len(transformed), 2)
|
|
|
|
|
for t in transformed:
|
|
|
|
|
self.assertTrue(isinstance(t, float))
|
|
|
|
|
self.assertGreater(t, 0.0)
|
|
|
|
|
self.assertLess(t, 100.0)
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_touch(self):
|
|
|
|
|
keys = ['type', 'time', 'slot', 'seat_slot']
|
|
|
|
|
for e in self.libinput_events():
|
|
|
|
|
if (not e['type'].startswith('TOUCH_') or
|
|
|
|
|
e['type'] == 'TOUCH_FRAME'):
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
for k in keys:
|
|
|
|
|
self.assertIn(k, e.keys())
|
|
|
|
|
slot = e['slot']
|
|
|
|
|
seat_slot = e['seat_slot']
|
|
|
|
|
|
|
|
|
|
self.assertGreaterEqual(slot, 0)
|
|
|
|
|
self.assertGreaterEqual(seat_slot, 0)
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_touch_down(self):
|
|
|
|
|
keys = ['type', 'time', 'slot', 'seat_slot', 'point', 'transformed']
|
|
|
|
|
for e in self.libinput_events('TOUCH_DOWN'):
|
2018-04-19 16:01:42 +10:00
|
|
|
self.dict_key_crosscheck(e, keys)
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
point = e['point']
|
|
|
|
|
self.assertTrue(isinstance(point, list))
|
|
|
|
|
self.assertEqual(len(point), 2)
|
|
|
|
|
for p in point:
|
|
|
|
|
self.assertTrue(isinstance(p, float))
|
|
|
|
|
self.assertGreater(p, 0.0)
|
|
|
|
|
self.assertLess(p, 300.0)
|
|
|
|
|
|
|
|
|
|
transformed = e['transformed']
|
|
|
|
|
self.assertTrue(isinstance(transformed, list))
|
|
|
|
|
self.assertEqual(len(transformed), 2)
|
|
|
|
|
for t in transformed:
|
|
|
|
|
self.assertTrue(isinstance(t, float))
|
|
|
|
|
self.assertGreater(t, 0.0)
|
|
|
|
|
self.assertLess(t, 100.0)
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_touch_motion(self):
|
|
|
|
|
keys = ['type', 'time', 'slot', 'seat_slot', 'point', 'transformed']
|
|
|
|
|
for e in self.libinput_events('TOUCH_MOTION'):
|
2018-04-19 16:01:42 +10:00
|
|
|
self.dict_key_crosscheck(e, keys)
|
tools: libinput-record: add support for printing libinput events
Collect libinput events together with the evdev events and print them to the
log. This makes it possible to debug the full behavior of a user's machine
rather than having to replay it with potential different race conditions/side
effects.
Example event output:
- evdev:
- [ 2, 314443, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 314443, 1, 57, 1] # EV_KEY / KEY_SPACE 1
- [ 2, 314443, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +87ms
libinput:
- {time: 2.314443, type: KEYBOARD_KEY, key: 57, state: pressed}
- evdev:
- [ 2, 377203, 4, 4, 57] # EV_MSC / MSC_SCAN 57
- [ 2, 377203, 1, 57, 0] # EV_KEY / KEY_SPACE 0
- [ 2, 377203, 0, 0, 0] # ------------ SYN_REPORT (0) ---------- +63ms
libinput:
- {time: 2.377203, type: KEYBOARD_KEY, key: 57, state: released}
Note that the only way to know that events are within the same frame is to
check the timestamp. libinput keeps those intact which means we can tell that
if we just had an evdev frame with timestamp T and get a pointer motion with
timestamp T, that frame caused the motion event.
So far, only key, pointer and touch events are printed. We also
hardcode-enable tapping where available until we have options to enable this
on the commandline just because that's useful to have.
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
2018-03-01 10:04:11 +10:00
|
|
|
point = e['point']
|
|
|
|
|
self.assertTrue(isinstance(point, list))
|
|
|
|
|
self.assertEqual(len(point), 2)
|
|
|
|
|
for p in point:
|
|
|
|
|
self.assertTrue(isinstance(p, float))
|
|
|
|
|
self.assertGreater(p, 0.0)
|
|
|
|
|
self.assertLess(p, 300.0)
|
|
|
|
|
|
|
|
|
|
transformed = e['transformed']
|
|
|
|
|
self.assertTrue(isinstance(transformed, list))
|
|
|
|
|
self.assertEqual(len(transformed), 2)
|
|
|
|
|
for t in transformed:
|
|
|
|
|
self.assertTrue(isinstance(t, float))
|
|
|
|
|
self.assertGreater(t, 0.0)
|
|
|
|
|
self.assertLess(t, 100.0)
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_touch_frame(self):
|
|
|
|
|
devices = self.yaml['devices']
|
|
|
|
|
for d in devices:
|
|
|
|
|
events = d['events']
|
|
|
|
|
for e in events:
|
|
|
|
|
try:
|
|
|
|
|
evdev = e['libinput']
|
|
|
|
|
except KeyError:
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
need_frame = False
|
|
|
|
|
for ev in evdev:
|
|
|
|
|
t = ev['type']
|
|
|
|
|
if not t.startswith('TOUCH_'):
|
|
|
|
|
self.assertFalse(need_frame)
|
|
|
|
|
continue
|
|
|
|
|
|
|
|
|
|
self.assertTrue(need_frame)
|
|
|
|
|
need_frame = False
|
|
|
|
|
else:
|
|
|
|
|
need_frame = True
|
|
|
|
|
|
|
|
|
|
self.assertFalse(need_frame)
|
|
|
|
|
|
2018-04-19 13:48:25 +10:00
|
|
|
def test_events_libinput_gesture_pinch(self):
|
|
|
|
|
keys = ['type', 'time', 'nfingers', 'delta',
|
|
|
|
|
'unaccel', 'angle_delta', 'scale']
|
|
|
|
|
for e in self.libinput_events(['GESTURE_PINCH_BEGIN',
|
|
|
|
|
'GESTURE_PINCH_UPDATE',
|
|
|
|
|
'GESTURE_PINCH_END']):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
delta = e['delta']
|
|
|
|
|
self.assertTrue(isinstance(delta, list))
|
|
|
|
|
self.assertEqual(len(delta), 2)
|
|
|
|
|
for d in delta:
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
unaccel = e['unaccel']
|
|
|
|
|
self.assertTrue(isinstance(unaccel, list))
|
|
|
|
|
self.assertEqual(len(unaccel), 2)
|
|
|
|
|
for d in unaccel:
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
|
|
|
|
|
adelta = e['angle_delta']
|
|
|
|
|
self.assertTrue(isinstance(adelta, list))
|
|
|
|
|
self.assertEqual(len(adelta), 2)
|
|
|
|
|
for d in adelta:
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
|
|
|
|
|
scale = e['scale']
|
|
|
|
|
self.assertTrue(isinstance(scale, list))
|
|
|
|
|
self.assertEqual(len(scale), 2)
|
|
|
|
|
for d in scale:
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_gesture_swipe(self):
|
|
|
|
|
keys = ['type', 'time', 'nfingers', 'delta',
|
|
|
|
|
'unaccel']
|
|
|
|
|
for e in self.libinput_events(['GESTURE_SWIPE_BEGIN',
|
|
|
|
|
'GESTURE_SWIPE_UPDATE',
|
|
|
|
|
'GESTURE_SWIPE_END']):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
delta = e['delta']
|
|
|
|
|
self.assertTrue(isinstance(delta, list))
|
|
|
|
|
self.assertEqual(len(delta), 2)
|
|
|
|
|
for d in delta:
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
unaccel = e['unaccel']
|
|
|
|
|
self.assertTrue(isinstance(unaccel, list))
|
|
|
|
|
self.assertEqual(len(unaccel), 2)
|
|
|
|
|
for d in unaccel:
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
|
2018-05-02 10:50:20 +10:00
|
|
|
def test_events_libinput_tablet_pad_button(self):
|
|
|
|
|
keys = ['type', 'time', 'button', 'state', 'mode', 'is-toggle']
|
|
|
|
|
|
|
|
|
|
for e in self.libinput_events('TABLET_PAD_BUTTON'):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
|
|
|
|
|
b = e['button']
|
|
|
|
|
self.assertTrue(isinstance(b, int))
|
|
|
|
|
self.assertGreaterEqual(b, 0)
|
|
|
|
|
self.assertLessEqual(b, 16)
|
|
|
|
|
|
|
|
|
|
state = e['state']
|
|
|
|
|
self.assertIn(state, ['pressed', 'released'])
|
|
|
|
|
|
|
|
|
|
m = e['mode']
|
|
|
|
|
self.assertTrue(isinstance(m, int))
|
|
|
|
|
self.assertGreaterEqual(m, 0)
|
|
|
|
|
self.assertLessEqual(m, 3)
|
|
|
|
|
|
|
|
|
|
t = e['is-toggle']
|
|
|
|
|
self.assertTrue(isinstance(t, bool))
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_tablet_pad_ring(self):
|
|
|
|
|
keys = ['type', 'time', 'number', 'position', 'source', 'mode']
|
|
|
|
|
|
|
|
|
|
for e in self.libinput_events('TABLET_PAD_RING'):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
|
|
|
|
|
n = e['number']
|
|
|
|
|
self.assertTrue(isinstance(n, int))
|
|
|
|
|
self.assertGreaterEqual(n, 0)
|
|
|
|
|
self.assertLessEqual(n, 4)
|
|
|
|
|
|
|
|
|
|
p = e['position']
|
|
|
|
|
self.assertTrue(isinstance(p, float))
|
|
|
|
|
if p != -1.0: # special 'end' case
|
|
|
|
|
self.assertGreaterEqual(p, 0.0)
|
|
|
|
|
self.assertLess(p, 360.0)
|
|
|
|
|
|
|
|
|
|
m = e['mode']
|
|
|
|
|
self.assertTrue(isinstance(m, int))
|
|
|
|
|
self.assertGreaterEqual(m, 0)
|
|
|
|
|
self.assertLessEqual(m, 3)
|
|
|
|
|
|
|
|
|
|
s = e['source']
|
|
|
|
|
self.assertIn(s, ['finger', 'unknown'])
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_tablet_pad_strip(self):
|
|
|
|
|
keys = ['type', 'time', 'number', 'position', 'source', 'mode']
|
|
|
|
|
|
|
|
|
|
for e in self.libinput_events('TABLET_PAD_STRIP'):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
|
|
|
|
|
n = e['number']
|
|
|
|
|
self.assertTrue(isinstance(n, int))
|
|
|
|
|
self.assertGreaterEqual(n, 0)
|
|
|
|
|
self.assertLessEqual(n, 4)
|
|
|
|
|
|
|
|
|
|
p = e['position']
|
|
|
|
|
self.assertTrue(isinstance(p, float))
|
|
|
|
|
if p != -1.0: # special 'end' case
|
|
|
|
|
self.assertGreaterEqual(p, 0.0)
|
|
|
|
|
self.assertLessEqual(p, 1.0)
|
|
|
|
|
|
|
|
|
|
m = e['mode']
|
|
|
|
|
self.assertTrue(isinstance(m, int))
|
|
|
|
|
self.assertGreaterEqual(m, 0)
|
|
|
|
|
self.assertLessEqual(m, 3)
|
|
|
|
|
|
|
|
|
|
s = e['source']
|
|
|
|
|
self.assertIn(s, ['finger', 'unknown'])
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_tablet_tool_proximity(self):
|
|
|
|
|
keys = ['type', 'time', 'proximity', 'tool-type', 'serial', 'axes']
|
|
|
|
|
|
|
|
|
|
for e in self.libinput_events('TABLET_TOOL_PROXIMITY'):
|
|
|
|
|
for k in keys:
|
|
|
|
|
self.assertIn(k, e)
|
|
|
|
|
|
|
|
|
|
p = e['proximity']
|
|
|
|
|
self.assertIn(p, ['in', 'out'])
|
|
|
|
|
|
|
|
|
|
p = e['tool-type']
|
|
|
|
|
self.assertIn(p, ['pen', 'eraser', 'brush', 'airbrush', 'mouse',
|
|
|
|
|
'lens', 'unknown'])
|
|
|
|
|
|
|
|
|
|
s = e['serial']
|
|
|
|
|
self.assertTrue(isinstance(s, int))
|
|
|
|
|
self.assertGreaterEqual(s, 0)
|
|
|
|
|
|
|
|
|
|
a = e['axes']
|
|
|
|
|
for ax in e['axes']:
|
|
|
|
|
self.assertIn(a, 'pdtrsw')
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_tablet_tool(self):
|
|
|
|
|
keys = ['type', 'time', 'tip']
|
|
|
|
|
|
|
|
|
|
for e in self.libinput_events(['TABLET_TOOL_AXIS',
|
|
|
|
|
'TABLET_TOOL_TIP']):
|
|
|
|
|
for k in keys:
|
|
|
|
|
self.assertIn(k, e)
|
|
|
|
|
|
|
|
|
|
t = e['tip']
|
|
|
|
|
self.assertIn(t, ['down', 'up'])
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_tablet_tool_button(self):
|
|
|
|
|
keys = ['type', 'time', 'button', 'state']
|
|
|
|
|
|
|
|
|
|
for e in self.libinput_events('TABLET_TOOL_BUTTON'):
|
|
|
|
|
self.dict_key_crosscheck(e, keys)
|
|
|
|
|
|
|
|
|
|
b = e['button']
|
|
|
|
|
# STYLUS, STYLUS2, STYLUS3
|
|
|
|
|
self.assertIn(b, [0x14b, 0x14c, 0x139])
|
|
|
|
|
|
|
|
|
|
s = e['state']
|
|
|
|
|
self.assertIn(s, ['pressed', 'released'])
|
|
|
|
|
|
|
|
|
|
def test_events_libinput_tablet_tool_axes(self):
|
|
|
|
|
for e in self.libinput_events(['TABLET_TOOL_PROXIMITY',
|
|
|
|
|
'TABLET_TOOL_AXIS',
|
|
|
|
|
'TABLET_TOOL_TIP']):
|
|
|
|
|
|
|
|
|
|
point = e['point']
|
|
|
|
|
self.assertTrue(isinstance(point, list))
|
|
|
|
|
self.assertEqual(len(point), 2)
|
|
|
|
|
for p in point:
|
|
|
|
|
self.assertTrue(isinstance(p, float))
|
|
|
|
|
self.assertGreater(p, 0.0)
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
tilt = e['tilt']
|
|
|
|
|
self.assertTrue(isinstance(tilt, list))
|
|
|
|
|
self.assertEqual(len(tilt), 2)
|
|
|
|
|
for t in tilt:
|
|
|
|
|
self.assertTrue(isinstance(t, float))
|
|
|
|
|
except KeyError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
d = e['distance']
|
|
|
|
|
self.assertTrue(isinstance(d, float))
|
|
|
|
|
self.assertGreaterEqual(d, 0.0)
|
|
|
|
|
self.assertNotIn('pressure', e)
|
|
|
|
|
except KeyError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
p = e['pressure']
|
|
|
|
|
self.assertTrue(isinstance(p, float))
|
|
|
|
|
self.assertGreaterEqual(p, 0.0)
|
|
|
|
|
self.assertNotIn('distance', e)
|
|
|
|
|
except KeyError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
r = e['rotation']
|
|
|
|
|
self.assertTrue(isinstance(r, float))
|
|
|
|
|
self.assertGreaterEqual(r, 0.0)
|
|
|
|
|
except KeyError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
s = e['slider']
|
|
|
|
|
self.assertTrue(isinstance(s, float))
|
|
|
|
|
self.assertGreaterEqual(s, 0.0)
|
|
|
|
|
except KeyError:
|
|
|
|
|
pass
|
|
|
|
|
|
|
|
|
|
try:
|
|
|
|
|
w = e['wheel']
|
|
|
|
|
self.assertTrue(isinstance(w, float))
|
|
|
|
|
self.assertGreaterEqual(w, 0.0)
|
|
|
|
|
self.assertIn('wheel-discrete', e)
|
|
|
|
|
wd = e['wheel-discrete']
|
|
|
|
|
self.assertTrue(isinstance(wd, 1))
|
|
|
|
|
self.assertGreaterEqual(wd, 0.0)
|
|
|
|
|
|
|
|
|
|
def sign(x): (1, -1)[x < 0]
|
|
|
|
|
self.assertTrue(sign(w), sign(wd))
|
|
|
|
|
except KeyError:
|
|
|
|
|
pass
|
|
|
|
|
|
2018-03-09 14:23:55 +10:00
|
|
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
|
|
parser = argparse.ArgumentParser(description='Verify a YAML recording')
|
|
|
|
|
parser.add_argument('recording', metavar='recorded-file.yaml',
|
|
|
|
|
type=str, help='Path to device recording')
|
|
|
|
|
parser.add_argument('--verbose', action='store_true')
|
|
|
|
|
args = parser.parse_args()
|
|
|
|
|
TestYaml.filename = args.recording
|
|
|
|
|
verbosity = 1
|
|
|
|
|
if args.verbose:
|
|
|
|
|
verbosity = 3
|
|
|
|
|
del sys.argv[1:]
|
|
|
|
|
unittest.main(verbosity=verbosity)
|