#include "test.h" #include "store_mdb.h" #include "assets.h" static char *path = "/tmp/testdb"; static void rmdb() { char data_path[32], lock_path[32]; sprintf(data_path, "%s/data.mdb", path); sprintf(lock_path, "%s/lock.mdb", path); printf("Removing %s\n", data_path); remove(data_path); printf("Removing %s\n", lock_path); remove(lock_path); printf("Removing %s\n", path); remove(path); } /** @brief Test triple store. */ static int test_triple_store() { rmdb(); EXPECT_PASS(LSUP_store_setup(&path)); LSUP_MDBStore *store; store = LSUP_store_new(path, NULL); // triple store. ASSERT(store != NULL, "Error initializing store!"); LSUP_Triple *trp = create_triples(); LSUP_SerTerm sterms[NUM_TRP][3]; LSUP_SerTriple ser_trp[NUM_TRP]; for (int i = 0; i < NUM_TRP; i++) { ser_trp[i].s = sterms[i]; ser_trp[i].p = sterms[i] + 1; ser_trp[i].o = sterms[i] + 2; for (int j = 0; j < 3; j++) { LSUP_term_serialize( LSUP_triple_term_by_pos(trp + i, j), LSUP_ser_triple_term_by_pos(ser_trp + i, j)); } } // Test adding. EXPECT_PASS(LSUP_store_add(store, NULL, ser_trp, NUM_TRP)); EXPECT_INT_EQ(LSUP_store_size(store), 8); // Test lookups. size_t ct; LSUP_SerTerm *lut[12][4] = { {NULL, NULL, NULL, NULL}, {ser_trp[0].s, NULL, NULL, NULL}, {ser_trp[2].s, NULL, NULL, ser_trp[2].s}, {NULL, ser_trp[0].p, NULL, NULL}, {NULL, ser_trp[0].s, NULL, NULL}, {NULL, NULL, ser_trp[6].o, NULL}, {ser_trp[4].s, ser_trp[4].p, NULL, NULL}, {NULL, ser_trp[7].p, ser_trp[7].o, NULL}, {ser_trp[5].s, NULL, ser_trp[5].o, NULL}, {ser_trp[6].s, NULL, ser_trp[5].o, ser_trp[2].s}, {ser_trp[4].s, ser_trp[4].p, ser_trp[4].o, NULL}, {ser_trp[4].s, ser_trp[4].p, ser_trp[5].o, NULL}, }; size_t results[12] = { 8, 5, 1, 1, 0, 1, 2, 1, 2, 0, 1, 0, }; for (int i = 0; i < 8; i++) { TRACE("Testing triple lookup #%d.\n", i); int rc = LSUP_store_lookup(store, lut[i], &ct, NULL, NULL); if (ct > 0) EXPECT_INT_EQ(rc, LSUP_OK); else if (ct == 0) EXPECT_INT_EQ(rc, LSUP_NORESULT); EXPECT_INT_EQ(ct, results[i]); } for (int i = 0; i < NUM_TRP; i++) { LSUP_buffer_done(ser_trp[i].s); LSUP_buffer_done(ser_trp[i].p); LSUP_buffer_done(ser_trp[i].o); } LSUP_store_free(store); free_triples(trp); return 0; } /** @brief Test quad store. * * Insert the same triple set twice with different contexts. */ static int test_quad_store() { rmdb(); EXPECT_PASS(LSUP_store_setup(&path)); LSUP_Term *ctx1 = LSUP_uri_new("urn:c:1"); LSUP_SerTerm sc1_s; LSUP_SerTerm *sc1 = &sc1_s; LSUP_term_serialize(ctx1, sc1); LSUP_MDBStore *store; store = LSUP_store_new(path, sc1); // quad store. ASSERT(store != NULL, "Error initializing store!"); LSUP_Triple *trp = create_triples(); LSUP_SerTerm sterms[NUM_TRP][3]; LSUP_SerTriple ser_trp[NUM_TRP]; for (int i = 0; i < NUM_TRP; i++) { ser_trp[i].s = sterms[i]; ser_trp[i].p = sterms[i] + 1; ser_trp[i].o = sterms[i] + 2; for (int j = 0; j < 3; j++) { LSUP_term_serialize( LSUP_triple_term_by_pos(trp + i, j), LSUP_ser_triple_term_by_pos(ser_trp + i, j)); } } // Only triples 0÷5 in default context. EXPECT_PASS(LSUP_store_add(store, NULL, ser_trp, 6)); LSUP_Term *ctx2 = LSUP_uri_new("urn:c:2"); LSUP_SerTerm sc2_s; LSUP_SerTerm *sc2 = &sc2_s; LSUP_term_serialize(ctx2, sc2); // Only triples 4÷9 in default context. EXPECT_PASS(LSUP_store_add(store, &sc2_s, ser_trp + 4, 6)); // 6 triples in ctx1 + 6 in ctx2 - 2 duplicates EXPECT_INT_EQ(LSUP_store_size(store), 10); // Test lookups. // This context is not with any triple. LSUP_Term *ctx3 = LSUP_uri_new("urn:c:3"); LSUP_SerTerm sc3_s; LSUP_SerTerm *sc3 = &sc3_s; LSUP_term_serialize(ctx2, &sc3_s); size_t ct; LSUP_SerTerm *lut[41][4] = { // Any context {NULL, NULL, NULL, NULL}, {ser_trp[0].s, NULL, NULL, NULL}, {NULL, ser_trp[0].p, NULL, NULL}, {NULL, ser_trp[0].s, NULL, NULL}, {NULL, NULL, ser_trp[6].o, NULL}, {ser_trp[4].s, ser_trp[4].p, NULL, NULL}, {NULL, ser_trp[7].p, ser_trp[7].o, NULL}, {ser_trp[5].s, NULL, ser_trp[5].o, NULL}, {ser_trp[4].s, ser_trp[4].p, ser_trp[4].o, NULL}, {ser_trp[2].s, ser_trp[4].p, ser_trp[5].o, NULL}, // Context 1 (trp[0÷5]) {NULL, NULL, NULL, sc1}, {ser_trp[0].s, NULL, NULL, sc1}, {ser_trp[2].s, NULL, NULL, sc1}, {NULL, ser_trp[0].p, NULL, sc1}, {NULL, ser_trp[6].p, NULL, sc1}, {NULL, NULL, ser_trp[6].o, sc1}, {ser_trp[4].s, ser_trp[4].p, NULL, sc1}, {NULL, ser_trp[7].p, ser_trp[7].o, sc1}, {ser_trp[5].s, NULL, ser_trp[5].o, sc1}, {ser_trp[4].s, ser_trp[4].p, ser_trp[4].o, sc1}, {ser_trp[6].s, ser_trp[6].p, ser_trp[6].o, sc1}, // Context 2 (trp[4÷9]) {NULL, NULL, NULL, sc2}, {ser_trp[0].s, NULL, NULL, sc2}, {NULL, ser_trp[0].p, NULL, sc2}, {NULL, ser_trp[0].s, NULL, sc2}, {NULL, NULL, ser_trp[6].o, sc2}, {ser_trp[4].s, ser_trp[4].p, NULL, sc2}, {NULL, ser_trp[7].p, ser_trp[7].o, sc2}, {ser_trp[5].s, NULL, ser_trp[5].o, sc2}, {ser_trp[4].s, ser_trp[4].p, ser_trp[4].o, sc2}, {ser_trp[6].s, ser_trp[6].p, ser_trp[6].o, sc2}, // Non-existing context {NULL, NULL, NULL, sc3}, {ser_trp[0].s, NULL, NULL, sc3}, {NULL, ser_trp[0].p, NULL, sc3}, {NULL, ser_trp[0].s, NULL, sc3}, {NULL, NULL, ser_trp[6].o, sc3}, {ser_trp[4].s, ser_trp[4].p, NULL, sc3}, {NULL, ser_trp[7].p, ser_trp[7].o, sc3}, {ser_trp[5].s, NULL, ser_trp[5].o, sc3}, {ser_trp[4].s, ser_trp[4].p, ser_trp[4].o, sc3}, {ser_trp[6].s, ser_trp[6].p, ser_trp[6].o, sc3}, }; size_t results[40] = { // NULL ctx 8, 5, 1, 0, 1, 2, 1, 2, 1, 0, // ctx1 6, 4, 1, 0, 0, 1, 0, 0, 1, 0, // ctx2 4, 3, 0, 0, 1, 2, 1, 1, 1, 1, // ctx3 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; for (int i = 0; i < 41; i++) { printf("Testing triple lookup #%d: {", i); if(lut[i][0]) LSUP_buffer_print(lut[i][0]); else printf("NULL"); printf(" "); if(lut[i][1]) LSUP_buffer_print(lut[i][1]); else printf("NULL"); printf(" "); if(lut[i][2]) LSUP_buffer_print(lut[i][2]); else printf("NULL"); printf(" "); if(lut[i][3]) LSUP_buffer_print(lut[i][3]); else printf("NULL"); printf("}\n"); int rc = LSUP_store_lookup(store, lut[i], &ct, NULL, NULL); if (ct > 0) EXPECT_INT_EQ(rc, LSUP_OK); else if (ct == 0) EXPECT_INT_EQ(rc, LSUP_NORESULT); EXPECT_INT_EQ(ct, results[i]); } for (int i = 0; i < NUM_TRP; i++) { LSUP_buffer_done(ser_trp[i].s); LSUP_buffer_done(ser_trp[i].p); LSUP_buffer_done(ser_trp[i].o); } LSUP_term_free(ctx1); LSUP_term_free(ctx2); LSUP_buffer_done(&sc1_s); LSUP_buffer_done(&sc2_s); free_triples(trp); LSUP_store_free(store); return 0; } int store_mdb_test() { RUN(test_triple_store); RUN(test_quad_store); return 0; }