#ifndef _POSIX_C_SOURCE #define _POSIX_C_SOURCE 200809L #endif #include "amduatd_fed_push_plan.h" #include "amduatd_fed_cursor.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 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; } int main(void) { amduatd_fed_cfg_t cfg; amduat_asl_store_t store; amduatd_fed_push_plan_status_t status; amduatd_fed_cfg_init(&cfg); memset(&store, 0, sizeof(store)); status = amduatd_fed_push_plan_check(&cfg, &store); expect(status == AMDUATD_FED_PUSH_PLAN_ERR_DISABLED, "disabled federation check"); cfg.enabled = true; status = amduatd_fed_push_plan_check(&cfg, &store); expect(status == AMDUATD_FED_PUSH_PLAN_ERR_UNSUPPORTED, "unsupported backend check"); { amduatd_fed_push_plan_input_t input; amduat_fed_record_t records[2]; amduat_reference_t ref0; amduat_reference_t ref1; char *json = NULL; char *ref0_hex = NULL; if (!amduatd_make_test_ref(0x01, &ref0) || !amduatd_make_test_ref(0x02, &ref1)) { fprintf(stderr, "FAIL: make refs\n"); return 1; } memset(records, 0, sizeof(records)); records[0].id.type = AMDUAT_FED_REC_ARTIFACT; records[0].id.ref = ref0; records[0].logseq = 1u; records[1].id.type = AMDUAT_FED_REC_PER; records[1].id.ref = ref1; records[1].logseq = 2u; memset(&input, 0, sizeof(input)); input.peer_key = "1"; input.domain_id = 42u; input.cursor_present = false; input.records = records; input.record_count = 2u; status = amduatd_fed_push_plan_json(&input, &json); expect(status == AMDUATD_FED_PUSH_PLAN_OK, "plan json missing cursor"); expect(json != NULL && strstr(json, "\"present\":false") != NULL, "cursor present false"); expect(json != NULL && strstr(json, "\"record_count\":2") != NULL, "record count"); expect(json != NULL && strstr(json, "\"last_logseq\":2") != NULL, "next cursor candidate"); expect(json != NULL && strstr(json, "\"domain_id\":42") != NULL, "domain id"); expect(json != NULL && strstr(json, "\"record_type\":\"per\"") != NULL, "record type per"); if (amduat_asl_ref_encode_hex(ref0, &ref0_hex)) { expect(json != NULL && strstr(json, ref0_hex) != NULL, "required artifacts include ref"); } else { fprintf(stderr, "FAIL: encode ref\n"); failures++; } free(ref0_hex); free(json); amduat_reference_free(&ref0); amduat_reference_free(&ref1); } { amduatd_fed_push_plan_input_t input; amduatd_fed_cursor_record_t cursor; amduat_reference_t cursor_ref; amduat_reference_t record_ref; char *json = NULL; char *cursor_ref_hex = NULL; amduatd_fed_cursor_record_init(&cursor); cursor.peer_key = strdup("7"); cursor.space_id = NULL; if (cursor.peer_key == NULL) { fprintf(stderr, "FAIL: cursor peer allocation\n"); return 1; } cursor.has_logseq = true; cursor.last_logseq = 5u; if (!amduatd_make_test_ref(0x03, &record_ref)) { fprintf(stderr, "FAIL: make cursor record ref\n"); return 1; } cursor.has_record_ref = true; cursor.last_record_ref = record_ref; if (!amduatd_make_test_ref(0x04, &cursor_ref)) { fprintf(stderr, "FAIL: make cursor ref\n"); amduatd_fed_cursor_record_free(&cursor); return 1; } if (!amduat_asl_ref_encode_hex(cursor_ref, &cursor_ref_hex)) { fprintf(stderr, "FAIL: encode cursor ref\n"); amduat_reference_free(&cursor_ref); amduatd_fed_cursor_record_free(&cursor); return 1; } memset(&input, 0, sizeof(input)); input.peer_key = "7"; input.domain_id = 7u; input.cursor_present = true; input.cursor = &cursor; input.cursor_ref = &cursor_ref; input.records = NULL; input.record_count = 0u; status = amduatd_fed_push_plan_json(&input, &json); expect(status == AMDUATD_FED_PUSH_PLAN_OK, "plan json with cursor"); expect(json != NULL && strstr(json, "\"present\":true") != NULL, "cursor present true"); expect(json != NULL && strstr(json, "\"last_logseq\":5") != NULL, "cursor logseq echoed"); expect(json != NULL && strstr(json, "\"next_cursor_candidate\":{\"last_logseq\":null") != NULL, "next cursor candidate empty"); expect(json != NULL && strstr(json, cursor_ref_hex) != NULL, "cursor ref echoed"); free(cursor_ref_hex); free(json); amduat_reference_free(&cursor_ref); amduatd_fed_cursor_record_free(&cursor); } return failures == 0 ? 0 : 1; }