From 5fbc38c938489619f30bb6644e2ba096c7c11486 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 2 Apr 2020 20:08:25 +0200 Subject: [PATCH 01/21] tests/fprintd-utils: Run super setUp/tearDown functions --- tests/test_fprintd_utils.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index e1ff4f9..e5bfe2c 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -61,6 +61,7 @@ class TestFprintd(dbusmock.DBusTestCase): klass.sleep_time *= 2 def setUp(self): + super().setUp() (self.p_mock, self.obj_fprintd_manager) = self.spawn_server_template( self.template_name, {}, stdout=subprocess.PIPE) # set log to nonblocking @@ -71,6 +72,7 @@ class TestFprintd(dbusmock.DBusTestCase): def tearDown(self): self.p_mock.terminate() self.p_mock.wait() + super().tearDown() def setup_device(self): device_path = self.obj_fprintd_mock.AddDevice('FDO Trigger Finger Laser Reader', 3, 'swipe') -- GitLab From a5063dc0e42ccc7143e11a505d8db59f39e385e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 2 Apr 2020 20:09:36 +0200 Subject: [PATCH 02/21] tests/fprintd-utils: Setup the device on setUp() No need to repeat the action in every unit test, but move the tests to a different class to easily allow adding another class with tests with no such initialization --- tests/test_fprintd_utils.py | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index e5bfe2c..d27086c 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -24,7 +24,7 @@ import time dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) -class TestFprintd(dbusmock.DBusTestCase): +class TestFprintdUtilsBase(dbusmock.DBusTestCase): '''Test fprintd utilities''' @classmethod @@ -109,9 +109,13 @@ class TestFprintd(dbusmock.DBusTestCase): return self.get_process_output(proc) - def test_fprintd_enroll(self): + +class TestFprintdUtils(TestFprintdUtilsBase): + def setUp(self): + super().setUp() self.setup_device() + def test_fprintd_enroll(self): process = self.start_utility_process('enroll', ['-f', 'right-index-finger', 'toto']) out = self.get_process_output(process) @@ -124,8 +128,6 @@ class TestFprintd(dbusmock.DBusTestCase): self.assertRegex(out, 'Enroll result: enroll-completed') def test_fprintd_verify(self): - self.setup_device() - process = self.start_utility_process('verify', ['toto']) out = self.get_process_output(process) @@ -139,7 +141,6 @@ class TestFprintd(dbusmock.DBusTestCase): self.assertRegex(out, 'Verify result: verify-match \(done\)') def test_fprintd_verify_script(self): - self.setup_device() script = [ ( 'verify-match', True, 2 ) ] @@ -157,8 +158,6 @@ class TestFprintd(dbusmock.DBusTestCase): self.assertRegex(out, 'Verify result: verify-match \(done\)') def test_fprintd_list(self): - self.setup_device() - # Rick has no fingerprints enrolled out = self.run_utility_process('list', ['rick']) self.assertRegex(out, r'has no fingers enrolled for') @@ -168,8 +167,6 @@ class TestFprintd(dbusmock.DBusTestCase): self.assertRegex(out, r'right-little-finger') def test_fprintd_delete(self): - self.setup_device() - # Has fingerprints enrolled out = self.run_utility_process('list', ['toto']) self.assertRegex(out, r'left-little-finger') -- GitLab From 93bcac946e80d1c7637a414e9ad0a7645bf422db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 2 Apr 2020 20:38:28 +0200 Subject: [PATCH 03/21] tests/fprintd-utils: Move verification tests to a single class We can factorize various checks, so let's simplify test code --- tests/test_fprintd_utils.py | 79 ++++++++++++++++++++++--------------- 1 file changed, 48 insertions(+), 31 deletions(-) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index d27086c..4cc1841 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -77,7 +77,12 @@ class TestFprintdUtilsBase(dbusmock.DBusTestCase): def setup_device(self): device_path = self.obj_fprintd_mock.AddDevice('FDO Trigger Finger Laser Reader', 3, 'swipe') self.device_mock = self.dbus_con.get_object('net.reactivated.Fprint', device_path) - self.device_mock.SetEnrolledFingers('toto', ['left-little-finger', 'right-little-finger']) + self.set_enrolled_fingers(['left-little-finger', 'right-little-finger']) + + def set_enrolled_fingers(self, fingers, user='toto'): + self.enrolled_fingers = fingers + self.device_mock.SetEnrolledFingers('toto', self.enrolled_fingers, + signature='sas') def start_utility_process(self, utility_name, args=[], sleep=True): utility = [ os.path.join(self.tools_prefix, 'fprintd-{}'.format(utility_name)) ] @@ -127,36 +132,6 @@ class TestFprintdUtils(TestFprintdUtilsBase): out = self.get_process_output(process) self.assertRegex(out, 'Enroll result: enroll-completed') - def test_fprintd_verify(self): - process = self.start_utility_process('verify', ['toto']) - - out = self.get_process_output(process) - self.assertRegex(out, r'left-little-finger') - self.assertNotRegex(out, 'Verify result: verify-match \(done\)') - - self.device_mock.EmitVerifyStatus('verify-match', True) - time.sleep(self.sleep_time) - - out = self.get_process_output(process) - self.assertRegex(out, 'Verify result: verify-match \(done\)') - - def test_fprintd_verify_script(self): - script = [ - ( 'verify-match', True, 2 ) - ] - self.device_mock.SetVerifyScript(script) - - process = self.start_utility_process('verify', ['toto']) - - out = self.get_process_output(process) - self.assertRegex(out, r'left-little-finger') - self.assertNotRegex(out, 'Verify result: verify-match \(done\)') - - time.sleep(self.sleep_time * 4) - - out = self.get_process_output(process) - self.assertRegex(out, 'Verify result: verify-match \(done\)') - def test_fprintd_list(self): # Rick has no fingerprints enrolled out = self.run_utility_process('list', ['rick']) @@ -180,6 +155,48 @@ class TestFprintdUtils(TestFprintdUtilsBase): out = self.run_utility_process('list', ['toto']) self.assertRegex(out, r'has no fingers enrolled for') + +class TestFprintdUtilsVerify(TestFprintdUtilsBase): + def setUp(self): + super().setUp() + self.setup_device() + + def start_verify_process(self, user='toto', finger=None, checkEnrolled=True): + args = [user] + if finger: + args += ['-f', finger] + + self.process = self.start_utility_process('verify', args) + out = self.get_process_output(self.process) + + self.assertNotIn('Verify result:', out) + + if checkEnrolled: + for f in self.enrolled_fingers: + self.assertIn(f, out) + + def assertVerifyMatch(self, match): + self.assertIn('Verify result: {} (done)'.format( + 'verify-match' if match else 'verify-no-match'), + self.get_process_output(self.process)) + + def test_fprintd_verify(self): + self.start_verify_process() + + self.device_mock.EmitVerifyStatus('verify-match', True) + time.sleep(self.sleep_time) + self.assertVerifyMatch(True) + + def test_fprintd_verify_script(self): + script = [ + ( 'verify-match', True, 2 ) + ] + self.device_mock.SetVerifyScript(script) + + self.start_verify_process() + time.sleep(self.sleep_time * 4) + self.assertVerifyMatch(True) + if __name__ == '__main__': # avoid writing to stderr unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2)) -- GitLab From 59b3d2af8dbf6f730221f686a645ae4a8578dbc0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 2 Apr 2020 21:15:39 +0200 Subject: [PATCH 04/21] tests/fprintd-utils: Call addCleanup actions in reverse order unittest addCleanup calls are called in reverse order, so we need to reverse the order of the calls as well, otherwise we won't correctly terminate the subprocess children --- tests/fprintd.py | 2 +- tests/test_fprintd_utils.py | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/fprintd.py b/tests/fprintd.py index 0bd9ac3..7351980 100755 --- a/tests/fprintd.py +++ b/tests/fprintd.py @@ -1123,8 +1123,8 @@ class FPrintdUtilsTest(FPrintdVirtualDeviceBaseTest): env=env, stdout=None, stderr=subprocess.STDOUT) - self.addCleanup(self.utils_proc[name].terminate) self.addCleanup(self.utils_proc[name].wait) + self.addCleanup(self.utils_proc[name].terminate) return self.utils_proc[name] def test_vanished_client_operation_is_cancelled(self): diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 4cc1841..e609b83 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -93,9 +93,9 @@ class TestFprintdUtilsBase(dbusmock.DBusTestCase): flags = fcntl.fcntl(process.stdout, fcntl.F_GETFL) fcntl.fcntl(process.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) - self.addCleanup(lambda: print(process.stdout.read())) - self.addCleanup(process.terminate) self.addCleanup(process.wait) + self.addCleanup(process.terminate) + self.addCleanup(lambda: print(process.stdout.read())) if sleep: time.sleep(self.sleep_time) -- GitLab From 4b0cde81fd96dc83b822435013cdc6e4e3f21cac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 2 Apr 2020 21:24:43 +0200 Subject: [PATCH 05/21] tests/fprintd-utils: Add utility function to stop the utility process This avoids addCleanup ordering errors and also errors when we may try to print an invalid stdout pipe (like when we have processed it all), as python might fail with something like: ====================================================================== ERROR: test_fprintd_multiple_verify_fails (__main__.TestFprintdUtilsVerify) ---------------------------------------------------------------------- Traceback (most recent call last): File "~/GNOME/fprintd/tests/test_fprintd_utils.py", line 102, in self.addCleanup(lambda: print(process.stdout.read())) File "/usr/lib/python3.8/codecs.py", line 321, in decode data = self.buffer + input TypeError: can't concat NoneType to bytes --- tests/test_fprintd_utils.py | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index e609b83..129cc25 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -93,15 +93,24 @@ class TestFprintdUtilsBase(dbusmock.DBusTestCase): flags = fcntl.fcntl(process.stdout, fcntl.F_GETFL) fcntl.fcntl(process.stdout, fcntl.F_SETFL, flags | os.O_NONBLOCK) - self.addCleanup(process.wait) - self.addCleanup(process.terminate) - self.addCleanup(lambda: print(process.stdout.read())) + self.addCleanup(self.try_stop_utility_process, process) if sleep: time.sleep(self.sleep_time) return process + def stop_utility_process(self, process): + print(process.stdout.read()) + process.terminate() + process.wait() + + def try_stop_utility_process(self, process): + try: + self.stop_utility_process(process) + except: + pass + def get_process_output(self, process): out = process.stdout.read() self.addCleanup(print, out) -- GitLab From 870b48637a18abb429d2d737d0560e06943b4822 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 2 Apr 2020 21:25:13 +0200 Subject: [PATCH 06/21] tests/fprintd-utils: Verify errors if the device is already claimed --- tests/test_fprintd_utils.py | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 129cc25..2fd644f 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -178,6 +178,7 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): self.process = self.start_utility_process('verify', args) out = self.get_process_output(self.process) + self.assertNotRegex(out, r'Device already in use by [A-z]+') self.assertNotIn('Verify result:', out) if checkEnrolled: @@ -206,6 +207,12 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): time.sleep(self.sleep_time * 4) self.assertVerifyMatch(True) + def test_fprintd_multiple_verify_fails(self): + self.start_verify_process() + + with self.assertRaisesRegex(AssertionError, r'Device already in use'): + self.start_verify_process() + if __name__ == '__main__': # avoid writing to stderr unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2)) -- GitLab From 6641cb6da8eb8947547d90fef5d4c49bb8cd698b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 2 Apr 2020 22:23:41 +0200 Subject: [PATCH 07/21] tests/fprintd-utils: Verify that we can match all the enrolled fingers --- tests/test_fprintd_utils.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 2fd644f..48c248f 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -197,6 +197,14 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): time.sleep(self.sleep_time) self.assertVerifyMatch(True) + def test_fprintd_verify_enrolled_fingers(self): + for finger in self.enrolled_fingers: + self.start_verify_process(finger=finger) + + self.device_mock.EmitVerifyStatus('verify-match', True) + time.sleep(self.sleep_time) + self.assertVerifyMatch(True) + def test_fprintd_verify_script(self): script = [ ( 'verify-match', True, 2 ) -- GitLab From 5a703baa20f2eeb29806bcfa09485e88651e9859 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Thu, 2 Apr 2020 22:21:06 +0200 Subject: [PATCH 08/21] verify: Fail if we try to verify a non-enrolled finger Since we list the fingers available fail early in case it's not found --- tests/test_fprintd_utils.py | 25 +++++++++++++++++++++++++ utils/verify.c | 8 ++++++++ 2 files changed, 33 insertions(+) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 48c248f..9c98274 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -22,6 +22,20 @@ import fcntl import os import time + +VALID_FINGER_NAMES = [ + 'left-thumb', + 'left-index-finger', + 'left-middle-finger', + 'left-ring-finger', + 'left-little-finger', + 'right-thumb', + 'right-index-finger', + 'right-middle-finger', + 'right-ring-finger', + 'right-little-finger' +] + dbus.mainloop.glib.DBusGMainLoop(set_as_default=True) class TestFprintdUtilsBase(dbusmock.DBusTestCase): @@ -181,6 +195,10 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): self.assertNotRegex(out, r'Device already in use by [A-z]+') self.assertNotIn('Verify result:', out) + if checkEnrolled and finger: + self.assertNotIn('''Finger '{}' not enrolled for user {}'''.format( + finger, user), out) + if checkEnrolled: for f in self.enrolled_fingers: self.assertIn(f, out) @@ -205,6 +223,13 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): time.sleep(self.sleep_time) self.assertVerifyMatch(True) + def test_fprintd_verify_not_enrolled_fingers(self): + for finger in [f for f in VALID_FINGER_NAMES if f not in self.enrolled_fingers]: + regex = r'Finger \'{}\' not enrolled'.format(finger) + with self.assertRaisesRegex(AssertionError, regex): + self.start_verify_process(finger=finger) + self.device_mock.Release() + def test_fprintd_verify_script(self): script = [ ( 'verify-match', True, 2 ) diff --git a/utils/verify.c b/utils/verify.c index 2989a49..71952b0 100644 --- a/utils/verify.c +++ b/utils/verify.c @@ -100,6 +100,14 @@ static void find_finger(DBusGProxy *dev, const char *username) g_print(" - #%d: %s\n", i, fingers[i]); } + if (finger_name && !g_str_equal (finger_name, "any") && + !g_strv_contains ((const char **) fingers, finger_name)) { + g_print("Finger '%s' not enrolled for user %s.\n", finger_name, + username); + g_free (finger_name); + exit(1); + } + if (finger_name == NULL || strcmp (finger_name, "any") == 0) { g_free (finger_name); finger_name = g_strdup (fingers[0]); -- GitLab From 629f7fcc11da0103cb2d79b84e60c99179a2a200 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:08:17 +0200 Subject: [PATCH 09/21] dbusmock/fprintd: Reset the current action on release So it happens in the real daemon --- tests/dbusmock/fprintd.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/dbusmock/fprintd.py b/tests/dbusmock/fprintd.py index 0fcbe58..f4cf00e 100644 --- a/tests/dbusmock/fprintd.py +++ b/tests/dbusmock/fprintd.py @@ -186,6 +186,7 @@ def Release(device): 'Device was not claimed before use', name='net.reactivated.Fprint.Error.ClaimDevice') device.claimed_user = None + device.action = None def can_verify_finger(device, finger_name): # We should already have checked that there are enrolled fingers -- GitLab From ac98b881be01d1c860c5ece4f3ec160e321e275a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:07:32 +0200 Subject: [PATCH 10/21] dbusmock/fprintd: Make possible to retrieve the finger selected for verification So that we can ensure that the client requested the one we expect --- tests/dbusmock/fprintd.py | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/tests/dbusmock/fprintd.py b/tests/dbusmock/fprintd.py index f4cf00e..c99315a 100644 --- a/tests/dbusmock/fprintd.py +++ b/tests/dbusmock/fprintd.py @@ -141,6 +141,7 @@ def AddDevice(self, device_name, num_enroll_stages, scan_type): device.fingers = {} device.claimed_user = None device.action = None + device.selected_finger = None device.verify_script = [] return path @@ -187,6 +188,7 @@ def Release(device): name='net.reactivated.Fprint.Error.ClaimDevice') device.claimed_user = None device.action = None + device.selected_finger = None def can_verify_finger(device, finger_name): # We should already have checked that there are enrolled fingers @@ -231,6 +233,7 @@ def VerifyStart(device, finger_name): if finger_name == 'any': finger_name = device.fingers[device.claimed_user][0] + device.selected_finger = finger_name device.EmitSignal(DEVICE_IFACE, 'VerifyFingerSelected', 's', [ finger_name ]) @@ -263,6 +266,7 @@ def VerifyStop(device): 'No verification to stop', name='net.reactivated.Fprint.Error.NoActionInProgress') device.action = None + device.selected_finger = None @dbus.service.method(DEVICE_IFACE, in_signature='s', out_signature='') @@ -331,6 +335,20 @@ def SetEnrolledFingers(device, user, fingers): device.fingers[user] = fingers +@dbus.service.method(DEVICE_MOCK_IFACE, + in_signature='', out_signature='s') +def GetSelectedFinger(device): + '''Convenience method to get the finger under verification + + Returns the finger name that the user has selected for verifying + ''' + if not device.selected_finger: + raise dbus.exceptions.DBusException( + 'Device is not verifying', + name='net.reactivated.Fprint.Error.NoActionInProgress') + + return device.selected_finger + @dbus.service.method(DEVICE_MOCK_IFACE, in_signature='a(sbi)', out_signature='') def SetVerifyScript(device, script): -- GitLab From 5635383c96b936de1b180d62653259c529c727a4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:11:52 +0200 Subject: [PATCH 11/21] tests/fprintd-utils: Check that fprintd-verify requests the expected finger --- tests/test_fprintd_utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 9c98274..27744df 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -203,6 +203,10 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): for f in self.enrolled_fingers: self.assertIn(f, out) + if finger: + expected_finger = finger + self.assertEqual(self.device_mock.GetSelectedFinger(), expected_finger) + def assertVerifyMatch(self, match): self.assertIn('Verify result: {} (done)'.format( 'verify-match' if match else 'verify-no-match'), -- GitLab From 94d3a18dcd1d31ef8b2c77c69b418202658b0ef7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:12:41 +0200 Subject: [PATCH 12/21] tests/fprintd-utils: Check that verify returns an error if no finger is set --- tests/dbusmock/fprintd.py | 5 ----- tests/test_fprintd_utils.py | 5 +++++ 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/dbusmock/fprintd.py b/tests/dbusmock/fprintd.py index c99315a..a3cea2d 100644 --- a/tests/dbusmock/fprintd.py +++ b/tests/dbusmock/fprintd.py @@ -322,11 +322,6 @@ def SetEnrolledFingers(device, user, fingers): Returns nothing. ''' - if len(fingers) < 1: - raise dbus.exceptions.DBusException( - 'Fingers array must not be empty', - name='org.freedesktop.DBus.Error.InvalidArgs') - for k in fingers: if k not in VALID_FINGER_NAMES: raise dbus.exceptions.DBusException( diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 27744df..62b3681 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -234,6 +234,11 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): self.start_verify_process(finger=finger) self.device_mock.Release() + def test_fprintd_verify_no_enrolled_fingers(self): + self.set_enrolled_fingers([]) + self.start_verify_process() + self.assertEqual(self.process.poll(), 1) + def test_fprintd_verify_script(self): script = [ ( 'verify-match', True, 2 ) -- GitLab From d33a7c7e9d9b2ed7bf6e7ee4675b5433e00eb142 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:55:48 +0200 Subject: [PATCH 13/21] tests/fprintd-utils: Check that all fingers are listed --- tests/test_fprintd_utils.py | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 62b3681..70c380f 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -239,6 +239,10 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): self.start_verify_process() self.assertEqual(self.process.poll(), 1) + def test_fprintd_list_all_fingers(self): + self.set_enrolled_fingers(VALID_FINGER_NAMES) + self.start_verify_process() + def test_fprintd_verify_script(self): script = [ ( 'verify-match', True, 2 ) -- GitLab From d6c70be8227d2844ed4d78c60c9a90c7ee9021fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:49:25 +0200 Subject: [PATCH 14/21] dbusmock/fprintd: Add ability to remove devices --- tests/dbusmock/fprintd.py | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/tests/dbusmock/fprintd.py b/tests/dbusmock/fprintd.py index a3cea2d..51faa0b 100644 --- a/tests/dbusmock/fprintd.py +++ b/tests/dbusmock/fprintd.py @@ -146,6 +146,19 @@ def AddDevice(self, device_name, num_enroll_stages, scan_type): return path +@dbus.service.method(MANAGER_MOCK_IFACE, + in_signature='o') +def RemoveDevice(self, path): + # This isn't compatible with hotplugging devices, which fprintd doesn't + # support yet, but it's meant to remove devices added to the mock for + # testing purposes. + if not path: + raise dbus.exceptions.DBusException( + 'Invalid empty path.', + name='org.freedesktop.DBus.Error.InvalidArgs') + + self.RemoveObject(path) + @dbus.service.method(DEVICE_IFACE, in_signature='s', out_signature='as') def ListEnrolledFingers(device, user): -- GitLab From 6797928884abae06266c3910ccaaf9cfcbc882d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:50:42 +0200 Subject: [PATCH 15/21] dbusmock/fprintd: Add ability to add a device with Identification support Devices which have identification support "any" finger and do not fallback to a single-finger check. --- tests/dbusmock/fprintd.py | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/tests/dbusmock/fprintd.py b/tests/dbusmock/fprintd.py index 51faa0b..d7530fe 100644 --- a/tests/dbusmock/fprintd.py +++ b/tests/dbusmock/fprintd.py @@ -93,8 +93,9 @@ def GetDefaultDevice(self): return devices[0] @dbus.service.method(MANAGER_MOCK_IFACE, - in_signature='sis', out_signature='s') -def AddDevice(self, device_name, num_enroll_stages, scan_type): + in_signature='sisb', out_signature='s') +def AddDevice(self, device_name, num_enroll_stages, scan_type, + has_identification=False): '''Convenience method to add a fingerprint reader device You have to specify a device name, the number of enrollment @@ -139,6 +140,7 @@ def AddDevice(self, device_name, num_enroll_stages, scan_type): device = mockobject.objects[path] device.fingers = {} + device.has_identification = has_identification device.claimed_user = None device.action = None device.selected_finger = None @@ -244,7 +246,7 @@ def VerifyStart(device, finger_name): name='net.reactivated.Fprint.Error.AlreadyInUse') device.action = 'verify' - if finger_name == 'any': + if finger_name == 'any' and not device.has_identification: finger_name = device.fingers[device.claimed_user][0] device.selected_finger = finger_name device.EmitSignal(DEVICE_IFACE, 'VerifyFingerSelected', 's', [ @@ -357,6 +359,16 @@ def GetSelectedFinger(device): return device.selected_finger +@dbus.service.method(DEVICE_MOCK_IFACE, + in_signature='', out_signature='b') +def HasIdentification(device): + '''Convenience method to get if a device supports identification + + Returns whether identification is supported. + ''' + + return device.has_identification + @dbus.service.method(DEVICE_MOCK_IFACE, in_signature='a(sbi)', out_signature='') def SetVerifyScript(device, script): -- GitLab From d7ca9e6095d1bc38643ebcad76c7d82e01074259 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:23:04 +0200 Subject: [PATCH 16/21] tests/fprintd-utils: Verify happens on first finger if device has no identification Ensure that this is true when using the utility --- tests/test_fprintd_utils.py | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 70c380f..de9df50 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -205,6 +205,8 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): if finger: expected_finger = finger + if finger == 'any' and not self.device_mock.HasIdentification(): + expected_finger = self.enrolled_fingers[0] self.assertEqual(self.device_mock.GetSelectedFinger(), expected_finger) def assertVerifyMatch(self, match): @@ -227,6 +229,13 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): time.sleep(self.sleep_time) self.assertVerifyMatch(True) + def test_fprintd_verify_any_finger_no_identification(self): + self.start_verify_process(finger='any') + + self.device_mock.EmitVerifyStatus('verify-match', True) + time.sleep(self.sleep_time) + self.assertVerifyMatch(True) + def test_fprintd_verify_not_enrolled_fingers(self): for finger in [f for f in VALID_FINGER_NAMES if f not in self.enrolled_fingers]: regex = r'Finger \'{}\' not enrolled'.format(finger) -- GitLab From f6eb3b3ea5f40777e2244ad4f7c029f154a8b49f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 02:55:33 +0200 Subject: [PATCH 17/21] verify: Pass the "any" finger parameter to the daemon fprintd supports "any" finger parameter for the VerifyStart call, and it's up to the daemon to pick the first known if the device doesn't support identification. So remove the check to verify utility and add a test to verify this is respected. --- tests/test_fprintd_utils.py | 19 +++++++++++++++++-- utils/verify.c | 3 +-- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index de9df50..03b61fe 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -89,8 +89,10 @@ class TestFprintdUtilsBase(dbusmock.DBusTestCase): super().tearDown() def setup_device(self): - device_path = self.obj_fprintd_mock.AddDevice('FDO Trigger Finger Laser Reader', 3, 'swipe') - self.device_mock = self.dbus_con.get_object('net.reactivated.Fprint', device_path) + self.device_path = self.obj_fprintd_mock.AddDevice( + 'FDO Trigger Finger Laser Reader', 3, 'swipe') + self.device_mock = self.dbus_con.get_object('net.reactivated.Fprint', + self.device_path) self.set_enrolled_fingers(['left-little-finger', 'right-little-finger']) def set_enrolled_fingers(self, fingers, user='toto'): @@ -236,6 +238,19 @@ class TestFprintdUtilsVerify(TestFprintdUtilsBase): time.sleep(self.sleep_time) self.assertVerifyMatch(True) + def test_fprintd_verify_any_finger_identification(self): + self.obj_fprintd_mock.RemoveDevice(self.device_path) + self.device_path = self.obj_fprintd_mock.AddDevice('Full powered device', + 3, 'press', True) + self.device_mock = self.dbus_con.get_object('net.reactivated.Fprint', + self.device_path) + self.set_enrolled_fingers(VALID_FINGER_NAMES) + self.start_verify_process(finger='any') + + self.device_mock.EmitVerifyStatus('verify-match', True) + time.sleep(self.sleep_time) + self.assertVerifyMatch(True) + def test_fprintd_verify_not_enrolled_fingers(self): for finger in [f for f in VALID_FINGER_NAMES if f not in self.enrolled_fingers]: regex = r'Finger \'{}\' not enrolled'.format(finger) diff --git a/utils/verify.c b/utils/verify.c index 71952b0..719b736 100644 --- a/utils/verify.c +++ b/utils/verify.c @@ -108,8 +108,7 @@ static void find_finger(DBusGProxy *dev, const char *username) exit(1); } - if (finger_name == NULL || strcmp (finger_name, "any") == 0) { - g_free (finger_name); + if (finger_name == NULL) { finger_name = g_strdup (fingers[0]); } -- GitLab From 091f373109c9bf730f8b91a9d9d540df798ab7d6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 03:14:44 +0200 Subject: [PATCH 18/21] tests/fprintd-utils: Check the tools return values in some tests --- tests/test_fprintd_utils.py | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index 03b61fe..dcae5d1 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -137,7 +137,7 @@ class TestFprintdUtilsBase(dbusmock.DBusTestCase): ret = proc.wait(timeout=timeout if timeout is not None else self.sleep_time * 4) self.assertLessEqual(ret, 128) - return self.get_process_output(proc) + return self.get_process_output(proc), ret class TestFprintdUtils(TestFprintdUtilsBase): @@ -159,26 +159,31 @@ class TestFprintdUtils(TestFprintdUtilsBase): def test_fprintd_list(self): # Rick has no fingerprints enrolled - out = self.run_utility_process('list', ['rick']) + out, ret = self.run_utility_process('list', ['rick']) self.assertRegex(out, r'has no fingers enrolled for') + self.assertEqual(ret, 0) # Toto does - out = self.run_utility_process('list', ['toto']) + out, ret = self.run_utility_process('list', ['toto']) self.assertRegex(out, r'right-little-finger') + self.assertEqual(ret, 0) def test_fprintd_delete(self): # Has fingerprints enrolled - out = self.run_utility_process('list', ['toto']) + out, ret = self.run_utility_process('list', ['toto']) self.assertRegex(out, r'left-little-finger') + self.assertEqual(ret, 0) self.assertRegex(out, r'right-little-finger') # Delete fingerprints - out = self.run_utility_process('delete', ['toto']) + out, ret = self.run_utility_process('delete', ['toto']) self.assertRegex(out, r'Fingerprints deleted') + self.assertEqual(ret, 0) # Doesn't have fingerprints - out = self.run_utility_process('list', ['toto']) + out, ret = self.run_utility_process('list', ['toto']) self.assertRegex(out, r'has no fingers enrolled for') + self.assertEqual(ret, 0) class TestFprintdUtilsVerify(TestFprintdUtilsBase): -- GitLab From ecc02cb5882dc2d38d3f8c6666b7aa49312f81ae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 03:29:12 +0200 Subject: [PATCH 19/21] utils: Uniform the no-devices error messages removing duplicated checks Use error messages to be consistent, and avoid checking for a returned value when dbus-glib function to fetch it returned false, as it's implicit that we had a failure. Otherwise if didn't fail we are sure that we got the requested value. --- utils/delete.c | 4 ++-- utils/enroll.c | 7 +------ utils/list.c | 4 ++-- utils/verify.c | 7 +------ 4 files changed, 6 insertions(+), 16 deletions(-) diff --git a/utils/delete.c b/utils/delete.c index cf27ebf..0c25b7b 100644 --- a/utils/delete.c +++ b/utils/delete.c @@ -89,12 +89,12 @@ static void process_devices(char **argv) guint i; if (!net_reactivated_Fprint_Manager_get_devices(manager, &devices, &error)) { - g_print("list_devices failed: %s\n", error->message); + g_print("Impossible to get devices: %s\n", error->message); exit (1); } if (devices->len == 0) { - g_print("No devices found\n"); + g_print("No devices available\n"); exit(1); } diff --git a/utils/enroll.c b/utils/enroll.c index 4dd3359..8bd55e9 100644 --- a/utils/enroll.c +++ b/utils/enroll.c @@ -57,14 +57,9 @@ static DBusGProxy *open_device(const char *username) DBusGProxy *dev; if (!net_reactivated_Fprint_Manager_get_default_device(manager, &path, &error)) { - g_print("list_devices failed: %s\n", error->message); + g_print("Impossible to enroll: %s\n", error->message); exit (1); } - - if (path == NULL) { - g_print("No devices found\n"); - exit(1); - } g_print("Using device %s\n", path); diff --git a/utils/list.c b/utils/list.c index 8098c0c..54bc34b 100644 --- a/utils/list.c +++ b/utils/list.c @@ -94,12 +94,12 @@ static void process_devices(char **argv) guint i; if (!net_reactivated_Fprint_Manager_get_devices(manager, &devices, &error)) { - g_print("list_devices failed: %s\n", error->message); + g_print("Impossible to get devices: %s\n", error->message); exit (1); } if (devices->len == 0) { - g_print("No devices found\n"); + g_print("No devices available\n"); exit(1); } diff --git a/utils/verify.c b/utils/verify.c index 719b736..caac88e 100644 --- a/utils/verify.c +++ b/utils/verify.c @@ -54,14 +54,9 @@ static DBusGProxy *open_device(const char *username) DBusGProxy *dev; if (!net_reactivated_Fprint_Manager_get_default_device(manager, &path, &error)) { - g_print("list_devices failed: %s\n", error->message); + g_print("Impossible to verify: %s\n", error->message); exit (1); } - - if (path == NULL) { - g_print("No devices found\n"); - exit(1); - } g_print("Using device %s\n", path); -- GitLab From c85ca09e35ee0177c8c9669bac9c3d067214f6d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 03:15:20 +0200 Subject: [PATCH 20/21] tests/fprintd-utils: Ensure that we exit with error if we have no device --- tests/test_fprintd_utils.py | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/tests/test_fprintd_utils.py b/tests/test_fprintd_utils.py index dcae5d1..afcea53 100755 --- a/tests/test_fprintd_utils.py +++ b/tests/test_fprintd_utils.py @@ -186,6 +186,28 @@ class TestFprintdUtils(TestFprintdUtilsBase): self.assertEqual(ret, 0) +class TestFprintdUtilsNoDeviceTests(TestFprintdUtilsBase): + def test_fprintd_enroll(self): + out, ret = self.run_utility_process('enroll', ['toto']) + self.assertIn('No devices available', out) + self.assertEqual(ret, 1) + + def test_fprintd_list(self): + out, ret = self.run_utility_process('list', ['toto']) + self.assertIn('No devices available', out) + self.assertEqual(ret, 1) + + def test_fprintd_delete(self): + out, ret = self.run_utility_process('delete', ['toto']) + self.assertIn('No devices available', out) + self.assertEqual(ret, 1) + + def test_fprintd_verify(self): + out, ret = self.run_utility_process('verify', ['toto']) + self.assertIn('No devices available', out) + self.assertEqual(ret, 1) + + class TestFprintdUtilsVerify(TestFprintdUtilsBase): def setUp(self): super().setUp() -- GitLab From 3419901f653f71fb36a9af3fd8094563c960d4f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Fri, 3 Apr 2020 04:49:47 +0200 Subject: [PATCH 21/21] build: Don't add the utils tests under the daemon suite --- tests/meson.build | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/meson.build b/tests/meson.build index 289958a..495acbc 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -38,7 +38,7 @@ foreach t: tests fprintd, fprintd_utils, ], - 'suite': ['daemon'], + 'suite': [t == 'fprintd' ? 'daemon' : ''], } ] endforeach -- GitLab