test_graph.c 20 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697
  1. #include "test.h"
  2. #include "graph.h"
  3. #include "assets/triples.h"
  4. #define N_LUT 13
  5. static int
  6. _graph_new (LSUP_StoreType type)
  7. {
  8. const LSUP_StoreInt *sif = LSUP_store_int (type);
  9. if (sif->setup_fn) sif->setup_fn (NULL, true);
  10. LSUP_Graph *gr;
  11. LSUP_Store *store;
  12. if (type == LSUP_STORE_HTABLE) {
  13. gr = LSUP_graph_new (NULL, NULL, NULL);
  14. } else {
  15. store = LSUP_store_new (type, NULL, 0);
  16. gr = LSUP_graph_new (store, NULL, NULL);
  17. }
  18. ASSERT (gr != NULL, "Error creating graph!");
  19. EXPECT_PASS (LSUP_graph_set_uri (gr, "urn:gr:1"));
  20. EXPECT_STR_EQ (LSUP_graph_uri (gr)->data, "urn:gr:1");
  21. // Check that setup function is idempotent with clear == false.
  22. if (sif->setup_fn) EXPECT_INT_EQ (
  23. sif->setup_fn (NULL, false), LSUP_NOACTION);
  24. ASSERT (
  25. strcmp (LSUP_graph_uri (gr)->data, "urn:gr:1") == 0,
  26. "Graph URI mismatch!");
  27. EXPECT_INT_EQ (LSUP_graph_size (gr), 0);
  28. LSUP_graph_free (gr);
  29. if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
  30. return 0;
  31. }
  32. static int
  33. _graph_add (LSUP_StoreType type)
  34. {
  35. const LSUP_StoreInt *sif = LSUP_store_int (type);
  36. if (sif->setup_fn) sif->setup_fn (NULL, true);
  37. LSUP_Triple **trp = create_triples();
  38. LSUP_Graph *gr;
  39. LSUP_Store *store;
  40. if (type == LSUP_STORE_HTABLE) store = NULL;
  41. else store = LSUP_store_new (type, NULL, 0);
  42. gr = LSUP_graph_new (store, NULL, NULL);
  43. ASSERT (gr != NULL, "Error creating graph!");
  44. size_t ct;
  45. LSUP_graph_add (gr, trp, &ct);
  46. EXPECT_INT_EQ (ct, 8);
  47. EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
  48. for (int i = 0; i < sizeof (trp); i++) {
  49. log_info ("checking triple #%d.", i);
  50. ASSERT (LSUP_graph_contains (gr, trp[i]), "Triple not in graph!");
  51. }
  52. LSUP_Triple *missing_trp = LSUP_triple_new (
  53. trp[1]->s, trp[6]->p, trp[4]->o);
  54. ASSERT (! LSUP_graph_contains (gr, missing_trp), "Triple in graph!");
  55. free (missing_trp);
  56. free_triples (trp); // gr copied data.
  57. // Check size again after freeing triples.
  58. EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
  59. LSUP_Graph *gr2 = LSUP_graph_new (NULL, NULL, NULL);
  60. // Test equality against empty graph.
  61. ASSERT (!LSUP_graph_equals (gr, gr2), "Graphs should not be equal!");
  62. ASSERT (!LSUP_graph_equals (gr2, gr), "Graphs should not be equal!");
  63. LSUP_graph_free (gr);
  64. LSUP_graph_free (gr2);
  65. if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
  66. return 0;
  67. }
  68. static int
  69. _graph_get (LSUP_StoreType type)
  70. {
  71. const LSUP_StoreInt *sif = LSUP_store_int (type);
  72. // Skip if the store doesn't support contexts.
  73. if (!(sif->features & LSUP_STORE_CTX)) return 0;
  74. if (sif->setup_fn) sif->setup_fn (NULL, true);
  75. LSUP_Triple **trp = create_triples();
  76. LSUP_Store *store = LSUP_store_new (type, NULL, 0);
  77. LSUP_Graph
  78. *gr1 = LSUP_graph_new (store, NULL, NULL),
  79. *gr2 = LSUP_graph_new (store, NULL, NULL);
  80. ASSERT (gr1 != NULL, "Error creating graph!");
  81. ASSERT (gr2 != NULL, "Error creating graph!");
  82. // Add 2 groups of triples to different graphs.
  83. void *it1 = LSUP_graph_add_init (gr1);
  84. for (size_t i = 0; i < 5; i++) {
  85. LSUP_graph_add_iter(it1, trp[i]);
  86. }
  87. LSUP_graph_add_done (it1);
  88. void *it2 = LSUP_graph_add_init (gr2);
  89. for (size_t i = 5; i < NUM_TRP; i++) {
  90. LSUP_graph_add_iter(it2, trp[i]);
  91. }
  92. LSUP_graph_add_done (it2);
  93. EXPECT_INT_EQ (LSUP_graph_size (gr1), 5);
  94. EXPECT_INT_EQ (LSUP_graph_size (gr2), 3);
  95. size_t ct3, ct4;
  96. LSUP_Graph
  97. *gr3 = LSUP_graph_get (store, LSUP_graph_uri (gr1), &ct3),
  98. *gr4 = LSUP_graph_get (store, LSUP_graph_uri (gr2), &ct4);
  99. EXPECT_INT_EQ (LSUP_graph_size (gr3), LSUP_graph_size (gr1));
  100. EXPECT_INT_EQ (LSUP_graph_size (gr4), LSUP_graph_size (gr2));
  101. ASSERT (!LSUP_graph_equals (gr1, gr2), "Graphs 1 and 2 are equal!");
  102. ASSERT (!LSUP_graph_equals (gr3, gr4), "Graphs 3 and 4 are equal!");
  103. ASSERT (LSUP_graph_equals (gr1, gr3), "Graphs 1 and 3 are not equal!");
  104. ASSERT (LSUP_graph_equals (gr2, gr4), "Graphs 2 and 4 are not equal!");
  105. LSUP_graph_free (gr1);
  106. LSUP_graph_free (gr2);
  107. LSUP_graph_free (gr3);
  108. LSUP_graph_free (gr4);
  109. free_triples (trp);
  110. if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
  111. return 0;
  112. }
  113. static int
  114. _graph_bool_ops (LSUP_StoreType type)
  115. {
  116. const LSUP_StoreInt *sif = LSUP_store_int (type);
  117. // Skip if the store doesn't support contexts.
  118. if (!(sif->features & LSUP_STORE_CTX)) return 0;
  119. if (sif->setup_fn) sif->setup_fn (NULL, true);
  120. LSUP_Triple **trp = create_triples();
  121. LSUP_Store *store = LSUP_store_new (type, NULL, 0);
  122. LSUP_Graph
  123. *gr1 = LSUP_graph_new (store, NULL, NULL),
  124. *gr2 = LSUP_graph_new (store, NULL, NULL),
  125. *gr_dest;
  126. // Add 2 groups of triples to different graphs.
  127. void *it;
  128. it = LSUP_graph_add_init (gr1);
  129. for (size_t i = 0; i < 4; i++) {
  130. LSUP_graph_add_iter(it, trp[i]);
  131. }
  132. LSUP_graph_add_done (it);
  133. // Skip duplicate triples, we already tested those.
  134. // trp[3] is in both graphs.
  135. it = LSUP_graph_add_init (gr2);
  136. for (size_t i = 3; i < 8; i++) {
  137. LSUP_graph_add_iter(it, trp[i]);
  138. }
  139. LSUP_graph_add_done (it);
  140. // Test union.
  141. gr_dest = LSUP_graph_new (store, NULL, NULL);
  142. EXPECT_PASS (LSUP_graph_bool_op (LSUP_BOOL_UNION, gr1, gr2, gr_dest));
  143. for (size_t i = 0; i < 8; i++)
  144. ASSERT (LSUP_graph_contains (gr_dest, trp[i]), "Union test failed!");
  145. LSUP_graph_free (gr_dest);
  146. // Test subtraction.
  147. gr_dest = LSUP_graph_new (store, NULL, NULL);
  148. EXPECT_PASS (LSUP_graph_bool_op (
  149. LSUP_BOOL_SUBTRACTION, gr1, gr2, gr_dest));
  150. for (size_t i = 0; i < 3; i++)
  151. ASSERT (LSUP_graph_contains (
  152. gr_dest, trp[i]), "Subtraction test is missing triples!");
  153. for (size_t i = 3; i < 8; i++)
  154. ASSERT (!LSUP_graph_contains (
  155. gr_dest, trp[i]), "Subtraction test has excess triples!");
  156. LSUP_graph_free (gr_dest);
  157. gr_dest = LSUP_graph_new (store, NULL, NULL);
  158. EXPECT_PASS (LSUP_graph_bool_op (
  159. LSUP_BOOL_SUBTRACTION, gr2, gr1, gr_dest));
  160. for (size_t i = 0; i < 4; i++)
  161. ASSERT (!LSUP_graph_contains (
  162. gr_dest, trp[i]), "Subtraction test is missing triples!");
  163. for (size_t i = 4; i < 8; i++)
  164. ASSERT (LSUP_graph_contains (
  165. gr_dest, trp[i]), "Subtraction test has excess triples!");
  166. LSUP_graph_free (gr_dest);
  167. // Test intersection.
  168. gr_dest = LSUP_graph_new (store, NULL, NULL);
  169. EXPECT_PASS (LSUP_graph_bool_op (
  170. LSUP_BOOL_INTERSECTION, gr1, gr2, gr_dest));
  171. for (size_t i = 0; i < 3; i++)
  172. ASSERT (!LSUP_graph_contains (
  173. gr_dest, trp[i]), "Intersection is missing triples!");
  174. ASSERT (LSUP_graph_contains (
  175. gr_dest, trp[3]), "Intersection test failed!");
  176. for (size_t i = 4; i < 8; i++)
  177. ASSERT (!LSUP_graph_contains (
  178. gr_dest, trp[i]), "Intersection test has excess triples!");
  179. LSUP_graph_free (gr_dest);
  180. // Test XOR.
  181. gr_dest = LSUP_graph_new (store, NULL, NULL);
  182. EXPECT_PASS (LSUP_graph_bool_op (LSUP_BOOL_XOR, gr1, gr2, gr_dest));
  183. for (size_t i = 0; i < 3; i++)
  184. ASSERT (LSUP_graph_contains (
  185. gr_dest, trp[i]), "XOR test is missing triples!");
  186. ASSERT (!LSUP_graph_contains (
  187. gr_dest, trp[3]), "XOR test has excess triples!");
  188. for (size_t i = 4; i < 8; i++)
  189. ASSERT (LSUP_graph_contains (
  190. gr_dest, trp[i]), "XOR test is missing triples!");
  191. LSUP_graph_free (gr_dest);
  192. // Test union with result graph as one of the sources.
  193. EXPECT_PASS (LSUP_graph_bool_op (LSUP_BOOL_UNION, gr1, gr2, gr1));
  194. for (size_t i = 0; i < 8; i++)
  195. ASSERT (LSUP_graph_contains (gr1, trp[i]), "Self-union test failed!");
  196. LSUP_graph_free (gr1);
  197. LSUP_graph_free (gr2);
  198. free_triples (trp);
  199. if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
  200. return 0;
  201. }
  202. static int
  203. _graph_lookup (LSUP_StoreType type)
  204. {
  205. const LSUP_StoreInt *sif = LSUP_store_int (type);
  206. LSUP_Triple **trp = create_triples();
  207. // Lookup triples.
  208. LSUP_Term *lu_trp[N_LUT][3] = {
  209. {NULL, NULL, NULL}, // 8 matches
  210. {trp[0]->s, NULL, NULL}, // 5 matches
  211. {NULL, trp[2]->p, NULL}, // 3 matches
  212. {NULL, NULL, trp[5]->o}, // 2 matches
  213. {trp[0]->s, trp[0]->p, NULL}, // 1 match
  214. {NULL, trp[0]->p, trp[0]->o}, // 1 match
  215. {trp[0]->s, trp[2]->p, trp[5]->o}, // 1 match
  216. {trp[0]->p, NULL, NULL}, // 0 matches
  217. {NULL, trp[2]->s, NULL}, // 0 matches
  218. {NULL, NULL, trp[5]->p}, // 0 matches
  219. {trp[2]->s, trp[6]->p, NULL}, // 0 matches
  220. {NULL, trp[1]->p, trp[5]->o}, // 0 matches
  221. {trp[2]->s, trp[2]->p, trp[5]->o}, // 0 matches
  222. };
  223. // Lookup result counts.
  224. size_t lu_ct[N_LUT] = {
  225. 8,
  226. 5, 3, 2,
  227. 1, 1, 1,
  228. 0, 0, 0,
  229. 0, 0, 0
  230. };
  231. /* TODO
  232. // Index of lookup matches from trp.
  233. size_t lu_match[N_LUT][8] = {
  234. {0, 1, 2, 3, 4, 5, 6, 7},
  235. {0, 3, 4, 5, 7}, {2, 4, 7}, {5, 7},
  236. {0}, {0}, {7},
  237. {}, {}, {},
  238. {}, {}, {},
  239. };
  240. // Index of lookup non-matches from trp.
  241. size_t lu_no_match[N_LUT][8] = {
  242. {},
  243. {1, 2, 6}, {0, 1, 3, 5, 6}, {0, 1, 2, 3, 4, 6},
  244. {1, 2, 3, 4, 5, 6, 7}, {1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6},
  245. {0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7},
  246. {0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7}, {0, 1, 2, 3, 4, 5, 6, 7},
  247. };
  248. */
  249. if (sif->setup_fn) sif->setup_fn (NULL, true);
  250. LSUP_Graph *gr;
  251. LSUP_Store *store;
  252. if (type == LSUP_STORE_HTABLE) {
  253. gr = LSUP_graph_new (NULL, NULL, NULL);
  254. } else {
  255. store = LSUP_store_new (type, NULL, 0);
  256. gr = LSUP_graph_new (store, NULL, NULL);
  257. }
  258. size_t ct;
  259. LSUP_graph_add (gr, trp, &ct);
  260. EXPECT_INT_EQ (ct, 8);
  261. EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
  262. for (int i = 0; i < N_LUT; i++) {
  263. log_info ("Checking triple #%d on %d.", i, type);
  264. LSUP_GraphIterator *it = LSUP_graph_lookup (
  265. gr, lu_trp[i][0], lu_trp[i][1], lu_trp[i][2], &ct);
  266. EXPECT_INT_EQ (ct, lu_ct[i]);
  267. // Verify that iteration count matches stat count.
  268. LSUP_Triple *spo = NULL;
  269. ct = 0;
  270. while (LSUP_graph_iter_next (it, &spo) != LSUP_END) {
  271. ct++;
  272. // TODO do something useful with the triple.
  273. LSUP_triple_free (spo);
  274. spo = NULL;
  275. }
  276. LSUP_triple_free (spo);
  277. EXPECT_INT_EQ (ct, lu_ct[i]);
  278. /* TODO
  279. for (int j = 0; j < 8; j++) {
  280. for (int k = 0; LSUP_graph_iter_next(it) != LSUP_END; k++) {
  281. ASSERT (
  282. LSUP_graph_contains (trp[lu_match[j]]),
  283. "Triple not found!");
  284. ASSERT (
  285. !(LSUP_graph_contains (trp[lu_no_match[j]])),
  286. "Unexpected triple found!");
  287. }
  288. }
  289. */
  290. LSUP_graph_iter_free (it);
  291. };
  292. #if 0
  293. // Enable to test print functionality and exit early.
  294. LSUP_graph_print (gr);
  295. return 1;
  296. #endif
  297. free_triples (trp);
  298. LSUP_graph_free (gr);
  299. if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
  300. return 0;
  301. }
  302. static int
  303. _graph_remove (LSUP_StoreType type)
  304. {
  305. const LSUP_StoreInt *sif = LSUP_store_int (type);
  306. if (sif->setup_fn) sif->setup_fn (NULL, true);
  307. LSUP_Triple **trp = create_triples();
  308. LSUP_Graph *gr;
  309. LSUP_Store *store;
  310. if (type == LSUP_STORE_HTABLE) {
  311. gr = LSUP_graph_new (NULL, NULL, NULL);
  312. } else {
  313. store = LSUP_store_new (type, NULL, 0);
  314. gr = LSUP_graph_new (store, NULL, NULL);
  315. }
  316. size_t ct;
  317. LSUP_graph_add (gr, trp, &ct);
  318. EXPECT_INT_EQ (ct, 8);
  319. EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
  320. // Triples 0, 3, 4, 5, 7 will be removed.
  321. LSUP_graph_remove (gr, trp[0]->s, NULL, NULL, &ct);
  322. EXPECT_INT_EQ (ct, 5);
  323. EXPECT_INT_EQ (LSUP_graph_size (gr), 3);
  324. ASSERT (!LSUP_graph_contains (gr, trp[0]), "Unexpected triple found!");
  325. ASSERT (LSUP_graph_contains (gr, trp[1]), "Triple not in graph!");
  326. ASSERT (LSUP_graph_contains (gr, trp[2]), "Triple not in graph!");
  327. ASSERT (!LSUP_graph_contains (gr, trp[3]), "Unexpected triple found!");
  328. ASSERT (!LSUP_graph_contains (gr, trp[4]), "Unexpected triple found!");
  329. ASSERT (!LSUP_graph_contains (gr, trp[5]), "Unexpected triple found!");
  330. ASSERT (LSUP_graph_contains (gr, trp[6]), "Triple not in graph!");
  331. ASSERT (!LSUP_graph_contains (gr, trp[7]), "Unexpected triple found!");
  332. free_triples (trp); // gr copied data.
  333. LSUP_graph_free (gr);
  334. if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
  335. // TODO Test complete removal of triples from index when they are not
  336. // in another context.
  337. return 0;
  338. }
  339. static int
  340. _graph_txn (LSUP_StoreType type)
  341. {
  342. const LSUP_StoreInt *sif = LSUP_store_int (type);
  343. if (!(sif->features & LSUP_STORE_TXN)) return 0;
  344. if (sif->setup_fn) sif->setup_fn (NULL, true);
  345. LSUP_Triple **trp = create_triples();
  346. LSUP_Graph *gr;
  347. LSUP_Store *store =
  348. type == LSUP_STORE_HTABLE ? NULL
  349. : LSUP_store_new (type, NULL, 0);
  350. gr = LSUP_graph_new (store, NULL, NULL);
  351. void *txn;
  352. size_t ct;
  353. EXPECT_PASS (LSUP_store_begin (store, 0, &txn));
  354. EXPECT_PASS (LSUP_graph_add_txn (txn, gr, trp, &ct));
  355. LSUP_store_abort (store, txn);
  356. // NOTE that ct reports the count before the txn was aborted. This is
  357. // intentional.
  358. EXPECT_INT_EQ (ct, 8);
  359. EXPECT_INT_EQ (LSUP_graph_size (gr), 0);
  360. EXPECT_PASS (LSUP_store_begin (store, 0, &txn));
  361. EXPECT_PASS (LSUP_graph_add_txn (txn, gr, trp, &ct));
  362. LSUP_store_commit (store, txn);
  363. EXPECT_INT_EQ (ct, 8);
  364. EXPECT_INT_EQ (LSUP_graph_size (gr), 8);
  365. LSUP_graph_free (gr);
  366. if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
  367. free_triples (trp); // gr copied data.
  368. return 0;
  369. }
  370. static int
  371. _graph_relative (LSUP_StoreType type)
  372. {
  373. const LSUP_StoreInt *sif = LSUP_store_int (type);
  374. if (sif->setup_fn) sif->setup_fn (NULL, true);
  375. LSUP_Term
  376. *s = LSUP_iriref_new ("http://onto.knowledgetx.com/gr1/s1", NULL),
  377. *s2 = LSUP_iriref_new ("http://onto.knowledgetx.com/gr2/s1", NULL),
  378. *p = LSUP_iriref_new ("http://onto.knowledgetx.com/vocab/p1", NULL),
  379. *o = LSUP_iriref_new ("http://onto.knowledgetx.com/gr1/o1", NULL),
  380. *o2 = LSUP_iriref_new ("http://onto.knowledgetx.com/gr2/o1", NULL),
  381. *c = LSUP_iriref_new ("http://onto.knowledgetx.com/gr1/", NULL),
  382. *rel_s = LSUP_iriref_relative (c, s),
  383. *rel_o = LSUP_iriref_relative (c, o);
  384. LSUP_Triple *spo[2] = {
  385. LSUP_triple_new (s, p, o),
  386. NULL
  387. };
  388. LSUP_Triple *rel_spo = LSUP_triple_new (rel_s, p, rel_o);
  389. LSUP_Store *store =
  390. type == LSUP_STORE_HTABLE ? NULL
  391. : LSUP_store_new (type, NULL, 0);
  392. LSUP_Graph *gr = LSUP_graph_new (store, c->data, NULL);
  393. size_t ct;
  394. LSUP_graph_add (gr, spo, &ct);
  395. // Both absolute and relative IRIs should be found.
  396. ASSERT (LSUP_graph_contains (gr, rel_spo), "Relative triple not found!");
  397. ASSERT (LSUP_graph_contains (gr, spo[0]), "Absolute triple not found!");
  398. // Change graph URI and verify that relative URIs are still found, and
  399. // that absolute URIs change with it.
  400. spo[0]->s = s2;
  401. LSUP_term_free (s);
  402. spo[0]->o = o2;
  403. LSUP_term_free (o);
  404. LSUP_graph_set_uri (gr, "http://onto.knowledgetx.com/gr2/");
  405. LSUP_term_free (c);
  406. ASSERT (LSUP_graph_contains (gr, rel_spo), "Relative triple not found!");
  407. ASSERT (LSUP_graph_contains (gr, spo[0]), "Absolute triple not found!");
  408. LSUP_triple_free (spo[0]);
  409. LSUP_term_free (rel_s);
  410. LSUP_term_free (rel_o);
  411. free (rel_spo);
  412. LSUP_graph_free (gr);
  413. if (type != LSUP_STORE_HTABLE) LSUP_store_free (store);
  414. return 0;
  415. }
  416. static int
  417. test_environment()
  418. {
  419. // The env should already be initialized and re-initializing it is idempotent.
  420. EXPECT_INT_EQ (LSUP_IS_INIT, true);
  421. ASSERT (LSUP_init() > 0, "Error initializing environment!");
  422. EXPECT_INT_EQ (LSUP_IS_INIT, true);
  423. // Tearing down is idempotent too.
  424. LSUP_done();
  425. EXPECT_INT_EQ (LSUP_IS_INIT, false);
  426. LSUP_done();
  427. EXPECT_INT_EQ (LSUP_IS_INIT, false);
  428. ASSERT (LSUP_init() >= 0, "Environment not initialized!");
  429. EXPECT_INT_EQ (LSUP_IS_INIT, true);
  430. ASSERT (LSUP_init() >= 0, "Environment not initialized!");
  431. EXPECT_INT_EQ (LSUP_IS_INIT, true);
  432. return 0;
  433. }
  434. static int test_graph_new() {
  435. #define ENTRY(a, b) \
  436. if (_graph_new (LSUP_STORE_##a) != 0) return -1;
  437. BACKEND_TBL
  438. #undef ENTRY
  439. return 0;
  440. }
  441. static int test_graph_add() {
  442. #define ENTRY(a, b) \
  443. if (_graph_add (LSUP_STORE_##a) != 0) return -1;
  444. BACKEND_TBL
  445. #undef ENTRY
  446. return 0;
  447. }
  448. static int test_graph_get() {
  449. #define ENTRY(a, b) \
  450. if (_graph_get (LSUP_STORE_##a) != 0) return -1;
  451. BACKEND_TBL
  452. #undef ENTRY
  453. return 0;
  454. }
  455. static int test_graph_bool_ops() {
  456. #define ENTRY(a, b) \
  457. if (_graph_bool_ops (LSUP_STORE_##a) != 0) return -1;
  458. BACKEND_TBL
  459. #undef ENTRY
  460. return 0;
  461. }
  462. static int test_graph_lookup() {
  463. #define ENTRY(a, b) \
  464. if (_graph_lookup (LSUP_STORE_##a) != 0) return -1;
  465. BACKEND_TBL
  466. #undef ENTRY
  467. return 0;
  468. }
  469. static int test_graph_remove() {
  470. #define ENTRY(a, b) \
  471. if (_graph_remove (LSUP_STORE_##a) != 0) return -1;
  472. BACKEND_TBL
  473. #undef ENTRY
  474. return 0;
  475. }
  476. static int test_graph_txn()
  477. {
  478. /*
  479. * Test transactions only if the backend supports them.
  480. */
  481. #define ENTRY(a, b) \
  482. if (_graph_txn (LSUP_STORE_##a) != 0) return -1;
  483. BACKEND_TBL
  484. #undef ENTRY
  485. return 0;
  486. }
  487. static int test_graph_relative()
  488. {
  489. /*
  490. * Test relative URIs in graphs.
  491. */
  492. #define ENTRY(a, b) \
  493. if (_graph_relative (LSUP_STORE_##a) != 0) return -1;
  494. BACKEND_TBL
  495. #undef ENTRY
  496. return 0;
  497. }
  498. static int test_graph_copy()
  499. {
  500. LSUP_Triple **trp = create_triples();
  501. LSUP_Graph *gr1 = LSUP_graph_new (NULL, NULL, NULL);
  502. ASSERT (gr1 != NULL, "Error creating graph!");
  503. LSUP_graph_add (gr1, trp, NULL);
  504. // Copy to graph with same store type.
  505. LSUP_Graph *gr2 = LSUP_graph_new (NULL, NULL, NULL);
  506. EXPECT_PASS (LSUP_graph_copy_contents (gr1, gr2, NULL, NULL, NULL));
  507. EXPECT_INT_EQ (LSUP_graph_size (gr1), LSUP_graph_size (gr2));
  508. for (int i = 0; i < sizeof (trp); i++) {
  509. log_info ("checking triple #%d.", i);
  510. ASSERT (
  511. LSUP_graph_contains (gr2, trp[i]),
  512. "Triple not in copied graph!");
  513. }
  514. // Copy to graph with a different store type.
  515. LSUP_Graph *gr3 = LSUP_graph_new (NULL, NULL, NULL);
  516. EXPECT_PASS (LSUP_graph_copy_contents (gr1, gr3, NULL, NULL, NULL));
  517. EXPECT_INT_EQ (LSUP_graph_size (gr1), LSUP_graph_size (gr2));
  518. for (int i = 0; i < sizeof (trp); i++) {
  519. log_info ("checking triple #%d.", i);
  520. ASSERT (
  521. LSUP_graph_contains (gr3, trp[i]),
  522. "Triple not in copied graph!");
  523. }
  524. LSUP_graph_free (gr3);
  525. LSUP_graph_free (gr2);
  526. LSUP_graph_free (gr1);
  527. free_triples (trp);
  528. return 0;
  529. }
  530. int graph_tests()
  531. {
  532. RUN (test_environment);
  533. RUN (test_graph_new);
  534. RUN (test_graph_add);
  535. RUN (test_graph_get);
  536. RUN (test_graph_bool_ops);
  537. RUN (test_graph_lookup);
  538. RUN (test_graph_remove);
  539. RUN (test_graph_copy);
  540. RUN (test_graph_txn);
  541. RUN (test_graph_relative);
  542. return 0;
  543. }