#include "amduat/asl/asl_derivation_index_fs.h" #include #include #include #include #include #include #include #include #include #include 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); } return amduat_reference(0x0001u, amduat_octets(bytes, len)); } 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; if (amduat_asl_derivation_index_fs_add(&index, artifact_ref, &record) != AMDUAT_ASL_STORE_OK) { fprintf(stderr, "add record failed\n"); goto cleanup_records; } if (amduat_asl_derivation_index_fs_add(&index, artifact_ref, &record2) != AMDUAT_ASL_STORE_OK) { fprintf(stderr, "add record2 failed\n"); goto cleanup_records; } 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(); }