lardon3d/tests/test_optical_profiles.c

1875 lines
85 KiB
C

#include <sqlite3.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <lardon3d/acquisition_campaign_task.h>
#include <lardon3d/optical_profiles.h>
#include <lardon3d/project_db.h>
#include <lardon3d/sparse_sfm_model.h>
#define CHECK(condition) \
do { \
if (!(condition)) { \
fprintf(stderr, "optical profiles failure at line %d: %s\n", __LINE__, \
#condition); \
return false; \
} \
} while (0)
static bool raw_sql(const char *path, const char *sql) {
sqlite3 *database = NULL;
if (sqlite3_open(path, &database) != SQLITE_OK)
return false;
int code = sqlite3_exec(database, sql, NULL, NULL, NULL);
return sqlite3_close(database) == SQLITE_OK && code == SQLITE_OK;
}
static bool raw_integer(const char *path, const char *sql,
sqlite3_int64 *value) {
sqlite3 *database = NULL;
sqlite3_stmt *statement = NULL;
bool ok = sqlite3_open(path, &database) == SQLITE_OK &&
sqlite3_prepare_v2(database, sql, -1, &statement, NULL) == SQLITE_OK &&
sqlite3_step(statement) == SQLITE_ROW &&
sqlite3_column_type(statement, 0) == SQLITE_INTEGER;
if (ok)
*value = sqlite3_column_int64(statement, 0);
(void)sqlite3_finalize(statement);
if (database)
ok = sqlite3_close(database) == SQLITE_OK && ok;
return ok;
}
static bool all_bytes_zero(const void *value, size_t size) {
const unsigned char *bytes = value;
for (size_t index = 0; index < size; ++index)
if (bytes[index] != 0)
return false;
return true;
}
static bool raw_object_sql(const char *path, const char *name, char *output,
size_t capacity) {
sqlite3 *database = NULL;
sqlite3_stmt *statement = NULL;
bool ok = sqlite3_open(path, &database) == SQLITE_OK &&
sqlite3_prepare_v2(
database,
"SELECT sql FROM sqlite_master WHERE name=?1 AND sql IS NOT NULL",
-1, &statement, NULL) == SQLITE_OK;
if (ok)
(void)sqlite3_bind_text(statement, 1, name, -1, SQLITE_TRANSIENT);
if (ok)
ok = sqlite3_step(statement) == SQLITE_ROW &&
sqlite3_column_type(statement, 0) == SQLITE_TEXT;
if (ok) {
int bytes = sqlite3_column_bytes(statement, 0);
const unsigned char *text = sqlite3_column_text(statement, 0);
ok = bytes >= 0 && (size_t)bytes < capacity && text;
if (ok) {
memcpy(output, text, (size_t)bytes);
output[bytes] = '\0';
}
}
(void)sqlite3_finalize(statement);
if (database)
ok = sqlite3_close(database) == SQLITE_OK && ok;
return ok;
}
static bool make_database_path(char directory[64], char path[256]) {
memcpy(directory, "/tmp/lardon3d-optical-XXXXXX", 29);
if (!mkdtemp(directory))
return false;
int bytes = snprintf(path, 256, "%s/project.db", directory);
return bytes > 0 && bytes < 256;
}
static bool create_sparse_calibration(Lardon3DProjectDb *database,
unsigned char fingerprint_byte,
uint32_t width, uint32_t height,
Lardon3DSparseCalibration *output) {
Lardon3DSparseCalibration input = {
.model_kind = LARDON3D_SPARSE_SFM_CALIBRATION_KIND_PINHOLE,
.model_version = LARDON3D_SPARSE_SFM_CALIBRATION_VERSION,
.width = width,
.height = height,
.fx = (double)width * 0.75,
.fy = (double)height,
.cx = (double)width * 0.5,
.cy = (double)height * 0.5,
.provenance_kind = LARDON3D_SPARSE_SFM_PROVENANCE_USER_EXPLICIT,
};
input.provenance_fingerprint[0] = fingerprint_byte;
return lardon3d_sparse_calibration_create(database, &input, output) ==
LARDON3D_PROJECT_DB_OK;
}
static bool seed_campaign(Lardon3DProjectDb *database, uint64_t task_id,
uint64_t scanset_id, uint32_t group_count) {
Lardon3DTaskDurableSnapshot snapshot = {
.id = task_id,
.saved_state = TASK_PENDING,
.recovery_state = TASK_PENDING,
};
memcpy(snapshot.name, "optical campaign", 17);
static const unsigned char request[] = {0x4c, 0x33, 0x44, 0x4f};
Lardon3DProjectDbAcquisitionCampaignTask campaign = {
.task_id = task_id,
.scanset_id = scanset_id,
.next_group_id = 0,
.group_count = group_count,
.request = request,
.request_size = sizeof(request),
};
return lardon3d_project_db_record_acquisition_campaign_task(
database, &snapshot, LARDON3D_ACQUISITION_CAMPAIGN_TASK_KIND,
LARDON3D_ACQUISITION_CAMPAIGN_TASK_KIND_VERSION, NULL, &campaign,
1) == LARDON3D_PROJECT_DB_OK;
}
typedef struct {
uint64_t scanset_id;
uint64_t configuration_id;
uint64_t alternate_configuration_id;
uint64_t capture_id;
} RepairOpticalFixture;
static bool seed_repair_optical_fixture(Lardon3DProjectDb *database,
RepairOpticalFixture *fixture) {
memset(fixture, 0, sizeof(*fixture));
Lardon3DProjectDbScanSet scanset;
if (lardon3d_project_db_create_scanset(database, "repair optical fixture",
&scanset) != LARDON3D_PROJECT_DB_OK)
return false;
Lardon3DOpticalCameraBodyProfile body_input = {0};
memcpy(body_input.manufacturer, "Generic", sizeof("Generic"));
memcpy(body_input.model, "Repair body", sizeof("Repair body"));
memcpy(body_input.name, "Repair body profile",
sizeof("Repair body profile"));
Lardon3DOpticalCameraBodyProfile body;
if (lardon3d_optical_camera_body_create(database, &body_input, &body) !=
LARDON3D_PROJECT_DB_OK)
return false;
Lardon3DOpticalLensProfile lens_input = {
.interface_kind = LARDON3D_OPTICAL_LENS_ELECTRONIC,
.focal_range_kind = LARDON3D_OPTICAL_FOCAL_RANGE_ZOOM,
.minimum_focal_um = 16000,
.maximum_focal_um = 50000,
};
memcpy(lens_input.manufacturer, "Generic", sizeof("Generic"));
memcpy(lens_input.model, "Repair zoom", sizeof("Repair zoom"));
memcpy(lens_input.name, "Repair 16-50 zoom",
sizeof("Repair 16-50 zoom"));
Lardon3DOpticalLensProfile lens;
if (lardon3d_optical_lens_create(database, &lens_input, &lens) !=
LARDON3D_PROJECT_DB_OK)
return false;
Lardon3DOpticalConfiguration configuration_input = {
.camera_body_profile_id = body.camera_body_profile_id,
.lens_profile_id = lens.lens_profile_id,
.has_focal_length = true,
.focal_length_um = 16000,
};
Lardon3DOpticalConfiguration configuration;
if (lardon3d_optical_configuration_create(database, &configuration_input,
&configuration) !=
LARDON3D_PROJECT_DB_OK)
return false;
configuration_input.focal_length_um = 24000;
Lardon3DOpticalConfiguration alternate;
if (lardon3d_optical_configuration_create(database, &configuration_input,
&alternate) !=
LARDON3D_PROJECT_DB_OK)
return false;
Lardon3DProjectDbCapture capture;
if (lardon3d_project_db_create_capture(database, scanset.scanset_id, 1,
&capture) != LARDON3D_PROJECT_DB_OK)
return false;
fixture->scanset_id = scanset.scanset_id;
fixture->configuration_id = configuration.optical_configuration_id;
fixture->alternate_configuration_id = alternate.optical_configuration_id;
fixture->capture_id = capture.capture_id;
return true;
}
static bool expect_group_assign_corrupt_without_row(
const char *path, uint64_t task_id, uint64_t configuration_id) {
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
if (lardon3d_project_db_open(path, &database, error) !=
LARDON3D_PROJECT_DB_OK)
return false;
bool ok = lardon3d_optical_campaign_group_assign(
database, task_id, 1, configuration_id) ==
LARDON3D_PROJECT_DB_CORRUPT;
lardon3d_project_db_close(database);
sqlite3_int64 count = -1;
return ok &&
raw_integer(path,
"SELECT COUNT(*) FROM acquisition_campaign_group_optics",
&count) &&
count == 0;
}
static bool expect_retain_result_unadvanced(
const char *path, uint64_t task_id, uint64_t capture_id,
Lardon3DProjectDbResult expected) {
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
if (lardon3d_project_db_open(path, &database, error) !=
LARDON3D_PROJECT_DB_OK)
return false;
bool ok = lardon3d_project_db_retain_acquisition_campaign_capture(
database, task_id, 1, capture_id, 1) == expected;
unsigned char request[16];
Lardon3DProjectDbAcquisitionCampaignTask campaign;
Lardon3DProjectDbAcquisitionCampaignCapture mapping;
ok = ok &&
lardon3d_project_db_load_acquisition_campaign_task(
database, task_id, request, sizeof(request), &campaign) ==
LARDON3D_PROJECT_DB_OK &&
campaign.next_group_id == 0 &&
lardon3d_project_db_load_acquisition_campaign_capture(
database, task_id, 1, &mapping) == LARDON3D_PROJECT_DB_NOT_FOUND;
lardon3d_project_db_close(database);
return ok;
}
static bool test_profiles_assignments_and_calibrations(void) {
char directory[64];
char path[256];
CHECK(make_database_path(directory, path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_project_db_schema_version(database) ==
LARDON3D_PROJECT_DB_SCHEMA_VERSION);
Lardon3DProjectDbScanSet scanset;
CHECK(lardon3d_project_db_create_scanset(database, "mixed optical campaign",
&scanset) == LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCameraBodyProfile sony_input = {0};
memcpy(sony_input.manufacturer, "Sony", 5);
memcpy(sony_input.model, "ILCE-6000", 10);
memcpy(sony_input.name, "A6000 body", 11);
Lardon3DOpticalCameraBodyProfile sony;
CHECK(lardon3d_optical_camera_body_create(database, &sony_input, &sony) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCameraBodyProfile retry_body;
CHECK(lardon3d_optical_camera_body_create(database, &sony_input, &retry_body) ==
LARDON3D_PROJECT_DB_OK &&
retry_body.camera_body_profile_id == sony.camera_body_profile_id);
Lardon3DOpticalCameraBodyAlias body_alias;
CHECK(lardon3d_optical_camera_body_alias_add(
database, sony.camera_body_profile_id, "SONY", "ILCE-6000",
&body_alias) == LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCameraBodyProfile alias_body;
CHECK(lardon3d_optical_camera_body_find_exact_alias(
database, "SONY", "ILCE-6000", &alias_body) ==
LARDON3D_PROJECT_DB_OK &&
alias_body.camera_body_profile_id == sony.camera_body_profile_id);
memset(&alias_body, 0x7f, sizeof(alias_body));
CHECK(lardon3d_optical_camera_body_find_exact_alias(
database, "sony", "ILCE-6000", &alias_body) ==
LARDON3D_PROJECT_DB_NOT_FOUND &&
alias_body.camera_body_profile_id == 0 && alias_body.name[0] == '\0');
Lardon3DOpticalCameraBodyProfile second_body_input = {0};
memcpy(second_body_input.manufacturer, "Samsung", 8);
memcpy(second_body_input.model, "SM-G990B", 9);
memcpy(second_body_input.name, "S21 FE body", 12);
Lardon3DOpticalCameraBodyProfile second_body;
CHECK(lardon3d_optical_camera_body_create(database, &second_body_input,
&second_body) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCameraBodyAlias conflict_alias;
CHECK(lardon3d_optical_camera_body_alias_add(
database, second_body.camera_body_profile_id, "SONY", "ILCE-6000",
&conflict_alias) == LARDON3D_PROJECT_DB_CONSTRAINT);
Lardon3DOpticalLensProfile zoom_input = {
.interface_kind = LARDON3D_OPTICAL_LENS_ELECTRONIC,
.focal_range_kind = LARDON3D_OPTICAL_FOCAL_RANGE_ZOOM,
.minimum_focal_um = 16000,
.maximum_focal_um = 50000,
};
memcpy(zoom_input.manufacturer, "Sony", 5);
memcpy(zoom_input.model, "SELP1650", 9);
memcpy(zoom_input.name, "E PZ 16-50 OSS", 15);
Lardon3DOpticalLensProfile zoom;
CHECK(lardon3d_optical_lens_create(database, &zoom_input, &zoom) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalLensAlias zoom_alias;
CHECK(lardon3d_optical_lens_alias_add(
database, zoom.lens_profile_id, "SONY",
"E PZ 16-50mm F3.5-5.6 OSS", &zoom_alias) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalLensProfile exact_lens;
CHECK(lardon3d_optical_lens_find_exact_alias(
database, "SONY", "E PZ 16-50mm F3.5-5.6 OSS", &exact_lens) ==
LARDON3D_PROJECT_DB_OK &&
exact_lens.lens_profile_id == zoom.lens_profile_id);
/* A manual lens has no electronics and therefore legitimately has an empty
alias page. It remains fully usable by explicit profile/config selection. */
Lardon3DOpticalLensProfile meike_input = {
.interface_kind = LARDON3D_OPTICAL_LENS_MANUAL,
.focal_range_kind = LARDON3D_OPTICAL_FOCAL_RANGE_PRIME,
.minimum_focal_um = 12000,
.maximum_focal_um = 12000,
};
memcpy(meike_input.manufacturer, "Meike", 6);
memcpy(meike_input.model, "12mm F2.8", sizeof("12mm F2.8"));
memcpy(meike_input.name, "Meike manual 12 mm", 19);
Lardon3DOpticalLensProfile meike;
CHECK(lardon3d_optical_lens_create(database, &meike_input, &meike) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalLensAlias no_alias_items[2];
size_t no_alias_count = 99;
uint64_t no_alias_next = 99;
CHECK(lardon3d_optical_lens_alias_list(
database, meike.lens_profile_id, 0, no_alias_items, 2,
&no_alias_count, &no_alias_next) == LARDON3D_PROJECT_DB_OK &&
no_alias_count == 0 && no_alias_next == 0);
Lardon3DOpticalLensProfile prime_input = {
.interface_kind = LARDON3D_OPTICAL_LENS_ELECTRONIC,
.focal_range_kind = LARDON3D_OPTICAL_FOCAL_RANGE_PRIME,
.minimum_focal_um = 50000,
.maximum_focal_um = 50000,
};
memcpy(prime_input.manufacturer, "Generic", 8);
memcpy(prime_input.model, "50 Prime", 9);
memcpy(prime_input.name, "New 50 mm profile", 18);
Lardon3DOpticalLensProfile prime;
CHECK(lardon3d_optical_lens_create(database, &prime_input, &prime) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalLensProfile lens_page[2];
size_t lens_count = 0;
uint64_t lens_next = 0;
CHECK(lardon3d_optical_lens_list(database, 0, lens_page, 2, &lens_count,
&lens_next) == LARDON3D_PROJECT_DB_OK &&
lens_count == 2 && lens_next == meike.lens_profile_id);
CHECK(lardon3d_optical_lens_list(database, lens_next, lens_page, 2,
&lens_count, &lens_next) ==
LARDON3D_PROJECT_DB_OK &&
lens_count == 1 && lens_page[0].lens_profile_id == prime.lens_profile_id);
Lardon3DOpticalLensProfile unknown_manual_input = {
.interface_kind = LARDON3D_OPTICAL_LENS_MANUAL,
.focal_range_kind = LARDON3D_OPTICAL_FOCAL_RANGE_UNKNOWN,
};
memcpy(unknown_manual_input.name, "Unidentified manual lens",
sizeof("Unidentified manual lens"));
Lardon3DOpticalLensProfile unknown_manual;
CHECK(lardon3d_optical_lens_create(database, &unknown_manual_input,
&unknown_manual) ==
LARDON3D_PROJECT_DB_OK &&
unknown_manual.manufacturer[0] == '\0' &&
unknown_manual.model[0] == '\0' &&
unknown_manual.minimum_focal_um == 0 &&
unknown_manual.maximum_focal_um == 0);
Lardon3DOpticalConfiguration configuration_input = {
.camera_body_profile_id = sony.camera_body_profile_id,
.lens_profile_id = zoom.lens_profile_id,
.has_focal_length = true,
.focal_length_um = 16000,
};
Lardon3DOpticalConfiguration config16;
CHECK(lardon3d_optical_configuration_create(database, &configuration_input,
&config16) ==
LARDON3D_PROJECT_DB_OK);
configuration_input.focal_length_um = 24000;
Lardon3DOpticalConfiguration config24;
CHECK(lardon3d_optical_configuration_create(database, &configuration_input,
&config24) ==
LARDON3D_PROJECT_DB_OK);
configuration_input.focal_length_um = 50000;
Lardon3DOpticalConfiguration config50;
CHECK(lardon3d_optical_configuration_create(database, &configuration_input,
&config50) ==
LARDON3D_PROJECT_DB_OK);
CHECK(config16.optical_configuration_id != config24.optical_configuration_id &&
config24.optical_configuration_id != config50.optical_configuration_id);
configuration_input.focal_length_um = 51000;
Lardon3DOpticalConfiguration invalid_configuration;
CHECK(lardon3d_optical_configuration_create(database, &configuration_input,
&invalid_configuration) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
Lardon3DOpticalConfiguration meike_configuration_input = {
.camera_body_profile_id = sony.camera_body_profile_id,
.lens_profile_id = meike.lens_profile_id,
.has_focal_length = true,
.focal_length_um = 12000,
};
Lardon3DOpticalConfiguration meike_configuration;
CHECK(lardon3d_optical_configuration_create(
database, &meike_configuration_input, &meike_configuration) ==
LARDON3D_PROJECT_DB_OK);
meike_configuration_input.focal_length_um = 13000;
CHECK(lardon3d_optical_configuration_create(
database, &meike_configuration_input, &invalid_configuration) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
Lardon3DProjectDbCapture captures[5];
for (size_t index = 0; index < 5; ++index)
CHECK(lardon3d_project_db_create_capture(database, scanset.scanset_id,
(int64_t)index + 1,
&captures[index]) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCaptureAssignment unresolved;
memset(&unresolved, 0x7f, sizeof(unresolved));
CHECK(lardon3d_optical_capture_assignment_load(
database, captures[4].capture_id, &unresolved) ==
LARDON3D_PROJECT_DB_NOT_FOUND &&
unresolved.capture_id == 0 && unresolved.optical_configuration_id == 0);
CHECK(lardon3d_optical_capture_assign_explicit(
database, captures[3].capture_id,
meike_configuration.optical_configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, captures[3].capture_id,
meike_configuration.optical_configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, captures[3].capture_id,
config16.optical_configuration_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
Lardon3DOpticalCaptureAssignment manual_assignment;
CHECK(lardon3d_optical_capture_assignment_load(
database, captures[3].capture_id, &manual_assignment) ==
LARDON3D_PROJECT_DB_OK &&
manual_assignment.provenance ==
LARDON3D_OPTICAL_ASSIGNMENT_CALLER_EXPLICIT &&
!manual_assignment.has_campaign_origin);
CHECK(seed_campaign(database, 101, scanset.scanset_id, 1));
CHECK(lardon3d_optical_campaign_group_assign(
database, 101, 1, config16.optical_configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_project_db_retain_acquisition_campaign_capture(
database, 101, 1, captures[3].capture_id, 1) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
Lardon3DProjectDbAcquisitionCampaignCapture conflicted_mapping;
CHECK(lardon3d_project_db_load_acquisition_campaign_capture(
database, 101, 1, &conflicted_mapping) ==
LARDON3D_PROJECT_DB_NOT_FOUND);
unsigned char conflict_request[16];
Lardon3DProjectDbAcquisitionCampaignTask conflict_campaign;
CHECK(lardon3d_project_db_load_acquisition_campaign_task(
database, 101, conflict_request, sizeof(conflict_request),
&conflict_campaign) == LARDON3D_PROJECT_DB_OK &&
conflict_campaign.next_group_id == 0);
CHECK(seed_campaign(database, 100, scanset.scanset_id, 3));
CHECK(lardon3d_optical_campaign_group_assign(
database, 100, 1, config16.optical_configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_campaign_group_assign(
database, 100, 3, config50.optical_configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_campaign_group_assign(
database, 100, 1, config16.optical_configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_campaign_group_assign(
database, 100, 1, config24.optical_configuration_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
Lardon3DOpticalCampaignGroupAssignment loaded_group;
CHECK(lardon3d_optical_campaign_group_load(database, 100, 1, &loaded_group) ==
LARDON3D_PROJECT_DB_OK &&
loaded_group.optical_configuration_id ==
config16.optical_configuration_id);
memset(&loaded_group, 0x7f, sizeof(loaded_group));
CHECK(lardon3d_optical_campaign_group_load(database, 100, 2, &loaded_group) ==
LARDON3D_PROJECT_DB_NOT_FOUND &&
loaded_group.campaign_task_id == 0);
CHECK(lardon3d_project_db_retain_acquisition_campaign_capture(
database, 100, 1, captures[0].capture_id, 1) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCaptureAssignment campaign_assignment;
CHECK(lardon3d_optical_capture_assignment_load(
database, captures[0].capture_id, &campaign_assignment) ==
LARDON3D_PROJECT_DB_OK &&
campaign_assignment.optical_configuration_id ==
config16.optical_configuration_id &&
campaign_assignment.provenance == LARDON3D_OPTICAL_ASSIGNMENT_CAMPAIGN &&
campaign_assignment.has_campaign_origin &&
campaign_assignment.campaign_task_id == 100 &&
campaign_assignment.campaign_group_id == 1);
CHECK(lardon3d_project_db_retain_acquisition_campaign_capture(
database, 100, 1, captures[0].capture_id, 1) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_campaign_group_assign(
database, 100, 2, config24.optical_configuration_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
CHECK(lardon3d_project_db_retain_acquisition_campaign_capture(
database, 100, 2, captures[1].capture_id, 2) ==
LARDON3D_PROJECT_DB_OK);
memset(&unresolved, 0x7f, sizeof(unresolved));
CHECK(lardon3d_optical_capture_assignment_load(
database, captures[1].capture_id, &unresolved) ==
LARDON3D_PROJECT_DB_NOT_FOUND &&
unresolved.capture_id == 0);
/* Failure after mapping+optics insertion but before cursor publication must
roll back all three durable facts as one unit. */
CHECK(setenv("LARDON3D_TEST_PROJECT_DB_FAIL_CAMPAIGN_OPTICS_COPY", "1", 1) ==
0);
CHECK(lardon3d_project_db_retain_acquisition_campaign_capture(
database, 100, 3, captures[2].capture_id, 3) !=
LARDON3D_PROJECT_DB_OK);
CHECK(unsetenv("LARDON3D_TEST_PROJECT_DB_FAIL_CAMPAIGN_OPTICS_COPY") == 0);
Lardon3DProjectDbAcquisitionCampaignCapture missing_mapping;
CHECK(lardon3d_project_db_load_acquisition_campaign_capture(
database, 100, 3, &missing_mapping) == LARDON3D_PROJECT_DB_NOT_FOUND);
CHECK(lardon3d_optical_capture_assignment_load(
database, captures[2].capture_id, &unresolved) ==
LARDON3D_PROJECT_DB_NOT_FOUND);
unsigned char campaign_request[16];
Lardon3DProjectDbAcquisitionCampaignTask campaign_state;
CHECK(lardon3d_project_db_load_acquisition_campaign_task(
database, 100, campaign_request, sizeof(campaign_request),
&campaign_state) == LARDON3D_PROJECT_DB_OK &&
campaign_state.next_group_id == 2);
CHECK(lardon3d_project_db_retain_acquisition_campaign_capture(
database, 100, 3, captures[2].capture_id, 3) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assignment_load(
database, captures[2].capture_id, &campaign_assignment) ==
LARDON3D_PROJECT_DB_OK &&
campaign_assignment.optical_configuration_id ==
config50.optical_configuration_id);
Lardon3DSparseCalibration calibration_a;
Lardon3DSparseCalibration calibration_b;
Lardon3DSparseCalibration calibration_other;
CHECK(create_sparse_calibration(database, 1, 6000, 4000, &calibration_a));
CHECK(create_sparse_calibration(database, 2, 6000, 4000, &calibration_b));
CHECK(create_sparse_calibration(database, 3, 4000, 3000,
&calibration_other));
Lardon3DOpticalCalibrationProfile compatible[3];
size_t compatible_count = 77;
uint64_t compatible_next = 77;
CHECK(lardon3d_optical_calibration_profile_list_compatible(
database, config16.optical_configuration_id, 0, compatible, 3,
&compatible_count, &compatible_next) == LARDON3D_PROJECT_DB_OK &&
compatible_count == 0 && compatible_next == 0);
Lardon3DOpticalCalibrationProfile profile_input = {
.optical_configuration_id = config16.optical_configuration_id,
.sparse_calibration_id = calibration_a.calibration_id,
.profile_version = 1,
.applicability = LARDON3D_OPTICAL_CALIBRATION_EXACT_CONFIGURATION,
.created_at = 100,
};
memcpy(profile_input.name, "Lab calibration", 16);
memcpy(profile_input.provenance, "Dedicated checkerboard session", 31);
Lardon3DOpticalCalibrationProfile profile_a;
CHECK(lardon3d_optical_calibration_profile_create(database, &profile_input,
&profile_a) ==
LARDON3D_PROJECT_DB_OK);
compatible_count = 0;
compatible_next = 0;
CHECK(lardon3d_optical_calibration_profile_list_compatible(
database, config16.optical_configuration_id, 0, compatible, 3,
&compatible_count, &compatible_next) == LARDON3D_PROJECT_DB_OK &&
compatible_count == 1 &&
compatible[0].calibration_profile_id == profile_a.calibration_profile_id);
Lardon3DOpticalCalibrationProfile profile_retry;
CHECK(lardon3d_optical_calibration_profile_create(database, &profile_input,
&profile_retry) ==
LARDON3D_PROJECT_DB_OK &&
profile_retry.calibration_profile_id == profile_a.calibration_profile_id);
profile_input.sparse_calibration_id = calibration_b.calibration_id;
memcpy(profile_input.name, "Field calibration", 18);
profile_input.created_at = 101;
Lardon3DOpticalCalibrationProfile profile_b;
CHECK(lardon3d_optical_calibration_profile_create(database, &profile_input,
&profile_b) ==
LARDON3D_PROJECT_DB_OK);
profile_input.optical_configuration_id = config50.optical_configuration_id;
profile_input.sparse_calibration_id = calibration_other.calibration_id;
memcpy(profile_input.name, "Fifty calibration", 18);
profile_input.created_at = 102;
Lardon3DOpticalCalibrationProfile profile_other;
CHECK(lardon3d_optical_calibration_profile_create(database, &profile_input,
&profile_other) ==
LARDON3D_PROJECT_DB_OK);
profile_input.sparse_calibration_id = INT64_MAX;
memcpy(profile_input.name, "Missing calibration", 20);
CHECK(lardon3d_optical_calibration_profile_create(database, &profile_input,
&profile_retry) ==
LARDON3D_PROJECT_DB_NOT_FOUND &&
profile_retry.calibration_profile_id == 0);
compatible_count = 0;
compatible_next = 0;
CHECK(lardon3d_optical_calibration_profile_list_compatible(
database, config16.optical_configuration_id, 0, compatible, 3,
&compatible_count, &compatible_next) == LARDON3D_PROJECT_DB_OK &&
compatible_count == 2 &&
compatible[0].calibration_profile_id == profile_a.calibration_profile_id &&
compatible[1].calibration_profile_id == profile_b.calibration_profile_id);
Lardon3DOpticalCaptureCalibrationSelection selection;
memset(&selection, 0x7f, sizeof(selection));
CHECK(lardon3d_optical_capture_calibration_selection_load(
database, captures[0].capture_id, &selection) ==
LARDON3D_PROJECT_DB_NOT_FOUND &&
selection.capture_id == 0);
CHECK(lardon3d_optical_capture_calibration_select(
database, captures[0].capture_id,
profile_other.calibration_profile_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
CHECK(lardon3d_optical_capture_calibration_select(
database, captures[0].capture_id, profile_a.calibration_profile_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_select(
database, captures[0].capture_id, profile_a.calibration_profile_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_select(
database, captures[0].capture_id, profile_b.calibration_profile_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
CHECK(lardon3d_optical_capture_calibration_selection_load(
database, captures[0].capture_id, &selection) ==
LARDON3D_PROJECT_DB_OK &&
selection.calibration_profile_id == profile_a.calibration_profile_id &&
selection.optical_configuration_id == config16.optical_configuration_id &&
selection.sparse_calibration_id == calibration_a.calibration_id);
CHECK(lardon3d_optical_capture_calibration_select(
database, captures[1].capture_id, profile_a.calibration_profile_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
lardon3d_project_db_close(database);
database = NULL;
/* Dynamic SQLite typing is adversarially corrupted after disabling checks;
public loaders must reject before narrowing and leave outputs zeroed. */
char corruption[1024];
int corruption_bytes = snprintf(
corruption, sizeof(corruption),
"PRAGMA ignore_check_constraints=ON;UPDATE lens_profiles SET "
"focal_range_kind='zoom-ish' WHERE lens_profile_id=%llu;",
(unsigned long long)zoom.lens_profile_id);
CHECK(corruption_bytes > 0 && (size_t)corruption_bytes < sizeof(corruption));
CHECK(raw_sql(path, corruption));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
memset(&exact_lens, 0x7f, sizeof(exact_lens));
CHECK(lardon3d_optical_lens_load(database, zoom.lens_profile_id, &exact_lens) ==
LARDON3D_PROJECT_DB_CORRUPT &&
exact_lens.lens_profile_id == 0 && exact_lens.name[0] == '\0');
lardon3d_project_db_close(database);
database = NULL;
corruption_bytes = snprintf(
corruption, sizeof(corruption),
"PRAGMA ignore_check_constraints=ON;UPDATE lens_profiles SET "
"focal_range_kind=3 WHERE lens_profile_id=%llu;UPDATE "
"optical_configurations SET focal_length_um='16000x' WHERE "
"optical_configuration_id=%llu;",
(unsigned long long)zoom.lens_profile_id,
(unsigned long long)config16.optical_configuration_id);
CHECK(corruption_bytes > 0 && (size_t)corruption_bytes < sizeof(corruption));
CHECK(raw_sql(path, corruption));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalConfiguration corrupt_configuration;
memset(&corrupt_configuration, 0x7f, sizeof(corrupt_configuration));
CHECK(lardon3d_optical_configuration_load(
database, config16.optical_configuration_id,
&corrupt_configuration) == LARDON3D_PROJECT_DB_CORRUPT &&
corrupt_configuration.optical_configuration_id == 0);
lardon3d_project_db_close(database);
database = NULL;
corruption_bytes = snprintf(
corruption, sizeof(corruption),
"PRAGMA foreign_keys=OFF;UPDATE optical_configurations SET "
"focal_length_um=16000 WHERE optical_configuration_id=%llu;"
"UPDATE captures SET scanset_id=9223372036854775807 WHERE "
"capture_id=%llu;",
(unsigned long long)config16.optical_configuration_id,
(unsigned long long)captures[3].capture_id);
CHECK(corruption_bytes > 0 && (size_t)corruption_bytes < sizeof(corruption));
CHECK(raw_sql(path, corruption));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
memset(&manual_assignment, 0x7f, sizeof(manual_assignment));
CHECK(lardon3d_optical_capture_assignment_load(
database, captures[3].capture_id, &manual_assignment) ==
LARDON3D_PROJECT_DB_CORRUPT &&
manual_assignment.capture_id == 0);
lardon3d_project_db_close(database);
database = NULL;
CHECK(raw_sql(path,
"PRAGMA ignore_check_constraints=ON;UPDATE "
"acquisition_campaign_captures SET group_id='1x' WHERE "
"task_id=100 AND group_id=1;"));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_campaign_group_assign(
database, 100, 1, config16.optical_configuration_id) ==
LARDON3D_PROJECT_DB_CORRUPT);
memset(&loaded_group, 0x7f, sizeof(loaded_group));
CHECK(lardon3d_optical_campaign_group_load(database, 100, 1, &loaded_group) ==
LARDON3D_PROJECT_DB_CORRUPT &&
loaded_group.campaign_task_id == 0);
memset(&campaign_assignment, 0x7f, sizeof(campaign_assignment));
CHECK(lardon3d_optical_capture_assignment_load(
database, captures[0].capture_id, &campaign_assignment) ==
LARDON3D_PROJECT_DB_CORRUPT &&
campaign_assignment.capture_id == 0);
lardon3d_project_db_close(database);
CHECK(unlink(path) == 0);
CHECK(rmdir(directory) == 0);
return true;
}
static bool test_calibration_conflict_result_contract(void) {
char directory[64];
char path[256];
CHECK(make_database_path(directory, path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
RepairOpticalFixture fixture;
CHECK(seed_repair_optical_fixture(database, &fixture));
Lardon3DSparseCalibration calibration;
CHECK(create_sparse_calibration(database, 71, 6000, 4000, &calibration));
Lardon3DOpticalCalibrationProfile input = {
.optical_configuration_id = fixture.configuration_id,
.sparse_calibration_id = calibration.calibration_id,
.profile_version = 1,
.applicability = LARDON3D_OPTICAL_CALIBRATION_EXACT_CONFIGURATION,
.created_at = 10,
};
memcpy(input.name, "Retry identity", sizeof("Retry identity"));
memcpy(input.provenance, "Original provenance",
sizeof("Original provenance"));
Lardon3DOpticalCalibrationProfile created;
CHECK(lardon3d_optical_calibration_profile_create(database, &input, &created) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCalibrationProfile conflict = input;
memset(conflict.provenance, 0, sizeof(conflict.provenance));
memcpy(conflict.provenance, "Different valid provenance",
sizeof("Different valid provenance"));
Lardon3DOpticalCalibrationProfile conflict_output;
memset(&conflict_output, 0x7f, sizeof(conflict_output));
CHECK(lardon3d_optical_calibration_profile_create(
database, &conflict, &conflict_output) ==
LARDON3D_PROJECT_DB_CONSTRAINT &&
conflict_output.calibration_profile_id == 0 &&
conflict_output.provenance[0] == '\0');
Lardon3DOpticalCalibrationProfile unchanged;
CHECK(lardon3d_optical_calibration_profile_load(
database, created.calibration_profile_id, &unchanged) ==
LARDON3D_PROJECT_DB_OK &&
strcmp(unchanged.provenance, input.provenance) == 0 &&
unchanged.created_at == input.created_at);
lardon3d_project_db_close(database);
database = NULL;
sqlite3_int64 count = 0;
CHECK(raw_integer(path, "SELECT COUNT(*) FROM optical_calibration_profiles",
&count) &&
count == 1);
/* A BLOB in the TEXT property is durable corruption, not a second kind of
caller conflict, even when the natural-key fields still match. */
CHECK(raw_sql(path,
"PRAGMA ignore_check_constraints=ON;UPDATE "
"optical_calibration_profiles SET provenance=X'626164';"));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
memset(&conflict_output, 0x7f, sizeof(conflict_output));
CHECK(lardon3d_optical_calibration_profile_create(
database, &input, &conflict_output) == LARDON3D_PROJECT_DB_CORRUPT &&
conflict_output.calibration_profile_id == 0 &&
conflict_output.provenance[0] == '\0');
lardon3d_project_db_close(database);
CHECK(raw_integer(path, "SELECT COUNT(*) FROM optical_calibration_profiles",
&count) &&
count == 1);
CHECK(unlink(path) == 0);
CHECK(rmdir(directory) == 0);
return true;
}
static bool test_calibration_dependency_corruption_precedence(void) {
char directory[64];
char path[256];
CHECK(make_database_path(directory, path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
RepairOpticalFixture fixture;
CHECK(seed_repair_optical_fixture(database, &fixture));
Lardon3DSparseCalibration calibration;
Lardon3DSparseCalibration alternate_calibration;
CHECK(create_sparse_calibration(database, 81, 6000, 4000, &calibration));
CHECK(create_sparse_calibration(database, 82, 6000, 4000,
&alternate_calibration));
Lardon3DOpticalCalibrationProfile input = {
.optical_configuration_id = fixture.configuration_id,
.sparse_calibration_id = calibration.calibration_id,
.profile_version = 1,
.applicability = LARDON3D_OPTICAL_CALIBRATION_EXACT_CONFIGURATION,
.created_at = 20,
};
memcpy(input.name, "Dependency identity", sizeof("Dependency identity"));
memcpy(input.provenance, "Dependency provenance",
sizeof("Dependency provenance"));
Lardon3DOpticalCalibrationProfile created;
CHECK(lardon3d_optical_calibration_profile_create(database, &input, &created) ==
LARDON3D_PROJECT_DB_OK);
lardon3d_project_db_close(database);
database = NULL;
char sql[512];
char unchanged_query[512];
int unchanged_bytes = snprintf(
unchanged_query, sizeof(unchanged_query),
"SELECT COUNT(*) FROM optical_calibration_profiles WHERE "
"calibration_profile_id=%llu AND optical_configuration_id=%llu AND "
"sparse_calibration_id=%llu AND name='Dependency identity' AND "
"profile_version=1 AND provenance='Dependency provenance' AND "
"applicability=1 AND created_at=20",
(unsigned long long)created.calibration_profile_id,
(unsigned long long)fixture.configuration_id,
(unsigned long long)calibration.calibration_id);
CHECK(unchanged_bytes > 0 &&
(size_t)unchanged_bytes < sizeof(unchanged_query));
int bytes = snprintf(
sql, sizeof(sql),
"UPDATE sparse_calibrations SET scientific_hash=zeroblob(32) WHERE "
"calibration_id=%llu",
(unsigned long long)calibration.calibration_id);
CHECK(bytes > 0 && (size_t)bytes < sizeof(sql));
CHECK(raw_sql(path, sql));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
/* The natural-key row is durable, so its malformed scientific dependency
must win over both exact-retry and caller-conflict classification. */
Lardon3DOpticalCalibrationProfile output;
memset(&output, 0x7f, sizeof(output));
CHECK(lardon3d_optical_calibration_profile_create(database, &input, &output) ==
LARDON3D_PROJECT_DB_CORRUPT &&
all_bytes_zero(&output, sizeof(output)));
Lardon3DOpticalCalibrationProfile alternate = input;
alternate.sparse_calibration_id = alternate_calibration.calibration_id;
memset(&output, 0x7f, sizeof(output));
CHECK(lardon3d_optical_calibration_profile_create(
database, &alternate, &output) == LARDON3D_PROJECT_DB_CORRUPT &&
all_bytes_zero(&output, sizeof(output)));
lardon3d_project_db_close(database);
database = NULL;
sqlite3_int64 count = 0;
CHECK(raw_integer(path, unchanged_query, &count) && count == 1);
bytes = snprintf(sql, sizeof(sql),
"PRAGMA foreign_keys=OFF;DELETE FROM sparse_calibrations "
"WHERE calibration_id=%llu",
(unsigned long long)calibration.calibration_id);
CHECK(bytes > 0 && (size_t)bytes < sizeof(sql));
CHECK(raw_sql(path, sql));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
memset(&output, 0x7f, sizeof(output));
CHECK(lardon3d_optical_calibration_profile_create(database, &input, &output) ==
LARDON3D_PROJECT_DB_CORRUPT &&
all_bytes_zero(&output, sizeof(output)));
memset(&output, 0x7f, sizeof(output));
CHECK(lardon3d_optical_calibration_profile_create(
database, &alternate, &output) == LARDON3D_PROJECT_DB_CORRUPT &&
all_bytes_zero(&output, sizeof(output)));
lardon3d_project_db_close(database);
CHECK(raw_integer(path, "SELECT COUNT(*) FROM optical_calibration_profiles",
&count) &&
count == 1);
CHECK(raw_integer(path, unchanged_query, &count) && count == 1);
CHECK(unlink(path) == 0);
CHECK(rmdir(directory) == 0);
return true;
}
static bool test_campaign_request_corruption_prevents_optics_mutation(void) {
char directory[64];
char path[256];
CHECK(make_database_path(directory, path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
RepairOpticalFixture fixture;
CHECK(seed_repair_optical_fixture(database, &fixture));
CHECK(seed_campaign(database, 200, fixture.scanset_id, 1));
lardon3d_project_db_close(database);
CHECK(raw_sql(path,
"UPDATE acquisition_campaign_tasks SET request='not-a-blob' "
"WHERE task_id=200;"));
CHECK(expect_group_assign_corrupt_without_row(
path, 200, fixture.configuration_id));
CHECK(raw_sql(path,
"PRAGMA ignore_check_constraints=ON;UPDATE "
"acquisition_campaign_tasks SET request=X'' WHERE task_id=200;"));
CHECK(expect_group_assign_corrupt_without_row(
path, 200, fixture.configuration_id));
char oversized_update[256];
int bytes = snprintf(
oversized_update, sizeof(oversized_update),
"UPDATE acquisition_campaign_tasks SET request=zeroblob(%zu) WHERE "
"task_id=200;",
LARDON3D_ACQUISITION_CAMPAIGN_TASK_REQUEST_MAX_BYTES + 1u);
CHECK(bytes > 0 && (size_t)bytes < sizeof(oversized_update));
CHECK(raw_sql(path, oversized_update));
CHECK(expect_group_assign_corrupt_without_row(
path, 200, fixture.configuration_id));
CHECK(unlink(path) == 0);
CHECK(rmdir(directory) == 0);
return true;
}
static bool test_capture_optics_conflict_and_corruption_rollback(void) {
char directory[64];
char path[256];
CHECK(make_database_path(directory, path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
RepairOpticalFixture fixture;
CHECK(seed_repair_optical_fixture(database, &fixture));
CHECK(seed_campaign(database, 300, fixture.scanset_id, 1));
CHECK(lardon3d_optical_campaign_group_assign(
database, 300, 1, fixture.configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, fixture.capture_id,
fixture.alternate_configuration_id) == LARDON3D_PROJECT_DB_OK);
lardon3d_project_db_close(database);
CHECK(expect_retain_result_unadvanced(
path, 300, fixture.capture_id, LARDON3D_PROJECT_DB_CONSTRAINT));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCaptureAssignment assignment;
CHECK(lardon3d_optical_capture_assignment_load(
database, fixture.capture_id, &assignment) ==
LARDON3D_PROJECT_DB_OK &&
assignment.provenance ==
LARDON3D_OPTICAL_ASSIGNMENT_CALLER_EXPLICIT &&
assignment.optical_configuration_id ==
fixture.alternate_configuration_id);
lardon3d_project_db_close(database);
char mutation[512];
int bytes = snprintf(
mutation, sizeof(mutation),
"PRAGMA ignore_check_constraints=ON;UPDATE "
"capture_optical_configurations SET assignment_provenance=X'31' WHERE "
"capture_id=%llu;",
(unsigned long long)fixture.capture_id);
CHECK(bytes > 0 && (size_t)bytes < sizeof(mutation));
CHECK(raw_sql(path, mutation));
CHECK(expect_retain_result_unadvanced(
path, 300, fixture.capture_id, LARDON3D_PROJECT_DB_CORRUPT));
bytes = snprintf(
mutation, sizeof(mutation),
"PRAGMA ignore_check_constraints=ON;UPDATE "
"capture_optical_configurations SET assignment_provenance=9,"
"campaign_task_id=NULL,campaign_group_id=NULL WHERE capture_id=%llu;",
(unsigned long long)fixture.capture_id);
CHECK(bytes > 0 && (size_t)bytes < sizeof(mutation));
CHECK(raw_sql(path, mutation));
CHECK(expect_retain_result_unadvanced(
path, 300, fixture.capture_id, LARDON3D_PROJECT_DB_CORRUPT));
bytes = snprintf(
mutation, sizeof(mutation),
"PRAGMA ignore_check_constraints=ON;UPDATE "
"capture_optical_configurations SET assignment_provenance=2,"
"campaign_task_id=300,campaign_group_id=1 WHERE capture_id=%llu;",
(unsigned long long)fixture.capture_id);
CHECK(bytes > 0 && (size_t)bytes < sizeof(mutation));
CHECK(raw_sql(path, mutation));
CHECK(expect_retain_result_unadvanced(
path, 300, fixture.capture_id, LARDON3D_PROJECT_DB_CORRUPT));
bytes = snprintf(
mutation, sizeof(mutation),
"PRAGMA foreign_keys=OFF;PRAGMA ignore_check_constraints=ON;DELETE FROM "
"capture_optical_configurations WHERE capture_id=%llu;INSERT INTO "
"capture_optical_configurations(capture_id,optical_configuration_id,"
"assignment_provenance,campaign_task_id,campaign_group_id) VALUES("
"%llu,%llu,1,300,1);",
(unsigned long long)fixture.capture_id,
(unsigned long long)fixture.capture_id,
(unsigned long long)fixture.configuration_id);
CHECK(bytes > 0 && (size_t)bytes < sizeof(mutation));
CHECK(raw_sql(path, mutation));
/* This exact-looking row is ahead of the cursor and must not be repaired by
the mapping insertion that is later rolled back. */
CHECK(expect_retain_result_unadvanced(
path, 300, fixture.capture_id, LARDON3D_PROJECT_DB_CORRUPT));
sqlite3_int64 count = 0;
CHECK(raw_integer(path,
"SELECT COUNT(*) FROM capture_optical_configurations",
&count) &&
count == 1);
CHECK(raw_integer(path, "SELECT COUNT(*) FROM acquisition_campaign_captures",
&count) &&
count == 0);
CHECK(unlink(path) == 0);
CHECK(rmdir(directory) == 0);
return true;
}
static bool test_malformed_configuration_rolls_back_campaign_retention(void) {
char directory[64];
char path[256];
CHECK(make_database_path(directory, path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
RepairOpticalFixture fixture;
CHECK(seed_repair_optical_fixture(database, &fixture));
CHECK(seed_campaign(database, 301, fixture.scanset_id, 1));
CHECK(lardon3d_optical_campaign_group_assign(
database, 301, 1, fixture.configuration_id) ==
LARDON3D_PROJECT_DB_OK);
lardon3d_project_db_close(database);
char mutation[512];
int bytes = snprintf(
mutation, sizeof(mutation),
"PRAGMA ignore_check_constraints=ON;UPDATE optical_configurations SET "
"focal_length_um='16000x' WHERE optical_configuration_id=%llu;",
(unsigned long long)fixture.configuration_id);
CHECK(bytes > 0 && (size_t)bytes < sizeof(mutation));
CHECK(raw_sql(path, mutation));
CHECK(expect_retain_result_unadvanced(
path, 301, fixture.capture_id, LARDON3D_PROJECT_DB_CORRUPT));
sqlite3_int64 count = 0;
CHECK(raw_integer(path, "SELECT COUNT(*) FROM acquisition_campaign_captures",
&count) &&
count == 0);
CHECK(raw_integer(path,
"SELECT COUNT(*) FROM capture_optical_configurations",
&count) &&
count == 0);
bytes = snprintf(
mutation, sizeof(mutation),
"PRAGMA ignore_check_constraints=ON;UPDATE optical_configurations SET "
"focal_length_um=16000 WHERE optical_configuration_id=%llu;UPDATE "
"lens_profiles SET focal_range_kind=2,minimum_focal_um=24000,"
"maximum_focal_um=24000;",
(unsigned long long)fixture.configuration_id);
CHECK(bytes > 0 && (size_t)bytes < sizeof(mutation));
CHECK(raw_sql(path, mutation));
CHECK(expect_retain_result_unadvanced(
path, 301, fixture.capture_id, LARDON3D_PROJECT_DB_CORRUPT));
CHECK(raw_integer(path, "SELECT COUNT(*) FROM acquisition_campaign_captures",
&count) &&
count == 0);
CHECK(raw_integer(path,
"SELECT COUNT(*) FROM capture_optical_configurations",
&count) &&
count == 0);
CHECK(unlink(path) == 0);
CHECK(rmdir(directory) == 0);
return true;
}
static bool downgrade_to_v22_fixture(const char *path) {
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
if (lardon3d_project_db_open(path, &database, error) != LARDON3D_PROJECT_DB_OK)
return false;
Lardon3DProjectDbScanSet a6000;
Lardon3DProjectDbScanSet s21;
Lardon3DProjectDbCapture capture;
Lardon3DSparseCalibration calibration;
bool ok = lardon3d_project_db_create_scanset(database, "A6000 originals",
&a6000) ==
LARDON3D_PROJECT_DB_OK &&
lardon3d_project_db_create_scanset(database, "S21 originals", &s21) ==
LARDON3D_PROJECT_DB_OK &&
lardon3d_project_db_create_capture(database, a6000.scanset_id, 1,
&capture) ==
LARDON3D_PROJECT_DB_OK &&
create_sparse_calibration(database, 91, 6000, 4000, &calibration) &&
seed_campaign(database, 500, a6000.scanset_id, 1) &&
lardon3d_project_db_retain_acquisition_campaign_capture(
database, 500, 1, capture.capture_id, 1) ==
LARDON3D_PROJECT_DB_OK;
lardon3d_project_db_close(database);
if (!ok)
return false;
/* This removes only objects introduced by the test-created v23 database,
yielding a deterministic v22 fixture without rewriting any real project. */
return raw_sql(
path,
"PRAGMA foreign_keys=OFF;BEGIN IMMEDIATE;"
"DROP TABLE IF EXISTS optical_focus_domain_tokens_v2;"
"DROP TABLE IF EXISTS optical_focus_domains_v2;"
"DROP TABLE IF EXISTS capture_calibration_selections_v2;"
"DROP TABLE IF EXISTS optical_calibration_applicabilities_v2;"
"DROP TABLE IF EXISTS capture_geometric_states;"
"DROP TABLE IF EXISTS feature_extract_batch_tasks;"
"DROP TABLE raw_development_batch_tasks;"
"DROP TABLE capture_calibration_selections;"
"DROP TABLE optical_calibration_profiles;"
"DROP TABLE capture_optical_configurations;"
"DROP INDEX acquisition_campaign_capture_identity_v23;"
"DROP TABLE acquisition_campaign_group_optics;"
"DROP TABLE optical_configurations;"
"DROP TABLE lens_profile_aliases;DROP TABLE lens_profiles;"
"DROP TABLE camera_body_aliases;DROP TABLE camera_body_profiles;"
"UPDATE metadata SET value=22 WHERE key='schema_version';COMMIT;");
}
static bool test_v26_exact_geometric_applicability(void) {
char directory[64];
char path[256];
CHECK(make_database_path(directory, path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
RepairOpticalFixture fixture;
CHECK(seed_repair_optical_fixture(database, &fixture));
CHECK(lardon3d_optical_capture_assign_explicit(database, fixture.capture_id,
fixture.configuration_id) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DProjectDbCapture peer;
Lardon3DProjectDbCapture alternate;
CHECK(lardon3d_project_db_create_capture(database, fixture.scanset_id, 2,
&peer) == LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_project_db_create_capture(database, fixture.scanset_id, 3,
&alternate) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(database, peer.capture_id,
fixture.configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, alternate.capture_id,
fixture.alternate_configuration_id) == LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCalibrationResolutionV2 resolution;
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, fixture.capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_REQUIRED);
/* Positive applicability fixtures must fully observe every field capable of
changing geometry; UNKNOWN is exercised separately below. */
Lardon3DOpticalCaptureGeometricState state = {
.capture_id = fixture.capture_id,
.optical_configuration_id = fixture.configuration_id,
.state_version = 1,
.provenance = LARDON3D_OPTICAL_GEOMETRIC_STATE_METADATA,
.focus_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.aperture_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.aperture_x1000 = 5600,
.stabilization = LARDON3D_OPTICAL_STABILIZATION_OFF,
.crop_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.pipeline_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.representation_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.decoded_geometry_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.decoded_width = 6000,
.decoded_height = 4000,
};
memcpy(state.focus_observation, "af-s", sizeof("af-s"));
memcpy(state.crop_observation, "full-sensor", sizeof("full-sensor"));
memcpy(state.pipeline_observation, "raw-policy-v1", sizeof("raw-policy-v1"));
memcpy(state.representation_observation, "L3DRAWD1-png",
sizeof("L3DRAWD1-png"));
Lardon3DOpticalCaptureGeometricState stored;
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
CHECK(stored.focus_state == LARDON3D_OPTICAL_OBSERVATION_OBSERVED &&
strcmp(stored.focus_observation, "af-s") == 0);
Lardon3DOpticalCaptureGeometricState retry;
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &retry) == LARDON3D_PROJECT_DB_OK &&
retry.capture_id == state.capture_id);
state.decoded_width = 5999;
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &retry) == LARDON3D_PROJECT_DB_CONSTRAINT);
state.decoded_width = 6000;
state.capture_id = peer.capture_id;
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
state.capture_id = alternate.capture_id;
state.optical_configuration_id = fixture.alternate_configuration_id;
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
state.optical_configuration_id = fixture.configuration_id;
Lardon3DSparseCalibration calibration;
CHECK(create_sparse_calibration(database, 0xa6, 6000, 4000, &calibration));
Lardon3DOpticalCalibrationProfile profile_input = {
.optical_configuration_id = fixture.configuration_id,
.sparse_calibration_id = calibration.calibration_id,
.profile_version = 2,
.applicability = LARDON3D_OPTICAL_CALIBRATION_EXACT_CONFIGURATION,
.created_at = 100,
};
memcpy(profile_input.name, "v26 exact A", sizeof("v26 exact A"));
memcpy(profile_input.provenance, "v26 test", sizeof("v26 test"));
Lardon3DOpticalCalibrationProfile profile_a;
CHECK(lardon3d_optical_calibration_profile_create(
database, &profile_input, &profile_a) == LARDON3D_PROJECT_DB_OK);
memcpy(profile_input.name, "v26 exact B", sizeof("v26 exact B"));
Lardon3DOpticalCalibrationProfile profile_b;
CHECK(lardon3d_optical_calibration_profile_create(
database, &profile_input, &profile_b) == LARDON3D_PROJECT_DB_OK);
Lardon3DProjectDbCapture incomplete_exemplar;
CHECK(lardon3d_project_db_create_capture(database, fixture.scanset_id, 11,
&incomplete_exemplar) ==
LARDON3D_PROJECT_DB_OK &&
lardon3d_optical_capture_assign_explicit(
database, incomplete_exemplar.capture_id,
fixture.configuration_id) == LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCaptureGeometricState incomplete_state = state;
incomplete_state.capture_id = incomplete_exemplar.capture_id;
incomplete_state.focus_state = LARDON3D_OPTICAL_OBSERVATION_UNKNOWN;
incomplete_state.focus_observation[0] = '\0';
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &incomplete_state, &stored) == LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCalibrationApplicabilityV2 rejected_applicability;
CHECK(lardon3d_optical_calibration_applicability_v2_create(
database, profile_a.calibration_profile_id,
incomplete_exemplar.capture_id, &rejected_applicability) ==
LARDON3D_PROJECT_DB_CONSTRAINT &&
rejected_applicability.applicability_id == 0);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, peer.capture_id, &resolution) == LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_REQUIRED);
Lardon3DOpticalCalibrationApplicabilityV2 applicability_a;
CHECK(lardon3d_optical_calibration_applicability_v2_create(
database, profile_a.calibration_profile_id, fixture.capture_id,
&applicability_a) == LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCalibrationApplicabilityV2 applicability_retry;
CHECK(lardon3d_optical_calibration_applicability_v2_create(
database, profile_a.calibration_profile_id, fixture.capture_id,
&applicability_retry) == LARDON3D_PROJECT_DB_OK &&
applicability_retry.applicability_id ==
applicability_a.applicability_id);
for (uint32_t unknown_field = 0; unknown_field < 7; ++unknown_field) {
Lardon3DProjectDbCapture unresolved;
CHECK(lardon3d_project_db_create_capture(
database, fixture.scanset_id, 4 + unknown_field, &unresolved) ==
LARDON3D_PROJECT_DB_OK &&
lardon3d_optical_capture_assign_explicit(
database, unresolved.capture_id, fixture.configuration_id) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCaptureGeometricState unresolved_state = state;
unresolved_state.capture_id = unresolved.capture_id;
if (unknown_field == 0) {
unresolved_state.focus_state = LARDON3D_OPTICAL_OBSERVATION_UNKNOWN;
unresolved_state.focus_observation[0] = '\0';
} else if (unknown_field == 1) {
unresolved_state.aperture_state = LARDON3D_OPTICAL_OBSERVATION_UNKNOWN;
unresolved_state.aperture_x1000 = 0;
} else if (unknown_field == 2) {
unresolved_state.stabilization = LARDON3D_OPTICAL_STABILIZATION_UNKNOWN;
} else if (unknown_field == 3) {
unresolved_state.crop_state = LARDON3D_OPTICAL_OBSERVATION_UNKNOWN;
unresolved_state.crop_observation[0] = '\0';
} else if (unknown_field == 4) {
unresolved_state.pipeline_state = LARDON3D_OPTICAL_OBSERVATION_UNKNOWN;
unresolved_state.pipeline_observation[0] = '\0';
} else if (unknown_field == 5) {
unresolved_state.representation_state =
LARDON3D_OPTICAL_OBSERVATION_UNKNOWN;
unresolved_state.representation_observation[0] = '\0';
} else {
unresolved_state.decoded_geometry_state =
LARDON3D_OPTICAL_OBSERVATION_UNKNOWN;
unresolved_state.decoded_width = 0;
unresolved_state.decoded_height = 0;
}
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &unresolved_state, &stored) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, unresolved.capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_REQUIRED);
CHECK(lardon3d_optical_capture_calibration_select_v2(
database, unresolved.capture_id,
applicability_a.applicability_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
Lardon3DOpticalCaptureCalibrationSelectionV2 unresolved_selection;
CHECK(lardon3d_optical_capture_calibration_selection_load_v2(
database, unresolved.capture_id, &unresolved_selection) ==
LARDON3D_PROJECT_DB_NOT_FOUND &&
unresolved_selection.capture_id == 0);
}
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, peer.capture_id, &resolution) == LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_RESOLVED &&
resolution.calibration_profile_id == profile_a.calibration_profile_id);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, alternate.capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_REQUIRED);
Lardon3DOpticalCalibrationApplicabilityV2 applicability_b;
CHECK(lardon3d_optical_calibration_applicability_v2_create(
database, profile_b.calibration_profile_id, fixture.capture_id,
&applicability_b) == LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, peer.capture_id, &resolution) == LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_SELECTION_REQUIRED);
CHECK(lardon3d_optical_capture_calibration_select_v2(
database, peer.capture_id, applicability_a.applicability_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_select_v2(
database, peer.capture_id, applicability_a.applicability_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_select_v2(
database, peer.capture_id, applicability_b.applicability_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
CHECK(lardon3d_optical_capture_calibration_select_v2(
database, alternate.capture_id, applicability_a.applicability_id) ==
LARDON3D_PROJECT_DB_CONSTRAINT);
Lardon3DOpticalCaptureCalibrationSelectionV2 selection;
CHECK(lardon3d_optical_capture_calibration_selection_load_v2(
database, peer.capture_id, &selection) == LARDON3D_PROJECT_DB_OK &&
selection.calibration_profile_id == profile_a.calibration_profile_id &&
selection.sparse_calibration_id == calibration.calibration_id);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, peer.capture_id, &resolution) == LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_RESOLVED &&
resolution.applicability_id == applicability_a.applicability_id);
lardon3d_project_db_close(database);
char corruption[256];
int corruption_bytes = snprintf(
corruption, sizeof(corruption),
"PRAGMA foreign_keys=OFF;DELETE FROM capture_geometric_states WHERE "
"capture_id=%llu;",
(unsigned long long)fixture.capture_id);
CHECK(corruption_bytes > 0 &&
(size_t)corruption_bytes < sizeof(corruption) &&
raw_sql(path, corruption));
database = NULL;
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, peer.capture_id, &resolution) ==
LARDON3D_PROJECT_DB_CORRUPT);
lardon3d_project_db_close(database);
/* A v25 project contains no durable observation from which v26 state could
be inferred. Re-migration therefore recreates only empty additive tables.
*/
CHECK(raw_sql(
path, "PRAGMA foreign_keys=OFF;BEGIN IMMEDIATE;"
"DROP TABLE optical_focus_domain_tokens_v2;"
"DROP TABLE optical_focus_domains_v2;"
"DROP TABLE capture_calibration_selections_v2;"
"DROP TABLE optical_calibration_applicabilities_v2;"
"DROP TABLE capture_geometric_states;"
"UPDATE metadata SET value=25 WHERE key='schema_version';COMMIT;"));
database = NULL;
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
lardon3d_project_db_close(database);
sqlite3_int64 migrated_count = -1;
CHECK(raw_integer(path, "SELECT COUNT(*) FROM capture_geometric_states",
&migrated_count) &&
migrated_count == 0);
CHECK(raw_integer(
path, "SELECT COUNT(*) FROM optical_calibration_applicabilities_v2",
&migrated_count) &&
migrated_count == 0);
CHECK(raw_integer(path,
"SELECT COUNT(*) FROM capture_calibration_selections_v2",
&migrated_count) &&
migrated_count == 0);
CHECK(unlink(path) == 0);
CHECK(rmdir(directory) == 0);
return true;
}
static Lardon3DOpticalCaptureGeometricState complete_focus_state(
uint64_t capture_id, uint64_t configuration_id, const char *focus_token) {
Lardon3DOpticalCaptureGeometricState state = {
.capture_id = capture_id,
.optical_configuration_id = configuration_id,
.state_version = 1,
.provenance = LARDON3D_OPTICAL_GEOMETRIC_STATE_METADATA,
.focus_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.aperture_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.aperture_x1000 = 5600,
.stabilization = LARDON3D_OPTICAL_STABILIZATION_OFF,
.crop_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.pipeline_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.representation_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.decoded_geometry_state = LARDON3D_OPTICAL_OBSERVATION_OBSERVED,
.decoded_width = 6000,
.decoded_height = 4000,
};
(void)snprintf(state.focus_observation, sizeof(state.focus_observation),
"%s", focus_token);
memcpy(state.crop_observation, "full-sensor", sizeof("full-sensor"));
memcpy(state.pipeline_observation, "raw-policy-v1",
sizeof("raw-policy-v1"));
memcpy(state.representation_observation, "L3DRAWD1-png",
sizeof("L3DRAWD1-png"));
return state;
}
static bool test_v27_discrete_focus_domains(void) {
char directory[64];
char path[256];
CHECK(make_database_path(directory, path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
RepairOpticalFixture fixture;
CHECK(seed_repair_optical_fixture(database, &fixture));
Lardon3DOpticalConfiguration base_configuration;
CHECK(lardon3d_optical_configuration_load(
database, fixture.configuration_id, &base_configuration) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCameraBodyProfile other_body_input = {0};
memcpy(other_body_input.manufacturer, "Generic", sizeof("Generic"));
memcpy(other_body_input.model, "Other body", sizeof("Other body"));
memcpy(other_body_input.name, "Other body profile",
sizeof("Other body profile"));
Lardon3DOpticalCameraBodyProfile other_body;
CHECK(lardon3d_optical_camera_body_create(database, &other_body_input,
&other_body) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalLensProfile other_lens_input = {
.interface_kind = LARDON3D_OPTICAL_LENS_ELECTRONIC,
.focal_range_kind = LARDON3D_OPTICAL_FOCAL_RANGE_PRIME,
.minimum_focal_um = 16000,
.maximum_focal_um = 16000,
};
memcpy(other_lens_input.manufacturer, "Generic", sizeof("Generic"));
memcpy(other_lens_input.model, "Other lens", sizeof("Other lens"));
memcpy(other_lens_input.name, "Other lens profile",
sizeof("Other lens profile"));
Lardon3DOpticalLensProfile other_lens;
CHECK(lardon3d_optical_lens_create(database, &other_lens_input, &other_lens) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalConfiguration configuration_input = {
.camera_body_profile_id = other_body.camera_body_profile_id,
.lens_profile_id = base_configuration.lens_profile_id,
.has_focal_length = true,
.focal_length_um = 16000,
};
Lardon3DOpticalConfiguration other_body_configuration;
CHECK(lardon3d_optical_configuration_create(
database, &configuration_input, &other_body_configuration) ==
LARDON3D_PROJECT_DB_OK);
configuration_input.camera_body_profile_id =
base_configuration.camera_body_profile_id;
configuration_input.lens_profile_id = other_lens.lens_profile_id;
Lardon3DOpticalConfiguration other_lens_configuration;
CHECK(lardon3d_optical_configuration_create(
database, &configuration_input, &other_lens_configuration) ==
LARDON3D_PROJECT_DB_OK);
enum { TARGET_COUNT = 5 };
Lardon3DProjectDbCapture targets[TARGET_COUNT];
for (size_t index = 0; index < TARGET_COUNT; ++index)
CHECK(lardon3d_project_db_create_capture(database, fixture.scanset_id,
(uint32_t)(index + 2),
&targets[index]) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, fixture.capture_id, fixture.configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, targets[0].capture_id, fixture.configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, targets[1].capture_id, fixture.configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, targets[2].capture_id,
fixture.alternate_configuration_id) == LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, targets[3].capture_id,
other_body_configuration.optical_configuration_id) ==
LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_assign_explicit(
database, targets[4].capture_id,
other_lens_configuration.optical_configuration_id) ==
LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCaptureGeometricState state = complete_focus_state(
fixture.capture_id, fixture.configuration_id, "synthetic-focus-a");
Lardon3DOpticalCaptureGeometricState stored;
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
state = complete_focus_state(
targets[3].capture_id,
other_body_configuration.optical_configuration_id, "synthetic-focus-b");
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
state = complete_focus_state(
targets[4].capture_id,
other_lens_configuration.optical_configuration_id, "synthetic-focus-b");
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
state = complete_focus_state(targets[0].capture_id, fixture.configuration_id,
"synthetic-focus-b");
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
state = complete_focus_state(targets[1].capture_id, fixture.configuration_id,
"synthetic-focus-outside");
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
/* The identical focus token at another focal configuration must not cross
the exact body/lens/focal applicability boundary. */
state = complete_focus_state(targets[2].capture_id,
fixture.alternate_configuration_id,
"synthetic-focus-b");
CHECK(lardon3d_optical_capture_geometric_state_create(
database, &state, &stored) == LARDON3D_PROJECT_DB_OK);
Lardon3DSparseCalibration calibration;
CHECK(create_sparse_calibration(database, 0xd1, 6000, 4000, &calibration));
Lardon3DOpticalCalibrationProfile profile_input = {
.optical_configuration_id = fixture.configuration_id,
.sparse_calibration_id = calibration.calibration_id,
.profile_version = 2,
.applicability = LARDON3D_OPTICAL_CALIBRATION_EXACT_CONFIGURATION,
.created_at = 200,
};
memcpy(profile_input.name, "focus domain A", sizeof("focus domain A"));
memcpy(profile_input.provenance, "synthetic physical evidence",
sizeof("synthetic physical evidence"));
Lardon3DOpticalCalibrationProfile profile_a;
CHECK(lardon3d_optical_calibration_profile_create(
database, &profile_input, &profile_a) == LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCalibrationApplicabilityV2 applicability_a;
CHECK(lardon3d_optical_calibration_applicability_v2_create(
database, profile_a.calibration_profile_id, fixture.capture_id,
&applicability_a) == LARDON3D_PROJECT_DB_OK);
const char *tokens[] = {"synthetic-focus-b", "synthetic-focus-a"};
unsigned char evidence[LARDON3D_OPTICAL_FOCUS_DOMAIN_DIGEST_SIZE] = {0};
evidence[0] = 0x71;
Lardon3DOpticalFocusDomainV2 domain_a;
CHECK(lardon3d_optical_focus_domain_v2_create(
database, applicability_a.applicability_id, 1, evidence, tokens,
2, &domain_a) == LARDON3D_PROJECT_DB_OK &&
domain_a.token_count == 2);
const char *retry_tokens[] = {"synthetic-focus-a", "synthetic-focus-b"};
Lardon3DOpticalFocusDomainV2 domain_retry;
CHECK(lardon3d_optical_focus_domain_v2_create(
database, applicability_a.applicability_id, 1, evidence,
retry_tokens, 2, &domain_retry) == LARDON3D_PROJECT_DB_OK &&
domain_retry.focus_domain_id == domain_a.focus_domain_id);
evidence[1] = 1;
CHECK(lardon3d_optical_focus_domain_v2_create(
database, applicability_a.applicability_id, 1, evidence,
retry_tokens, 2, &domain_retry) == LARDON3D_PROJECT_DB_CONSTRAINT &&
domain_retry.focus_domain_id == 0);
evidence[1] = 0;
Lardon3DOpticalCalibrationResolutionV2 resolution;
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, targets[0].capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_RESOLVED &&
resolution.applicability_id == applicability_a.applicability_id);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, targets[1].capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_REQUIRED);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, targets[2].capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_REQUIRED);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, targets[3].capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_REQUIRED);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, targets[4].capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_REQUIRED);
/* A domain cannot repair incomplete exemplar evidence. Corrupting the
schema-valid focus state must fail closed before candidate enumeration. */
lardon3d_project_db_close(database);
database = NULL;
char corruption[512];
int corruption_bytes = snprintf(
corruption, sizeof(corruption),
"UPDATE capture_geometric_states SET focus_state=1,"
"focus_observation='' WHERE capture_id=%llu;",
(unsigned long long)fixture.capture_id);
CHECK(corruption_bytes > 0 &&
(size_t)corruption_bytes < sizeof(corruption) &&
raw_sql(path, corruption));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
memset(&resolution, 0x7f, sizeof(resolution));
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, targets[0].capture_id, &resolution) ==
LARDON3D_PROJECT_DB_CORRUPT &&
resolution.kind == 0 &&
resolution.applicability_id == 0);
lardon3d_project_db_close(database);
database = NULL;
corruption_bytes = snprintf(
corruption, sizeof(corruption),
"UPDATE capture_geometric_states SET focus_state=2,"
"focus_observation='synthetic-focus-a' WHERE capture_id=%llu;",
(unsigned long long)fixture.capture_id);
CHECK(corruption_bytes > 0 &&
(size_t)corruption_bytes < sizeof(corruption) &&
raw_sql(path, corruption));
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
memcpy(profile_input.name, "focus domain B", sizeof("focus domain B"));
Lardon3DOpticalCalibrationProfile profile_b;
CHECK(lardon3d_optical_calibration_profile_create(
database, &profile_input, &profile_b) == LARDON3D_PROJECT_DB_OK);
Lardon3DOpticalCalibrationApplicabilityV2 applicability_b;
CHECK(lardon3d_optical_calibration_applicability_v2_create(
database, profile_b.calibration_profile_id, fixture.capture_id,
&applicability_b) == LARDON3D_PROJECT_DB_OK);
evidence[0] = 0x72;
const char *overlap_tokens[] = {"synthetic-focus-b"};
Lardon3DOpticalFocusDomainV2 domain_b;
CHECK(lardon3d_optical_focus_domain_v2_create(
database, applicability_b.applicability_id, 1, evidence,
overlap_tokens, 1, &domain_b) == LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_resolve_v2(
database, targets[0].capture_id, &resolution) ==
LARDON3D_PROJECT_DB_OK &&
resolution.kind == LARDON3D_OPTICAL_CALIBRATION_SELECTION_REQUIRED);
CHECK(lardon3d_optical_capture_calibration_select_v2(
database, targets[0].capture_id,
applicability_a.applicability_id) == LARDON3D_PROJECT_DB_OK);
CHECK(lardon3d_optical_capture_calibration_select_v2(
database, targets[0].capture_id,
applicability_a.applicability_id) == LARDON3D_PROJECT_DB_OK);
lardon3d_project_db_close(database);
/* v26 contains observations but no retained physical-domain evidence. The
additive migration must recreate empty domain tables without inference. */
CHECK(raw_sql(path, "PRAGMA foreign_keys=OFF;BEGIN IMMEDIATE;"
"DROP TABLE optical_focus_domain_tokens_v2;"
"DROP TABLE optical_focus_domains_v2;"
"UPDATE metadata SET value=26 WHERE key='schema_version';"
"COMMIT;"));
database = NULL;
CHECK(lardon3d_project_db_open(path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
lardon3d_project_db_close(database);
sqlite3_int64 count = -1;
CHECK(raw_integer(path, "SELECT COUNT(*) FROM optical_focus_domains_v2",
&count) &&
count == 0);
CHECK(raw_integer(path,
"SELECT COUNT(*) FROM optical_focus_domain_tokens_v2",
&count) &&
count == 0);
CHECK(unlink(path) == 0);
CHECK(rmdir(directory) == 0);
return true;
}
static bool test_migration_rollback_retry_and_equivalence(void) {
char migrated_directory[64];
char migrated_path[256];
char fresh_directory[64];
char fresh_path[256];
CHECK(make_database_path(migrated_directory, migrated_path));
CHECK(make_database_path(fresh_directory, fresh_path));
CHECK(downgrade_to_v22_fixture(migrated_path));
Lardon3DProjectDb *database = NULL;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY];
CHECK(setenv("LARDON3D_TEST_PROJECT_DB_FAIL_MIGRATION_V23", "1", 1) == 0);
CHECK(lardon3d_project_db_open(migrated_path, &database, error) !=
LARDON3D_PROJECT_DB_OK &&
database == NULL);
CHECK(unsetenv("LARDON3D_TEST_PROJECT_DB_FAIL_MIGRATION_V23") == 0);
sqlite3_int64 value = 0;
CHECK(raw_integer(migrated_path,
"SELECT value FROM metadata WHERE key='schema_version'",
&value) &&
value == 22);
CHECK(raw_integer(migrated_path,
"SELECT COUNT(*) FROM sqlite_master WHERE name="
"'camera_body_profiles'",
&value) &&
value == 0);
CHECK(raw_integer(migrated_path, "SELECT COUNT(*) FROM captures", &value) &&
value == 1);
CHECK(raw_integer(migrated_path, "SELECT COUNT(*) FROM sparse_calibrations",
&value) &&
value == 1);
CHECK(raw_integer(migrated_path,
"SELECT COUNT(*) FROM acquisition_campaign_captures",
&value) &&
value == 1);
CHECK(lardon3d_project_db_open(migrated_path, &database, error) ==
LARDON3D_PROJECT_DB_OK &&
lardon3d_project_db_schema_version(database) ==
LARDON3D_PROJECT_DB_SCHEMA_VERSION);
Lardon3DOpticalCaptureAssignment migrated_unresolved;
CHECK(lardon3d_optical_capture_assignment_load(database, 1,
&migrated_unresolved) ==
LARDON3D_PROJECT_DB_NOT_FOUND &&
migrated_unresolved.capture_id == 0);
unsigned char migrated_request[16];
Lardon3DProjectDbAcquisitionCampaignTask migrated_campaign;
CHECK(lardon3d_project_db_load_acquisition_campaign_task(
database, 500, migrated_request, sizeof(migrated_request),
&migrated_campaign) == LARDON3D_PROJECT_DB_OK &&
migrated_campaign.next_group_id == 1);
Lardon3DProjectDbAcquisitionCampaignCapture migrated_mapping;
CHECK(lardon3d_project_db_load_acquisition_campaign_capture(
database, 500, 1, &migrated_mapping) == LARDON3D_PROJECT_DB_OK &&
migrated_mapping.capture_id == 1);
lardon3d_project_db_close(database);
database = NULL;
CHECK(raw_integer(migrated_path, "SELECT COUNT(*) FROM captures", &value) &&
value == 1);
CHECK(raw_integer(migrated_path, "SELECT COUNT(*) FROM sparse_calibrations",
&value) &&
value == 1);
const char *empty_tables[] = {
"camera_body_profiles",
"camera_body_aliases",
"lens_profiles",
"lens_profile_aliases",
"optical_configurations",
"acquisition_campaign_group_optics",
"capture_optical_configurations",
"optical_calibration_profiles",
"capture_calibration_selections",
"capture_geometric_states",
"optical_calibration_applicabilities_v2",
"capture_calibration_selections_v2",
"optical_focus_domains_v2",
"optical_focus_domain_tokens_v2",
};
char query[256];
for (size_t index = 0; index < sizeof(empty_tables) / sizeof(empty_tables[0]);
++index) {
CHECK(snprintf(query, sizeof(query), "SELECT COUNT(*) FROM %s",
empty_tables[index]) > 0);
CHECK(raw_integer(migrated_path, query, &value) && value == 0);
}
CHECK(lardon3d_project_db_open(fresh_path, &database, error) ==
LARDON3D_PROJECT_DB_OK);
lardon3d_project_db_close(database);
database = NULL;
const char *objects[] = {
"camera_body_profiles",
"camera_body_aliases",
"camera_body_aliases_profile_idx",
"lens_profiles",
"lens_profile_aliases",
"lens_profile_aliases_profile_idx",
"optical_configurations",
"optical_configurations_body_idx",
"optical_configurations_lens_idx",
"acquisition_campaign_group_optics",
"acquisition_campaign_capture_identity_v23",
"capture_optical_configurations",
"capture_optical_configurations_config_idx",
"optical_calibration_profiles",
"optical_calibration_profiles_config_idx",
"optical_calibration_profiles_sparse_idx",
"capture_calibration_selections",
"capture_geometric_states",
"capture_geometric_states_exact_idx",
"optical_calibration_applicabilities_v2",
"optical_calibration_applicabilities_v2_config_idx",
"capture_calibration_selections_v2",
"optical_focus_domains_v2",
"optical_focus_domain_tokens_v2",
"optical_focus_domain_tokens_v2_token_idx",
};
char migrated_sql[8192];
char fresh_sql[8192];
for (size_t index = 0; index < sizeof(objects) / sizeof(objects[0]); ++index) {
CHECK(raw_object_sql(migrated_path, objects[index], migrated_sql,
sizeof(migrated_sql)));
CHECK(raw_object_sql(fresh_path, objects[index], fresh_sql,
sizeof(fresh_sql)));
CHECK(strcmp(migrated_sql, fresh_sql) == 0);
}
CHECK(unlink(migrated_path) == 0);
CHECK(rmdir(migrated_directory) == 0);
CHECK(unlink(fresh_path) == 0);
CHECK(rmdir(fresh_directory) == 0);
return true;
}
int main(void) {
return test_profiles_assignments_and_calibrations() &&
test_v26_exact_geometric_applicability() &&
test_v27_discrete_focus_domains() &&
test_calibration_conflict_result_contract() &&
test_calibration_dependency_corruption_precedence() &&
test_campaign_request_corruption_prevents_optics_mutation() &&
test_capture_optics_conflict_and_corruption_rollback() &&
test_malformed_configuration_rolls_back_campaign_retention() &&
test_migration_rollback_retry_and_equivalence()
? EXIT_SUCCESS
: EXIT_FAILURE;
}