diff --git a/tests/meson.build b/tests/meson.build index b4022a4e..6a5eaffb 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -109,3 +109,45 @@ if valgrind.found() valgrind.path(), glib_suppressions, python_suppressions) ]) endif + +if get_option('tod') + tod_envs = envs + tod_envs.set('FP_TOD_DRIVERS_DIR', meson.current_build_dir()) + tod_envs.set('FP_TOD_KEEP_MODULES_OPEN', 'TRUE') + tod_envs.set('FP_VIRTUAL_FAKE_DEVICE', 'yes') + tod_envs.append('FP_DRIVERS_WHITELIST', 'fake_test_dev') + + fake_driver = shared_module('device-fake-tod-driver', + sources: [ + 'test-device-fake-tod.c', + ], + link_with: [ + test_utils, + libfprint_tod, + ], + include_directories: include_directories('../libfprint'), + dependencies: deps, + install: false + ) + + tod_unit_tests = [ + 'fp-context-tod', + 'fp-device-tod', + ] + + foreach test_name: tod_unit_tests + basename = 'test-' + test_name + test_exe = executable(basename, + sources: basename + '.c', + dependencies: libfprint_private_dep, + c_args: common_cflags, + link_with: test_utils, + ) + test(test_name, + find_program('test-runner.sh'), + suite: ['unit-tests', 'tod'], + args: [test_exe], + env: tod_envs, + ) + endforeach +endif diff --git a/tests/test-device-fake-tod.c b/tests/test-device-fake-tod.c new file mode 100644 index 00000000..aea73870 --- /dev/null +++ b/tests/test-device-fake-tod.c @@ -0,0 +1,28 @@ +/* + * Virtual driver for device debugging + * + * Copyright (C) 2019 Marco Trevisan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include "test-device-fake-tod.h" +#include "test-device-fake.h" + +GType +fpi_tod_shared_driver_get_type (void) +{ + return fpi_device_fake_get_type (); +} diff --git a/tests/test-device-fake-tod.h b/tests/test-device-fake-tod.h new file mode 100644 index 00000000..36602125 --- /dev/null +++ b/tests/test-device-fake-tod.h @@ -0,0 +1,25 @@ +/* + * Virtual driver for device debugging + * + * Copyright (C) 2019 Marco Trevisan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#pragma once + +#include + +GType fpi_tod_shared_driver_get_type (void); diff --git a/tests/test-fp-context-tod.c b/tests/test-fp-context-tod.c new file mode 100644 index 00000000..abafc62d --- /dev/null +++ b/tests/test-fp-context-tod.c @@ -0,0 +1,101 @@ +/* + * FpContext Unit tests + * Copyright (C) 2019 Marco Trevisan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +static void +test_context_new (void) +{ + g_autoptr(FpContext) context = fp_context_new (); + g_assert_true (FP_CONTEXT (context)); +} + +static void +test_context_has_no_devices (void) +{ + g_autoptr(FpContext) context = NULL; + GPtrArray *devices; + const char *old_drivers_dir = g_getenv ("FP_TOD_DRIVERS_DIR"); + + g_setenv ("FP_TOD_DRIVERS_DIR", "__HOPEFULLY_AN_INVALID_PATH", TRUE); + context = fp_context_new (); + devices = fp_context_get_devices (context); + g_setenv ("FP_TOD_DRIVERS_DIR", old_drivers_dir, TRUE); + + g_assert_nonnull (devices); + g_assert_cmpuint (devices->len, ==, 0); +} + +static void +test_context_has_fake_device (void) +{ + g_autoptr(FpContext) context = NULL; + FpDevice *fake_device = NULL; + GPtrArray *devices; + unsigned int i; + + context = fp_context_new (); + devices = fp_context_get_devices (context); + + g_assert_nonnull (devices); + g_assert_cmpuint (devices->len, ==, 1); + + for (i = 0; i < devices->len; ++i) + { + FpDevice *device = devices->pdata[i]; + + if (g_strcmp0 (fp_device_get_driver (device), "fake_test_dev") == 0) + { + fake_device = device; + break; + } + } + + g_assert_true (FP_IS_DEVICE (fake_device)); +} + +static void +test_context_enumerates_new_devices (void) +{ + g_autoptr(FpContext) context = NULL; + GPtrArray *devices; + + context = fp_context_new (); + + fp_context_enumerate (context); + devices = fp_context_get_devices (context); + + g_assert_nonnull (devices); + g_assert_cmpuint (devices->len, ==, 1); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_assert_nonnull (g_getenv ("FP_TOD_DRIVERS_DIR")); + + g_test_add_func ("/context/new", test_context_new); + g_test_add_func ("/context/no-devices", test_context_has_no_devices); + g_test_add_func ("/context/has-virtual-device", test_context_has_fake_device); + g_test_add_func ("/context/enumerates-new-devices", test_context_enumerates_new_devices); + + return g_test_run (); +} diff --git a/tests/test-fp-device-tod.c b/tests/test-fp-device-tod.c new file mode 100644 index 00000000..d1a132b7 --- /dev/null +++ b/tests/test-fp-device-tod.c @@ -0,0 +1,270 @@ +/* + * FpDevice Unit tests + * Copyright (C) 2019 Marco Trevisan + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include + +#include "test-utils.h" + +static FptContext * +fpt_context_new_with_fake_dev (void) +{ + FptContext *tctx; + GPtrArray *devices; + unsigned int i; + + tctx = fpt_context_new (); + devices = fp_context_get_devices (tctx->fp_context); + + g_assert_nonnull (devices); + g_assert_cmpuint (devices->len, ==, 1); + + for (i = 0; i < devices->len; ++i) + { + FpDevice *device = devices->pdata[i]; + + if (g_strcmp0 (fp_device_get_driver (device), "fake_test_dev") == 0) + { + tctx->device = device; + break; + } + } + + g_assert_true (FP_IS_DEVICE (tctx->device)); + g_object_add_weak_pointer (G_OBJECT (tctx->device), (gpointer) & tctx->device); + + return tctx; +} + +static void +on_device_opened (FpDevice *dev, GAsyncResult *res, FptContext *tctx) +{ + g_autoptr(GError) error = NULL; + + g_assert_true (fp_device_open_finish (dev, res, &error)); + g_assert_no_error (error); + g_assert_true (fp_device_is_open (tctx->device)); + + tctx->user_data = GUINT_TO_POINTER (TRUE); +} + +static void +test_device_open_async (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx); + + while (!GPOINTER_TO_UINT (tctx->user_data)) + g_main_context_iteration (NULL, TRUE); +} + +static void +on_device_closed (FpDevice *dev, GAsyncResult *res, FptContext *tctx) +{ + g_autoptr(GError) error = NULL; + + g_assert_true (fp_device_close_finish (dev, res, &error)); + g_assert_no_error (error); + g_assert_false (fp_device_is_open (tctx->device)); + + tctx->user_data = GUINT_TO_POINTER (TRUE); +} + +static void +test_device_close_async (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open (tctx->device, NULL, (GAsyncReadyCallback) on_device_opened, tctx); + while (!tctx->user_data) + g_main_context_iteration (NULL, TRUE); + + tctx->user_data = GUINT_TO_POINTER (FALSE); + fp_device_close (tctx->device, NULL, (GAsyncReadyCallback) on_device_closed, tctx); + + while (!GPOINTER_TO_UINT (tctx->user_data)) + g_main_context_iteration (NULL, TRUE); +} + +static void +test_device_open_sync (void) +{ + g_autoptr(GError) error = NULL; + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, &error); + g_assert_no_error (error); + g_assert_true (fp_device_is_open (tctx->device)); + + fp_device_open_sync (tctx->device, NULL, &error); + g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_ALREADY_OPEN); +} + +static void +on_open_notify (FpDevice *rdev, GParamSpec *spec, FptContext *tctx) +{ + g_assert_cmpstr (spec->name, ==, "open"); + tctx->user_data = GUINT_TO_POINTER (TRUE); +} + +static void +test_device_open_sync_notify (void) +{ + g_autoptr(GError) error = NULL; + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_open_notify), tctx); + fp_device_open_sync (tctx->device, NULL, &error); + g_assert_no_error (error); + g_assert_true (GPOINTER_TO_INT (tctx->user_data)); +} + +static void +test_device_close_sync (void) +{ + g_autoptr(GError) error = NULL; + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + fp_device_close_sync (tctx->device, NULL, &error); + g_assert_no_error (error); + g_assert_false (fp_device_is_open (tctx->device)); + + fp_device_close_sync (tctx->device, NULL, &error); + g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_OPEN); +} + +static void +on_close_notify (FpDevice *rdev, GParamSpec *spec, FptContext *tctx) +{ + g_assert_cmpstr (spec->name, ==, "open"); + tctx->user_data = GUINT_TO_POINTER (TRUE); +} + +static void +test_device_close_sync_notify (void) +{ + g_autoptr(GError) error = NULL; + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + + g_signal_connect (tctx->device, "notify::open", G_CALLBACK (on_close_notify), tctx); + fp_device_close_sync (tctx->device, NULL, &error); + g_assert_no_error (error); + g_assert_true (GPOINTER_TO_INT (tctx->user_data)); +} + +static void +test_device_get_driver (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_cmpstr (fp_device_get_driver (tctx->device), ==, "fake_test_dev"); +} + +static void +test_device_get_device_id (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_cmpstr (fp_device_get_device_id (tctx->device), ==, "fake_test_dev"); +} + +static void +test_device_get_name (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_cmpstr (fp_device_get_name (tctx->device), ==, + "Virtual device for debugging"); +} + +static void +test_device_get_scan_type (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_cmpint (fp_device_get_scan_type (tctx->device), ==, FP_SCAN_TYPE_PRESS); +} + +static void +test_device_get_nr_enroll_stages (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_cmpuint (fp_device_get_nr_enroll_stages (tctx->device), ==, 5); +} + +static void +test_device_supports_identify (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_true (fp_device_supports_identify (tctx->device)); +} + +static void +test_device_supports_capture (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_true (fp_device_supports_capture (tctx->device)); +} + +static void +test_device_has_storage (void) +{ + g_autoptr(FptContext) tctx = fpt_context_new_with_fake_dev (); + + fp_device_open_sync (tctx->device, NULL, NULL); + g_assert_true (fp_device_has_storage (tctx->device)); +} + +int +main (int argc, char *argv[]) +{ + g_test_init (&argc, &argv, NULL); + + g_assert_nonnull (g_getenv ("FP_TOD_DRIVERS_DIR")); + + g_test_add_func ("/device/async/open", test_device_open_async); + g_test_add_func ("/device/async/close", test_device_close_async); + g_test_add_func ("/device/sync/open", test_device_open_sync); + g_test_add_func ("/device/sync/open/notify", test_device_open_sync_notify); + g_test_add_func ("/device/sync/close", test_device_close_sync); + g_test_add_func ("/device/sync/close/notify", test_device_close_sync_notify); + g_test_add_func ("/device/sync/get_driver", test_device_get_driver); + g_test_add_func ("/device/sync/get_device_id", test_device_get_device_id); + g_test_add_func ("/device/sync/get_name", test_device_get_name); + g_test_add_func ("/device/sync/get_scan_type", test_device_get_scan_type); + g_test_add_func ("/device/sync/get_nr_enroll_stages", test_device_get_nr_enroll_stages); + g_test_add_func ("/device/sync/supports_identify", test_device_supports_identify); + g_test_add_func ("/device/sync/supports_capture", test_device_supports_capture); + g_test_add_func ("/device/sync/has_storage", test_device_has_storage); + + return g_test_run (); +}