Files
libfprint/tests/test-fpi-device.c
Dmitrii Shcherbakov 999bca076c Allow FpPrint data to be extended on enrollment.
* Allow FPI_PRINT_NBIS to be extended rather than overridden if a user
  supplies an existing FpPrint template with data;
* Prints will only be extended if a device has the required feature.
  For image-based devices this feature is added by default since they
  typically do not have storage (this can be overridden at the child
  class level).

Extending an existing FpPrint requires passing a template print with
existing data during the enrollment process. This is done because the
caller is responsible for maintaining the fingerprint database and doing
the necessary deserialization operations if needed. The existing
example program is updated to show how to do that.
2021-12-16 12:53:41 +01:00

3490 lines
129 KiB
C

/*
* Unit tests for the internal fingerprint drivers API
* Copyright (C) 2019 Marco Trevisan <marco.trevisan@canonical.com>
*
* 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 "fp-device.h"
#include "fp-enums.h"
#include <libfprint/fprint.h>
#define FP_COMPONENT "device"
#include "fpi-device.h"
#include "fpi-compat.h"
#include "fpi-log.h"
#include "test-device-fake.h"
#include "fp-print-private.h"
/* Utility functions */
typedef FpDevice FpAutoCloseDevice;
static FpAutoCloseDevice *
auto_close_fake_device_new (void)
{
g_autoptr(GError) error = NULL;
FpAutoCloseDevice *device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
if (!fp_device_open_sync (device, NULL, &error))
g_error ("Could not open device: %s", error->message);
return device;
}
static void
auto_close_fake_device_free (FpAutoCloseDevice *device)
{
g_autoptr(GError) error = NULL;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
if (fake_dev->return_action_error)
{
fake_dev->return_action_error = FALSE;
fake_dev->ret_error = NULL;
}
if (fp_device_is_open (device))
if (!fp_device_close_sync (device, NULL, &error))
g_error ("Could not close device: %s", error->message);
g_object_unref (device);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpAutoCloseDevice, auto_close_fake_device_free)
typedef FpDeviceClass FpAutoResetClass;
static FpAutoResetClass default_fake_dev_class = {0};
static FpAutoResetClass *
auto_reset_device_class (void)
{
g_autoptr(FpDeviceClass) type_class = NULL;
FpDeviceClass *dev_class = g_type_class_peek_static (FPI_TYPE_DEVICE_FAKE);
if (!dev_class)
{
type_class = g_type_class_ref (FPI_TYPE_DEVICE_FAKE);
dev_class = type_class;
g_assert_nonnull (dev_class);
}
default_fake_dev_class = *dev_class;
return dev_class;
}
static void
auto_reset_device_class_cleanup (FpAutoResetClass *dev_class)
{
*dev_class = default_fake_dev_class;
g_assert_cmpint (memcmp (dev_class, &default_fake_dev_class,
sizeof (FpAutoResetClass)), ==, 0);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (FpAutoResetClass, auto_reset_device_class_cleanup)
static void
assert_equal_galleries (GPtrArray *g1,
GPtrArray *g2)
{
unsigned i;
g_assert ((g1 && g2) || (!g1 || !g1));
if (g1 == g2)
return;
g_assert_cmpuint (g1->len, ==, g2->len);
for (i = 0; i < g1->len; i++)
{
FpPrint *print = g_ptr_array_index (g1, i);
g_assert_true (g_ptr_array_find_with_equal_func (g2, print, (GEqualFunc)
fp_print_equal, NULL));
}
}
static void
on_device_notify (FpDevice *device, GParamSpec *spec, gpointer user_data)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->last_called_function = on_device_notify;
fake_dev->user_data = g_param_spec_ref (spec);
}
static FpPrint *
make_fake_print (FpDevice *device,
GVariant *print_data)
{
FpPrint *enrolled_print = fp_print_new (device);
fpi_print_set_type (enrolled_print, FPI_PRINT_RAW);
if (!print_data)
print_data = g_variant_new_string ("Test print private data");
g_object_set (G_OBJECT (enrolled_print), "fpi-data", print_data, NULL);
return enrolled_print;
}
static FpPrint *
make_fake_nbis_print (FpDevice *device)
{
FpPrint *enrolled_print = fp_print_new (device);
fpi_print_set_type (enrolled_print, FPI_PRINT_NBIS);
return enrolled_print;
}
static FpPrint *
make_fake_print_reffed (FpDevice *device,
GVariant *print_data)
{
return g_object_ref_sink (make_fake_print (device, print_data));
}
static GPtrArray *
make_fake_prints_gallery (FpDevice *device,
size_t size)
{
GPtrArray *array;
size_t i;
array = g_ptr_array_new_full (size, g_object_unref);
for (i = 0; i < size; i++)
g_ptr_array_add (array, make_fake_print_reffed (device, g_variant_new_uint64 (i)));
return array;
}
/* Tests */
static void
test_driver_get_driver (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->id = "test-fpi-device-driver";
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_assert_cmpstr (fp_device_get_driver (device), ==, "test-fpi-device-driver");
}
static void
test_driver_get_device_id (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_assert_cmpstr (fp_device_get_device_id (device), ==, "0");
}
static void
test_driver_get_name (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->full_name = "Test Device Full Name!";
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_assert_cmpstr (fp_device_get_name (device), ==, "Test Device Full Name!");
}
static void
test_driver_is_open (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_assert_false (fp_device_is_open (device));
fp_device_open_sync (device, NULL, NULL);
g_assert_true (fp_device_is_open (device));
fp_device_close_sync (FP_DEVICE (device), NULL, NULL);
g_assert_false (fp_device_is_open (device));
}
static void
test_driver_get_scan_type_press (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->scan_type = FP_SCAN_TYPE_PRESS;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_assert_cmpuint (fp_device_get_scan_type (device), ==, FP_SCAN_TYPE_PRESS);
}
static void
test_driver_get_scan_type_swipe (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->scan_type = FP_SCAN_TYPE_SWIPE;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_assert_cmpuint (fp_device_get_scan_type (device), ==, FP_SCAN_TYPE_SWIPE);
}
static void
test_driver_set_scan_type_press (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_autoptr(GParamSpec) pspec = NULL;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_signal_connect (device, "notify::scan-type", G_CALLBACK (on_device_notify), NULL);
fpi_device_set_scan_type (device, FP_SCAN_TYPE_PRESS);
g_assert_cmpuint (fp_device_get_scan_type (device), ==, FP_SCAN_TYPE_PRESS);
g_assert (fake_dev->last_called_function == on_device_notify);
pspec = g_steal_pointer (&fake_dev->user_data);
g_assert_cmpstr (pspec->name, ==, "scan-type");
}
static void
test_driver_set_scan_type_swipe (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_autoptr(GParamSpec) pspec = NULL;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_signal_connect (device, "notify::scan-type", G_CALLBACK (on_device_notify), NULL);
fpi_device_set_scan_type (device, FP_SCAN_TYPE_SWIPE);
g_assert_cmpuint (fp_device_get_scan_type (device), ==, FP_SCAN_TYPE_SWIPE);
g_assert (fake_dev->last_called_function == on_device_notify);
pspec = g_steal_pointer (&fake_dev->user_data);
g_assert_cmpstr (pspec->name, ==, "scan-type");
}
static void
test_driver_finger_status_inactive (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpFingerStatusFlags finger_status;
g_signal_connect (device, "notify::finger-status", G_CALLBACK (on_device_notify), NULL);
g_assert_false (fpi_device_report_finger_status (device, FP_FINGER_STATUS_NONE));
g_assert_cmpuint (fp_device_get_finger_status (device), ==, FP_FINGER_STATUS_NONE);
g_object_get (fake_dev, "finger-status", &finger_status, NULL);
g_assert_cmpuint (finger_status, ==, FP_FINGER_STATUS_NONE);
g_assert (fake_dev->last_called_function != on_device_notify);
g_assert_null (g_steal_pointer (&fake_dev->user_data));
}
static void
test_driver_finger_status_needed (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_autoptr(GParamSpec) pspec = NULL;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpFingerStatusFlags finger_status;
g_signal_connect (device, "notify::finger-status", G_CALLBACK (on_device_notify), NULL);
g_assert_true (fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED));
g_assert_cmpuint (fp_device_get_finger_status (device), ==, FP_FINGER_STATUS_NEEDED);
g_object_get (fake_dev, "finger-status", &finger_status, NULL);
g_assert_cmpuint (finger_status, ==, FP_FINGER_STATUS_NEEDED);
g_assert (fake_dev->last_called_function == on_device_notify);
pspec = g_steal_pointer (&fake_dev->user_data);
g_assert_cmpstr (pspec->name, ==, "finger-status");
fake_dev->last_called_function = NULL;
g_assert_false (fpi_device_report_finger_status (device, FP_FINGER_STATUS_NEEDED));
g_assert_null (fake_dev->last_called_function);
g_assert_null (g_steal_pointer (&fake_dev->user_data));
}
static void
test_driver_finger_status_present (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_autoptr(GParamSpec) pspec = NULL;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpFingerStatusFlags finger_status;
g_signal_connect (device, "notify::finger-status", G_CALLBACK (on_device_notify), NULL);
g_assert_true (fpi_device_report_finger_status (device, FP_FINGER_STATUS_PRESENT));
g_assert_cmpuint (fp_device_get_finger_status (device), ==, FP_FINGER_STATUS_PRESENT);
g_object_get (fake_dev, "finger-status", &finger_status, NULL);
g_assert_cmpuint (finger_status, ==, FP_FINGER_STATUS_PRESENT);
g_assert (fake_dev->last_called_function == on_device_notify);
pspec = g_steal_pointer (&fake_dev->user_data);
g_assert_cmpstr (pspec->name, ==, "finger-status");
fake_dev->last_called_function = NULL;
g_assert_false (fpi_device_report_finger_status (device, FP_FINGER_STATUS_PRESENT));
g_assert_null (fake_dev->last_called_function);
g_assert_null (g_steal_pointer (&fake_dev->user_data));
}
static void
driver_finger_status_changes_check (FpDevice *device, gboolean add)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_autoptr(GFlagsClass) status_class = g_type_class_ref (FP_TYPE_FINGER_STATUS_FLAGS);
guint expected_status;
guint initial_value;
guint i;
gulong signal_id;
if (add)
initial_value = FP_FINGER_STATUS_NONE;
else
initial_value = status_class->mask;
g_assert_cmpuint (fp_device_get_finger_status (device), ==, initial_value);
signal_id = g_signal_connect (device, "notify::finger-status",
G_CALLBACK (on_device_notify), NULL);
for (i = 0, expected_status = initial_value; i < status_class->n_values; ++i)
{
g_autoptr(GParamSpec) pspec = NULL;
FpFingerStatusFlags finger_status = status_class->values[i].value;
FpFingerStatusFlags added_status = add ? finger_status : FP_FINGER_STATUS_NONE;
FpFingerStatusFlags removed_status = add ? FP_FINGER_STATUS_NONE : finger_status;
gboolean ret;
fake_dev->last_called_function = NULL;
ret = fpi_device_report_finger_status_changes (device,
added_status,
removed_status);
if (finger_status != FP_FINGER_STATUS_NONE)
g_assert_true (ret);
else
g_assert_false (ret);
expected_status |= added_status;
expected_status &= ~removed_status;
g_assert_cmpuint (fp_device_get_finger_status (device), ==, expected_status);
if (finger_status != FP_FINGER_STATUS_NONE)
{
g_assert (fake_dev->last_called_function == on_device_notify);
pspec = g_steal_pointer (&fake_dev->user_data);
g_assert_cmpstr (pspec->name, ==, "finger-status");
}
fake_dev->last_called_function = NULL;
g_assert_false (fpi_device_report_finger_status_changes (device,
added_status,
removed_status));
g_assert_null (fake_dev->last_called_function);
g_assert_null (g_steal_pointer (&fake_dev->user_data));
}
if (add)
g_assert_cmpuint (fp_device_get_finger_status (device), ==, status_class->mask);
else
g_assert_cmpuint (fp_device_get_finger_status (device), ==, FP_FINGER_STATUS_NONE);
fake_dev->last_called_function = NULL;
g_assert_false (fpi_device_report_finger_status_changes (device,
FP_FINGER_STATUS_NONE,
FP_FINGER_STATUS_NONE));
g_assert_null (fake_dev->last_called_function);
g_assert_null (g_steal_pointer (&fake_dev->user_data));
g_signal_handler_disconnect (device, signal_id);
}
static void
test_driver_finger_status_changes (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
driver_finger_status_changes_check (device, TRUE);
driver_finger_status_changes_check (device, FALSE);
}
static void
test_driver_get_nr_enroll_stages (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
int expected_stages = g_random_int_range (G_MININT32, G_MAXINT32);
dev_class->nr_enroll_stages = expected_stages;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_assert_cmpint (fp_device_get_nr_enroll_stages (device), ==, expected_stages);
}
static void
test_driver_set_nr_enroll_stages (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_autoptr(GParamSpec) pspec = NULL;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
int expected_stages = g_random_int_range (1, G_MAXINT32);
g_signal_connect (device, "notify::nr-enroll-stages", G_CALLBACK (on_device_notify), NULL);
fpi_device_set_nr_enroll_stages (device, expected_stages);
g_assert_cmpint (fp_device_get_nr_enroll_stages (device), ==, expected_stages);
g_assert (fake_dev->last_called_function == on_device_notify);
pspec = g_steal_pointer (&fake_dev->user_data);
g_assert_cmpstr (pspec->name, ==, "nr-enroll-stages");
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*enroll_stages > 0*");
fpi_device_set_nr_enroll_stages (device, 0);
g_assert_cmpint (fp_device_get_nr_enroll_stages (device), ==, expected_stages);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*enroll_stages > 0*");
fpi_device_set_nr_enroll_stages (device, -2);
g_assert_cmpint (fp_device_get_nr_enroll_stages (device), ==, expected_stages);
g_test_assert_expected_messages ();
}
static void
test_driver_get_usb_device (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->type = FP_DEVICE_TYPE_USB;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, "fpi-usb-device", NULL, NULL);
g_assert_null (fpi_device_get_usb_device (device));
g_clear_object (&device);
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*type*FP_DEVICE_TYPE_USB*failed*");
g_assert_null (fpi_device_get_usb_device (device));
g_test_assert_expected_messages ();
}
static void
test_driver_get_virtual_env (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->type = FP_DEVICE_TYPE_VIRTUAL;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, "fpi-environ", "TEST_VIRTUAL_ENV_GETTER", NULL);
g_assert_cmpstr (fpi_device_get_virtual_env (device), ==, "TEST_VIRTUAL_ENV_GETTER");
g_clear_object (&device);
dev_class->type = FP_DEVICE_TYPE_USB;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*type*FP_DEVICE_TYPE_VIRTUAL*failed*");
g_assert_null (fpi_device_get_virtual_env (device));
g_test_assert_expected_messages ();
}
static void
test_driver_get_driver_data (void)
{
g_autoptr(FpDevice) device = NULL;
guint64 driver_data;
driver_data = g_random_int ();
device = g_object_new (FPI_TYPE_DEVICE_FAKE, "fpi-driver-data", driver_data, NULL);
g_assert_cmpuint (fpi_device_get_driver_data (device), ==, driver_data);
}
static void
test_driver_features_probe_updates (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev;
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
/* Effectively clears FP_DEVICE_FEATURE_STORAGE_DELETE */
fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->probe_features_update = FP_DEVICE_FEATURE_STORAGE_LIST | FP_DEVICE_FEATURE_STORAGE_DELETE;
fake_dev->probe_features_value = FP_DEVICE_FEATURE_STORAGE_LIST;
g_async_initable_init_async (G_ASYNC_INITABLE (device),
G_PRIORITY_DEFAULT, NULL, NULL, NULL);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_CAPTURE));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_VERIFY));
g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_DUPLICATES_CHECK));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_LIST));
g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_DELETE));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_CLEAR));
g_assert_cmpuint (fp_device_get_features (device),
==,
FP_DEVICE_FEATURE_CAPTURE |
FP_DEVICE_FEATURE_IDENTIFY |
FP_DEVICE_FEATURE_VERIFY |
FP_DEVICE_FEATURE_STORAGE |
FP_DEVICE_FEATURE_STORAGE_LIST |
FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
g_async_initable_init_async (G_ASYNC_INITABLE (device),
G_PRIORITY_DEFAULT, NULL, NULL, NULL);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_CAPTURE));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_VERIFY));
g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_DUPLICATES_CHECK));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_LIST));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_DELETE));
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE_CLEAR));
g_assert_cmpuint (fp_device_get_features (device),
==,
FP_DEVICE_FEATURE_CAPTURE |
FP_DEVICE_FEATURE_IDENTIFY |
FP_DEVICE_FEATURE_VERIFY |
FP_DEVICE_FEATURE_STORAGE |
FP_DEVICE_FEATURE_STORAGE_LIST |
FP_DEVICE_FEATURE_STORAGE_DELETE |
FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features_none (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
dev_class->list = NULL;
dev_class->capture = NULL;
dev_class->verify = NULL;
dev_class->identify = NULL;
dev_class->delete = NULL;
dev_class->clear_storage = NULL;
dev_class->features = FP_DEVICE_FEATURE_NONE;
fpi_device_class_auto_initialize_features (dev_class);
g_assert_cmpuint (dev_class->features, ==, FP_DEVICE_FEATURE_NONE);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features_no_capture (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
dev_class->capture = NULL;
dev_class->features = FP_DEVICE_FEATURE_NONE;
fpi_device_class_auto_initialize_features (dev_class);
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features_no_verify (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
dev_class->verify = NULL;
dev_class->features = FP_DEVICE_FEATURE_NONE;
fpi_device_class_auto_initialize_features (dev_class);
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features_no_identify (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
dev_class->identify = NULL;
dev_class->features = FP_DEVICE_FEATURE_NONE;
fpi_device_class_auto_initialize_features (dev_class);
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features_no_storage (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
dev_class->delete = NULL;
dev_class->features = FP_DEVICE_FEATURE_NONE;
fpi_device_class_auto_initialize_features (dev_class);
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features_no_list (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
dev_class->list = NULL;
dev_class->features = FP_DEVICE_FEATURE_NONE;
fpi_device_class_auto_initialize_features (dev_class);
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features_no_delete (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
dev_class->delete = NULL;
dev_class->features = FP_DEVICE_FEATURE_NONE;
fpi_device_class_auto_initialize_features (dev_class);
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
test_driver_initial_features_no_clear (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
dev_class->clear_storage = NULL;
dev_class->features = FP_DEVICE_FEATURE_NONE;
fpi_device_class_auto_initialize_features (dev_class);
g_assert_cmpuint (dev_class->features, !=, FP_DEVICE_FEATURE_NONE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_CAPTURE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_IDENTIFY);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_VERIFY);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_DUPLICATES_CHECK);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_LIST);
g_assert_true (dev_class->features & FP_DEVICE_FEATURE_STORAGE_DELETE);
g_assert_false (dev_class->features & FP_DEVICE_FEATURE_STORAGE_CLEAR);
}
static void
on_driver_probe_async (GObject *initable, GAsyncResult *res, gpointer user_data)
{
g_autoptr(GError) error = NULL;
FpDevice **out_device = user_data;
FpDevice *device;
FpDeviceClass *dev_class;
FpiDeviceFake *fake_dev;
device = FP_DEVICE (g_async_initable_new_finish (G_ASYNC_INITABLE (initable), res, &error));
dev_class = FP_DEVICE_GET_CLASS (device);
fake_dev = FPI_DEVICE_FAKE (device);
g_assert (fake_dev->last_called_function == dev_class->probe);
g_assert_no_error (error);
g_assert_false (fp_device_is_open (device));
*out_device = device;
}
static void
test_driver_probe (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->id = "Probed device ID";
dev_class->full_name = "Probed device name";
g_async_initable_new_async (FPI_TYPE_DEVICE_FAKE, G_PRIORITY_DEFAULT, NULL,
on_driver_probe_async, &device, NULL);
while (!FP_IS_DEVICE (device))
g_main_context_iteration (NULL, TRUE);
g_assert_false (fp_device_is_open (device));
g_assert_cmpstr (fp_device_get_device_id (device), ==, "Probed device ID");
g_assert_cmpstr (fp_device_get_name (device), ==, "Probed device name");
}
static void
fake_device_probe_error (FpDevice *device)
{
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_PROBE);
fpi_device_probe_complete (device, dev_class->id, dev_class->full_name,
fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
static void
fake_device_probe_action_error (FpDevice *device)
{
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_PROBE);
fpi_device_action_error (device, fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED));
}
static void
on_driver_probe_error_async (GObject *initable, GAsyncResult *res, gpointer user_data)
{
g_autoptr(GError) error = NULL;
gboolean *out_done = user_data;
FpDevice *device;
device = FP_DEVICE (g_async_initable_new_finish (G_ASYNC_INITABLE (initable), res, &error));
g_assert_null (device);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED);
*out_done = TRUE;
}
static void
test_driver_probe_error (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
gboolean done = FALSE;
dev_class->id = "Error device ID";
dev_class->probe = fake_device_probe_error;
g_async_initable_new_async (FPI_TYPE_DEVICE_FAKE, G_PRIORITY_DEFAULT, NULL,
on_driver_probe_error_async, &done, NULL);
while (!done)
g_main_context_iteration (NULL, TRUE);
}
static void
test_driver_probe_action_error (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
gboolean done = FALSE;
dev_class->id = "Error device ID";
dev_class->probe = fake_device_probe_action_error;
g_async_initable_new_async (FPI_TYPE_DEVICE_FAKE, G_PRIORITY_DEFAULT, NULL,
on_driver_probe_error_async, &done, NULL);
while (!done)
g_main_context_iteration (NULL, TRUE);
}
static void
test_driver_open (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert (fake_dev->last_called_function != dev_class->probe);
g_assert_true (fp_device_open_sync (device, NULL, &error));
g_assert (fake_dev->last_called_function == dev_class->open);
g_assert_no_error (error);
g_assert_true (fp_device_is_open (device));
g_assert_true (fp_device_close_sync (FP_DEVICE (device), NULL, &error));
g_assert_no_error (error);
}
static void
test_driver_open_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
g_assert_false (fp_device_open_sync (device, NULL, &error));
g_assert (fake_dev->last_called_function == dev_class->open);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_false (fp_device_is_open (device));
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
}
static void
test_driver_close (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_true (fp_device_close_sync (device, NULL, &error));
g_assert (fake_dev->last_called_function == dev_class->close);
g_assert_no_error (error);
g_assert_false (fp_device_is_open (device));
}
static void
test_driver_close_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
g_assert_false (fp_device_close_sync (device, NULL, &error));
g_assert (fake_dev->last_called_function == dev_class->close);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_false (fp_device_is_open (device));
}
static void
test_driver_enroll (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(FpPrint) template_print = fp_print_new (device);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpPrint *out_print = NULL;
out_print =
fp_device_enroll_sync (device, template_print, NULL, NULL, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->enroll);
g_assert (fake_dev->action_data == template_print);
g_assert_no_error (error);
g_assert (out_print == template_print);
}
static void
test_driver_enroll_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpPrint *template_print = fp_print_new (device);
FpPrint *out_print = NULL;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
out_print =
fp_device_enroll_sync (device, template_print, NULL, NULL, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->enroll);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_null (out_print);
}
static void
test_driver_enroll_complete_simple (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->last_called_function = test_driver_enroll_complete_simple;
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_ENROLL);
fpi_device_enroll_complete (device, fake_dev->ret_print, fake_dev->ret_error);
}
static void
test_driver_enroll_error_no_print (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) out_print = NULL;
FpiDeviceFake *fake_dev;
dev_class->enroll = test_driver_enroll_complete_simple;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver did not provide a valid print and failed to provide an error*");
out_print =
fp_device_enroll_sync (device, fp_print_new (device), NULL, NULL, NULL, &error);
g_test_assert_expected_messages ();
g_assert (fake_dev->last_called_function == dev_class->enroll);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_null (out_print);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver passed an error but also provided a print, returning error*");
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
fake_dev->ret_print = make_fake_print_reffed (device, NULL);
g_object_add_weak_pointer (G_OBJECT (fake_dev->ret_print),
(gpointer) (&fake_dev->ret_print));
out_print =
fp_device_enroll_sync (device, fp_print_new (device), NULL, NULL, NULL, &error);
g_test_assert_expected_messages ();
g_assert (fake_dev->last_called_function == dev_class->enroll);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_null (out_print);
g_assert_null (fake_dev->ret_print);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver did not set the type on the returned print*");
fake_dev->ret_error = NULL;
fake_dev->ret_print = fp_print_new (device); /* Type not set. */
g_object_add_weak_pointer (G_OBJECT (fake_dev->ret_print),
(gpointer) (&fake_dev->ret_print));
out_print =
fp_device_enroll_sync (device, fp_print_new (device), NULL, NULL, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->enroll);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_null (out_print);
g_assert_null (fake_dev->ret_print);
g_clear_error (&error);
}
static void
test_driver_enroll_update_nbis (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) template_print = NULL;
FpiDeviceFake *fake_dev = NULL;
FpPrint *out_print = NULL;
dev_class->features |= FP_DEVICE_FEATURE_UPDATE_PRINT;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
template_print = make_fake_nbis_print (device);
fake_dev->ret_print = template_print;
out_print =
fp_device_enroll_sync (device, template_print, NULL, NULL, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->enroll);
g_assert (fake_dev->action_data == template_print);
g_assert_no_error (error);
g_assert (out_print == template_print);
}
static void
test_driver_enroll_update_nbis_wrong_device (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) template_print = NULL;
FpiDeviceFake *fake_dev = NULL;
FpPrint *out_print = NULL;
dev_class->features |= FP_DEVICE_FEATURE_UPDATE_PRINT;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
template_print = make_fake_nbis_print (device);
template_print->device_id = g_strdup ("wrong_device");
fake_dev->ret_print = template_print;
out_print =
fp_device_enroll_sync (device, template_print, NULL, NULL, NULL, &error);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_assert (out_print == NULL);
}
static void
test_driver_enroll_update_nbis_wrong_driver (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) template_print = NULL;
FpiDeviceFake *fake_dev = NULL;
FpPrint *out_print = NULL;
dev_class->features |= FP_DEVICE_FEATURE_UPDATE_PRINT;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
template_print = make_fake_nbis_print (device);
template_print->driver = g_strdup ("wrong_driver");
fake_dev->ret_print = template_print;
out_print =
fp_device_enroll_sync (device, template_print, NULL, NULL, NULL, &error);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_assert (out_print == NULL);
}
static void
test_driver_enroll_update_nbis_missing_feature (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) template_print = NULL;
FpiDeviceFake *fake_dev = NULL;
FpPrint *out_print = NULL;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
template_print = make_fake_nbis_print (device);
fake_dev->ret_print = template_print;
out_print =
fp_device_enroll_sync (device, template_print, NULL, NULL, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->open);
g_assert (fake_dev->action_data == NULL);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_assert (out_print == NULL);
}
typedef struct
{
gint completed_stages;
FpPrint *print;
GError *error;
} ExpectedEnrollData;
static void
test_driver_enroll_progress_callback (FpDevice *device,
gint completed_stages,
FpPrint *print,
gpointer user_data,
GError *error)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
ExpectedEnrollData *expected_data = user_data;
g_assert_cmpint (expected_data->completed_stages, ==, completed_stages);
g_assert (expected_data->print == print);
g_assert_true (print == NULL || FP_IS_PRINT (print));
g_assert (expected_data->error == error);
fake_dev->last_called_function = test_driver_enroll_progress_callback;
}
static void
test_driver_enroll_progress_vfunc (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
ExpectedEnrollData *expected_data = fake_dev->user_data;
g_autoptr(GError) error = NULL;
expected_data->completed_stages =
g_random_int_range (fp_device_get_nr_enroll_stages (device), G_MAXINT32);
expected_data->print = fp_print_new (device);
expected_data->error = NULL;
g_object_add_weak_pointer (G_OBJECT (expected_data->print),
(gpointer) & expected_data->print);
fpi_device_enroll_progress (device, expected_data->completed_stages,
expected_data->print, expected_data->error);
g_assert (fake_dev->last_called_function == test_driver_enroll_progress_callback);
g_assert_null (expected_data->print);
expected_data->completed_stages =
g_random_int_range (fp_device_get_nr_enroll_stages (device), G_MAXINT32);
expected_data->print = NULL;
expected_data->error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
fpi_device_enroll_progress (device, expected_data->completed_stages,
expected_data->print, expected_data->error);
g_assert (fake_dev->last_called_function == test_driver_enroll_progress_callback);
expected_data->completed_stages =
g_random_int_range (fp_device_get_nr_enroll_stages (device), G_MAXINT32);
expected_data->print = make_fake_print_reffed (device,
g_variant_new_int32 (expected_data->completed_stages));
expected_data->error = NULL;
error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*error*FP_DEVICE_RETRY*failed");
fpi_device_enroll_progress (device, expected_data->completed_stages,
expected_data->print, error);
g_assert (fake_dev->last_called_function == test_driver_enroll_progress_callback);
g_clear_object (&expected_data->print);
g_test_assert_expected_messages ();
expected_data->completed_stages =
g_random_int_range (fp_device_get_nr_enroll_stages (device), G_MAXINT32);
expected_data->print = NULL;
expected_data->error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver passed an error and also provided a print*");
fpi_device_enroll_progress (device, expected_data->completed_stages,
fp_print_new (device), expected_data->error);
g_assert (fake_dev->last_called_function == test_driver_enroll_progress_callback);
g_test_assert_expected_messages ();
default_fake_dev_class.enroll (device);
fake_dev->last_called_function = test_driver_enroll_progress_vfunc;
}
static void
test_driver_enroll_progress (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
G_GNUC_UNUSED g_autoptr(FpPrint) enrolled_print = NULL;
ExpectedEnrollData expected_enroll_data = {0};
FpiDeviceFake *fake_dev;
dev_class->nr_enroll_stages = g_random_int_range (10, G_MAXINT32);
dev_class->enroll = test_driver_enroll_progress_vfunc;
device = auto_close_fake_device_new ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*FPI_DEVICE_ACTION_ENROLL*failed");
fpi_device_enroll_progress (device, 0, NULL, NULL);
g_test_assert_expected_messages ();
fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->user_data = &expected_enroll_data;
enrolled_print = fp_device_enroll_sync (device, fp_print_new (device), NULL,
test_driver_enroll_progress_callback,
&expected_enroll_data, NULL);
g_assert (fake_dev->last_called_function == test_driver_enroll_progress_vfunc);
}
typedef struct
{
gboolean called;
FpPrint *match;
FpPrint *print;
GPtrArray *gallery;
GError *error;
} MatchCbData;
static void
test_driver_match_data_clear (MatchCbData *data)
{
data->called = FALSE;
g_clear_object (&data->match);
g_clear_object (&data->print);
g_clear_error (&data->error);
}
static void
test_driver_match_data_free (MatchCbData *data)
{
test_driver_match_data_clear (data);
g_free (data);
}
G_DEFINE_AUTOPTR_CLEANUP_FUNC (MatchCbData, test_driver_match_data_free);
static void
test_driver_match_cb (FpDevice *device,
FpPrint *match,
FpPrint *print,
gpointer user_data,
GError *error)
{
MatchCbData *data = user_data;
g_assert (data->called == FALSE);
data->called = TRUE;
if (match)
data->match = g_object_ref (match);
if (print)
data->print = g_object_ref (print);
if (error)
{
data->error = g_error_copy (error);
g_assert_null (match);
}
if (match)
g_assert_no_error (error);
/* Compar gallery if this is an identify operation */
if (data->gallery)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_false (fake_dev->action_data == data->gallery);
assert_equal_galleries (fake_dev->action_data, data->gallery);
}
}
static void
fake_device_stub_verify (FpDevice *device)
{
}
static void
test_driver_verify (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
g_autoptr(FpPrint) out_print = NULL;
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean match;
fake_dev->ret_result = FPI_MATCH_SUCCESS;
g_assert_true (fp_device_verify_sync (device, enrolled_print, NULL,
test_driver_match_cb, match_data,
&match, &out_print, &error));
g_assert (fake_dev->last_called_function == dev_class->verify);
g_assert (fake_dev->action_data == enrolled_print);
g_assert_no_error (error);
g_assert_true (match_data->called);
g_assert_nonnull (match_data->match);
g_assert_true (match_data->print == out_print);
g_assert_true (match_data->match == enrolled_print);
g_assert (out_print == enrolled_print);
g_assert_true (match);
}
static void
test_driver_verify_not_supported (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpPrint) enrolled_print = NULL;
g_autoptr(FpPrint) out_print = NULL;
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
FpiDeviceFake *fake_dev;
gboolean match;
dev_class->features &= ~FP_DEVICE_FEATURE_VERIFY;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->last_called_function = NULL;
enrolled_print = make_fake_print_reffed (device, g_variant_new_uint64 (3));
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL,
test_driver_match_cb, match_data,
&match, &out_print, &error));
g_assert_null (fake_dev->last_called_function);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED);
g_assert_false (match_data->called);
g_assert_no_error (match_data->error);
g_assert_null (out_print);
g_assert_false (match);
}
static void
test_driver_verify_fail (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(FpPrint) enrolled_print = NULL;
g_autoptr(FpPrint) out_print = NULL;
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean match;
enrolled_print = make_fake_print_reffed (device, g_variant_new_uint64 (3));
fake_dev->ret_result = FPI_MATCH_FAIL;
g_assert_true (fp_device_verify_sync (device, enrolled_print, NULL,
test_driver_match_cb, match_data,
&match, &out_print, &error));
g_assert (fake_dev->last_called_function == dev_class->verify);
g_assert_no_error (error);
g_assert_true (match_data->called);
g_assert_no_error (match_data->error);
g_assert_true (match_data->print == out_print);
g_assert_null (match_data->match);
g_assert (out_print == enrolled_print);
g_assert_false (match);
}
static void
test_driver_verify_retry (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
g_autoptr(FpPrint) out_print = NULL;
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean match;
fake_dev->ret_result = FPI_MATCH_ERROR;
fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL,
test_driver_match_cb, match_data,
&match, &out_print, &error));
g_assert_true (match_data->called);
g_assert_null (match_data->match);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_assert (fake_dev->last_called_function == dev_class->verify);
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_false (match);
}
static void
test_driver_verify_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
g_autoptr(FpPrint) out_print = NULL;
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean match;
fake_dev->ret_result = FPI_MATCH_ERROR;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL,
test_driver_match_cb, match_data,
&match, &out_print, &error));
g_assert_false (match_data->called);
g_assert_null (match_data->match);
g_assert_no_error (match_data->error);
g_assert (fake_dev->last_called_function == dev_class->verify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_false (match);
}
static void
fake_device_verify_immediate_complete (FpDevice *device)
{
fpi_device_verify_complete (device, NULL);
}
static void
test_driver_verify_not_reported (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) enrolled_print = NULL;
g_autoptr(GError) error = NULL;
dev_class->verify = fake_device_verify_immediate_complete;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
enrolled_print = make_fake_print_reffed (device, NULL);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*reported successful verify complete*not report*result*");
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL,
NULL, NULL,
NULL, NULL, &error));
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_test_assert_expected_messages ();
}
static void
fake_device_verify_complete_error (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
GError *complete_error = fake_dev->user_data;
fake_dev->last_called_function = fake_device_verify_complete_error;
fpi_device_verify_report (device, fake_dev->ret_result, fake_dev->ret_print, fake_dev->ret_error);
fpi_device_verify_complete (device, complete_error);
}
static void
test_driver_verify_report_no_callback (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) enrolled_print = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(GError) error = NULL;
FpiDeviceFake *fake_dev;
gboolean match;
dev_class->verify = fake_device_verify_complete_error;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
enrolled_print = make_fake_print_reffed (device, NULL);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported a verify error that was not in the retry domain*");
fake_dev->ret_result = FPI_MATCH_ERROR;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED);
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL,
test_driver_match_cb, match_data,
&match, &print, &error));
g_test_assert_expected_messages ();
g_assert_false (match_data->called);
g_assert_null (match_data->match);
g_assert_no_error (match_data->error);
g_assert (fake_dev->last_called_function == dev_class->verify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_false (match);
}
static void
test_driver_verify_complete_retry (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) enrolled_print = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(GError) error = NULL;
FpiDeviceFake *fake_dev;
gboolean match;
dev_class->verify = fake_device_verify_complete_error;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
enrolled_print = make_fake_print_reffed (device, NULL);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported an error code without setting match result to error*");
test_driver_match_data_clear (match_data);
fake_dev->ret_result = FPI_MATCH_FAIL;
fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL, test_driver_match_cb,
match_data, &match, &print, &error));
g_test_assert_expected_messages ();
g_assert_true (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
g_assert_false (match);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
g_assert_null (print);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported an error code without setting match result to error*");
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported a retry error to fpi_device_verify_complete"
"*reporting general verification failure*");
test_driver_match_data_clear (match_data);
fake_dev->ret_result = FPI_MATCH_FAIL;
fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
fake_dev->user_data = g_error_copy (fake_dev->ret_error);
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL, test_driver_match_cb,
match_data, &match, &print, &error));
g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_steal_pointer (&fake_dev->user_data);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
g_assert_false (match);
g_assert_null (print);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported a retry error to fpi_device_verify_complete"
"*reporting general verification failure*");
test_driver_match_data_clear (match_data);
fake_dev->ret_result = FPI_MATCH_ERROR;
fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
fake_dev->user_data = g_error_copy (fake_dev->ret_error);
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL, test_driver_match_cb,
match_data, &match, &print, &error));
g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_steal_pointer (&fake_dev->user_data);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
g_assert_false (match);
g_assert_null (print);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported an error without specifying a retry "
"code, assuming general retry error*");
test_driver_match_data_clear (match_data);
fake_dev->ret_result = FPI_MATCH_ERROR;
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL, test_driver_match_cb,
match_data, &match, &print, &error));
g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_steal_pointer (&fake_dev->user_data);
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_assert_false (match);
g_assert_null (print);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported a print together with an error*");
test_driver_match_data_clear (match_data);
fake_dev->ret_result = FPI_MATCH_ERROR;
fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
fake_dev->ret_print = make_fake_print (device, NULL);
g_object_add_weak_pointer (G_OBJECT (fake_dev->ret_print),
(gpointer) (&fake_dev->ret_print));
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL, test_driver_match_cb,
match_data, &match, &print, &error));
g_test_assert_expected_messages ();
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
g_assert_true (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
g_assert_null (fake_dev->ret_print);
g_assert_false (match);
g_assert_null (print);
g_clear_error (&error);
}
static void
fake_device_stub_identify (FpDevice *device)
{
}
static void
test_driver_identify_cb (FpDevice *device,
GAsyncResult *res,
gpointer user_data)
{
MatchCbData *data = user_data;
gboolean r;
g_assert (data->called == FALSE);
data->called = TRUE;
r = fp_device_identify_finish (device, res, &data->match, &data->print, &data->error);
if (r)
g_assert_no_error (data->error);
else
g_assert_nonnull (data->error);
if (data->match)
g_assert_no_error (data->error);
}
static void
test_driver_supports_identify (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->identify = fake_device_stub_identify;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_true (fp_device_supports_identify (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY));
}
static void
test_driver_do_not_support_identify (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->features &= ~FP_DEVICE_FEATURE_IDENTIFY;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_false (fp_device_supports_identify (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY));
}
static void
test_driver_identify (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(FpPrint) matched_print = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(GPtrArray) prints = make_fake_prints_gallery (device, 500);
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpPrint *expected_matched;
expected_matched = g_ptr_array_index (prints, g_random_int_range (0, 499));
fp_print_set_description (expected_matched, "fake-verified");
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_true (fp_device_supports_identify (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY));
match_data->gallery = prints;
fake_dev->ret_print = make_fake_print (device, NULL);
g_assert_true (fp_device_identify_sync (device, prints, NULL,
test_driver_match_cb, match_data,
&matched_print, &print, &error));
g_assert_true (match_data->called);
g_assert_nonnull (match_data->match);
g_assert_true (match_data->match == matched_print);
g_assert_true (match_data->print == print);
g_assert (fake_dev->last_called_function == dev_class->identify);
g_assert_no_error (error);
g_assert (print != NULL && print == fake_dev->ret_print);
g_assert (expected_matched == matched_print);
}
static void
test_driver_identify_fail (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(FpPrint) matched_print = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(GPtrArray) prints = make_fake_prints_gallery (device, 500);
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_true (fp_device_supports_identify (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY));
fake_dev->ret_print = make_fake_print (device, NULL);
g_assert_true (fp_device_identify_sync (device, prints, NULL,
test_driver_match_cb, match_data,
&matched_print, &print, &error));
g_assert_true (match_data->called);
g_assert_null (match_data->match);
g_assert_no_error (match_data->error);
g_assert_true (match_data->match == matched_print);
g_assert_true (match_data->print == print);
g_assert (fake_dev->last_called_function == dev_class->identify);
g_assert_no_error (error);
g_assert (print != NULL && print == fake_dev->ret_print);
g_assert_null (matched_print);
}
static void
test_driver_identify_retry (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(FpPrint) matched_print = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(GPtrArray) prints = make_fake_prints_gallery (device, 500);
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpPrint *expected_matched;
expected_matched = g_ptr_array_index (prints, g_random_int_range (0, 499));
fp_print_set_description (expected_matched, "fake-verified");
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_true (fp_device_supports_identify (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY));
fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_GENERAL);
g_assert_false (fp_device_identify_sync (device, prints, NULL,
test_driver_match_cb, match_data,
&matched_print, &print, &error));
g_assert_true (match_data->called);
g_assert_null (match_data->match);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_assert (fake_dev->last_called_function == dev_class->identify);
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_null (matched_print);
g_assert_null (print);
}
static void
test_driver_identify_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(FpPrint) matched_print = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(GPtrArray) prints = make_fake_prints_gallery (device, 500);
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpPrint *expected_matched;
expected_matched = g_ptr_array_index (prints, g_random_int_range (0, 499));
fp_print_set_description (expected_matched, "fake-verified");
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_true (fp_device_supports_identify (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_IDENTIFY));
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
g_assert_false (fp_device_identify_sync (device, prints, NULL,
test_driver_match_cb, match_data,
&matched_print, &print, &error));
g_assert_false (match_data->called);
g_assert_null (match_data->match);
g_assert_no_error (match_data->error);
g_assert (fake_dev->last_called_function == dev_class->identify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_null (matched_print);
g_assert_null (print);
}
static void
fake_device_identify_immediate_complete (FpDevice *device)
{
fpi_device_identify_complete (device, NULL);
}
static void
test_driver_identify_not_reported (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(GError) error = NULL;
dev_class->identify = fake_device_identify_immediate_complete;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
prints = make_fake_prints_gallery (device, 500);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*reported successful identify complete*not report*result*");
g_assert_false (fp_device_identify_sync (device, prints, NULL,
NULL, NULL,
NULL, NULL, &error));
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_test_assert_expected_messages ();
}
static void
fake_device_identify_complete_error (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
GError *complete_error = fake_dev->user_data;
fake_dev->last_called_function = fake_device_identify_complete_error;
fpi_device_identify_report (device, fake_dev->ret_match, fake_dev->ret_print, fake_dev->ret_error);
fpi_device_identify_complete (device, complete_error);
}
static void
test_driver_identify_complete_retry (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(FpPrint) match = NULL;
g_autoptr(GError) error = NULL;
FpiDeviceFake *fake_dev;
dev_class->identify = fake_device_identify_complete_error;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
prints = make_fake_prints_gallery (device, 500);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported a retry error to fpi_device_identify_complete"
"*reporting general identification failure*");
test_driver_match_data_clear (match_data);
fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_TOO_SHORT);
fake_dev->user_data = g_error_copy (fake_dev->ret_error);
g_assert_false (fp_device_identify_sync (device, prints, NULL,
test_driver_match_cb, match_data,
&match, &print, &error));
g_test_assert_expected_messages ();
g_assert_true (error != g_steal_pointer (&fake_dev->ret_error));
g_steal_pointer (&fake_dev->user_data);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_TOO_SHORT);
g_assert_null (match);
g_assert_null (print);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported a match to a print that was not in the gallery*");
test_driver_match_data_clear (match_data);
fake_dev->ret_match = make_fake_print_reffed (device, NULL);
g_object_add_weak_pointer (G_OBJECT (fake_dev->ret_match),
(gpointer) (&fake_dev->ret_match));
g_assert_true (fp_device_identify_sync (device, prints, NULL,
test_driver_match_cb, match_data,
&match, &print, &error));
g_test_assert_expected_messages ();
g_object_unref (fake_dev->ret_match);
g_assert_null (fake_dev->ret_match);
g_assert_true (match_data->called);
g_assert_no_error (match_data->error);
g_assert_no_error (error);
g_assert_false (match);
g_assert_null (print);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported an error code but also provided a match*");
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported a print together with an error*");
test_driver_match_data_clear (match_data);
fake_dev->ret_error = fpi_device_retry_new (FP_DEVICE_RETRY_REMOVE_FINGER);
fake_dev->ret_match = prints->pdata[0];
fake_dev->ret_print = make_fake_print (device, NULL);
g_object_add_weak_pointer (G_OBJECT (fake_dev->ret_print),
(gpointer) (&fake_dev->ret_print));
g_assert_false (fp_device_identify_sync (device, prints, NULL,
test_driver_match_cb, match_data,
&match, &print, &error));
g_test_assert_expected_messages ();
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_REMOVE_FINGER);
g_assert_true (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_null (fake_dev->ret_print);
g_assert_true (match_data->called);
g_assert_error (match_data->error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_REMOVE_FINGER);
g_assert_false (match);
g_assert_null (print);
g_clear_error (&error);
}
static void
test_driver_identify_report_no_callback (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(FpAutoCloseDevice) device = NULL;
G_GNUC_UNUSED g_autoptr(FpPrint) enrolled_print = NULL;
g_autoptr(FpPrint) print = NULL;
g_autoptr(FpPrint) match = NULL;
g_autoptr(GError) error = NULL;
FpiDeviceFake *fake_dev;
dev_class->identify = fake_device_identify_complete_error;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
prints = make_fake_prints_gallery (device, 0);
enrolled_print = make_fake_print_reffed (device, NULL);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Driver reported a verify error that was not in the retry domain*");
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED);
g_assert_false (fp_device_identify_sync (device, prints, NULL,
test_driver_match_cb, match_data,
&match, &print, &error));
g_test_assert_expected_messages ();
g_assert_null (match);
g_assert_null (print);
g_assert_false (match_data->called);
g_assert_null (match_data->match);
g_assert_no_error (match_data->error);
g_assert (fake_dev->last_called_function == dev_class->identify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_false (match);
}
static void
test_driver_identify_suspend_continues (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(MatchCbData) identify_data = g_new0 (MatchCbData, 1);
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GError) error = NULL;
void (*orig_identify) (FpDevice *device);
FpiDeviceFake *fake_dev;
FpPrint *expected_matched;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
orig_identify = dev_class->identify;
dev_class->identify = fake_device_stub_identify;
prints = make_fake_prints_gallery (device, 500);
expected_matched = g_ptr_array_index (prints, g_random_int_range (0, 499));
fp_print_set_description (expected_matched, "fake-verified");
match_data->gallery = prints;
fake_dev->ret_print = make_fake_print (device, NULL);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
fp_device_identify (device, prints, NULL,
test_driver_match_cb, match_data, NULL,
(GAsyncReadyCallback) test_driver_identify_cb, identify_data);
while (g_main_context_iteration (NULL, FALSE))
continue;
fake_dev->ret_suspend = NULL;
fp_device_suspend_sync (device, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->suspend);
g_assert_no_error (error);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert_false (match_data->called);
g_assert_false (identify_data->called);
fake_dev->ret_resume = NULL;
fp_device_resume_sync (device, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->resume);
g_assert_no_error (error);
orig_identify (device);
/* This currently happens immediately (not ABI though) */
g_assert_true (match_data->called);
g_assert (match_data->match == expected_matched);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert_true (identify_data->called);
g_assert (identify_data->match == expected_matched);
g_assert (fake_dev->last_called_function == orig_identify);
}
static void
test_driver_identify_suspend_succeeds (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(MatchCbData) identify_data = g_new0 (MatchCbData, 1);
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GError) error = NULL;
void (*orig_identify) (FpDevice *device);
FpiDeviceFake *fake_dev;
FpPrint *expected_matched;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
orig_identify = dev_class->identify;
dev_class->identify = fake_device_stub_identify;
prints = make_fake_prints_gallery (device, 500);
expected_matched = g_ptr_array_index (prints, g_random_int_range (0, 499));
fp_print_set_description (expected_matched, "fake-verified");
match_data->gallery = prints;
g_assert_true (fp_device_open_sync (device, NULL, NULL));
fake_dev->ret_print = make_fake_print (device, NULL);
fp_device_identify (device, prints, NULL,
test_driver_match_cb, match_data, NULL,
(GAsyncReadyCallback) test_driver_identify_cb, identify_data);
while (g_main_context_iteration (NULL, FALSE))
continue;
/* suspend_sync hangs until cancellation, so we need to trigger orig_identify
* from the mainloop after calling suspend_sync.
*/
fpi_device_add_timeout (device, 0, (FpTimeoutFunc) orig_identify, NULL, NULL);
fake_dev->ret_suspend = fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED);
fp_device_suspend_sync (device, NULL, &error);
/* At this point we are done with everything */
g_assert (fake_dev->last_called_function == orig_identify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED);
g_clear_error (&error);
/* We suspended, but device reported success and that will be reported. */
g_assert_true (match_data->called);
g_assert (match_data->match == expected_matched);
g_assert_true (identify_data->called);
g_assert (identify_data->match == expected_matched);
/* Resuming the device does not call resume handler, as the action was
* cancelled already.
*/
fake_dev->last_called_function = NULL;
fp_device_resume_sync (device, NULL, &error);
g_assert (fake_dev->last_called_function == NULL);
g_assert_no_error (error);
}
static void
test_driver_identify_suspend_busy_error (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(MatchCbData) match_data = g_new0 (MatchCbData, 1);
g_autoptr(MatchCbData) identify_data = g_new0 (MatchCbData, 1);
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GError) error = NULL;
void (*orig_identify) (FpDevice *device);
FpiDeviceFake *fake_dev;
FpPrint *expected_matched;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
orig_identify = dev_class->identify;
dev_class->identify = fake_device_stub_identify;
prints = make_fake_prints_gallery (device, 500);
expected_matched = g_ptr_array_index (prints, g_random_int_range (0, 499));
fp_print_set_description (expected_matched, "fake-verified");
match_data->gallery = prints;
g_assert_true (fp_device_open_sync (device, NULL, NULL));
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
fake_dev->ret_print = make_fake_print (device, NULL);
fp_device_identify (device, prints, NULL,
test_driver_match_cb, match_data, NULL,
(GAsyncReadyCallback) test_driver_identify_cb, identify_data);
while (g_main_context_iteration (NULL, FALSE))
continue;
/* suspend_sync hangs until cancellation, so we need to trigger orig_identify
* from the mainloop after calling suspend_sync.
*/
fpi_device_add_timeout (device, 0, (FpTimeoutFunc) orig_identify, NULL, NULL);
fake_dev->ret_suspend = fpi_device_error_new (FP_DEVICE_ERROR_NOT_SUPPORTED);
fp_device_suspend_sync (device, NULL, &error);
fake_dev->ret_error = NULL;
/* At this point we are done with everything */
g_assert (fake_dev->last_called_function == orig_identify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED);
g_clear_error (&error);
/* The device reported an error, an this error will be overwritten.
*/
g_assert_false (match_data->called);
g_assert_true (identify_data->called);
g_assert_null (identify_data->match);
g_assert_error (identify_data->error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_BUSY);
fake_dev->last_called_function = NULL;
fp_device_resume_sync (device, NULL, &error);
g_assert (fake_dev->last_called_function == NULL);
g_assert_no_error (error);
}
static void
test_driver_identify_suspend_while_idle (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GError) error = NULL;
FpiDeviceFake *fake_dev;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
/* Suspending and resuming a closed device works */
fp_device_suspend (device, NULL, (GAsyncReadyCallback) fp_device_suspend_finish, &error);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == NULL);
g_assert_no_error (error);
fp_device_resume (device, NULL, (GAsyncReadyCallback) fp_device_resume_finish, NULL);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == NULL);
g_assert_no_error (error);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
fake_dev->last_called_function = NULL;
fp_device_suspend (device, NULL, (GAsyncReadyCallback) fp_device_suspend_finish, &error);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == NULL);
g_assert_no_error (error);
fp_device_resume (device, NULL, (GAsyncReadyCallback) fp_device_resume_finish, NULL);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == NULL);
g_assert_no_error (error);
}
static void
test_driver_identify_warmup_cooldown (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(MatchCbData) identify_data = g_new0 (MatchCbData, 1);
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GError) error = NULL;
void (*orig_identify) (FpDevice *device);
FpiDeviceFake *fake_dev;
gint64 start_time;
dev_class->temp_hot_seconds = 2;
dev_class->temp_cold_seconds = 5;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
orig_identify = dev_class->identify;
dev_class->identify = fake_device_stub_identify;
prints = make_fake_prints_gallery (device, 500);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
fake_dev->last_called_function = NULL;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
/* Undefined: Whether match_cb is called. */
fp_device_identify (device, prints, NULL,
NULL, NULL, NULL,
(GAsyncReadyCallback) test_driver_identify_cb, identify_data);
/* Identify is running, the temperature will change after only a short time.
* Changes are delayed by 100ms and we give 150ms of slack for the test.
*/
start_time = g_get_monotonic_time ();
g_assert_cmpint (fp_device_get_temperature (device), ==, FP_TEMPERATURE_COLD);
while (fp_device_get_temperature (device) == FP_TEMPERATURE_COLD)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (fp_device_get_temperature (device), ==, FP_TEMPERATURE_WARM);
g_assert_false (g_cancellable_is_cancelled (fpi_device_get_cancellable (device)));
g_assert_cmpint (g_get_monotonic_time () - start_time, <, 0 + 250000);
/* we reach hot 2 seconds later */
while (fp_device_get_temperature (device) == FP_TEMPERATURE_WARM)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (fp_device_get_temperature (device), ==, FP_TEMPERATURE_HOT);
g_assert_true (g_cancellable_is_cancelled (fpi_device_get_cancellable (device)));
g_assert_cmpint (g_get_monotonic_time () - start_time, <, 2000000 + 250000);
/* cancel vfunc will be called now */
g_assert (fake_dev->last_called_function == NULL);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == dev_class->cancel);
orig_identify (device);
fake_dev->ret_error = NULL;
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert_true (identify_data->called);
g_assert_error (identify_data->error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_TOO_HOT);
/* Now, wait for it to cool down again;
* WARM should be reached after about 2s
* COLD after 5s but give it some more slack. */
start_time = g_get_monotonic_time ();
while (fp_device_get_temperature (device) == FP_TEMPERATURE_HOT)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (fp_device_get_temperature (device), ==, FP_TEMPERATURE_WARM);
g_assert_cmpint (g_get_monotonic_time () - start_time, <, 2000000 + 250000);
while (fp_device_get_temperature (device) == FP_TEMPERATURE_WARM)
g_main_context_iteration (NULL, TRUE);
g_assert_cmpint (fp_device_get_temperature (device), ==, FP_TEMPERATURE_COLD);
g_assert_cmpint (g_get_monotonic_time () - start_time, <, 5000000 + 500000);
}
static void
fake_device_stub_capture (FpDevice *device)
{
}
static void
test_driver_supports_capture (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->features |= FP_DEVICE_FEATURE_CAPTURE;
dev_class->capture = fake_device_stub_capture;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_true (fp_device_supports_capture (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_CAPTURE));
}
static void
test_driver_do_not_support_capture (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->features &= ~FP_DEVICE_FEATURE_CAPTURE;
dev_class->capture = NULL;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_false (fp_device_supports_capture (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_CAPTURE));
}
static void
test_driver_capture (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpImage) image = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean wait_for_finger = TRUE;
fake_dev->ret_image = fp_image_new (500, 500);
image = fp_device_capture_sync (device, wait_for_finger, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->capture);
g_assert_true (GPOINTER_TO_UINT (fake_dev->action_data));
g_assert_no_error (error);
g_assert (image == fake_dev->ret_image);
}
static void
test_driver_capture_not_supported (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpImage) image = NULL;
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
gboolean wait_for_finger = TRUE;
FpiDeviceFake *fake_dev;
dev_class->features &= ~FP_DEVICE_FEATURE_CAPTURE;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->last_called_function = NULL;
image = fp_device_capture_sync (device, wait_for_finger, NULL, &error);
g_assert_null (fake_dev->last_called_function);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED);
g_assert_null (image);
}
static void
test_driver_capture_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpImage) image = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean wait_for_finger = TRUE;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
image = fp_device_capture_sync (device, wait_for_finger, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->capture);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_null (image);
}
static void
test_driver_has_storage (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->features |= FP_DEVICE_FEATURE_STORAGE;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_true (fp_device_has_storage (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_true (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE));
}
static void
test_driver_has_not_storage (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpDevice) device = NULL;
dev_class->features &= ~FP_DEVICE_FEATURE_STORAGE;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_false (fp_device_has_storage (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE));
}
static void
test_driver_list (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(GPtrArray) prints = make_fake_prints_gallery (device, 500);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->ret_list = g_steal_pointer (&prints);
prints = fp_device_list_prints_sync (device, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->list);
g_assert_no_error (error);
g_assert (prints == fake_dev->ret_list);
}
static void
test_driver_list_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_autoptr(GPtrArray) prints = NULL;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
prints = fp_device_list_prints_sync (device, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->list);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_null (prints);
}
static void
test_driver_list_no_storage (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GPtrArray) prints = NULL;
g_autoptr(GError) error = NULL;
dev_class->features &= ~FP_DEVICE_FEATURE_STORAGE;
device = auto_close_fake_device_new ();
G_GNUC_BEGIN_IGNORE_DEPRECATIONS
g_assert_false (fp_device_has_storage (device));
G_GNUC_END_IGNORE_DEPRECATIONS
g_assert_false (fp_device_has_feature (device, FP_DEVICE_FEATURE_STORAGE));
prints = fp_device_list_prints_sync (device, NULL, &error);
g_assert_null (prints);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_NOT_SUPPORTED);
}
static void
test_driver_delete (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean ret;
ret = fp_device_delete_print_sync (device, enrolled_print, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->delete);
g_assert (fake_dev->action_data == enrolled_print);
g_assert_no_error (error);
g_assert_true (ret);
}
static void
test_driver_delete_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean ret;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
ret = fp_device_delete_print_sync (device, enrolled_print, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->delete);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_false (ret);
}
static void
test_driver_clear_storage (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean ret;
ret = fp_device_clear_storage_sync (device, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->clear_storage);
g_assert_no_error (error);
g_assert_true (ret);
}
static void
test_driver_clear_storage_error (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
gboolean ret;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_GENERAL);
ret = fp_device_clear_storage_sync (device, NULL, &error);
g_assert (fake_dev->last_called_function == dev_class->clear_storage);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_assert (error == g_steal_pointer (&fake_dev->ret_error));
g_assert_false (ret);
}
static gboolean
fake_device_delete_wait_for_cancel_timeout (gpointer data)
{
FpDevice *device = data;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
g_assert (fake_dev->last_called_function == dev_class->cancel);
default_fake_dev_class.delete (device);
g_assert (fake_dev->last_called_function == default_fake_dev_class.delete);
fake_dev->last_called_function = fake_device_delete_wait_for_cancel_timeout;
return G_SOURCE_REMOVE;
}
static void
fake_device_delete_wait_for_cancel (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->last_called_function = fake_device_delete_wait_for_cancel;
g_timeout_add (100, fake_device_delete_wait_for_cancel_timeout, device);
}
static void
on_driver_cancel_delete (GObject *obj, GAsyncResult *res, gpointer user_data)
{
g_autoptr(GError) error = NULL;
FpDevice *device = FP_DEVICE (obj);
gboolean *completed = user_data;
fp_device_delete_print_finish (device, res, &error);
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
*completed = TRUE;
}
static void
test_driver_cancel (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GCancellable) cancellable = NULL;
g_autoptr(FpPrint) enrolled_print = NULL;
gboolean completed = FALSE;
FpiDeviceFake *fake_dev;
dev_class->delete = fake_device_delete_wait_for_cancel;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
cancellable = g_cancellable_new ();
enrolled_print = make_fake_print_reffed (device, NULL);
fp_device_delete_print (device, enrolled_print, cancellable,
on_driver_cancel_delete, &completed);
g_cancellable_cancel (cancellable);
while (!completed)
g_main_context_iteration (NULL, TRUE);
g_assert (fake_dev->last_called_function == fake_device_delete_wait_for_cancel_timeout);
}
static void
test_driver_cancel_fail (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_true (fp_device_delete_print_sync (device, enrolled_print, cancellable, &error));
g_assert (fake_dev->last_called_function == dev_class->delete);
g_cancellable_cancel (cancellable);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == dev_class->delete);
g_assert_no_error (error);
}
static void
test_driver_critical (void)
{
g_autoptr(FpAutoCloseDevice) device = auto_close_fake_device_new ();
g_autoptr(GCancellable) cancellable = g_cancellable_new ();
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
void (*orig_verify) (FpDevice *device) = dev_class->verify;
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->last_called_function = NULL;
dev_class->verify = fake_device_stub_verify;
fp_device_verify (device, enrolled_print, cancellable,
NULL, NULL, NULL,
NULL, NULL);
/* We started a verify operation, now emulate a "critical" section */
fpi_device_critical_enter (device);
/* Throw a suspend and external cancellation against it. */
fp_device_suspend (device, NULL, NULL, NULL);
g_cancellable_cancel (cancellable);
/* The only thing that happens is that the cancellable is cancelled */
g_assert_true (fpi_device_action_is_cancelled (device));
g_assert (fake_dev->last_called_function == NULL);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == NULL);
/* Leaving and entering the critical section in the same mainloop iteration
* does not do anything. */
fpi_device_critical_leave (device);
fpi_device_critical_enter (device);
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == NULL);
/* Leaving it and running the mainloop will first run the cancel handler */
fpi_device_critical_leave (device);
while (g_main_context_iteration (NULL, FALSE) && !fake_dev->last_called_function)
continue;
g_assert (fake_dev->last_called_function == dev_class->cancel);
g_assert_true (fpi_device_action_is_cancelled (device));
fake_dev->last_called_function = NULL;
/* Then the suspend handler */
while (g_main_context_iteration (NULL, FALSE) && !fake_dev->last_called_function)
continue;
g_assert (fake_dev->last_called_function == dev_class->suspend);
fake_dev->last_called_function = NULL;
/* Nothing happens afterwards */
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == NULL);
/* Throw a resume at the system */
fpi_device_critical_enter (device);
fp_device_resume (device, NULL, NULL, NULL);
/* Nothing will happen, as the resume is delayed */
while (g_main_context_iteration (NULL, FALSE))
continue;
g_assert (fake_dev->last_called_function == NULL);
/* Finally the resume is called from the mainloop after leaving the critical section */
fpi_device_critical_leave (device);
g_assert (fake_dev->last_called_function == NULL);
while (g_main_context_iteration (NULL, FALSE) && !fake_dev->last_called_function)
continue;
g_assert (fake_dev->last_called_function == dev_class->resume);
fake_dev->last_called_function = NULL;
/* The "verify" operation is still ongoing, finish it. */
orig_verify (device);
while (g_main_context_iteration (NULL, FALSE))
continue;
}
static void
test_driver_current_action (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_assert_cmpint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_NONE);
}
static void
test_driver_current_action_open_vfunc (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_OPEN);
fake_dev->last_called_function = test_driver_current_action_open_vfunc;
fpi_device_open_complete (device, NULL);
}
static void
test_driver_current_action_open (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
FpiDeviceFake *fake_dev;
dev_class->open = test_driver_current_action_open_vfunc;
device = auto_close_fake_device_new ();
fake_dev = FPI_DEVICE_FAKE (device);
g_assert (fake_dev->last_called_function == test_driver_current_action_open_vfunc);
g_assert_cmpint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_NONE);
}
static void
test_driver_action_get_cancellable_open_vfunc (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_OPEN);
fake_dev->last_called_function = test_driver_action_get_cancellable_open_vfunc;
g_assert_true (G_IS_CANCELLABLE (fpi_device_get_cancellable (device)));
fpi_device_open_complete (device, NULL);
}
static void
test_driver_action_get_cancellable_open (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GCancellable) cancellable = NULL;
FpiDeviceFake *fake_dev;
dev_class->open = test_driver_action_get_cancellable_open_vfunc;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
cancellable = g_cancellable_new ();
g_assert_true (fp_device_open_sync (device, cancellable, NULL));
g_assert (fake_dev->last_called_function == test_driver_action_get_cancellable_open_vfunc);
}
static void
test_driver_action_get_cancellable_open_internal_vfunc (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_OPEN);
fake_dev->last_called_function = test_driver_action_get_cancellable_open_internal_vfunc;
g_assert_true (G_IS_CANCELLABLE (fpi_device_get_cancellable (device)));
fpi_device_open_complete (device, NULL);
}
static void
test_driver_action_get_cancellable_open_internal (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
FpiDeviceFake *fake_dev;
dev_class->open = test_driver_action_get_cancellable_open_internal_vfunc;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
g_assert_true (fp_device_open_sync (device, NULL, NULL));
g_assert (fake_dev->last_called_function == test_driver_action_get_cancellable_open_internal_vfunc);
}
static void
test_driver_action_get_cancellable_error (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*FPI_DEVICE_ACTION_NONE*failed");
g_assert_null (fpi_device_get_cancellable (device));
g_test_assert_expected_messages ();
}
static void
test_driver_action_is_cancelled_open_vfunc (FpDevice *device)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
g_assert_cmpuint (fpi_device_get_current_action (device), ==, FPI_DEVICE_ACTION_OPEN);
fake_dev->last_called_function = test_driver_action_is_cancelled_open_vfunc;
g_assert_true (G_IS_CANCELLABLE (fpi_device_get_cancellable (device)));
g_assert_false (fpi_device_action_is_cancelled (device));
if (fake_dev->ext_cancellable)
g_cancellable_cancel (fake_dev->ext_cancellable);
else
g_cancellable_cancel (fpi_device_get_cancellable (device));
g_assert_true (fpi_device_action_is_cancelled (device));
fpi_device_open_complete (device, NULL);
}
static void
test_driver_action_is_cancelled_open (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GCancellable) cancellable = NULL;
g_autoptr(GError) error = NULL;
FpiDeviceFake *fake_dev;
dev_class->open = test_driver_action_is_cancelled_open_vfunc;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
cancellable = fake_dev->ext_cancellable = g_cancellable_new ();
g_assert_false (fp_device_open_sync (device, cancellable, &error));
g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
g_assert (fake_dev->last_called_function == test_driver_action_is_cancelled_open_vfunc);
}
static void
test_driver_action_internally_cancelled_open (void)
{
g_autoptr(FpAutoResetClass) dev_class = auto_reset_device_class ();
g_autoptr(FpAutoCloseDevice) device = NULL;
g_autoptr(GCancellable) cancellable = NULL;
g_autoptr(GError) error = NULL;
FpiDeviceFake *fake_dev;
dev_class->open = test_driver_action_is_cancelled_open_vfunc;
device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
fake_dev = FPI_DEVICE_FAKE (device);
/* No error, just some internal cancellation but we let nothing happen externally. */
cancellable = g_cancellable_new ();
g_assert_true (fp_device_open_sync (device, cancellable, &error));
g_assert_null (error);
g_assert (fake_dev->last_called_function == test_driver_action_is_cancelled_open_vfunc);
}
static void
test_driver_action_is_cancelled_error (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*FPI_DEVICE_ACTION_NONE*failed");
g_assert_true (fpi_device_action_is_cancelled (device));
g_test_assert_expected_messages ();
}
static void
test_driver_complete_actions_errors (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_probe_complete (device, NULL, NULL, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_open_complete (device, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_close_complete (device, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_enroll_complete (device, NULL, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_verify_complete (device, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_identify_complete (device, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_capture_complete (device, NULL, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_delete_complete (device, NULL);
g_test_assert_expected_messages ();
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*failed");
fpi_device_list_complete (device, NULL, NULL);
g_test_assert_expected_messages ();
}
static void
test_driver_action_error_error (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL,
"*assertion*current_action*FPI_DEVICE_ACTION_NONE*failed");
fpi_device_action_error (device, NULL);
g_test_assert_expected_messages ();
}
static void
test_driver_action_error_all (void)
{
g_autoptr(FpAutoCloseDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
g_autoptr(GPtrArray) prints = make_fake_prints_gallery (device, 0);
g_autoptr(GError) error = NULL;
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev;
fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->return_action_error = TRUE;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_false (fp_device_open_sync (device, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->open);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
fake_dev->return_action_error = FALSE;
fake_dev->ret_error = NULL;
g_assert_true (fp_device_open_sync (device, NULL, NULL));
fake_dev->return_action_error = TRUE;
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_null (fp_device_enroll_sync (device, fp_print_new (device), NULL,
NULL, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->enroll);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL,
NULL, NULL, NULL, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->verify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_false (fp_device_identify_sync (device, prints, NULL,
NULL, NULL, NULL, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->identify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_null (fp_device_capture_sync (device, TRUE, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->capture);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_null (fp_device_list_prints_sync (device, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->list);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_false (fp_device_delete_print_sync (device, enrolled_print, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->delete);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_false (fp_device_clear_storage_sync (device, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->clear_storage);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
/* Test close last, as we can't operate on a closed device. */
fake_dev->ret_error = fpi_device_error_new (FP_DEVICE_ERROR_DATA_INVALID);
g_assert_false (fp_device_close_sync (device, NULL, &error));
g_assert_true (fake_dev->last_called_function == dev_class->close);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_DATA_INVALID);
g_clear_error (&error);
}
static void
test_driver_action_error_fallback_all (void)
{
g_autoptr(FpAutoCloseDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_autoptr(FpPrint) enrolled_print = make_fake_print_reffed (device, NULL);
g_autoptr(GPtrArray) prints = make_fake_prints_gallery (device, 0);
g_autoptr(GError) error = NULL;
FpDeviceClass *dev_class = FP_DEVICE_GET_CLASS (device);
FpiDeviceFake *fake_dev;
fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->return_action_error = TRUE;
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_false (fp_device_open_sync (device, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->open);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
fake_dev->return_action_error = FALSE;
g_assert_true (fp_device_open_sync (device, NULL, NULL));
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
fake_dev->return_action_error = TRUE;
g_assert_null (fp_device_enroll_sync (device, fp_print_new (device), NULL,
NULL, NULL, &error));
g_test_assert_expected_messages ();
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->enroll);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_false (fp_device_verify_sync (device, enrolled_print, NULL,
NULL, NULL, NULL, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->verify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_false (fp_device_identify_sync (device, prints, NULL,
NULL, NULL, NULL, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->identify);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_null (fp_device_capture_sync (device, TRUE, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->capture);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_null (fp_device_list_prints_sync (device, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->list);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_false (fp_device_delete_print_sync (device, enrolled_print, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->delete);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_false (fp_device_clear_storage_sync (device, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->clear_storage);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
/* Test close last, as we can't operate on a closed device. */
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING,
"*Device failed to pass an error to generic action "
"error function*");
g_assert_false (fp_device_close_sync (device, NULL, &error));
g_test_assert_expected_messages ();
g_assert_true (fake_dev->last_called_function == dev_class->close);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_clear_error (&error);
}
static void
test_driver_add_timeout_func (FpDevice *device, gpointer user_data)
{
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
fake_dev->last_called_function = test_driver_add_timeout_func;
}
static void
test_driver_add_timeout (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpDevice *data_check = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
g_object_add_weak_pointer (G_OBJECT (data_check), (gpointer) & data_check);
fpi_device_add_timeout (device, 50, test_driver_add_timeout_func,
data_check, g_object_unref);
g_assert_nonnull (data_check);
while (FP_IS_DEVICE (data_check))
g_main_context_iteration (NULL, TRUE);
g_assert_null (data_check);
g_assert (fake_dev->last_called_function == test_driver_add_timeout_func);
}
static gboolean
test_driver_add_timeout_cancelled_timeout (gpointer data)
{
GSource *source = data;
g_source_destroy (source);
return G_SOURCE_REMOVE;
}
static void
test_driver_add_timeout_cancelled (void)
{
g_autoptr(FpDevice) device = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
FpiDeviceFake *fake_dev = FPI_DEVICE_FAKE (device);
FpDevice *data_check = g_object_new (FPI_TYPE_DEVICE_FAKE, NULL);
GSource *source;
g_object_add_weak_pointer (G_OBJECT (data_check), (gpointer) & data_check);
source = fpi_device_add_timeout (device, 2000, test_driver_add_timeout_func,
data_check, g_object_unref);
g_timeout_add (20, test_driver_add_timeout_cancelled_timeout, source);
g_assert_nonnull (data_check);
while (FP_IS_DEVICE (data_check))
g_main_context_iteration (NULL, TRUE);
g_assert_null (data_check);
g_assert_null (fake_dev->last_called_function);
}
static void
test_driver_error_types (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(GEnumClass) errors_enum = g_type_class_ref (FP_TYPE_DEVICE_ERROR);
int i;
for (i = 0; g_enum_get_value (errors_enum, i); ++i)
{
g_autoptr(GError) e = NULL;
g_autoptr(GError) msg_e = NULL;
g_autofree char *expected_msg = NULL;
g_autofree char *enum_string = g_enum_to_string (FP_TYPE_DEVICE_ERROR, i);
e = fpi_device_error_new (i);
g_assert_error (e, FP_DEVICE_ERROR, i);
expected_msg = g_strdup_printf ("Error message %s", enum_string);
msg_e = fpi_device_error_new_msg (i, "Error message %s", enum_string);
g_assert_error (msg_e, FP_DEVICE_ERROR, i);
g_assert_cmpstr (msg_e->message, ==, expected_msg);
}
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*Unsupported error*");
error = fpi_device_error_new (i + 1);
g_assert_error (error, FP_DEVICE_ERROR, FP_DEVICE_ERROR_GENERAL);
g_test_assert_expected_messages ();
}
static void
test_driver_retry_error_types (void)
{
g_autoptr(GError) error = NULL;
g_autoptr(GEnumClass) errors_enum = g_type_class_ref (FP_TYPE_DEVICE_RETRY);
int i;
for (i = 0; g_enum_get_value (errors_enum, i); ++i)
{
g_autoptr(GError) e = NULL;
g_autoptr(GError) msg_e = NULL;
g_autofree char *expected_msg = NULL;
g_autofree char *enum_string = g_enum_to_string (FP_TYPE_DEVICE_RETRY, i);
e = fpi_device_retry_new (i);
g_assert_error (e, FP_DEVICE_RETRY, i);
expected_msg = g_strdup_printf ("Retry error message %s", enum_string);
msg_e = fpi_device_retry_new_msg (i, "Retry error message %s", enum_string);
g_assert_error (msg_e, FP_DEVICE_RETRY, i);
g_assert_cmpstr (msg_e->message, ==, expected_msg);
}
g_test_expect_message (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, "*Unsupported error*");
error = fpi_device_retry_new (i + 1);
g_assert_error (error, FP_DEVICE_RETRY, FP_DEVICE_RETRY_GENERAL);
g_test_assert_expected_messages ();
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/driver/get_driver", test_driver_get_driver);
g_test_add_func ("/driver/get_device_id", test_driver_get_device_id);
g_test_add_func ("/driver/get_name", test_driver_get_name);
g_test_add_func ("/driver/is_open", test_driver_is_open);
g_test_add_func ("/driver/get_scan_type/press", test_driver_get_scan_type_press);
g_test_add_func ("/driver/get_scan_type/swipe", test_driver_get_scan_type_swipe);
g_test_add_func ("/driver/set_scan_type/press", test_driver_set_scan_type_press);
g_test_add_func ("/driver/set_scan_type/swipe", test_driver_set_scan_type_swipe);
g_test_add_func ("/driver/finger_status/inactive", test_driver_finger_status_inactive);
g_test_add_func ("/driver/finger_status/waiting", test_driver_finger_status_needed);
g_test_add_func ("/driver/finger_status/present", test_driver_finger_status_present);
g_test_add_func ("/driver/finger_status/changes", test_driver_finger_status_changes);
g_test_add_func ("/driver/get_nr_enroll_stages", test_driver_get_nr_enroll_stages);
g_test_add_func ("/driver/set_nr_enroll_stages", test_driver_set_nr_enroll_stages);
g_test_add_func ("/driver/supports_identify", test_driver_supports_identify);
g_test_add_func ("/driver/supports_capture", test_driver_supports_capture);
g_test_add_func ("/driver/has_storage", test_driver_has_storage);
g_test_add_func ("/driver/do_not_support_identify", test_driver_do_not_support_identify);
g_test_add_func ("/driver/do_not_support_capture", test_driver_do_not_support_capture);
g_test_add_func ("/driver/has_not_storage", test_driver_has_not_storage);
g_test_add_func ("/driver/get_usb_device", test_driver_get_usb_device);
g_test_add_func ("/driver/get_virtual_env", test_driver_get_virtual_env);
g_test_add_func ("/driver/get_driver_data", test_driver_get_driver_data);
g_test_add_func ("/driver/features/probe_updates", test_driver_features_probe_updates);
g_test_add_func ("/driver/initial_features", test_driver_initial_features);
g_test_add_func ("/driver/initial_features/none", test_driver_initial_features_none);
g_test_add_func ("/driver/initial_features/no_capture", test_driver_initial_features_no_capture);
g_test_add_func ("/driver/initial_features/no_verify", test_driver_initial_features_no_verify);
g_test_add_func ("/driver/initial_features/no_identify", test_driver_initial_features_no_identify);
g_test_add_func ("/driver/initial_features/no_storage", test_driver_initial_features_no_storage);
g_test_add_func ("/driver/initial_features/no_list", test_driver_initial_features_no_list);
g_test_add_func ("/driver/initial_features/no_delete", test_driver_initial_features_no_delete);
g_test_add_func ("/driver/initial_features/no_clear", test_driver_initial_features_no_clear);
g_test_add_func ("/driver/probe", test_driver_probe);
g_test_add_func ("/driver/probe/error", test_driver_probe_error);
g_test_add_func ("/driver/probe/action_error", test_driver_probe_action_error);
g_test_add_func ("/driver/open", test_driver_open);
g_test_add_func ("/driver/open/error", test_driver_open_error);
g_test_add_func ("/driver/close", test_driver_close);
g_test_add_func ("/driver/close/error", test_driver_close_error);
g_test_add_func ("/driver/enroll", test_driver_enroll);
g_test_add_func ("/driver/enroll/error", test_driver_enroll_error);
g_test_add_func ("/driver/enroll/error/no_print", test_driver_enroll_error_no_print);
g_test_add_func ("/driver/enroll/progress", test_driver_enroll_progress);
g_test_add_func ("/driver/enroll/update_nbis", test_driver_enroll_update_nbis);
g_test_add_func ("/driver/enroll/update_nbis_wrong_device",
test_driver_enroll_update_nbis_wrong_device);
g_test_add_func ("/driver/enroll/update_nbis_wrong_driver",
test_driver_enroll_update_nbis_wrong_driver);
g_test_add_func ("/driver/enroll/update_nbis_missing_feature",
test_driver_enroll_update_nbis_missing_feature);
g_test_add_func ("/driver/verify", test_driver_verify);
g_test_add_func ("/driver/verify/fail", test_driver_verify_fail);
g_test_add_func ("/driver/verify/retry", test_driver_verify_retry);
g_test_add_func ("/driver/verify/error", test_driver_verify_error);
g_test_add_func ("/driver/verify/not_supported", test_driver_verify_not_supported);
g_test_add_func ("/driver/verify/report_no_cb", test_driver_verify_report_no_callback);
g_test_add_func ("/driver/verify/not_reported", test_driver_verify_not_reported);
g_test_add_func ("/driver/verify/complete_retry", test_driver_verify_complete_retry);
g_test_add_func ("/driver/identify", test_driver_identify);
g_test_add_func ("/driver/identify/fail", test_driver_identify_fail);
g_test_add_func ("/driver/identify/retry", test_driver_identify_retry);
g_test_add_func ("/driver/identify/error", test_driver_identify_error);
g_test_add_func ("/driver/identify/not_reported", test_driver_identify_not_reported);
g_test_add_func ("/driver/identify/complete_retry", test_driver_identify_complete_retry);
g_test_add_func ("/driver/identify/report_no_cb", test_driver_identify_report_no_callback);
g_test_add_func ("/driver/identify/suspend_continues", test_driver_identify_suspend_continues);
g_test_add_func ("/driver/identify/suspend_succeeds", test_driver_identify_suspend_succeeds);
g_test_add_func ("/driver/identify/suspend_busy_error", test_driver_identify_suspend_busy_error);
g_test_add_func ("/driver/identify/suspend_while_idle", test_driver_identify_suspend_while_idle);
g_test_add_func ("/driver/identify/warmup_cooldown", test_driver_identify_warmup_cooldown);
g_test_add_func ("/driver/capture", test_driver_capture);
g_test_add_func ("/driver/capture/not_supported", test_driver_capture_not_supported);
g_test_add_func ("/driver/capture/error", test_driver_capture_error);
g_test_add_func ("/driver/list", test_driver_list);
g_test_add_func ("/driver/list/error", test_driver_list_error);
g_test_add_func ("/driver/list/no_storage", test_driver_list_no_storage);
g_test_add_func ("/driver/delete", test_driver_delete);
g_test_add_func ("/driver/delete/error", test_driver_delete_error);
g_test_add_func ("/driver/clear_storage", test_driver_clear_storage);
g_test_add_func ("/driver/clear_storage/error", test_driver_clear_storage_error);
g_test_add_func ("/driver/cancel", test_driver_cancel);
g_test_add_func ("/driver/cancel/fail", test_driver_cancel_fail);
g_test_add_func ("/driver/critical", test_driver_critical);
g_test_add_func ("/driver/get_current_action", test_driver_current_action);
g_test_add_func ("/driver/get_current_action/open", test_driver_current_action_open);
g_test_add_func ("/driver/get_cancellable/error", test_driver_action_get_cancellable_error);
g_test_add_func ("/driver/get_cancellable/open", test_driver_action_get_cancellable_open);
g_test_add_func ("/driver/get_cancellable/open/internal", test_driver_action_get_cancellable_open_internal);
g_test_add_func ("/driver/action_is_cancelled/open", test_driver_action_is_cancelled_open);
g_test_add_func ("/driver/action_is_cancelled/open/internal", test_driver_action_internally_cancelled_open);
g_test_add_func ("/driver/action_is_cancelled/error", test_driver_action_is_cancelled_error);
g_test_add_func ("/driver/complete_action/all/error", test_driver_complete_actions_errors);
g_test_add_func ("/driver/action_error/error", test_driver_action_error_error);
g_test_add_func ("/driver/action_error/all", test_driver_action_error_all);
g_test_add_func ("/driver/action_error/fail", test_driver_action_error_fallback_all);
g_test_add_func ("/driver/timeout", test_driver_add_timeout);
g_test_add_func ("/driver/timeout/cancelled", test_driver_add_timeout_cancelled);
g_test_add_func ("/driver/error_types", test_driver_error_types);
g_test_add_func ("/driver/retry_error_types", test_driver_retry_error_types);
return g_test_run ();
}