Browse Source

Add transaction tests; fix profiler.

Stefano Cossu 2 years ago
parent
commit
479b22c115
3 changed files with 169 additions and 7 deletions
  1. 2 2
      TODO.md
  2. 3 4
      profile.c
  3. 164 1
      test/test_store.c

+ 2 - 2
TODO.md

@@ -22,8 +22,8 @@
     - *D* Subclass term types
 - *D* Namespaced IRIs
 - *D* Relative IRIs
-- D Flexible store interface
-- *P* Transaction control
+- *D* Flexible store interface
+- *D* Transaction control
 - *P* Turtle serialization / deserialization
 - *P* Full UTF-8 support
 - *P* Extended tests

+ 3 - 4
profile.c

@@ -31,14 +31,13 @@ int main(int argc, char *argv[])
 {
     size_t nt = (argc > 1) ? atoi (argv[1]) : NT;
     // Set env variable to test path.
-    putenv ("LSUP_MDB_STORE_PATH=" TMPDIR "/lsup_profile_mdb");
-    // Clear out database from previous test.
-    rm_r (getenv ("LSUP_MDB_STORE_PATH"));
+    putenv ("LSUP_MDB_STORE_URN=file://" TMPDIR "/lsup_profile_mdb");
 
     if (LSUP_init() != LSUP_OK) {
         log_fatal ("Failed to initialize LSUP environment.");
         exit (-1);
     }
+    LSUP_store_int (LSUP_STORE_MDB)->setup_fn (NULL, true);
 
     int rc;
     clock_t start, tc1, tc2, end;
@@ -54,7 +53,7 @@ int main(int argc, char *argv[])
 
     log_info ("Inserting triples.");
     LSUP_Graph *gr = LSUP_graph_new (
-            LSUP_iriref_new (NULL, NULL), LSUP_STORE_MDB);
+            LSUP_iriref_new (NULL, NULL), LSUP_STORE_MDB, NULL, NULL, nt);
     if (!gr) {
         log_error ("Error creating graph!");
         return -1;

+ 164 - 1
test/test_store.c

@@ -368,6 +368,167 @@ static int test_quad_store()
 }
 
 
