229 lines
6 KiB
C
229 lines
6 KiB
C
|
|
#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_pointer_fs.h"
|
||
|
|
#include "amduat/asl/asl_store_fs_meta.h"
|
||
|
|
#include "amduat/asl/none.h"
|
||
|
|
|
||
|
|
#include <stdio.h>
|
||
|
|
#include <stdlib.h>
|
||
|
|
#include <string.h>
|
||
|
|
|
||
|
|
static char *amduatd_test_make_temp_dir(void) {
|
||
|
|
char tmpl[] = "/tmp/amduatd-sync-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 int amduatd_test_empty_peers(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 peers;
|
||
|
|
|
||
|
|
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, "alpha", false)) {
|
||
|
|
fprintf(stderr, "failed to init space\n");
|
||
|
|
free(root);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!amduatd_space_roots_list_cursor_peers(root, &space, &peers)) {
|
||
|
|
fprintf(stderr, "cursor peer list failed\n");
|
||
|
|
free(root);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (peers.len != 0u) {
|
||
|
|
fprintf(stderr, "expected empty peers list\n");
|
||
|
|
amduatd_space_roots_list_free(&peers);
|
||
|
|
free(root);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
amduatd_space_roots_list_free(&peers);
|
||
|
|
free(root);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
static int amduatd_test_peer_discovery(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 pull_name = amduat_octets(NULL, 0u);
|
||
|
|
amduat_octets_t push_name = amduat_octets(NULL, 0u);
|
||
|
|
amduatd_space_roots_list_t peers;
|
||
|
|
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, "1", &pull_name) ||
|
||
|
|
!amduatd_fed_push_cursor_pointer_name(&space, "2", &push_name)) {
|
||
|
|
fprintf(stderr, "failed to build cursor names\n");
|
||
|
|
free(root);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (amduat_asl_pointer_cas(&pointer_store,
|
||
|
|
(const char *)pull_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(&pull_name);
|
||
|
|
amduat_octets_free(&push_name);
|
||
|
|
free(root);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!amduatd_space_roots_list_cursor_peers(root, &space, &peers)) {
|
||
|
|
fprintf(stderr, "cursor peer list failed\n");
|
||
|
|
amduat_octets_free(&pull_name);
|
||
|
|
amduat_octets_free(&push_name);
|
||
|
|
free(root);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
if (peers.len != 2u ||
|
||
|
|
!amduatd_list_contains(&peers, "1") ||
|
||
|
|
!amduatd_list_contains(&peers, "2") ||
|
||
|
|
!amduatd_list_sorted(&peers)) {
|
||
|
|
fprintf(stderr, "unexpected peers list\n");
|
||
|
|
amduatd_space_roots_list_free(&peers);
|
||
|
|
amduat_octets_free(&pull_name);
|
||
|
|
amduat_octets_free(&push_name);
|
||
|
|
free(root);
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
|
||
|
|
amduatd_space_roots_list_free(&peers);
|
||
|
|
amduat_octets_free(&pull_name);
|
||
|
|
amduat_octets_free(&push_name);
|
||
|
|
free(root);
|
||
|
|
return 0;
|
||
|
|
}
|
||
|
|
|
||
|
|
int main(void) {
|
||
|
|
if (amduatd_test_empty_peers() != 0) {
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
if (amduatd_test_peer_discovery() != 0) {
|
||
|
|
return 1;
|
||
|
|
}
|
||
|
|
return 0;
|
||
|
|
}
|