#ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L #endif #include "amduatd_space_roots.h" #include "amduatd_fed_cursor.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/none.h" #include #include #include static char *amduatd_test_make_temp_dir(void) { char tmpl[] = "/tmp/amduatd-roots-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_list_contains(const amduatd_space_roots_list_t *list, const char *name) { if (list == NULL || name == NULL) { return false; } for (size_t i = 0u; i < list->len; ++i) { if (strcmp(list->names[i], name) == 0) { return true; } } return false; } static bool amduatd_list_sorted(const amduatd_space_roots_list_t *list) { if (list == NULL || list->len < 2u) { return true; } for (size_t i = 1u; i < list->len; ++i) { if (strcmp(list->names[i - 1u], list->names[i]) > 0) { return false; } } return true; } static bool amduatd_build_collection_head_name(const char *name, char **out_name) { size_t name_len; size_t total_len; char *buffer; size_t offset = 0u; if (name == NULL || out_name == NULL) { return false; } if (!amduat_asl_pointer_name_is_valid(name)) { return false; } name_len = strlen(name); total_len = 11u + name_len + 5u + 1u; buffer = (char *)malloc(total_len); if (buffer == NULL) { return false; } memcpy(buffer + offset, "collection/", 11u); offset += 11u; memcpy(buffer + offset, name, name_len); offset += name_len; memcpy(buffer + offset, "/head", 5u); offset += 5u; buffer[offset] = '\0'; *out_name = buffer; return true; } static bool amduatd_build_collection_log_head_name(const char *name, char **out_name) { size_t name_len; size_t total_len; char *buffer; size_t offset = 0u; if (name == NULL || out_name == NULL) { return false; } if (!amduat_asl_pointer_name_is_valid(name)) { return false; } name_len = strlen(name); total_len = 4u + 11u + name_len + 4u + 5u + 1u; buffer = (char *)malloc(total_len); if (buffer == NULL) { return false; } memcpy(buffer + offset, "log/", 4u); offset += 4u; memcpy(buffer + offset, "collection/", 11u); offset += 11u; memcpy(buffer + offset, name, name_len); offset += name_len; memcpy(buffer + offset, "/log", 4u); offset += 4u; memcpy(buffer + offset, "/head", 5u); offset += 5u; buffer[offset] = '\0'; *out_name = buffer; return true; } static int amduatd_test_empty_store(void) { char *root = amduatd_test_make_temp_dir(); amduat_asl_store_fs_config_t cfg; amduat_asl_pointer_store_t pointer_store; amduatd_space_t space; amduatd_space_roots_list_t list; 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; } 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, NULL, false)) { fprintf(stderr, "failed to init space\n"); free(root); return 1; } if (!amduatd_space_roots_list(root, &pointer_store, &space, &list)) { fprintf(stderr, "roots list failed\n"); free(root); return 1; } if (list.len != 3u || !amduatd_list_contains(&list, "daemon/edges/index/head") || !amduatd_list_contains(&list, "collection/daemon/edges/head") || !amduatd_list_contains(&list, "log/collection/daemon/edges/log/head") || !amduatd_list_sorted(&list)) { fprintf(stderr, "unexpected empty-store roots list\n"); amduatd_space_roots_list_free(&list); free(root); return 1; } amduatd_space_roots_list_free(&list); free(root); return 0; } static int amduatd_test_cursor_roots(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_artifact_t none_artifact; amduat_reference_t none_ref; amduat_octets_t cursor_name = amduat_octets(NULL, 0u); amduat_octets_t push_name = amduat_octets(NULL, 0u); amduat_octets_t edges_collection = amduat_octets(NULL, 0u); amduat_octets_t edges_index_head = amduat_octets(NULL, 0u); char *collection_head = NULL; char *collection_log_head = NULL; amduatd_space_roots_list_t list; bool swapped = false; 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 (!amduat_asl_none_artifact(&none_artifact)) { fprintf(stderr, "failed to build none artifact\n"); free(root); return 1; } if (amduat_asl_store_put(&store, none_artifact, &none_ref) != AMDUAT_ASL_STORE_OK) { fprintf(stderr, "failed to store none artifact\n"); amduat_artifact_free(&none_artifact); free(root); return 1; } amduat_artifact_free(&none_artifact); if (!amduatd_fed_cursor_pointer_name(&space, "peer-a", &cursor_name) || !amduatd_fed_push_cursor_pointer_name(&space, "peer-b", &push_name)) { fprintf(stderr, "failed to build cursor names\n"); free(root); return 1; } if (amduat_asl_pointer_cas(&pointer_store, (const char *)cursor_name.data, false, NULL, &none_ref, &swapped) != AMDUAT_ASL_POINTER_OK || !swapped || amduat_asl_pointer_cas(&pointer_store, (const char *)push_name.data, false, NULL, &none_ref, &swapped) != AMDUAT_ASL_POINTER_OK || !swapped) { fprintf(stderr, "failed to seed cursor pointers\n"); amduat_octets_free(&cursor_name); amduat_octets_free(&push_name); free(root); return 1; } if (!amduatd_space_roots_list(root, &pointer_store, &space, &list)) { fprintf(stderr, "roots list failed\n"); amduat_octets_free(&cursor_name); amduat_octets_free(&push_name); free(root); return 1; } if (!amduatd_space_edges_collection_name(&space, &edges_collection) || !amduatd_space_edges_index_head_name(&space, &edges_index_head) || !amduatd_build_collection_head_name( (const char *)edges_collection.data, &collection_head) || !amduatd_build_collection_log_head_name( (const char *)edges_collection.data, &collection_log_head)) { fprintf(stderr, "failed to build static root names\n"); amduat_octets_free(&cursor_name); amduat_octets_free(&push_name); amduatd_space_roots_list_free(&list); free(root); return 1; } if (list.len != 5u || !amduatd_list_contains(&list, (const char *)cursor_name.data) || !amduatd_list_contains(&list, (const char *)push_name.data) || !amduatd_list_contains(&list, (const char *)edges_index_head.data) || !amduatd_list_contains(&list, collection_head) || !amduatd_list_contains(&list, collection_log_head) || !amduatd_list_sorted(&list)) { fprintf(stderr, "unexpected cursor roots list\n"); amduat_octets_free(&cursor_name); amduat_octets_free(&push_name); amduat_octets_free(&edges_collection); amduat_octets_free(&edges_index_head); free(collection_head); free(collection_log_head); amduatd_space_roots_list_free(&list); free(root); return 1; } amduat_octets_free(&cursor_name); amduat_octets_free(&push_name); amduat_octets_free(&edges_collection); amduat_octets_free(&edges_index_head); free(collection_head); free(collection_log_head); amduatd_space_roots_list_free(&list); free(root); return 0; } int main(void) { if (amduatd_test_empty_store() != 0) { return 1; } if (amduatd_test_cursor_roots() != 0) { return 1; } return 0; }