+static int test_txn_commit (void)
+{
+    if (!(store->sif->features & LSUP_STORE_TXN)) return 0;
+
+    ASSERT (
+            store->sif->txn_begin_fn != NULL,
+            "Transaction begin function is NULL!");
+    ASSERT (
+            store->sif->txn_commit_fn != NULL,
+            "Transaction commit function is NULL!");
+    ASSERT (
+            store->sif->txn_abort_fn != NULL,
+            "Transaction abort function is NULL!");
+    ASSERT (
+            store->sif->add_abort_fn != NULL,
+            "Add abort function is NULL!");
+    ASSERT (
+            store->sif->iter_txn_fn != NULL,
+            "Iterator transaction function is NULL!");
+
+    if (store->sif->setup_fn)
+        EXPECT_PASS (store->sif->setup_fn (store->id, true));
+
+    log_info ("Testing transaction control for %s", store->id);
+    store->data = store->sif->new_fn (store->id, 0);
+    ASSERT (store->data != NULL, "Error creating store data back end!");
+
+    LSUP_Triple *trp = create_triples();
+    LSUP_BufferTriple ser_trp[NUM_TRP];
+
+    for (int i = 0; i < NUM_TRP; i++) {
+        LSUP_BufferTriple *tmp = LSUP_triple_serialize (trp + i);
+        ser_trp[i] = *tmp;
+        free (tmp);
+    }
+
+    void *it;
+    // Start adding then commit.
+    it = store->sif->add_init_fn (store->data, NULL, NULL);
+    for (size_t i = 0; i < NUM_TRP; i++) {
+        LSUP_rc rc = store->sif->add_iter_fn (it, ser_trp + i);
+        ASSERT (rc >= 0, "Error inserting triples!");
+    }
+    store->sif->add_abort_fn (it);
+
+    EXPECT_INT_EQ (store->sif->size_fn (store->data), 0);
+
+    // Add within a transaction, commit, then commit parent transaction.
+    void *txn;
+    EXPECT_PASS (store->sif->txn_begin_fn (store->data, 0, &txn));
+    it = store->sif->add_init_fn (store->data, NULL, txn);
+    for (size_t i = 0; i < NUM_TRP; i++) {
+        LSUP_rc rc = store->sif->add_iter_fn (it, ser_trp + i);
+        ASSERT (rc >= 0, "Error inserting triples!");
+    }
+    store->sif->add_done_fn (it);
+
+    // Triples are added in child txn but parent is still open.
+    // Size function always calculates outside of all transactions.
+    EXPECT_INT_EQ (store->sif->size_fn (store->data), 0);
+
+    size_t ct;
+    it = store->sif->lookup_fn (
+            store->data, NULL, NULL, NULL, NULL, txn, &ct);
+    store->sif->lu_free_fn (it);
+    // Should show triples added within the parent txn.
+    EXPECT_INT_EQ (ct, 8);
+
+    // commit child txn operations.
+    EXPECT_PASS (store->sif->txn_commit_fn (txn));
+    it = store->sif->lookup_fn (
+            store->data, NULL, NULL, NULL, NULL, NULL, &ct);
+    store->sif->lu_free_fn (it);
+    EXPECT_INT_EQ (ct, 8);
+    EXPECT_INT_EQ (store->sif->size_fn (store->data), 8);
+
+    for (int i = 0; i < NUM_TRP; i++) {
+        LSUP_buffer_free (ser_trp[i].s);
+        LSUP_buffer_free (ser_trp[i].p);
+        LSUP_buffer_free (ser_trp[i].o);
+    }
+
+    store->sif->free_fn (store->data);
+    free_triples (trp);
+
+    return 0;
+}
+
+
+static int test_txn_abort (void)
+{
+    if (!(store->sif->features & LSUP_STORE_TXN)) return 0;
+
+    if (store->sif->setup_fn)
+        EXPECT_PASS (store->sif->setup_fn (store->id, true));
+
+    log_info ("Testing transaction control for %s", store->id);
+    store->data = store->sif->new_fn (store->id, 0);
+    ASSERT (store->data != NULL, "Error creating store data back end!");
+
+    LSUP_Triple *trp = create_triples();
+    LSUP_BufferTriple ser_trp[NUM_TRP];
+
+    for (int i = 0; i < NUM_TRP; i++) {
+        LSUP_BufferTriple *tmp = LSUP_triple_serialize (trp + i);
+        ser_trp[i] = *tmp;
+        free (tmp);
+    }
+
+    void *it;
+    // Start adding then abort.
+    it = store->sif->add_init_fn (store->data, NULL, NULL);
+    for (size_t i = 0; i < NUM_TRP; i++) {
+        LSUP_rc rc = store->sif->add_iter_fn (it, ser_trp + i);
+        ASSERT (rc >= 0, "Error inserting triples!");
+    }
+    store->sif->add_abort_fn (it);
+
+    EXPECT_INT_EQ (store->sif->size_fn (store->data), 0);
+
+    // Add within a transaction, commit, then abort parent transaction.
+    void *txn;
+    EXPECT_PASS (store->sif->txn_begin_fn (store->data, 0, &txn));
+    it = store->sif->add_init_fn (store->data, NULL, txn);
+    for (size_t i = 0; i < NUM_TRP; i++) {
+        LSUP_rc rc = store->sif->add_iter_fn (it, ser_trp + i);
+        ASSERT (rc >= 0, "Error inserting triples!");
+    }
+    store->sif->add_done_fn (it);
+
+    // Triples are added in child txn but parent is still open.
+    // Size function always calculates outside of all transactions.
+    EXPECT_INT_EQ (store->sif->size_fn (store->data), 0);
+
+    size_t ct;
+    it = store->sif->lookup_fn (
+            store->data, NULL, NULL, NULL, NULL, txn, &ct);
+    store->sif->lu_free_fn (it);
+    // Should show triples added within the parent txn.
+    EXPECT_INT_EQ (ct, 8);
+
+    // Discard child txn operations.
+    store->sif->txn_abort_fn (txn);
+    it = store->sif->lookup_fn (
+            store->data, NULL, NULL, NULL, NULL, NULL, &ct);
+    store->sif->lu_free_fn (it);
+    EXPECT_INT_EQ (ct, 0);
+
+    for (int i = 0; i < NUM_TRP; i++) {
+        LSUP_buffer_free (ser_trp[i].s);
+        LSUP_buffer_free (ser_trp[i].p);
+        LSUP_buffer_free (ser_trp[i].o);
+    }
+
+    store->sif->free_fn (store->data);
+    free_triples (trp);
+
+    return 0;
+}
+
+
 int store_tests()
 {
 #define ENTRY(a, b) \
@@ -375,7 +536,9 @@ int store_tests()
     store->id = STORE_ID_##a; \
     store->sif = &b; \
     RUN (test_triple_store); \
-    RUN (test_quad_store);
+    RUN (test_quad_store); \
+    RUN (test_txn_commit); \
+    RUN (test_txn_abort);
 BACKEND_TBL
 #undef ENTRY
     return 0;