libfprint/tests/test-validity-sensor.c
Leonardo Francisco 4bf976c7b5 validity: fix code style (uncrustify) and test assertions
Apply uncrustify formatting to all validity driver and test files
to pass the CI test_indent check.

Fix two pre-existing test failures:
- test-validity-capture: LED command blobs are 125 bytes, not 128
- test-validity-enroll: add 2-byte length prefix to test data to
  match parser's expected format, fix empty-data assertion (parser
  returns FALSE for data_len < 2)

All 41 tests pass, 0 failures.
2026-04-22 03:06:34 +00:00

349 lines
12 KiB
C

/*
* Unit tests for validity sensor identification and HAL tables
*
* Copyright (C) 2024 libfprint contributors
*
* 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.
*/
#include <glib.h>
#include <string.h>
#include "fpi-byte-utils.h"
#include "drivers/validity/validity_sensor.h"
/* ================================================================
* T4.1: test_identify_sensor_parse
*
* Verify that a valid cmd 0x75 response is parsed correctly into
* a ValiditySensorIdent (hw_major + hw_version).
*
* Wire format (after 2-byte status stripped):
* [zeroes:4 LE] [version:2 LE] [major:2 LE]
* ================================================================ */
static void
test_identify_sensor_parse (void)
{
ValiditySensorIdent ident;
/* Build synthetic response: zeroes=0, version=0x13, major=0x004a */
guint8 data[8];
FP_WRITE_UINT32_LE (&data[0], 0); /* zeroes */
FP_WRITE_UINT16_LE (&data[4], 0x0013); /* version */
FP_WRITE_UINT16_LE (&data[6], 0x004a); /* major */
gboolean ok = validity_sensor_parse_identify (data, sizeof (data), &ident);
g_assert_true (ok);
g_assert_cmpuint (ident.hw_major, ==, 0x004a);
g_assert_cmpuint (ident.hw_version, ==, 0x0013);
}
/* ================================================================
* T4.2: test_identify_sensor_parse_truncated
*
* Verify that a response shorter than 8 bytes returns FALSE.
* ================================================================ */
static void
test_identify_sensor_parse_truncated (void)
{
ValiditySensorIdent ident;
guint8 data[7] = { 0 };
g_assert_false (validity_sensor_parse_identify (data, sizeof (data), &ident));
/* Also test with 0 length */
g_assert_false (validity_sensor_parse_identify (data, 0, &ident));
}
/* ================================================================
* T4.3: test_device_info_lookup_exact
*
* Verify that lookup with major=0x004a, version=0x13 returns the
* correct DeviceInfo for the ThinkPad T480s sensor.
* ================================================================ */
static void
test_device_info_lookup_exact (void)
{
const ValidityDeviceInfo *info;
info = validity_device_info_lookup (0x004a, 0x13);
g_assert_nonnull (info);
g_assert_cmpuint (info->major, ==, 0x004a);
g_assert_cmpuint (info->type, ==, 0x00b5);
g_assert_cmpuint (info->version, ==, 0x13);
g_assert_cmpstr (info->name, ==, "SYN 57K0 FM3297-02");
}
/* ================================================================
* T4.4: test_device_info_lookup_another
*
* Verify that lookup with major=0x0071, version=0x01 returns
* the VSI 55E entry (type 0xdb).
* ================================================================ */
static void
test_device_info_lookup_another (void)
{
const ValidityDeviceInfo *info;
info = validity_device_info_lookup (0x0071, 0x01);
g_assert_nonnull (info);
g_assert_cmpuint (info->type, ==, 0x00db);
g_assert_cmpstr (info->name, ==, "VSI 55E FM72-001");
}
/* ================================================================
* T4.5: test_device_info_lookup_unknown
*
* Verify that a completely unknown major returns NULL.
* ================================================================ */
static void
test_device_info_lookup_unknown (void)
{
const ValidityDeviceInfo *info;
info = validity_device_info_lookup (0xffff, 0x01);
g_assert_null (info);
}
/* ================================================================
* T4.6: test_device_info_lookup_fuzzy
*
* Verify that when version_mask == 0x00, the entry matches any
* version (fuzzy match).
* ================================================================ */
static void
test_device_info_lookup_fuzzy (void)
{
const ValidityDeviceInfo *info;
/* major=0x0000 entries have version_mask=0x00 → always fuzzy match.
* But major=0x0000 needs to match the lookup major. */
info = validity_device_info_lookup (0x0000, 0x42);
/* Should match one of the wildcard entries */
g_assert_nonnull (info);
g_assert_cmpuint (info->major, ==, 0x0000);
}
/* ================================================================
* T4.7: test_sensor_type_info_lookup
*
* Verify lookup of sensor type 0x00b5 returns correct geometry.
* ================================================================ */
static void
test_sensor_type_info_lookup (void)
{
const ValiditySensorTypeInfo *info;
info = validity_sensor_type_info_lookup (0x00b5);
g_assert_nonnull (info);
g_assert_cmpuint (info->sensor_type, ==, 0x00b5);
g_assert_cmpuint (info->bytes_per_line, ==, 0x78);
g_assert_cmpuint (info->repeat_multiplier, ==, 2);
g_assert_cmpuint (info->lines_per_calibration_data, ==, 112);
g_assert_cmpuint (info->line_width, ==, 112);
g_assert_nonnull (info->calibration_blob);
g_assert_cmpuint (info->calibration_blob_len, ==, 112);
}
/* ================================================================
* T4.8: test_sensor_type_info_lookup_db
*
* Verify lookup of sensor type 0x00db (55E) returns correct geometry.
* ================================================================ */
static void
test_sensor_type_info_lookup_db (void)
{
const ValiditySensorTypeInfo *info;
info = validity_sensor_type_info_lookup (0x00db);
g_assert_nonnull (info);
g_assert_cmpuint (info->bytes_per_line, ==, 0x98);
g_assert_cmpuint (info->repeat_multiplier, ==, 1);
g_assert_cmpuint (info->lines_per_calibration_data, ==, 144);
g_assert_cmpuint (info->line_width, ==, 144);
}
/* ================================================================
* T4.9: test_sensor_type_info_lookup_unknown
*
* Verify that an unknown sensor type returns NULL.
* ================================================================ */
static void
test_sensor_type_info_lookup_unknown (void)
{
g_assert_null (validity_sensor_type_info_lookup (0xbeef));
}
/* ================================================================
* T4.10: test_factory_bits_cmd_format
*
* Verify that the factory bits command is built correctly.
* Expected: [0x6f] [0x00 0x0e] [0x00 0x00] [0x00 0x00 0x00 0x00]
* ================================================================ */
static void
test_factory_bits_cmd_format (void)
{
guint8 buf[16];
gsize len;
len = validity_sensor_build_factory_bits_cmd (0x0e00, buf, sizeof (buf));
g_assert_cmpuint (len, ==, 9);
g_assert_cmpuint (buf[0], ==, 0x6f);
/* tag = 0x0e00 LE */
g_assert_cmpuint (buf[1], ==, 0x00);
g_assert_cmpuint (buf[2], ==, 0x0e);
/* pad 2 bytes */
g_assert_cmpuint (buf[3], ==, 0x00);
g_assert_cmpuint (buf[4], ==, 0x00);
/* pad 4 bytes */
g_assert_cmpuint (buf[5], ==, 0x00);
g_assert_cmpuint (buf[6], ==, 0x00);
g_assert_cmpuint (buf[7], ==, 0x00);
g_assert_cmpuint (buf[8], ==, 0x00);
}
/* ================================================================
* T4.11: test_factory_bits_cmd_buffer_too_small
*
* Verify that a too-small buffer returns 0.
* ================================================================ */
static void
test_factory_bits_cmd_buffer_too_small (void)
{
guint8 buf[4];
gsize len;
len = validity_sensor_build_factory_bits_cmd (0x0e00, buf, sizeof (buf));
g_assert_cmpuint (len, ==, 0);
}
/* ================================================================
* T4.12: test_identify_then_lookup
*
* End-to-end: parse identify_sensor response → DeviceInfo lookup →
* SensorTypeInfo lookup. Simulates the T480s sensor (06cb:009a).
* ================================================================ */
static void
test_identify_then_lookup (void)
{
ValiditySensorIdent ident;
const ValidityDeviceInfo *dev_info;
const ValiditySensorTypeInfo *type_info;
/* Simulate cmd 0x75 response for T480s: major=0x004a, version=0x13 */
guint8 data[8];
FP_WRITE_UINT32_LE (&data[0], 0);
FP_WRITE_UINT16_LE (&data[4], 0x0013);
FP_WRITE_UINT16_LE (&data[6], 0x004a);
g_assert_true (validity_sensor_parse_identify (data, sizeof (data), &ident));
g_assert_cmpuint (ident.hw_major, ==, 0x004a);
g_assert_cmpuint (ident.hw_version, ==, 0x0013);
dev_info = validity_device_info_lookup (ident.hw_major, ident.hw_version);
g_assert_nonnull (dev_info);
g_assert_cmpuint (dev_info->type, ==, 0x00b5);
type_info = validity_sensor_type_info_lookup (dev_info->type);
g_assert_nonnull (type_info);
g_assert_cmpuint (type_info->bytes_per_line, ==, 0x78);
g_assert_cmpuint (type_info->line_width, ==, 112);
}
/* ================================================================
* T4.13: test_sensor_state_lifecycle
*
* Verify that init zeros the state and clear frees allocated data.
* ================================================================ */
static void
test_sensor_state_lifecycle (void)
{
ValiditySensorState state;
validity_sensor_state_init (&state);
g_assert_null (state.device_info);
g_assert_null (state.type_info);
g_assert_null (state.factory_bits);
g_assert_cmpuint (state.factory_bits_len, ==, 0);
/* Simulate storing factory bits */
state.factory_bits = g_memdup2 ("\x01\x02\x03", 3);
state.factory_bits_len = 3;
validity_sensor_state_clear (&state);
g_assert_null (state.factory_bits);
g_assert_cmpuint (state.factory_bits_len, ==, 0);
}
/* ================================================================
* T4.14: test_calibration_blob_present
*
* Verify that the calibration blob for type 0x00b5 has expected
* first and last bytes (from python-validity generated_tables).
* ================================================================ */
static void
test_calibration_blob_present (void)
{
const ValiditySensorTypeInfo *info;
info = validity_sensor_type_info_lookup (0x00b5);
g_assert_nonnull (info);
g_assert_nonnull (info->calibration_blob);
g_assert_cmpuint (info->calibration_blob_len, ==, 112);
/* First byte: 0x9b, last byte: 0x06 */
g_assert_cmpuint (info->calibration_blob[0], ==, 0x9b);
g_assert_cmpuint (info->calibration_blob[111], ==, 0x06);
}
int
main (int argc, char *argv[])
{
g_test_init (&argc, &argv, NULL);
g_test_add_func ("/validity/sensor/identify/parse",
test_identify_sensor_parse);
g_test_add_func ("/validity/sensor/identify/truncated",
test_identify_sensor_parse_truncated);
g_test_add_func ("/validity/sensor/devinfo/lookup_exact",
test_device_info_lookup_exact);
g_test_add_func ("/validity/sensor/devinfo/lookup_another",
test_device_info_lookup_another);
g_test_add_func ("/validity/sensor/devinfo/lookup_unknown",
test_device_info_lookup_unknown);
g_test_add_func ("/validity/sensor/devinfo/lookup_fuzzy",
test_device_info_lookup_fuzzy);
g_test_add_func ("/validity/sensor/typeinfo/lookup",
test_sensor_type_info_lookup);
g_test_add_func ("/validity/sensor/typeinfo/lookup_db",
test_sensor_type_info_lookup_db);
g_test_add_func ("/validity/sensor/typeinfo/lookup_unknown",
test_sensor_type_info_lookup_unknown);
g_test_add_func ("/validity/sensor/factory_bits/cmd_format",
test_factory_bits_cmd_format);
g_test_add_func ("/validity/sensor/factory_bits/buffer_too_small",
test_factory_bits_cmd_buffer_too_small);
g_test_add_func ("/validity/sensor/identify_then_lookup",
test_identify_then_lookup);
g_test_add_func ("/validity/sensor/state_lifecycle",
test_sensor_state_lifecycle);
g_test_add_func ("/validity/sensor/calibration_blob_present",
test_calibration_blob_present);
return g_test_run ();
}