summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Berg <bberg@redhat.com>2020-09-29 12:38:29 +0200
committerBenjamin Berg <bberg@redhat.com>2021-02-18 12:28:19 +0100
commit7ff36888b71e2bee9e14c9941f76faa1e166d29b (patch)
treec188c31ad0a2e76cadb910f0f7da68aade996287
parente3043123f5a9dec70cad50b0c84dac6064fda885 (diff)
tests: Add SDCP virtual device test
-rw-r--r--meson_options.txt5
-rw-r--r--tests/meson.build40
-rw-r--r--tests/virtual-sdcp.py144
3 files changed, 189 insertions, 0 deletions
diff --git a/meson_options.txt b/meson_options.txt
index 414695f..23058ba 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -22,3 +22,8 @@ option('doc',
description: 'Whether to build the API documentation',
type: 'boolean',
value: true)
+
+option('sdcp_virt_binary',
+ description: 'Path to virtual SDCP test binary, please refer to CI for more details.',
+ type: 'string',
+ value: '')
diff --git a/tests/meson.build b/tests/meson.build
index 291d806..293abe6 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -12,6 +12,9 @@ envs.prepend('LD_LIBRARY_PATH', join_paths(meson.build_root(), 'libfprint'))
# random numbers rather than proper ones)
envs.set('FP_DEVICE_EMULATION', '1')
+# Path to SDCP virtual device binary, only used for virtual-sdcp test
+envs.set('SDCP_VIRT_BINARY', get_option('sdcp_virt_binary'))
+
# Set a colon-separated list of native drivers we enable in tests
envs.set('FP_DRIVERS_WHITELIST', ':'.join([
'virtual_image',
@@ -79,6 +82,43 @@ if get_option('introspection')
endif
endforeach
+ if 'virtual_sdcp' in drivers and get_option('sdcp_virt_binary') != ''
+ python3 = find_program('python3')
+ unittest_inspector = find_program('unittest_inspector.py')
+ base_args = files('virtual-sdcp.py')
+ suite = []
+
+ r = run_command(unittest_inspector, files('virtual-sdcp.py'))
+ unit_tests = r.stdout().strip().split('\n')
+
+ if r.returncode() == 0 and unit_tests.length() > 0
+ suite += 'virtual-sdcp'
+ else
+ unit_tests = ['virtual-sdcp']
+ endif
+
+ foreach ut: unit_tests
+ ut_suite = suite
+ ut_args = base_args
+ if unit_tests.length() > 1
+ ut_args += ut
+ ut_suite += ut.split('.')[0]
+ endif
+ test(ut,
+ python3,
+ args: ut_args,
+ suite: ut_suite,
+ depends: libfprint_typelib,
+ env: envs,
+ )
+ endforeach
+ else
+ test('virtual-sdcp',
+ find_program('sh'),
+ args: ['-c', 'exit 77']
+ )
+ endif
+
foreach driver_test: drivers_tests
driver_envs = envs
driver_envs.set('FP_DRIVERS_WHITELIST', driver_test)
diff --git a/tests/virtual-sdcp.py b/tests/virtual-sdcp.py
new file mode 100644
index 0000000..6efb24d
--- /dev/null
+++ b/tests/virtual-sdcp.py
@@ -0,0 +1,144 @@
+#!/usr/bin/env python3
+
+import sys
+try:
+ import gi
+ import os
+
+ from gi.repository import GLib, Gio
+
+ import unittest
+ import subprocess
+ import shutil
+ import tempfile
+except Exception as e:
+ print("Missing dependencies: %s" % str(e))
+ sys.exit(77)
+
+FPrint = None
+
+# Re-run the test with the passed wrapper if set
+wrapper = os.getenv('LIBFPRINT_TEST_WRAPPER')
+if wrapper:
+ wrap_cmd = wrapper.split(' ') + [sys.executable, os.path.abspath(__file__)] + \
+ sys.argv[1:]
+ os.unsetenv('LIBFPRINT_TEST_WRAPPER')
+ sys.exit(subprocess.check_call(wrap_cmd))
+
+# Only permit loading virtual_sdcp driver for tests in this file
+os.environ['FP_DRIVERS_WHITELIST'] = 'virtual_sdcp'
+
+if hasattr(os.environ, 'MESON_SOURCE_ROOT'):
+ root = os.environ['MESON_SOURCE_ROOT']
+else:
+ root = os.path.join(os.path.dirname(__file__), '..')
+
+ctx = GLib.main_context_default()
+
+class VirtualSDCP(unittest.TestCase):
+
+ @classmethod
+ def setUpClass(cls):
+ os.environ['FP_VIRTUAL_SDCP'] = os.environ['SDCP_VIRT_BINARY']
+
+ cls.ctx = FPrint.Context()
+
+ cls.dev = None
+ for dev in cls.ctx.get_devices():
+ cls.dev = dev
+ break
+
+ assert cls.dev is not None, "You need to compile with virtual_sdcp for testing"
+
+ @classmethod
+ def tearDownClass(cls):
+ del cls.dev
+ del cls.ctx
+
+ def setUp(self):
+ pass
+
+ def tearDown(self):
+ pass
+
+ def enroll(self, progress_cb=None):
+ # Enroll another print
+ template = FPrint.Print.new(self.dev)
+ template.props.finger = FPrint.Finger.LEFT_THUMB
+ template.props.username = "testuser"
+ template.props.description = "test print"
+ datetime = GLib.DateTime.new_now_local()
+ date = GLib.Date()
+ date.set_dmy(*datetime.get_ymd()[::-1])
+ template.props.enroll_date = date
+ return self.dev.enroll_sync(template, None, progress_cb, None)
+
+ def test_connect(self):
+ self.dev.open_sync()
+ self.dev.close_sync()
+
+ def test_reconnect(self):
+ # Ensure device was opened once before, this may be a reconnect if
+ # it is the same process as another test.
+ self.dev.open_sync()
+ self.dev.close_sync()
+
+ # Check that a reconnect happens on next open. To know about this, we
+ # need to parse check log messages for that.
+ success = [False]
+ def log_func(domain, level, msg):
+ print("log: '%s', '%s', '%s'" % (str(domain), str(level), msg))
+ if msg == 'Reconnect succeeded':
+ success[0] = True
+
+ # Call default handler
+ GLib.log_default_handler(domain, level, msg)
+
+ handler_id = GLib.log_set_handler('libfprint-sdcp_device', GLib.LogLevelFlags.LEVEL_DEBUG, log_func)
+ self.dev.open_sync()
+ self.dev.close_sync()
+ GLib.log_remove_handler('libfprint-sdcp_device', handler_id)
+ assert success[0]
+
+ def test_enroll(self):
+ self.dev.open_sync()
+
+ # Must return a print
+ assert isinstance(self.enroll(), FPrint.Print)
+
+ self.dev.close_sync()
+
+
+ def test_verify(self):
+ self.dev.open_sync()
+
+ # Enroll a new print (will be the last), check that it verifies
+ p = self.enroll()
+ match, dev_print = self.dev.verify_sync(p)
+ assert match
+
+ # The returned "device" print is identical
+ assert p.equal(dev_print)
+
+ # We can do the same with it
+ match, dev_print2 = self.dev.verify_sync(dev_print)
+ assert match
+
+ # Now, enroll a new print, causing the old one to not match anymore
+ # (the device always claims to see the last enrolled print).
+ self.enroll()
+ match, dev_print = self.dev.verify_sync(p)
+ assert match is False
+
+ self.dev.close_sync()
+
+if __name__ == '__main__':
+ try:
+ gi.require_version('FPrint', '2.0')
+ from gi.repository import FPrint
+ except Exception as e:
+ print("Missing dependencies: %s" % str(e))
+ sys.exit(77)
+
+ # avoid writing to stderr
+ unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))