amduat/tests/asl/test_asl_derivation_index_fs.c

228 lines
5.8 KiB
C
Raw Normal View History

2026-01-18 07:27:48 +01:00
#include "amduat/asl/asl_derivation_index_fs.h"
#include <dirent.h>
#include <errno.h>
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
static char *make_temp_root(void) {
char *templ;
const char template_prefix[] =
"/tmp/amduat_test_asl_derivation_index_fs_XXXXXX";
templ = (char *)malloc(sizeof(template_prefix));
if (templ == NULL) {
return NULL;
}
memcpy(templ, template_prefix, sizeof(template_prefix));
if (mkdtemp(templ) == NULL) {
free(templ);
return NULL;
}
return templ;
}
static bool remove_tree(const char *path) {
DIR *dir;
struct dirent *entry;
struct stat st;
if (path == NULL) {
return false;
}
if (lstat(path, &st) != 0) {
return errno == ENOENT;
}
if (!S_ISDIR(st.st_mode)) {
return unlink(path) == 0;
}
dir = opendir(path);
if (dir == NULL) {
return false;
}
while ((entry = readdir(dir)) != NULL) {
char child[2048];
if (strcmp(entry->d_name, ".") == 0 ||
strcmp(entry->d_name, "..") == 0) {
continue;
}
snprintf(child, sizeof(child), "%s/%s", path, entry->d_name);
if (!remove_tree(child)) {
closedir(dir);
return false;
}
}
closedir(dir);
return rmdir(path) == 0;
}
static amduat_reference_t make_ref(uint8_t seed, size_t len) {
uint8_t *bytes = (uint8_t *)malloc(len);
if (bytes == NULL) {
return amduat_reference(0u, amduat_octets(NULL, 0u));
}
for (size_t i = 0; i < len; ++i) {
bytes[i] = (uint8_t)(seed + i);
}
2026-01-18 07:36:59 +01:00
return amduat_reference(0x1234u, amduat_octets(bytes, len));
2026-01-18 07:27:48 +01:00
}
static int test_round_trip(void) {
amduat_asl_derivation_index_fs_t index;
amduat_asl_derivation_record_t record;
amduat_asl_derivation_record_t record2;
amduat_asl_derivation_record_t *records = NULL;
size_t records_len = 0u;
amduat_reference_t artifact_ref;
amduat_reference_t inputs[2];
uint8_t sid_bytes[32];
uint8_t exec_bytes[4] = {0x01, 0x02, 0x03, 0x04};
char *root;
int exit_code = 1;
root = make_temp_root();
if (root == NULL) {
fprintf(stderr, "temp root failed\n");
return 1;
}
if (!amduat_asl_derivation_index_fs_init(&index, root)) {
fprintf(stderr, "index init failed\n");
goto cleanup;
}
artifact_ref = make_ref(0x10, 4);
record.program_ref = make_ref(0x20, 4);
inputs[0] = make_ref(0x30, 4);
inputs[1] = make_ref(0x40, 4);
memset(sid_bytes, 0xa5, sizeof(sid_bytes));
record.sid = amduat_octets(sid_bytes, sizeof(sid_bytes));
record.input_refs = inputs;
record.input_refs_len = 2u;
record.has_params_ref = true;
record.params_ref = make_ref(0x50, 4);
record.has_exec_profile = true;
record.exec_profile = amduat_octets(exec_bytes, sizeof(exec_bytes));
record2 = record;
record2.sid = amduat_octets(sid_bytes, sizeof(sid_bytes));
record2.has_params_ref = false;
record2.has_exec_profile = false;
2026-01-18 07:36:59 +01:00
{
amduat_asl_store_error_t err =
amduat_asl_derivation_index_fs_add(&index, artifact_ref, &record);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "add record failed: %d\n", err);
goto cleanup_records;
}
2026-01-18 07:27:48 +01:00
}
2026-01-18 07:36:59 +01:00
{
amduat_asl_store_error_t err =
amduat_asl_derivation_index_fs_add(&index, artifact_ref, &record2);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "add record2 failed: %d\n", err);
goto cleanup_records;
}
2026-01-18 07:27:48 +01:00
}
if (amduat_asl_derivation_index_fs_list(&index,
artifact_ref,
&records,
&records_len) !=
AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "list failed\n");
goto cleanup_records;
}
if (records_len != 2u) {
fprintf(stderr, "record count mismatch\n");
goto cleanup_records_list;
}
if (records[0].input_refs_len != 2u ||
records[0].has_params_ref != true ||
records[0].has_exec_profile != true) {
fprintf(stderr, "record fields mismatch\n");
goto cleanup_records_list;
}
if (records[1].has_params_ref != false ||
records[1].has_exec_profile != false) {
fprintf(stderr, "record2 flags mismatch\n");
goto cleanup_records_list;
}
exit_code = 0;
cleanup_records_list:
amduat_asl_derivation_records_free(records, records_len);
free(records);
cleanup_records:
amduat_reference_free(&artifact_ref);
amduat_reference_free(&record.program_ref);
amduat_reference_free(&record.params_ref);
amduat_reference_free(&inputs[0]);
amduat_reference_free(&inputs[1]);
cleanup:
if (!remove_tree(root)) {
fprintf(stderr, "cleanup failed\n");
exit_code = 1;
}
free(root);
return exit_code;
}
static int test_not_found(void) {
amduat_asl_derivation_index_fs_t index;
amduat_reference_t artifact_ref;
amduat_asl_derivation_record_t *records = NULL;
size_t records_len = 0u;
char *root;
int exit_code = 1;
root = make_temp_root();
if (root == NULL) {
fprintf(stderr, "temp root failed\n");
return 1;
}
if (!amduat_asl_derivation_index_fs_init(&index, root)) {
fprintf(stderr, "index init failed\n");
goto cleanup;
}
artifact_ref = make_ref(0x70, 4);
if (amduat_asl_derivation_index_fs_list(&index,
artifact_ref,
&records,
&records_len) !=
AMDUAT_ASL_STORE_ERR_NOT_FOUND) {
fprintf(stderr, "expected not found\n");
amduat_reference_free(&artifact_ref);
goto cleanup;
}
amduat_reference_free(&artifact_ref);
exit_code = 0;
cleanup:
if (!remove_tree(root)) {
fprintf(stderr, "cleanup failed\n");
exit_code = 1;
}
free(root);
return exit_code;
}
int main(void) {
if (test_round_trip() != 0) {
return 1;
}
return test_not_found();
}