#ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L #endif #include "amduatd_space_manifest.h" #include "amduatd_space.h" #include "amduatd_store.h" #include "amduat/asl/asl_store_fs_meta.h" #include "amduat/asl/asl_pointer_fs.h" #include "amduat/asl/record.h" #include "amduat/asl/ref_text.h" #include "amduat/hash/asl1.h" #include #include #include #include static int failures = 0; static void expect(bool cond, const char *msg) { if (!cond) { fprintf(stderr, "FAIL: %s\n", msg); failures++; } } static char *amduatd_test_make_temp_dir(void) { char tmpl[] = "/tmp/amduatd-space-manifest-XXXXXX"; char *dir = mkdtemp(tmpl); size_t len; char *copy; if (dir == NULL) { perror("mkdtemp"); return NULL; } len = strlen(dir); copy = (char *)malloc(len + 1u); if (copy == NULL) { fprintf(stderr, "failed to allocate temp dir copy\n"); return NULL; } memcpy(copy, dir, len + 1u); return copy; } static bool amduatd_make_test_ref(uint8_t fill, amduat_reference_t *out_ref) { uint8_t digest_bytes[32]; amduat_octets_t digest; if (out_ref == NULL) { return false; } memset(digest_bytes, fill, sizeof(digest_bytes)); if (!amduat_octets_clone(amduat_octets(digest_bytes, sizeof(digest_bytes)), &digest)) { return false; } *out_ref = amduat_reference(AMDUAT_HASH_ASL1_ID_SHA256, digest); return true; } static int amduatd_test_manifest_missing(void) { char *root = amduatd_test_make_temp_dir(); amduat_asl_store_fs_config_t cfg; amduatd_store_ctx_t store_ctx; amduat_asl_store_t store; amduat_asl_pointer_store_t pointer_store; amduatd_space_t space; amduatd_space_manifest_t manifest; amduat_reference_t ref; amduatd_space_manifest_status_t status; if (root == NULL) { return 1; } memset(&cfg, 0, sizeof(cfg)); if (!amduat_asl_store_fs_init_root(root, NULL, &cfg)) { fprintf(stderr, "failed to init store root\n"); free(root); return 1; } memset(&store_ctx, 0, sizeof(store_ctx)); memset(&store, 0, sizeof(store)); if (!amduatd_store_init(&store, &cfg, &store_ctx, root, AMDUATD_STORE_BACKEND_FS)) { fprintf(stderr, "failed to init store\n"); free(root); return 1; } if (!amduat_asl_pointer_store_init(&pointer_store, root)) { fprintf(stderr, "failed to init pointer store\n"); free(root); return 1; } if (!amduatd_space_init(&space, "alpha", false)) { fprintf(stderr, "failed to init space\n"); free(root); return 1; } memset(&manifest, 0, sizeof(manifest)); memset(&ref, 0, sizeof(ref)); status = amduatd_space_manifest_get(&store, &pointer_store, &space, &ref, &manifest); expect(status == AMDUATD_SPACE_MANIFEST_ERR_NOT_FOUND, "missing manifest returns not found"); amduatd_space_manifest_free(&manifest); amduat_reference_free(&ref); free(root); return failures == 0 ? 0 : 1; } static int amduatd_test_manifest_decode(void) { char *root = amduatd_test_make_temp_dir(); amduat_asl_store_fs_config_t cfg; amduatd_store_ctx_t store_ctx; amduat_asl_store_t store; amduat_asl_pointer_store_t pointer_store; amduatd_space_t space; amduat_reference_t pinned_ref; char *pinned_hex = NULL; char payload[512]; amduat_reference_t record_ref; amduat_octets_t pointer_name = amduat_octets(NULL, 0u); bool swapped = false; amduatd_space_manifest_t manifest; amduat_reference_t fetched_ref; amduatd_space_manifest_status_t status; if (root == NULL) { return 1; } memset(&cfg, 0, sizeof(cfg)); if (!amduat_asl_store_fs_init_root(root, NULL, &cfg)) { fprintf(stderr, "failed to init store root\n"); free(root); return 1; } memset(&store_ctx, 0, sizeof(store_ctx)); memset(&store, 0, sizeof(store)); if (!amduatd_store_init(&store, &cfg, &store_ctx, root, AMDUATD_STORE_BACKEND_FS)) { fprintf(stderr, "failed to init store\n"); free(root); return 1; } if (!amduat_asl_pointer_store_init(&pointer_store, root)) { fprintf(stderr, "failed to init pointer store\n"); free(root); return 1; } if (!amduatd_space_init(&space, "alpha", false)) { fprintf(stderr, "failed to init space\n"); free(root); return 1; } if (!amduatd_make_test_ref(0x11, &pinned_ref)) { fprintf(stderr, "failed to make pinned ref\n"); free(root); return 1; } if (!amduat_asl_ref_encode_hex(pinned_ref, &pinned_hex)) { fprintf(stderr, "failed to encode pinned ref\n"); amduat_reference_free(&pinned_ref); free(root); return 1; } { int n = snprintf( payload, sizeof(payload), "{" "\"version\":1," "\"mounts\":[" "{\"name\":\"beta\",\"peer_key\":\"peer-2\",\"space_id\":\"zeta\"," "\"mode\":\"track\"}," "{\"name\":\"alpha\",\"peer_key\":\"peer-1\",\"space_id\":\"zeta\"," "\"mode\":\"pinned\",\"pinned_root_ref\":\"%s\"}," "{\"name\":\"alpha\",\"peer_key\":\"peer-1\",\"space_id\":\"beta\"," "\"mode\":\"track\"}" "]" "}", pinned_hex); if (n <= 0 || (size_t)n >= sizeof(payload)) { fprintf(stderr, "failed to build manifest payload\n"); free(pinned_hex); amduat_reference_free(&pinned_ref); free(root); return 1; } } free(pinned_hex); if (amduat_asl_record_store_put( &store, amduat_octets(AMDUATD_SPACE_MANIFEST_1, strlen(AMDUATD_SPACE_MANIFEST_1)), amduat_octets((const uint8_t *)payload, strlen(payload)), &record_ref) != AMDUAT_ASL_STORE_OK) { fprintf(stderr, "failed to store manifest record\n"); amduat_reference_free(&pinned_ref); free(root); return 1; } if (!amduatd_space_scope_name(&space, "manifest/head", &pointer_name)) { fprintf(stderr, "failed to build manifest pointer name\n"); amduat_reference_free(&record_ref); amduat_reference_free(&pinned_ref); free(root); return 1; } if (amduat_asl_pointer_cas(&pointer_store, (const char *)pointer_name.data, false, NULL, &record_ref, &swapped) != AMDUAT_ASL_POINTER_OK || !swapped) { fprintf(stderr, "failed to set manifest pointer\n"); amduat_octets_free(&pointer_name); amduat_reference_free(&record_ref); amduat_reference_free(&pinned_ref); free(root); return 1; } amduat_octets_free(&pointer_name); memset(&manifest, 0, sizeof(manifest)); memset(&fetched_ref, 0, sizeof(fetched_ref)); status = amduatd_space_manifest_get(&store, &pointer_store, &space, &fetched_ref, &manifest); expect(status == AMDUATD_SPACE_MANIFEST_OK, "manifest get ok"); expect(amduat_reference_eq(fetched_ref, record_ref), "manifest ref matches pointer"); expect(manifest.version == 1u, "manifest version ok"); expect(manifest.mounts_len == 3u, "manifest mounts count"); if (manifest.mounts_len == 3u) { expect(strcmp(manifest.mounts[0].name, "alpha") == 0, "mount 0 name"); expect(strcmp(manifest.mounts[0].peer_key, "peer-1") == 0, "mount 0 peer"); expect(strcmp(manifest.mounts[0].space_id, "beta") == 0, "mount 0 space"); expect(manifest.mounts[0].mode == AMDUATD_SPACE_MANIFEST_MOUNT_TRACK, "mount 0 mode"); expect(strcmp(manifest.mounts[1].name, "alpha") == 0, "mount 1 name"); expect(strcmp(manifest.mounts[1].peer_key, "peer-1") == 0, "mount 1 peer"); expect(strcmp(manifest.mounts[1].space_id, "zeta") == 0, "mount 1 space"); expect(manifest.mounts[1].mode == AMDUATD_SPACE_MANIFEST_MOUNT_PINNED, "mount 1 mode"); expect(manifest.mounts[1].has_pinned_root_ref, "mount 1 pinned ref present"); expect(amduat_reference_eq(manifest.mounts[1].pinned_root_ref, pinned_ref), "mount 1 pinned ref"); expect(strcmp(manifest.mounts[2].name, "beta") == 0, "mount 2 name"); expect(strcmp(manifest.mounts[2].peer_key, "peer-2") == 0, "mount 2 peer"); expect(strcmp(manifest.mounts[2].space_id, "zeta") == 0, "mount 2 space"); expect(manifest.mounts[2].mode == AMDUATD_SPACE_MANIFEST_MOUNT_TRACK, "mount 2 mode"); } amduatd_space_manifest_free(&manifest); amduat_reference_free(&fetched_ref); amduat_reference_free(&record_ref); amduat_reference_free(&pinned_ref); free(root); return failures == 0 ? 0 : 1; } int main(void) { if (amduatd_test_manifest_missing() != 0) { return 1; } if (amduatd_test_manifest_decode() != 0) { return 1; } return failures == 0 ? 0 : 1; }