Add derivation index CLI

This commit is contained in:
Carl Niklas Rydberg 2026-01-18 07:27:48 +01:00
parent 8c5fa71388
commit 1d04c32401
5 changed files with 1779 additions and 2 deletions

View file

@ -133,6 +133,10 @@ set(AMDUAT_ASL_STORE_INDEX_FS_SRCS
src/adapters/asl_store_index_fs/asl_store_index_fs_layout.c
)
set(AMDUAT_ASL_DERIVATION_INDEX_FS_SRCS
src/adapters/asl_derivation_index_fs/asl_derivation_index_fs.c
)
set(AMDUAT_TGK_STORE_MEM_SRCS
src/adapters/tgk_store_mem/tgk_store_mem.c
)
@ -173,6 +177,10 @@ amduat_add_lib(asl_store_index_fs SRCS ${AMDUAT_ASL_STORE_INDEX_FS_SRCS})
amduat_link(asl_store_index_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
target_compile_definitions(amduat_asl_store_index_fs_obj PRIVATE _POSIX_C_SOURCE=200809L)
amduat_add_lib(asl_derivation_index_fs SRCS ${AMDUAT_ASL_DERIVATION_INDEX_FS_SRCS})
amduat_link(asl_derivation_index_fs amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
target_compile_definitions(amduat_asl_derivation_index_fs_obj PRIVATE _POSIX_C_SOURCE=200809L)
amduat_add_lib(tgk_store_mem SRCS ${AMDUAT_TGK_STORE_MEM_SRCS})
amduat_link(tgk_store_mem amduat_tgk amduat_asl amduat_enc amduat_hash_asl1 amduat_util)
@ -192,7 +200,7 @@ target_include_directories(amduat_asl_cli
)
target_link_libraries(amduat_asl_cli
PRIVATE amduat_format amduat_asl_store_fs amduat_asl_store_index_fs
amduat_asl amduat_enc
amduat_asl_derivation_index_fs amduat_asl amduat_enc
amduat_hash_asl1 amduat_util
)
set_target_properties(amduat_asl_cli PROPERTIES OUTPUT_NAME amduat-asl)
@ -431,6 +439,21 @@ target_link_libraries(amduat_test_asl_index_accel
)
add_test(NAME asl_index_accel COMMAND amduat_test_asl_index_accel)
add_executable(amduat_test_asl_derivation_index_fs
tests/asl/test_asl_derivation_index_fs.c)
target_include_directories(amduat_test_asl_derivation_index_fs
PRIVATE ${AMDUAT_INTERNAL_DIR}
PRIVATE ${AMDUAT_INCLUDE_DIR}
)
target_compile_definitions(amduat_test_asl_derivation_index_fs
PRIVATE _POSIX_C_SOURCE=200809L
)
target_link_libraries(amduat_test_asl_derivation_index_fs
PRIVATE amduat_asl_derivation_index_fs
)
add_test(NAME asl_derivation_index_fs
COMMAND amduat_test_asl_derivation_index_fs)
add_executable(amduat_test_pel_program_dag_exec
tests/pel/test_pel_program_dag_exec.c)
target_include_directories(amduat_test_pel_program_dag_exec

View file

@ -0,0 +1,58 @@
#ifndef AMDUAT_ASL_DERIVATION_INDEX_FS_H
#define AMDUAT_ASL_DERIVATION_INDEX_FS_H
#include "amduat/asl/core.h"
#include "amduat/asl/store.h"
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
extern "C" {
#endif
enum { AMDUAT_ASL_DERIVATION_INDEX_FS_ROOT_MAX = 1024 };
typedef struct {
amduat_octets_t sid;
amduat_reference_t program_ref;
amduat_reference_t *input_refs;
size_t input_refs_len;
bool has_params_ref;
amduat_reference_t params_ref;
bool has_exec_profile;
amduat_octets_t exec_profile;
} amduat_asl_derivation_record_t;
typedef struct {
char root_path[AMDUAT_ASL_DERIVATION_INDEX_FS_ROOT_MAX];
} amduat_asl_derivation_index_fs_t;
bool amduat_asl_derivation_index_fs_init(
amduat_asl_derivation_index_fs_t *index,
const char *root_path);
amduat_asl_store_error_t amduat_asl_derivation_index_fs_add(
amduat_asl_derivation_index_fs_t *index,
amduat_reference_t artifact_ref,
const amduat_asl_derivation_record_t *record);
amduat_asl_store_error_t amduat_asl_derivation_index_fs_list(
amduat_asl_derivation_index_fs_t *index,
amduat_reference_t artifact_ref,
amduat_asl_derivation_record_t **out_records,
size_t *out_count);
void amduat_asl_derivation_record_free(
amduat_asl_derivation_record_t *record);
void amduat_asl_derivation_records_free(
amduat_asl_derivation_record_t *records,
size_t count);
#ifdef __cplusplus
} /* extern "C" */
#endif
#endif /* AMDUAT_ASL_DERIVATION_INDEX_FS_H */

File diff suppressed because it is too large Load diff

View file

@ -5,6 +5,7 @@
#include "amduat/asl/parse.h"
#include "amduat/asl/ref_io.h"
#include "amduat/asl/ref_text.h"
#include "amduat/asl/asl_derivation_index_fs.h"
#include "amduat/asl/asl_store_index_fs.h"
#include "amduat/asl/store.h"
#include "amduat/enc/asl1_core.h"
@ -14,6 +15,7 @@
#include "amduat/format/parse.h"
#include "amduat/format/ref.h"
#include "amduat/hash/asl1.h"
#include "amduat/util/hex.h"
#include <dirent.h>
#include <errno.h>
#include <inttypes.h>
@ -96,6 +98,13 @@ static void amduat_asl_cli_print_usage(FILE *stream) {
" [--output-format raw|artifact]\n"
" [--expect-type-tag TAG] [--print-type-tag]\n"
" [--quiet]\n"
" amduat-asl derivations add --artifact-ref REF --sid SID\n"
" --program-ref REF [--input-ref REF...]\n"
" [--params-ref REF] [--exec-profile PATH|-]\n"
" [--root PATH] [--ref-format hex|bytes]\n"
" [--sid-format hex|bytes]\n"
" amduat-asl derivations list --artifact-ref REF [--root PATH]\n"
" [--ref-format hex|bytes]\n"
" amduat-asl log inspect [--root PATH]\n"
" amduat-asl index init [--root PATH] [--store-id ID]\n"
" [--profile PROFILE_ID|name]\n"
@ -113,7 +122,8 @@ static void amduat_asl_cli_print_usage(FILE *stream) {
" --ref-format hex\n"
"\n"
"notes:\n"
" --ref-format bytes expects --ref as a path or -\n",
" --ref-format bytes expects refs as paths or -\n"
" derivations list outputs refs/sid in hex\n",
AMDUAT_ASL_CLI_DEFAULT_ROOT);
}
@ -126,6 +136,71 @@ static void amduat_asl_cli_free_reference(amduat_reference_t *ref) {
ref->digest.len = 0u;
}
static bool amduat_asl_cli_decode_ref_arg(amduat_format_ref_format_t fmt,
const char *arg,
amduat_reference_t *out_ref) {
uint8_t *ref_bytes;
size_t ref_len;
if (arg == NULL || out_ref == NULL) {
return false;
}
memset(out_ref, 0, sizeof(*out_ref));
if (fmt == AMDUAT_FORMAT_REF_HEX) {
return amduat_asl_ref_decode_format(
fmt, amduat_octets(arg, strlen(arg)), out_ref);
}
ref_bytes = NULL;
ref_len = 0u;
if (!amduat_asl_read_path(arg, &ref_bytes, &ref_len)) {
return false;
}
if (!amduat_asl_ref_decode_format(
fmt, amduat_octets(ref_bytes, ref_len), out_ref)) {
free(ref_bytes);
return false;
}
free(ref_bytes);
return true;
}
static bool amduat_asl_cli_read_sid(const char *arg,
bool sid_is_hex,
amduat_octets_t *out_sid) {
uint8_t *bytes;
size_t len;
const char *text;
if (arg == NULL || out_sid == NULL) {
return false;
}
*out_sid = amduat_octets(NULL, 0u);
if (!sid_is_hex) {
bytes = NULL;
len = 0u;
if (!amduat_asl_read_path(arg, &bytes, &len)) {
return false;
}
*out_sid = amduat_octets(bytes, len);
return true;
}
text = arg;
if (text[0] == '0' && (text[1] == 'x' || text[1] == 'X')) {
text += 2;
}
bytes = NULL;
len = 0u;
if (!amduat_hex_decode_alloc(text, &bytes, &len)) {
return false;
}
*out_sid = amduat_octets(bytes, len);
return true;
}
static void amduat_asl_cli_print_store_meta(
const amduat_asl_store_fs_config_t *cfg) {
if (cfg == NULL) {
@ -1212,6 +1287,374 @@ static int amduat_asl_cli_cmd_get(int argc, char **argv) {
return exit_code;
}
static int amduat_asl_cli_cmd_derivations_add(int argc, char **argv) {
const char *root = AMDUAT_ASL_CLI_DEFAULT_ROOT;
const char *artifact_ref_arg = NULL;
const char *sid_arg = NULL;
const char *program_ref_arg = NULL;
const char *params_ref_arg = NULL;
const char *exec_profile_path = NULL;
amduat_format_ref_format_t ref_format = AMDUAT_FORMAT_REF_HEX;
bool sid_is_hex = true;
const char **input_args = NULL;
size_t input_len = 0u;
int exit_code = AMDUAT_ASL_CLI_EXIT_OK;
int i;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
root = argv[++i];
} else if (strcmp(argv[i], "--artifact-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --artifact-ref requires a value\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
artifact_ref_arg = argv[++i];
} else if (strcmp(argv[i], "--sid") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --sid requires a value\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
sid_arg = argv[++i];
} else if (strcmp(argv[i], "--program-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --program-ref requires a value\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
program_ref_arg = argv[++i];
} else if (strcmp(argv[i], "--input-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --input-ref requires a value\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
const char *val = argv[++i];
const char **next =
(const char **)realloc(input_args,
(input_len + 1u) * sizeof(*input_args));
if (next == NULL) {
free(input_args);
fprintf(stderr, "error: out of memory\n");
return AMDUAT_ASL_CLI_EXIT_IO;
}
input_args = next;
input_args[input_len++] = val;
} else if (strcmp(argv[i], "--params-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --params-ref requires a value\n");
free(input_args);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
params_ref_arg = argv[++i];
} else if (strcmp(argv[i], "--exec-profile") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --exec-profile requires a path or -\n");
free(input_args);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
exec_profile_path = argv[++i];
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
free(input_args);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
if (!amduat_format_ref_parse(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
free(input_args);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--sid-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --sid-format requires a value\n");
free(input_args);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
const char *fmt = argv[++i];
if (strcmp(fmt, "hex") == 0) {
sid_is_hex = true;
} else if (strcmp(fmt, "bytes") == 0) {
sid_is_hex = false;
} else {
fprintf(stderr, "error: invalid sid-format\n");
free(input_args);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
free(input_args);
amduat_asl_cli_print_usage(stdout);
return AMDUAT_ASL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
free(input_args);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
}
if (artifact_ref_arg == NULL || sid_arg == NULL || program_ref_arg == NULL) {
fprintf(stderr,
"error: --artifact-ref, --sid, and --program-ref are required\n");
free(input_args);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
{
amduat_asl_derivation_index_fs_t index;
amduat_asl_derivation_record_t record;
amduat_reference_t artifact_ref;
amduat_reference_t program_ref;
amduat_reference_t params_ref;
amduat_reference_t *inputs = NULL;
uint8_t *exec_bytes = NULL;
size_t exec_len = 0u;
size_t j;
if (!amduat_asl_derivation_index_fs_init(&index, root)) {
fprintf(stderr, "error: invalid root path\n");
exit_code = AMDUAT_ASL_CLI_EXIT_CONFIG;
goto cleanup_inputs;
}
if (!amduat_asl_cli_decode_ref_arg(ref_format, artifact_ref_arg,
&artifact_ref)) {
fprintf(stderr, "error: invalid artifact ref\n");
exit_code = AMDUAT_ASL_CLI_EXIT_CODEC;
goto cleanup_inputs;
}
if (!amduat_asl_cli_decode_ref_arg(ref_format, program_ref_arg,
&program_ref)) {
fprintf(stderr, "error: invalid program ref\n");
amduat_asl_cli_free_reference(&artifact_ref);
exit_code = AMDUAT_ASL_CLI_EXIT_CODEC;
goto cleanup_inputs;
}
if (input_len != 0u) {
inputs = (amduat_reference_t *)calloc(input_len, sizeof(*inputs));
if (inputs == NULL) {
fprintf(stderr, "error: out of memory\n");
amduat_asl_cli_free_reference(&artifact_ref);
amduat_asl_cli_free_reference(&program_ref);
exit_code = AMDUAT_ASL_CLI_EXIT_IO;
goto cleanup_inputs;
}
for (j = 0u; j < input_len; ++j) {
if (!amduat_asl_cli_decode_ref_arg(ref_format, input_args[j],
&inputs[j])) {
fprintf(stderr, "error: invalid input ref\n");
amduat_asl_cli_free_reference(&artifact_ref);
amduat_asl_cli_free_reference(&program_ref);
exit_code = AMDUAT_ASL_CLI_EXIT_CODEC;
goto cleanup_decoded;
}
}
}
memset(&record, 0, sizeof(record));
if (!amduat_asl_cli_read_sid(sid_arg, sid_is_hex, &record.sid)) {
fprintf(stderr, "error: invalid sid\n");
amduat_asl_cli_free_reference(&artifact_ref);
amduat_asl_cli_free_reference(&program_ref);
exit_code = AMDUAT_ASL_CLI_EXIT_CODEC;
goto cleanup_decoded;
}
record.program_ref = program_ref;
record.input_refs = inputs;
record.input_refs_len = input_len;
record.has_params_ref = false;
if (params_ref_arg != NULL) {
if (!amduat_asl_cli_decode_ref_arg(ref_format, params_ref_arg,
&params_ref)) {
fprintf(stderr, "error: invalid params ref\n");
exit_code = AMDUAT_ASL_CLI_EXIT_CODEC;
goto cleanup_record;
}
record.has_params_ref = true;
record.params_ref = params_ref;
}
record.has_exec_profile = false;
if (exec_profile_path != NULL) {
if (!amduat_asl_read_path(exec_profile_path, &exec_bytes, &exec_len)) {
fprintf(stderr, "error: failed to read exec profile\n");
exit_code = AMDUAT_ASL_CLI_EXIT_IO;
goto cleanup_record;
}
record.has_exec_profile = true;
record.exec_profile = amduat_octets(exec_bytes, exec_len);
}
{
amduat_asl_store_error_t err =
amduat_asl_derivation_index_fs_add(&index, artifact_ref, &record);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "error: derivation add failed: %s\n",
amduat_asl_cli_store_error_str(err));
exit_code = amduat_asl_cli_map_store_error(err);
}
}
cleanup_record:
amduat_octets_free(&record.sid);
if (record.has_params_ref) {
amduat_asl_cli_free_reference(&record.params_ref);
}
if (record.has_exec_profile) {
free(exec_bytes);
}
for (j = 0u; j < input_len; ++j) {
amduat_asl_cli_free_reference(&inputs[j]);
}
amduat_asl_cli_free_reference(&program_ref);
amduat_asl_cli_free_reference(&artifact_ref);
cleanup_decoded:
free(inputs);
cleanup_inputs:
free(input_args);
}
return exit_code;
}
static int amduat_asl_cli_cmd_derivations_list(int argc, char **argv) {
const char *root = AMDUAT_ASL_CLI_DEFAULT_ROOT;
const char *artifact_ref_arg = NULL;
amduat_format_ref_format_t ref_format = AMDUAT_FORMAT_REF_HEX;
int i;
for (i = 0; i < argc; ++i) {
if (strcmp(argv[i], "--root") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --root requires a path\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
root = argv[++i];
} else if (strcmp(argv[i], "--artifact-ref") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --artifact-ref requires a value\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
artifact_ref_arg = argv[++i];
} else if (strcmp(argv[i], "--ref-format") == 0) {
if (i + 1 >= argc) {
fprintf(stderr, "error: --ref-format requires a value\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
if (!amduat_format_ref_parse(argv[++i], &ref_format)) {
fprintf(stderr, "error: invalid ref-format\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
} else if (strcmp(argv[i], "--help") == 0 || strcmp(argv[i], "-h") == 0) {
amduat_asl_cli_print_usage(stdout);
return AMDUAT_ASL_CLI_EXIT_OK;
} else {
fprintf(stderr, "error: unknown option: %s\n", argv[i]);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
}
if (artifact_ref_arg == NULL) {
fprintf(stderr, "error: --artifact-ref is required\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
{
amduat_asl_derivation_index_fs_t index;
amduat_reference_t artifact_ref;
amduat_asl_derivation_record_t *records = NULL;
size_t records_len = 0u;
size_t j;
amduat_asl_store_error_t err;
if (!amduat_asl_derivation_index_fs_init(&index, root)) {
fprintf(stderr, "error: invalid root path\n");
return AMDUAT_ASL_CLI_EXIT_CONFIG;
}
if (!amduat_asl_cli_decode_ref_arg(ref_format, artifact_ref_arg,
&artifact_ref)) {
fprintf(stderr, "error: invalid artifact ref\n");
return AMDUAT_ASL_CLI_EXIT_CODEC;
}
err = amduat_asl_derivation_index_fs_list(&index,
artifact_ref,
&records,
&records_len);
if (err != AMDUAT_ASL_STORE_OK) {
fprintf(stderr, "error: derivation list failed: %s\n",
amduat_asl_cli_store_error_str(err));
amduat_asl_cli_free_reference(&artifact_ref);
return amduat_asl_cli_map_store_error(err);
}
for (j = 0u; j < records_len; ++j) {
char *sid_hex = NULL;
char *prog_hex = NULL;
char *params_hex = NULL;
char *exec_hex = NULL;
size_t k;
(void)amduat_hex_encode_alloc(records[j].sid.data,
records[j].sid.len,
&sid_hex);
(void)amduat_asl_ref_encode_hex(records[j].program_ref, &prog_hex);
if (records[j].has_params_ref) {
(void)amduat_asl_ref_encode_hex(records[j].params_ref, &params_hex);
}
if (records[j].has_exec_profile) {
(void)amduat_hex_encode_alloc(records[j].exec_profile.data,
records[j].exec_profile.len,
&exec_hex);
}
printf("sid=%s program=%s inputs=",
sid_hex == NULL ? "(null)" : sid_hex,
prog_hex == NULL ? "(null)" : prog_hex);
for (k = 0u; k < records[j].input_refs_len; ++k) {
char *input_hex = NULL;
(void)amduat_asl_ref_encode_hex(records[j].input_refs[k], &input_hex);
printf("%s%s",
k == 0u ? "" : ",",
input_hex == NULL ? "(null)" : input_hex);
free(input_hex);
}
printf(" params=%s exec_profile=%s\n",
params_hex == NULL ? "-" : params_hex,
exec_hex == NULL ? "-" : exec_hex);
free(exec_hex);
free(params_hex);
free(prog_hex);
free(sid_hex);
}
amduat_asl_derivation_records_free(records, records_len);
free(records);
amduat_asl_cli_free_reference(&artifact_ref);
}
return AMDUAT_ASL_CLI_EXIT_OK;
}
static int amduat_asl_cli_cmd_derivations(int argc, char **argv) {
if (argc < 1) {
fprintf(stderr, "error: derivations command requires a subcommand\n");
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
if (strcmp(argv[0], "add") == 0) {
return amduat_asl_cli_cmd_derivations_add(argc - 1, argv + 1);
}
if (strcmp(argv[0], "list") == 0) {
return amduat_asl_cli_cmd_derivations_list(argc - 1, argv + 1);
}
fprintf(stderr, "error: unknown derivations command: %s\n", argv[0]);
return AMDUAT_ASL_CLI_EXIT_USAGE;
}
static int amduat_asl_cli_cmd_log(int argc, char **argv) {
const char *root;
uint8_t *log_bytes;
@ -1706,6 +2149,9 @@ int main(int argc, char **argv) {
if (strcmp(argv[1], "get") == 0) {
return amduat_asl_cli_cmd_get(argc - 2, argv + 2);
}
if (strcmp(argv[1], "derivations") == 0) {
return amduat_asl_cli_cmd_derivations(argc - 2, argv + 2);
}
if (strcmp(argv[1], "log") == 0) {
return amduat_asl_cli_cmd_log(argc - 2, argv + 2);
}

View file

@ -0,0 +1,221 @@
#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(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();
}