diff --git a/tests/tgk/test_tgk_store_mem.c b/tests/tgk/test_tgk_store_mem.c index 8e56555..424acdc 100644 --- a/tests/tgk/test_tgk_store_mem.c +++ b/tests/tgk/test_tgk_store_mem.c @@ -323,6 +323,237 @@ static int test_init_rejects_unsupported_encoding(void) { return 0; } +static int test_init_rejects_duplicate_hash_id(void) { + amduat_tgk_store_mem_t mem; + amduat_tgk_store_config_t config; + amduat_tgk_identity_domain_t domains[2]; + + memset(&mem, 0, sizeof(mem)); + memset(&config, 0, sizeof(config)); + domains[0].encoding_profile = AMDUAT_ENC_ASL1_CORE_V1; + domains[0].hash_id = AMDUAT_HASH_ASL1_ID_SHA256; + domains[1].encoding_profile = AMDUAT_ENC_ASL1_CORE_V1; + domains[1].hash_id = AMDUAT_HASH_ASL1_ID_SHA256; + + config.id_space.domains = domains; + config.id_space.domains_len = 2; + + if (amduat_tgk_store_mem_init(&mem, config, NULL, 0)) { + fprintf(stderr, "init accepted duplicate hash_id domains\n"); + amduat_tgk_store_mem_free(&mem); + return 1; + } + return 0; +} + +static int test_duplicate_edge_ref_same_artifact(void) { + amduat_tgk_store_mem_t mem; + amduat_tgk_store_t store; + amduat_tgk_store_config_t config; + amduat_tgk_identity_domain_t domains[1]; + uint32_t edge_tags[1]; + amduat_tgk_edge_type_id_t edge_types[1]; + amduat_asl_encoding_profile_id_t encodings[1]; + amduat_tgk_store_mem_artifact_t artifacts[2]; + amduat_tgk_edge_body_t edge; + amduat_reference_t from_refs[1]; + amduat_reference_t to_refs[1]; + amduat_reference_t ref_edge; + amduat_reference_t node_a; + amduat_reference_t node_b; + amduat_reference_t payload; + amduat_octets_t edge_bytes; + amduat_tgk_edge_body_t body; + amduat_tgk_graph_scan_result_t scan; + uint8_t digest_edge[32]; + uint8_t digest_a[32]; + uint8_t digest_b[32]; + uint8_t digest_payload[32]; + + memset(&mem, 0, sizeof(mem)); + memset(&config, 0, sizeof(config)); + memset(&edge, 0, sizeof(edge)); + edge_bytes = amduat_octets(NULL, 0); + + domains[0].encoding_profile = AMDUAT_ENC_ASL1_CORE_V1; + domains[0].hash_id = AMDUAT_HASH_ASL1_ID_SHA256; + edge_tags[0] = TYPE_TAG_TGK1_EDGE_V1; + edge_types[0] = 0x10; + encodings[0] = TGK1_EDGE_ENC_V1; + + config.id_space.domains = domains; + config.id_space.domains_len = 1; + config.tgk_profiles.edge_tags = edge_tags; + config.tgk_profiles.edge_tags_len = 1; + config.tgk_profiles.edge_types = edge_types; + config.tgk_profiles.edge_types_len = 1; + config.tgk_profiles.encodings = encodings; + config.tgk_profiles.encodings_len = 1; + + ref_edge = make_ref(0x71, digest_edge); + node_a = make_ref(0xa1, digest_a); + node_b = make_ref(0xb1, digest_b); + payload = make_ref(0xe1, digest_payload); + + edge.type = 0x10; + from_refs[0] = node_a; + edge.from = from_refs; + edge.from_len = 1; + to_refs[0] = node_b; + edge.to = to_refs; + edge.to_len = 1; + edge.payload = payload; + + if (!amduat_enc_tgk1_edge_encode_v1(&edge, &edge_bytes)) { + fprintf(stderr, "duplicate ref encode failed\n"); + return 1; + } + + artifacts[0].ref = ref_edge; + artifacts[0].artifact = + amduat_artifact_with_type(edge_bytes, + amduat_type_tag(TYPE_TAG_TGK1_EDGE_V1)); + artifacts[1].ref = ref_edge; + artifacts[1].artifact = + amduat_artifact_with_type(edge_bytes, + amduat_type_tag(TYPE_TAG_TGK1_EDGE_V1)); + + if (!amduat_tgk_store_mem_init(&mem, config, artifacts, 2)) { + fprintf(stderr, "init rejected duplicate identical artifacts\n"); + free((void *)edge_bytes.data); + return 1; + } + + amduat_tgk_store_init(&store, config, amduat_tgk_store_mem_ops(), &mem); + + if (amduat_tgk_store_resolve_edge(&store, ref_edge, &body) != 0) { + fprintf(stderr, "resolve_edge failed for duplicate ref\n"); + amduat_tgk_store_mem_free(&mem); + free((void *)edge_bytes.data); + return 1; + } + amduat_tgk_edge_body_free(&body); + + if (!amduat_tgk_store_scan_edges(&store, + (amduat_tgk_edge_type_filter_t){0}, + amduat_octets(NULL, 0), false, &scan)) { + fprintf(stderr, "scan_edges failed for duplicate ref\n"); + amduat_tgk_store_mem_free(&mem); + free((void *)edge_bytes.data); + return 1; + } + if (scan.edges.len != 1) { + fprintf(stderr, "duplicate ref scan count mismatch\n"); + amduat_tgk_graph_scan_result_free(&scan); + amduat_tgk_store_mem_free(&mem); + free((void *)edge_bytes.data); + return 1; + } + amduat_tgk_graph_scan_result_free(&scan); + amduat_tgk_store_mem_free(&mem); + free((void *)edge_bytes.data); + return 0; +} + +static int test_duplicate_edge_ref_conflict(void) { + amduat_tgk_store_mem_t mem; + amduat_tgk_store_config_t config; + amduat_tgk_identity_domain_t domains[1]; + uint32_t edge_tags[1]; + amduat_tgk_edge_type_id_t edge_types[1]; + amduat_asl_encoding_profile_id_t encodings[1]; + amduat_tgk_store_mem_artifact_t artifacts[2]; + amduat_tgk_edge_body_t edge_a; + amduat_tgk_edge_body_t edge_b; + amduat_reference_t from_refs[1]; + amduat_reference_t to_refs[1]; + amduat_reference_t ref_edge; + amduat_reference_t node_a; + amduat_reference_t node_b; + amduat_reference_t payload_a; + amduat_reference_t payload_b; + amduat_octets_t bytes_a; + amduat_octets_t bytes_b; + uint8_t digest_edge[32]; + uint8_t digest_a[32]; + uint8_t digest_b[32]; + uint8_t digest_payload_a[32]; + uint8_t digest_payload_b[32]; + + memset(&mem, 0, sizeof(mem)); + memset(&config, 0, sizeof(config)); + memset(&edge_a, 0, sizeof(edge_a)); + memset(&edge_b, 0, sizeof(edge_b)); + bytes_a = amduat_octets(NULL, 0); + bytes_b = amduat_octets(NULL, 0); + + domains[0].encoding_profile = AMDUAT_ENC_ASL1_CORE_V1; + domains[0].hash_id = AMDUAT_HASH_ASL1_ID_SHA256; + edge_tags[0] = TYPE_TAG_TGK1_EDGE_V1; + edge_types[0] = 0x10; + encodings[0] = TGK1_EDGE_ENC_V1; + + config.id_space.domains = domains; + config.id_space.domains_len = 1; + config.tgk_profiles.edge_tags = edge_tags; + config.tgk_profiles.edge_tags_len = 1; + config.tgk_profiles.edge_types = edge_types; + config.tgk_profiles.edge_types_len = 1; + config.tgk_profiles.encodings = encodings; + config.tgk_profiles.encodings_len = 1; + + ref_edge = make_ref(0x72, digest_edge); + node_a = make_ref(0xa1, digest_a); + node_b = make_ref(0xb1, digest_b); + payload_a = make_ref(0xe1, digest_payload_a); + payload_b = make_ref(0xe2, digest_payload_b); + + edge_a.type = 0x10; + from_refs[0] = node_a; + edge_a.from = from_refs; + edge_a.from_len = 1; + to_refs[0] = node_b; + edge_a.to = to_refs; + edge_a.to_len = 1; + edge_a.payload = payload_a; + + edge_b.type = 0x10; + edge_b.from = from_refs; + edge_b.from_len = 1; + edge_b.to = to_refs; + edge_b.to_len = 1; + edge_b.payload = payload_b; + + if (!amduat_enc_tgk1_edge_encode_v1(&edge_a, &bytes_a) || + !amduat_enc_tgk1_edge_encode_v1(&edge_b, &bytes_b)) { + fprintf(stderr, "conflict encode failed\n"); + free((void *)bytes_a.data); + free((void *)bytes_b.data); + return 1; + } + + artifacts[0].ref = ref_edge; + artifacts[0].artifact = + amduat_artifact_with_type(bytes_a, + amduat_type_tag(TYPE_TAG_TGK1_EDGE_V1)); + artifacts[1].ref = ref_edge; + artifacts[1].artifact = + amduat_artifact_with_type(bytes_b, + amduat_type_tag(TYPE_TAG_TGK1_EDGE_V1)); + + if (amduat_tgk_store_mem_init(&mem, config, artifacts, 2)) { + fprintf(stderr, "init accepted conflicting duplicate artifacts\n"); + amduat_tgk_store_mem_free(&mem); + free((void *)bytes_a.data); + free((void *)bytes_b.data); + return 1; + } + + free((void *)bytes_a.data); + free((void *)bytes_b.data); + return 0; +} + static int test_resolve_edge_unsupported(const test_env_t *env) { amduat_reference_t ref; amduat_tgk_edge_body_t body; @@ -534,6 +765,9 @@ int main(void) { test_resolve_edge_missing(&env) != 0 || test_resolve_edge_unsupported(&env) != 0 || test_init_rejects_unsupported_encoding() != 0 || + test_init_rejects_duplicate_hash_id() != 0 || + test_duplicate_edge_ref_same_artifact() != 0 || + test_duplicate_edge_ref_conflict() != 0 || test_type_filter(&env) != 0 || test_ordering(&env) != 0 || test_adjacency(&env) != 0 ||