123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- #include "test.h"
- #include "graph.h"
- #include "assets/triples.h"
- #define N_LUT 13
- static int
- _graph_new (LSUP_StoreType type)
- {
- const LSUP_StoreInt *sif = LSUP_store_int (type);
- if (sif->setup_fn) sif->setup_fn (NULL, true);
- LSUP_Graph *gr;
- LSUP_Store *store;
- if (type == LSUP_STORE_HTABLE) {
- gr = LSUP_graph_new (NULL, NULL, NULL);
- } else {
- store = LSUP_store_new (type, NULL, 0);
- gr = LSUP_graph_new (store, NULL, NULL);
- }
- ASSERT (gr != NULL, "Error creating graph!");
- EXPECT_PASS (LSUP_graph_set_uri (gr, LSUP_iriref_new ("urn:gr:1", NULL)));
- EXPECT_STR_EQ (LSUP_graph_uri (gr)->data, "urn:gr:1");
- // Check that setup function is idempotent with clear == false.
- if (sif->setup_fn) EXPECT_INT_EQ (
- sif->setup_fn (NULL, false), LSUP_NOACTION);
- ASSERT (
- strcmp (LSUP_graph_uri (gr)->data, "urn:gr:1") == 0,
- "Graph URI mismatch!");
- EXPECT_INT_EQ (LSUP_graph_size (gr), 0);
- LSUP_graph_free (gr);
- if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
- return 0;
- }
- static int
- _graph_add (LSUP_StoreType type)
- {
- const LSUP_StoreInt *sif = LSUP_store_int (type);
- if (sif->setup_fn) sif->setup_fn (NULL, true);
- LSUP_Triple **trp = create_triples();
- LSUP_Graph *gr;
- LSUP_Store *store;
- if (type == LSUP_STORE_HTABLE) {
- gr = LSUP_graph_new (NULL, NULL, NULL);
- } else {
- store = LSUP_store_new (type, NULL, 0);
- gr = LSUP_graph_new (store, NULL, NULL);
- }
- ASSERT (gr != NULL, "Error creating graph!");
- size_t ct;
- LSUP_graph_add (gr, trp, &ct);
- EXPECT_INT_EQ (ct, 8);
- EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
- for (int i = 0; i < sizeof (trp); i++) {
- log_info ("checking triple #%d.", i);
- ASSERT (LSUP_graph_contains (gr, trp[i]), "Triple not in graph!");
- }
- LSUP_Triple *missing_trp = LSUP_triple_new (
- trp[1]->s, trp[6]->p, trp[4]->o);
- ASSERT (! LSUP_graph_contains (gr, missing_trp), "Triple in graph!");
- free (missing_trp);
- free_triples (trp); // gr copied data.
- LSUP_graph_free (gr);
- if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
- return 0;
- }
- static int
- _graph_get (LSUP_StoreType type)
- {
- const LSUP_StoreInt *sif = LSUP_store_int (type);
- // Skip if the store doesn't support contexts.
- if (!(sif->features & LSUP_STORE_CTX)) return 0;
- if (sif->setup_fn) sif->setup_fn (NULL, true);
- LSUP_Triple **trp = create_triples();
- LSUP_Store *store = LSUP_store_new (type, NULL, 0);
- LSUP_Graph
- *gr1 = LSUP_graph_new (store, NULL, NULL),
- *gr2 = LSUP_graph_new (store, NULL, NULL);
- ASSERT (gr1 != NULL, "Error creating graph!");
- ASSERT (gr2 != NULL, "Error creating graph!");
- // Add 2 groups of triples to different graphs.
- void *it1 = LSUP_graph_add_init (gr1);
- for (size_t i = 0; i < 5; i++) {
- LSUP_graph_add_iter(it1, trp[i]);
- }
- LSUP_graph_add_done (it1);
- void *it2 = LSUP_graph_add_init (gr2);
- for (size_t i = 5; i < NUM_TRP; i++) {
- LSUP_graph_add_iter(it2, trp[i]);
- }
- LSUP_graph_add_done (it2);
- EXPECT_INT_EQ (LSUP_graph_size (gr1), 5);
- EXPECT_INT_EQ (LSUP_graph_size (gr2), 3);
- size_t ct3, ct4;
- LSUP_Graph
- *gr3 = LSUP_graph_get (store, LSUP_graph_uri (gr1), &ct3),
- *gr4 = LSUP_graph_get (store, LSUP_graph_uri (gr2), &ct4);
- EXPECT_INT_EQ (LSUP_graph_size (gr3), LSUP_graph_size (gr1));
- EXPECT_INT_EQ (LSUP_graph_size (gr4), LSUP_graph_size (gr2));
- ASSERT (LSUP_graph_equals (gr1, gr3), "Graphs 1 and 3 are not equal!");
- ASSERT (LSUP_graph_equals (gr2, gr4), "Graphs 2 and 4 are not equal!");
- LSUP_graph_free (gr1);
- LSUP_graph_free (gr2);
- LSUP_graph_free (gr3);
- LSUP_graph_free (gr4);
- free_triples (trp);
- if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
- return 0;
- }
- static int
- _graph_lookup (LSUP_StoreType type)
- {
- const LSUP_StoreInt *sif = LSUP_store_int (type);
- LSUP_Triple **trp = create_triples();
- // Lookup triples.
- LSUP_Term *lu_trp[N_LUT][3] = {
- {NULL, NULL, NULL}, // 8 matches
- {trp[0]->s, NULL, NULL}, // 5 matches
- {NULL, trp[2]->p, NULL}, // 3 matches
- {NULL, NULL, trp[5]->o}, // 2 matches
- {trp[0]->s, trp[0]->p, NULL}, // 1 match
- {NULL, trp[0]->p, trp[0]->o}, // 1 match
- {trp[0]->s, trp[2]->p, trp[5]->o}, // 1 match
- {trp[0]->p, NULL, NULL}, // 0 matches
- {NULL, trp[2]->s, NULL}, // 0 matches
- {NULL, NULL, trp[5]->p}, // 0 matches
- {trp[2]->s, trp[6]->p, NULL}, // 0 matches
- {NULL, trp[1]->p, trp[5]->o}, // 0 matches
- {trp[2]->s, trp[2]->p, trp[5]->o}, // 0 matches
- };
- // Lookup result counts.
- size_t lu_ct[N_LUT] = {
- 8,
- 5, 3, 2,
- 1, 1, 1,
- 0, 0, 0,
- 0, 0, 0
- };
- /* TODO
- // Index of lookup matches from trp.
- size_t lu_match[N_LUT][8] = {
- {0, 1, 2, 3, 4, 5, 6, 7},
- {0, 3, 4, 5, 7}, {2, 4, 7}, {5, 7},
- {0}, {0}, {7},
- {}, {}, {},
- {}, {}, {},
- };
- // Index of lookup non-matches from trp.
- size_t lu_no_match[N_LUT][8] = {
- {},
- {1, 2, 6}, {0, 1, 3, 5, 6}, {0, 1, 2, 3, 4, 6},
- {1, 2, 3, 4, 5, 6, 7}, {1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6},
- {0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7},
- {0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7},
- };
- */
- if (sif->setup_fn) sif->setup_fn (NULL, true);
- LSUP_Graph *gr;
- LSUP_Store *store;
- if (type == LSUP_STORE_HTABLE) {
- gr = LSUP_graph_new (NULL, NULL, NULL);
- } else {
- store = LSUP_store_new (type, NULL, 0);
- gr = LSUP_graph_new (store, NULL, NULL);
- }
- size_t ct;
- LSUP_graph_add (gr, trp, &ct);
- EXPECT_INT_EQ (ct, 8);
- EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
- for (int i = 0; i < N_LUT; i++) {
- log_info ("Checking triple #%d on %d.", i, type);
- LSUP_GraphIterator *it = LSUP_graph_lookup (
- gr, lu_trp[i][0], lu_trp[i][1], lu_trp[i][2], &ct);
- EXPECT_INT_EQ (ct, lu_ct[i]);
- // Verify that iteration count matches stat count.
- LSUP_Triple *spo = NULL;
- ct = 0;
- while (LSUP_graph_iter_next (it, &spo) != LSUP_END) {
- ct++;
- // TODO do something useful with the triple.
- LSUP_triple_free (spo);
- spo = NULL;
- }
- LSUP_triple_free (spo);
- EXPECT_INT_EQ (ct, lu_ct[i]);
- /* TODO
- for (int j = 0; j < 8; j++) {
- for (int k = 0; LSUP_graph_iter_next(it) != LSUP_END; k++) {
- ASSERT (
- LSUP_graph_contains (trp[lu_match[j]]),
- "Triple not found!");
- ASSERT (
- !(LSUP_graph_contains (trp[lu_no_match[j]])),
- "Unexpected triple found!");
- }
- }
- */
- LSUP_graph_iter_free (it);
- };
- free_triples (trp);
- LSUP_graph_free (gr);
- if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
- return 0;
- }
- static int
- _graph_remove (LSUP_StoreType type)
- {
- const LSUP_StoreInt *sif = LSUP_store_int (type);
- if (sif->setup_fn) sif->setup_fn (NULL, true);
- LSUP_Triple **trp = create_triples();
- LSUP_Graph *gr;
- LSUP_Store *store;
- if (type == LSUP_STORE_HTABLE) {
- gr = LSUP_graph_new (NULL, NULL, NULL);
- } else {
- store = LSUP_store_new (type, NULL, 0);
- gr = LSUP_graph_new (store, NULL, NULL);
- }
- size_t ct;
- LSUP_graph_add (gr, trp, &ct);
- EXPECT_INT_EQ (ct, 8);
- EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
- // Triples 0, 3, 4, 5, 7 will be removed.
- LSUP_graph_remove (gr, trp[0]->s, NULL, NULL, &ct);
- EXPECT_INT_EQ (ct, 5);
- EXPECT_INT_EQ (LSUP_graph_size (gr), 3);
- ASSERT (!LSUP_graph_contains (gr, trp[0]), "Unexpected triple found!");
- ASSERT (LSUP_graph_contains (gr, trp[1]), "Triple not in graph!");
- ASSERT (LSUP_graph_contains (gr, trp[2]), "Triple not in graph!");
- ASSERT (!LSUP_graph_contains (gr, trp[3]), "Unexpected triple found!");
- ASSERT (!LSUP_graph_contains (gr, trp[4]), "Unexpected triple found!");
- ASSERT (!LSUP_graph_contains (gr, trp[5]), "Unexpected triple found!");
- ASSERT (LSUP_graph_contains (gr, trp[6]), "Triple not in graph!");
- ASSERT (!LSUP_graph_contains (gr, trp[7]), "Unexpected triple found!");
- free_triples (trp); // gr copied data.
- LSUP_graph_free (gr);
- if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
- // TODO Test complete removal of triples from index when they are not
- // in another context.
- return 0;
- }
- static int
- _graph_txn (LSUP_StoreType type)
- {
- const LSUP_StoreInt *sif = LSUP_store_int (type);
- if (!(sif->features & LSUP_STORE_TXN)) return 0;
- if (sif->setup_fn) sif->setup_fn (NULL, true);
- LSUP_Triple **trp = create_triples();
- LSUP_Graph *gr;
- LSUP_Store *store =
- type == LSUP_STORE_HTABLE ? NULL
- : LSUP_store_new (type, NULL, 0);
- gr = LSUP_graph_new (store, NULL, NULL);
- void *txn;
- size_t ct;
- EXPECT_PASS (LSUP_store_begin (store, 0, &txn));
- EXPECT_PASS (LSUP_graph_add_txn (txn, gr, trp, &ct));
- LSUP_store_abort (store, txn);
- // NOTE that ct reports the count before the txn was aborted. This is
- // intentional.
- EXPECT_INT_EQ (ct, 8);
- EXPECT_INT_EQ (LSUP_graph_size (gr), 0);
- EXPECT_PASS (LSUP_store_begin (store, 0, &txn));
- EXPECT_PASS (LSUP_graph_add_txn (txn, gr, trp, &ct));
- LSUP_store_commit (store, txn);
- EXPECT_INT_EQ (ct, 8);
- EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
- LSUP_graph_free (gr);
- if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
- free_triples (trp); // gr copied data.
- return 0;
- }
- static int
- test_environment()
- {
- // The env should already be initialized and re-initializing it is idempotent.
- EXPECT_INT_EQ (LSUP_IS_INIT, true);
- ASSERT (LSUP_init() > 0, "Error initializing environment!");
- EXPECT_INT_EQ (LSUP_IS_INIT, true);
- // Tearing down is idempotent too.
- LSUP_done();
- EXPECT_INT_EQ (LSUP_IS_INIT, false);
- LSUP_done();
- EXPECT_INT_EQ (LSUP_IS_INIT, false);
- ASSERT (LSUP_init() >= 0, "Environment not initialized!");
- EXPECT_INT_EQ (LSUP_IS_INIT, true);
- ASSERT (LSUP_init() >= 0, "Environment not initialized!");
- EXPECT_INT_EQ (LSUP_IS_INIT, true);
- return 0;
- }
- static int test_graph_new() {
- #define ENTRY(a, b) \
- if (_graph_new (LSUP_STORE_##a) != 0) return -1;
- BACKEND_TBL
- #undef ENTRY
- return 0;
- }
- static int test_graph_add() {
- #define ENTRY(a, b) \
- if (_graph_add (LSUP_STORE_##a) != 0) return -1;
- BACKEND_TBL
- #undef ENTRY
- return 0;
- }
- static int test_graph_get() {
- #define ENTRY(a, b) \
- if (_graph_get (LSUP_STORE_##a) != 0) return -1;
- BACKEND_TBL
- #undef ENTRY
- return 0;
- }
- static int test_graph_lookup() {
- #define ENTRY(a, b) \
- if (_graph_lookup (LSUP_STORE_##a) != 0) return -1;
- BACKEND_TBL
- #undef ENTRY
- return 0;
- }
- static int test_graph_remove() {
- #define ENTRY(a, b) \
- if (_graph_remove (LSUP_STORE_##a) != 0) return -1;
- BACKEND_TBL
- #undef ENTRY
- return 0;
- }
- static int test_graph_txn()
- {
- /*
- * Test transactions only if the backend supports them.
- */
- #define ENTRY(a, b) \
- if (_graph_txn (LSUP_STORE_##a) != 0) return -1;
- BACKEND_TBL
- #undef ENTRY
- return 0;
- }
- static int test_graph_copy()
- {
- LSUP_Triple **trp = create_triples();
- LSUP_Graph *gr1 = LSUP_graph_new (NULL, NULL, NULL);
- ASSERT (gr1 != NULL, "Error creating graph!");
- LSUP_graph_add (gr1, trp, NULL);
- // Copy to graph with same store type.
- LSUP_Graph *gr2 = LSUP_graph_new (NULL, NULL, NULL);
- EXPECT_PASS (LSUP_graph_copy_contents (gr1, gr2));
- EXPECT_INT_EQ (LSUP_graph_size (gr1), LSUP_graph_size (gr2));
- for (int i = 0; i < sizeof (trp); i++) {
- log_info ("checking triple #%d.", i);
- ASSERT (
- LSUP_graph_contains (gr2, trp[i]),
- "Triple not in copied graph!");
- }
- // Copy to graph with a different store type.
- LSUP_Graph *gr3 = LSUP_graph_new (NULL, NULL, NULL);
- EXPECT_PASS (LSUP_graph_copy_contents (gr1, gr3));
- EXPECT_INT_EQ (LSUP_graph_size (gr1), LSUP_graph_size (gr2));
- for (int i = 0; i < sizeof (trp); i++) {
- log_info ("checking triple #%d.", i);
- ASSERT (
- LSUP_graph_contains (gr3, trp[i]),
- "Triple not in copied graph!");
- }
- LSUP_graph_free (gr3);
- LSUP_graph_free (gr2);
- LSUP_graph_free (gr1);
- free_triples (trp);
- return 0;
- }
- int graph_tests()
- {
- RUN (test_environment);
- RUN (test_graph_new);
- RUN (test_graph_add);
- RUN (test_graph_get);
- RUN (test_graph_lookup);
- RUN (test_graph_remove);
- RUN (test_graph_copy);
- RUN (test_graph_txn);
- return 0;
- }
|