lardon3d/tests/test_calibration_workflow_ready.cpp

566 lines
23 KiB
C++

// The fixture calls the C Project DB API directly. Establish C linkage before
// Calibration Workflow's frozen Tooling/Bootstrap dependency chain.
extern "C" {
#include <lardon3d/project_db.h>
}
#include <lardon3d/calibration_workflow.h>
#include <lardon3d/optical_profiles.h>
#include <opencv2/imgcodecs.hpp>
#include <openssl/evp.h>
#include <sqlite3.h>
#include <array>
#include <cstdio>
#include <cstring>
#include <filesystem>
#include <fstream>
#include <iomanip>
#include <locale>
#include <sstream>
#include <string>
#include <vector>
#include <unistd.h>
#define CHECK(x) do { if (!(x)) { \
std::fprintf(stderr, "workflow ready failure %d: %s\n", __LINE__, #x); \
return false; \
} } while (0)
namespace {
constexpr size_t kViewCount = 60;
constexpr size_t kChecksPerView = 20;
constexpr size_t kCoordinateCount = kViewCount * kChecksPerView;
std::string hex_repeat(unsigned char value) {
static const char digits[] = "0123456789abcdef";
std::string out(64, '0');
for (size_t i = 0; i < 32; ++i) {
out[2 * i] = digits[value >> 4];
out[2 * i + 1] = digits[value & 15u];
}
return out;
}
std::string hex(const unsigned char value[32]) {
static const char digits[] = "0123456789abcdef";
std::string out(64, '0');
for (size_t i = 0; i < 32; ++i) {
out[2 * i] = digits[value[i] >> 4];
out[2 * i + 1] = digits[value[i] & 15u];
}
return out;
}
std::string hf(double value) {
std::ostringstream out;
out.imbue(std::locale::classic());
out << std::hexfloat << value;
return out.str();
}
bool write_text(const std::filesystem::path& path, const std::string& text) {
std::ofstream out(path, std::ios::binary | std::ios::trunc);
out << text;
return static_cast<bool>(out);
}
bool write_bytes(const std::filesystem::path& path,
const std::vector<unsigned char>& bytes) {
std::ofstream out(path, std::ios::binary | std::ios::trunc);
out.write(reinterpret_cast<const char *>(bytes.data()),
static_cast<std::streamsize>(bytes.size()));
return static_cast<bool>(out);
}
bool digest(const unsigned char *bytes, size_t size, unsigned char output[32]) {
unsigned int written = 0;
return EVP_Digest(bytes, size, output, &written, EVP_sha256(), nullptr) == 1 &&
written == 32;
}
std::string sha_file_hex(const std::filesystem::path& path) {
std::ifstream in(path, std::ios::binary);
std::ostringstream bytes;
bytes << in.rdbuf();
const std::string data = bytes.str();
unsigned char value[32]{};
if (!in || !digest(reinterpret_cast<const unsigned char *>(data.data()),
data.size(), value))
return {};
return hex(value);
}
bool raw_sql(const std::filesystem::path& path, const std::string& sql) {
sqlite3 *database = nullptr;
if (sqlite3_open(path.c_str(), &database) != SQLITE_OK) return false;
const int code = sqlite3_exec(database, sql.c_str(), nullptr, nullptr, nullptr);
return sqlite3_close(database) == SQLITE_OK && code == SQLITE_OK;
}
struct Fixture {
std::filesystem::path root;
std::filesystem::path db_path;
std::filesystem::path session;
std::filesystem::path detection;
std::filesystem::path solve;
std::filesystem::path evidence;
std::filesystem::path producer;
std::filesystem::path campaign;
std::filesystem::path image_path;
std::string image_asset_path;
std::vector<unsigned char> image_bytes;
Lardon3DProjectDb *database = nullptr;
uint64_t execution_id = 0;
uint64_t configuration_id = 0;
Lardon3DCalibrationWorkflowInputFiles files{};
};
void close_fixture(Fixture *fixture) {
if (fixture->database) {
lardon3d_project_db_close(fixture->database);
fixture->database = nullptr;
}
if (!fixture->root.empty()) {
std::error_code error;
std::filesystem::remove_all(fixture->root, error);
}
}
bool seed_database_rows(const Fixture& fixture,
const unsigned char image_sha[32]) {
std::ostringstream sql;
sql << "INSERT INTO scansets(scanset_id,name,created_at,updated_at) "
"VALUES(1,'scope',1,1);"
<< "INSERT INTO tasks VALUES(1,'quality','photo_quality.triage',1,"
"5,5,100,1,0,0,0,0,1);"
<< "INSERT INTO tasks VALUES(2,'campaign','acquisition_campaign.run',1,"
"5,5,100,1,0,0,0,0,1);"
<< "INSERT INTO photo_quality_triage_tasks VALUES(1,1,2,1,X'01');"
<< "INSERT INTO photo_quality_triage_results VALUES("
"1,1,0,1,0,1,0,100,100,100,100,1.0,1.0,0.0,0.0,1.0,1.0,0.0,'GOOD');"
<< "INSERT INTO acquisition_campaign_tasks VALUES(2,1,2,2,X'02');"
<< "INSERT INTO captures(capture_id,scanset_id,created_at) VALUES(1,1,1);"
<< "INSERT INTO acquisition_campaign_captures VALUES(2,2,1);"
<< "INSERT INTO image_assets(asset_id,sha256,path,size_bytes,state,created_at) "
"VALUES(1,X'" << hex(image_sha) << "','" << fixture.image_asset_path
<< "'," << fixture.image_bytes.size() << ",1,1);"
<< "INSERT INTO images(image_id,scanset_id,asset_id,original_name,"
"source_path,imported_at) VALUES("
"1,1,1,'selected.png','/source/selected.png',1);"
<< "INSERT INTO capture_images VALUES(1,1);";
return raw_sql(fixture.db_path, sql.str());
}
bool create_optical_configuration(Fixture *fixture) {
Lardon3DOpticalCameraBodyProfile body_input{};
std::memcpy(body_input.manufacturer, "Generic", sizeof("Generic"));
std::memcpy(body_input.model, "Workflow body", sizeof("Workflow body"));
std::memcpy(body_input.name, "Workflow body", sizeof("Workflow body"));
Lardon3DOpticalCameraBodyProfile body{};
if (lardon3d_optical_camera_body_create(fixture->database, &body_input, &body) !=
LARDON3D_PROJECT_DB_OK)
return false;
Lardon3DOpticalLensProfile lens_input{};
lens_input.interface_kind = LARDON3D_OPTICAL_LENS_MANUAL;
lens_input.focal_range_kind = LARDON3D_OPTICAL_FOCAL_RANGE_PRIME;
lens_input.minimum_focal_um = 35000;
lens_input.maximum_focal_um = 35000;
std::memcpy(lens_input.manufacturer, "Generic", sizeof("Generic"));
std::memcpy(lens_input.model, "Workflow 35", sizeof("Workflow 35"));
std::memcpy(lens_input.name, "Workflow 35 mm", sizeof("Workflow 35 mm"));
Lardon3DOpticalLensProfile lens{};
if (lardon3d_optical_lens_create(fixture->database, &lens_input, &lens) !=
LARDON3D_PROJECT_DB_OK)
return false;
Lardon3DOpticalConfiguration input{};
input.camera_body_profile_id = body.camera_body_profile_id;
input.lens_profile_id = lens.lens_profile_id;
input.has_focal_length = true;
input.focal_length_um = 35000;
Lardon3DOpticalConfiguration configuration{};
if (lardon3d_optical_configuration_create(
fixture->database, &input, &configuration) != LARDON3D_PROJECT_DB_OK)
return false;
if (lardon3d_optical_capture_assign_explicit(
fixture->database, 1, configuration.optical_configuration_id) !=
LARDON3D_PROJECT_DB_OK)
return false;
fixture->configuration_id = configuration.optical_configuration_id;
return true;
}
std::string parameters() {
const double values[8] = {1000.0, 1001.0, 500.0, 400.0,
0.01, -0.01, 0.001, -0.001};
std::ostringstream out;
out << '[';
for (size_t i = 0; i < 8; ++i) {
if (i) out << ',';
out << '"' << hf(values[i]) << '"';
}
out << ']';
return out.str();
}
std::string pose() {
return "{\"rvec\":[\"" + hf(0.0) + "\",\"" + hf(0.0) + "\",\"" +
hf(0.0) + "\"],\"tvec_m\":[\"" + hf(0.0) + "\",\"" + hf(0.0) +
"\",\"" + hf(1.0) + "\"]}";
}
bool write_external_inputs(Fixture *fixture, double holdout_rmse) {
const std::string optical = hex_repeat(0x11);
const std::string generator = hex_repeat(0x12);
const std::string planarity = hex_repeat(0x13);
static const std::array<const char *, 9> labels = {
"center", "top", "right", "bottom", "left", "top_left",
"top_right", "bottom_left", "bottom_right"};
static const uint32_t quadrants[10] = {0, 0, 1, 1, 2, 2, 3, 3, 4, 4};
static const uint32_t distances[10] = {0, 1, 2, 0, 1, 2, 0, 1, 2, 0};
static const double angles[10] = {25, 40, 55, 25, 40, 55, 25, 40, 55, 25};
std::ostringstream session;
session << "L3DCAL_SESSION_V1\n"
<< "target board " << generator << " DICT_5X5_100 9 7 30 21\n"
<< "measurement caliper 0.1 30 30 30 30 30 30 30 30 30 30\n"
<< "white_border 30\n"
<< "planarity PASS " << planarity << "\n"
<< "decoder qualified_decoder 1\n"
<< "optical_state " << optical
<< " body_objective_zoom_focus_stabilization_format_pipeline\n";
for (size_t i = 0; i < kViewCount; ++i) {
const std::string sha = hex_repeat(static_cast<unsigned char>(i + 0x20));
const uint32_t group = static_cast<uint32_t>(i / 6);
const double distance = 1.0 + static_cast<double>(distances[group]) * 0.3;
session << "image /retained/view-" << i << ".png " << sha << " 0\n"
<< "pre_solve " << sha << " 0.1\n"
<< "clipping " << sha << " 0\n"
<< "coordinate " << sha
<< " qualified_decoder 1 0 1000 800 20 0 0\n";
for (size_t point = 0; point < kChecksPerView; ++point) {
session << "coordinate_point " << sha << ' '
<< labels[point % labels.size()] << ' ' << point << ' ' << point + 1
<< ' ' << point << ' ' << point + 1 << "\n";
}
session << "distance " << sha << ' ' << std::setprecision(17)
<< std::defaultfloat << distance << ' ' << distances[group] << "\n";
}
if (!write_text(fixture->session, session.str())) return false;
std::ostringstream detection;
detection << "{\n\"format\":\"L3DCAL_DETECTION_V1\",\n"
<< "\"decoder\":\"qualified_decoder\",\n"
<< "\"decoder_version\":\"1\",\n\"views\":[\n";
for (size_t i = 0; i < kViewCount; ++i) {
const std::string sha = hex_repeat(static_cast<unsigned char>(i + 0x20));
const uint32_t group = static_cast<uint32_t>(i / 6);
const double distance = 1.0 + static_cast<double>(distances[group]) * 0.3;
detection << "{\"source_sha256\":\"" << sha
<< "\",\"orientation\":0,\"oriented_width\":1000,"
"\"oriented_height\":800,\"decision\":\"accepted\","
"\"reason\":\"-\",\"frame_region\":" << quadrants[group]
<< ",\"distance_band\":" << distances[group]
<< ",\"holdout\":" << ((i % 6) == 4 ? "true" : "false")
<< ",\"target_occupancy\":\"" << hf(0.4)
<< "\",\"normal_angle_degrees\":\"" << hf(angles[group])
<< "\",\"measured_distance_metres\":\"" << hf(distance)
<< "\",\"pre_solve_corner_rms_px\":\"" << hf(0.1)
<< "\",\"clipping_fraction\":\"" << hf(0.0)
<< "\",\"physical_target_quadrants\":3,"
"\"target_corner_quadrant_mask\":7,\"corner_count\":40,"
"\"residual_count\":40,\"high_residual_count\":0,"
"\"reprojection_rmse_px\":\"" << hf(0.4)
<< "\",\"maximum_residual_px\":\"" << hf(0.8)
<< "\",\"coordinate_equivalence\":{\"comparison_points\":20,"
"\"max_abs_dx_px\":\"" << hf(0.0)
<< "\",\"max_abs_dy_px\":\"" << hf(0.0)
<< "\",\"pass\":true},\"corners\":[";
for (size_t corner = 0; corner < 40; ++corner) {
if (corner) detection << ',';
detection << "{\"id\":" << corner << ",\"x\":\""
<< hf(100.0 + static_cast<double>(corner)) << "\",\"y\":\""
<< hf(200.0 + static_cast<double>(corner)) << "\"}";
}
detection << "]}" << (i + 1 == kViewCount ? "\n" : ",\n");
}
detection << "]\n}\n";
if (!write_text(fixture->detection, detection.str())) return false;
std::ostringstream solve;
solve << "{\n\"format\":\"L3DCAL_SOLVE_V1\",\n\"runs\":[\n";
for (size_t run = 0; run < 3; ++run) {
solve << "{\"run\":" << run << ",\"params\":" << parameters()
<< ",\"opencv_rms_px\":\"" << hf(0.4) << "\",\"poses\":[";
for (size_t i = 0; i < kViewCount; ++i) {
if (i) solve << ',';
solve << pose();
}
solve << "]}" << (run == 2 ? "\n" : ",\n");
}
solve << "],\n\"fit_params\":" << parameters() << "\n}\n";
if (!write_text(fixture->solve, solve.str())) return false;
std::ostringstream evidence;
evidence << "{\n\"format\":\"L3DCAL_EVIDENCE_BUNDLE_V1\",\n"
<< "\"target\":{\"id\":\"board\",\"generator_sha256\":\""
<< generator
<< "\",\"instrument\":\"caliper\",\"resolution_mm\":\""
<< hf(0.1) << "\",\"planarity_evidence_sha256\":\"" << planarity
<< "\"},\n\"optical_sha256\":\"" << optical
<< "\",\n\"optical_state\":"
"\"body_objective_zoom_focus_stabilization_format_pipeline\",\n"
<< "\"validation_flags\":\"0xf\",\n\"global_rmse_px\":\""
<< hf(0.4) << "\",\"maximum_residual_px\":\"" << hf(0.8)
<< "\",\"high_residual_fraction\":\"" << hf(0.0)
<< "\",\n\"holdout\":{\"rmse_px\":\"" << hf(holdout_rmse)
<< "\",\"maximum_px\":\"" << hf(0.8)
<< "\"},\n\"maximum_parameter_delta_px\":\"" << hf(0.0)
<< "\",\n\"deterministic_full_solve_equality\":true,\n"
"\"residuals\":[";
bool first = true;
for (size_t i = 0; i < kViewCount; ++i) {
const std::string sha = hex_repeat(static_cast<unsigned char>(i + 0x20));
for (size_t corner = 0; corner < 40; ++corner) {
if (!first) evidence << ',';
first = false;
evidence << "{\"source_sha256\":\"" << sha << "\",\"corner_id\":"
<< corner << ",\"dx_px\":\"" << hf(0.4)
<< "\",\"dy_px\":\"" << hf(0.0) << "\",\"rmse_px\":\""
<< hf(0.4) << "\"}";
}
}
evidence << "]\n}\n";
if (!write_text(fixture->evidence, evidence.str())) return false;
const std::string session_sha = sha_file_hex(fixture->session);
if (session_sha.empty()) return false;
if (!write_text(
fixture->producer,
"{\n\"format\":\"L3DCAL_PRODUCER_V1\",\n"
"\"solver_executable_sha256\":\"" + hex_repeat(0xa1) + "\",\n"
"\"solver_configuration_sha256\":\"" + hex_repeat(0xb1) + "\",\n"
"\"session_sha256\":\"" + session_sha + "\",\n"
"\"opencv_version\":\"5.0.0\",\n"
"\"opencv_build_sha256\":\"" + hex_repeat(0xc1) + "\",\n"
"\"threads\":1,\n\"rng_seed\":1278432342,\n"
"\"optical_sha256\":\"" + optical + "\"\n}\n"))
return false;
if (!write_text(
fixture->campaign,
"L3DCAL_CAMPAIGN_STATE_V1\nexecution " +
std::to_string(fixture->execution_id) +
"\noptical_configuration " + std::to_string(fixture->configuration_id) +
"\noptical_state " + optical +
" body_objective_zoom_focus_stabilization_format_pipeline\n"
"capture 0 1\n"))
return false;
fixture->files = {fixture->session.c_str(), fixture->detection.c_str(),
fixture->solve.c_str(), fixture->evidence.c_str(),
fixture->producer.c_str(), fixture->campaign.c_str()};
return true;
}
bool make_fixture(Fixture *fixture, double holdout_rmse = 0.4) {
char temporary[] = "/tmp/lardon3d-workflow-ready-XXXXXX";
char *root = mkdtemp(temporary);
if (!root) return false;
fixture->root = root;
fixture->db_path = fixture->root / "project.db";
fixture->session = fixture->root / "session";
fixture->detection = fixture->root / "detection";
fixture->solve = fixture->root / "solve";
fixture->evidence = fixture->root / "evidence";
fixture->producer = fixture->root / "producer";
fixture->campaign = fixture->root / "campaign";
cv::Mat image(800, 1000, CV_8UC1, cv::Scalar(127));
if (!cv::imencode(".png", image, fixture->image_bytes)) return false;
unsigned char image_sha[32]{};
if (!digest(fixture->image_bytes.data(), fixture->image_bytes.size(), image_sha))
return false;
const std::string image_hex = hex(image_sha);
// Binding accepts only the canonical content-addressed managed-asset layout;
// the session view hashes are external evidence and are not Capture identity.
fixture->image_asset_path =
"assets/images/" + image_hex.substr(0, 2) + "/" + image_hex;
fixture->image_path = fixture->root / fixture->image_asset_path;
if (!std::filesystem::create_directories(fixture->image_path.parent_path()) ||
!write_bytes(fixture->image_path, fixture->image_bytes))
return false;
char error[LARDON3D_PROJECT_DB_ERROR_CAPACITY]{};
if (lardon3d_project_db_open(fixture->db_path.c_str(), &fixture->database,
error) != LARDON3D_PROJECT_DB_OK)
return false;
lardon3d_project_db_close(fixture->database);
fixture->database = nullptr;
if (!seed_database_rows(*fixture, image_sha)) return false;
if (lardon3d_project_db_open(fixture->db_path.c_str(), &fixture->database,
error) != LARDON3D_PROJECT_DB_OK)
return false;
if (!create_optical_configuration(fixture)) return false;
if (lardon3d_project_db_set_selected_capture_image(fixture->database, 1, 1) !=
LARDON3D_PROJECT_DB_OK)
return false;
Lardon3DProjectDbSelectedExecutionItem item{};
item.item_index = 0;
item.quality_group_id = 1;
item.campaign_group_id = 2;
item.capture_id = 1;
item.representation_source = LARDON3D_SELECTED_REPRESENTATION_SOURCE_IMAGE;
Lardon3DProjectDbSelectedExecution execution{};
if (lardon3d_project_db_create_selected_execution(
fixture->database, 1, 2, &item, 1, 10, &execution) !=
LARDON3D_PROJECT_DB_OK)
return false;
fixture->execution_id = execution.execution_id;
if (lardon3d_project_db_record_selected_representation(
fixture->database, fixture->execution_id, 0, 1, 1) !=
LARDON3D_PROJECT_DB_OK)
return false;
return write_external_inputs(fixture, holdout_rmse);
}
bool is_calibration_without_scope(const Fixture& fixture) {
Lardon3DProjectDbSelectedExecution execution{};
return lardon3d_project_db_load_selected_execution(
fixture.database, fixture.execution_id, &execution) ==
LARDON3D_PROJECT_DB_OK &&
execution.stage == LARDON3D_SELECTED_EXECUTION_CALIBRATION &&
!execution.has_calibration_scope && execution.calibration_scope_id == 0;
}
Lardon3DCalibrationWorkflowResult complete(
Fixture *fixture, Lardon3DCalibrationToolingView *views, size_t view_capacity,
Lardon3DCalibrationToolingCoordinateCheck *checks, size_t check_capacity,
Lardon3DCalibrationToolingEntry *entries, unsigned char *artifact,
size_t artifact_capacity, size_t *artifact_size,
Lardon3DCalibrationBootstrapOutput *output) {
return lardon3d_calibration_workflow_complete(
fixture->database, fixture->root.c_str(), &fixture->files, views,
view_capacity, checks, check_capacity, entries, 1, artifact,
artifact_capacity, artifact_size, output);
}
bool happy_path_and_exact_retry() {
Fixture fixture;
CHECK(make_fixture(&fixture));
CHECK(is_calibration_without_scope(fixture));
Lardon3DCalibrationToolingView views[kViewCount]{};
Lardon3DCalibrationToolingCoordinateCheck checks[kCoordinateCount]{};
Lardon3DCalibrationToolingEntry entries[1]{};
unsigned char artifact[LARDON3D_CALIBRATION_BOOTSTRAP_MAX_BYTES]{};
size_t artifact_size = 0;
Lardon3DCalibrationBootstrapOutput output{};
CHECK(complete(&fixture, views, kViewCount, checks, kCoordinateCount, entries,
artifact, sizeof(artifact), &artifact_size, &output) ==
LARDON3D_CALIBRATION_WORKFLOW_OK);
CHECK(artifact_size == 292 && output.calibration_count == 1 &&
output.scope.scope_id != 0 && output.scope.member_count == 1);
Lardon3DProjectDbSelectedExecution ready{};
CHECK(lardon3d_project_db_load_selected_execution(
fixture.database, fixture.execution_id, &ready) ==
LARDON3D_PROJECT_DB_OK);
CHECK(ready.stage == LARDON3D_SELECTED_EXECUTION_READY &&
ready.has_calibration_scope &&
ready.calibration_scope_id == output.scope.scope_id);
const std::vector<unsigned char> first_artifact(
artifact, artifact + artifact_size);
const Lardon3DCalibrationBootstrapOutput first_output = output;
std::memset(artifact, 0, sizeof(artifact));
artifact_size = 0;
std::memset(&output, 0, sizeof(output));
CHECK(complete(&fixture, views, kViewCount, checks, kCoordinateCount, entries,
artifact, sizeof(artifact), &artifact_size, &output) ==
LARDON3D_CALIBRATION_WORKFLOW_OK);
CHECK(artifact_size == first_artifact.size() &&
std::memcmp(artifact, first_artifact.data(), artifact_size) == 0);
CHECK(output.scope.scope_id == first_output.scope.scope_id &&
output.scope.member_count == first_output.scope.member_count &&
std::memcmp(output.scope.scientific_hash,
first_output.scope.scientific_hash, 32) == 0 &&
std::memcmp(output.artifact_sha256,
first_output.artifact_sha256, 32) == 0);
close_fixture(&fixture);
return true;
}
bool pre_import_failures_preserve_calibration() {
Fixture fixture;
CHECK(make_fixture(&fixture));
const std::string optical = hex_repeat(0x11);
CHECK(write_text(
fixture.campaign,
"L3DCAL_CAMPAIGN_STATE_V1\nexecution " +
std::to_string(fixture.execution_id + 1) + "\noptical_configuration " +
std::to_string(fixture.configuration_id) + "\noptical_state " + optical +
" body_objective_zoom_focus_stabilization_format_pipeline\n"
"capture 0 1\n"));
Lardon3DCalibrationToolingView views[kViewCount]{};
Lardon3DCalibrationToolingCoordinateCheck checks[kCoordinateCount]{};
Lardon3DCalibrationToolingEntry entries[1]{};
unsigned char artifact[292]{};
size_t artifact_size = 99;
Lardon3DCalibrationBootstrapOutput output{};
CHECK(complete(&fixture, views, kViewCount, checks, kCoordinateCount, entries,
artifact, sizeof(artifact), &artifact_size, &output) ==
LARDON3D_CALIBRATION_WORKFLOW_PROVENANCE_MISMATCH);
CHECK(artifact_size == 0 && output.scope.scope_id == 0 &&
is_calibration_without_scope(fixture));
close_fixture(&fixture);
CHECK(make_fixture(&fixture));
artifact_size = 99;
std::memset(&output, 0x7f, sizeof(output));
CHECK(complete(&fixture, views, kViewCount - 1, checks, kCoordinateCount,
entries, artifact, sizeof(artifact), &artifact_size, &output) ==
LARDON3D_CALIBRATION_WORKFLOW_CAPACITY);
CHECK(artifact_size == 0 && output.scope.scope_id == 0 &&
is_calibration_without_scope(fixture));
close_fixture(&fixture);
return true;
}
bool tooling_science_rejection_is_not_ready() {
Fixture fixture;
// The external bundle is structurally and provenance-valid, but 0.8 px is
// deliberately above Tooling's frozen hold-out RMSE acceptance threshold.
CHECK(make_fixture(&fixture, 0.8));
Lardon3DCalibrationToolingView views[kViewCount]{};
Lardon3DCalibrationToolingCoordinateCheck checks[kCoordinateCount]{};
Lardon3DCalibrationToolingEntry entries[1]{};
unsigned char artifact[292]{};
size_t artifact_size = 99;
Lardon3DCalibrationBootstrapOutput output{};
CHECK(complete(&fixture, views, kViewCount, checks, kCoordinateCount, entries,
artifact, sizeof(artifact), &artifact_size, &output) ==
LARDON3D_CALIBRATION_WORKFLOW_MALFORMED_EVIDENCE);
CHECK(artifact_size == 0 && output.scope.scope_id == 0 &&
is_calibration_without_scope(fixture));
close_fixture(&fixture);
return true;
}
} // namespace
int main() {
if (!happy_path_and_exact_retry() ||
!pre_import_failures_preserve_calibration() ||
!tooling_science_rejection_is_not_ready())
return 1;
std::puts("CALIBRATION_WORKFLOW_READY_V1=PASS");
return 0;
}