232 lines
5.9 KiB
C
232 lines
5.9 KiB
C
#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);
|
|
}
|
|
return amduat_reference(0x1234u, 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);
|
|
record.output_index = 0u;
|
|
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.output_index = 1u;
|
|
record2.has_params_ref = false;
|
|
record2.has_exec_profile = false;
|
|
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
{
|
|
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;
|
|
}
|
|
}
|
|
|
|
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 ||
|
|
records[0].output_index != 0u) {
|
|
fprintf(stderr, "record fields mismatch\n");
|
|
goto cleanup_records_list;
|
|
}
|
|
if (records[1].has_params_ref != false ||
|
|
records[1].has_exec_profile != false ||
|
|
records[1].output_index != 1u) {
|
|
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();
|
|
}
|