test_graph.py 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691
  1. import pdb
  2. import pytest
  3. from shutil import rmtree
  4. from rdflib import Graph, Namespace, URIRef
  5. from lakesuperior.model.graph.graph import Graph
  6. from lakesuperior.store.ldp_rs.lmdb_store import LmdbStore
  7. @pytest.fixture(scope='class')
  8. def store():
  9. """
  10. Test LMDB store.
  11. This store has a different life cycle than the one used for tests in higher
  12. levels of the stack and is not bootstrapped (i.e. starts completely empty).
  13. """
  14. env_path = '/tmp/test_lmdbstore'
  15. # Remove previous test DBs
  16. rmtree(env_path, ignore_errors=True)
  17. store = LmdbStore(env_path)
  18. yield store
  19. store.close()
  20. store.destroy()
  21. @pytest.fixture(scope='class')
  22. def trp():
  23. return (
  24. (URIRef('urn:s:0'), URIRef('urn:p:0'), URIRef('urn:o:0')),
  25. # Exact same as [0].
  26. (URIRef('urn:s:0'), URIRef('urn:p:0'), URIRef('urn:o:0')),
  27. # NOTE: s and o are in reversed order.
  28. (URIRef('urn:o:0'), URIRef('urn:p:0'), URIRef('urn:s:0')),
  29. (URIRef('urn:s:0'), URIRef('urn:p:1'), URIRef('urn:o:0')),
  30. (URIRef('urn:s:0'), URIRef('urn:p:1'), URIRef('urn:o:1')),
  31. (URIRef('urn:s:1'), URIRef('urn:p:1'), URIRef('urn:o:1')),
  32. (URIRef('urn:s:1'), URIRef('urn:p:2'), URIRef('urn:o:2')),
  33. )
  34. @pytest.mark.usefixtures('trp')
  35. @pytest.mark.usefixtures('store')
  36. class TestGraphInit:
  37. """
  38. Test initialization of graphs with different base data sets.
  39. """
  40. def test_empty(self):
  41. """
  42. Test creation of an empty graph.
  43. """
  44. gr = Graph()
  45. assert len(gr) == 0
  46. def test_init_triples(self, trp, store):
  47. """
  48. Test creation using a Python set.
  49. """
  50. with store.txn_ctx(True):
  51. pdb.set_trace()
  52. gr = Graph(store, data=set(trp))
  53. assert len(gr) == 6
  54. for t in trp:
  55. assert t in gr
  56. @pytest.mark.usefixtures('trp')
  57. class TestGraphLookup:
  58. """
  59. Test triple lookup.
  60. TODO
  61. """
  62. @pytest.mark.skip(reason='TODO')
  63. def test_lookup_pattern(self, trp):
  64. """
  65. Test lookup by basic pattern.
  66. """
  67. pass
  68. @pytest.mark.usefixtures('trp')
  69. class TestGraphOps:
  70. """
  71. Test various graph operations.
  72. """
  73. def test_len(self, trp):
  74. """
  75. Test the length of a graph with and without duplicates.
  76. """
  77. gr = Graph()
  78. assert len(gr) == 0
  79. gr.add((trp[0],))
  80. assert len(gr) == 1
  81. gr.add((trp[1],)) # Same values
  82. assert len(gr) == 1
  83. gr.add((trp[2],))
  84. assert len(gr) == 2
  85. gr.add(trp)
  86. assert len(gr) == 6
  87. def test_dup(self, trp):
  88. """
  89. Test operations with duplicate triples.
  90. """
  91. gr = Graph()
  92. #import pdb; pdb.set_trace()
  93. gr.add((trp[0],))
  94. assert trp[1] in gr
  95. assert trp[2] not in gr
  96. def test_remove(self, trp):
  97. """
  98. Test adding and removing triples.
  99. """
  100. gr = Graph()
  101. gr.add(trp)
  102. gr.remove(trp[0])
  103. assert len(gr) == 5
  104. assert trp[0] not in gr
  105. assert trp[1] not in gr
  106. # This is the duplicate triple.
  107. gr.remove(trp[1])
  108. assert len(gr) == 5
  109. # This is the triple in reverse order.
  110. gr.remove(trp[2])
  111. assert len(gr) == 4
  112. gr.remove(trp[4])
  113. assert len(gr) == 3
  114. def test_union(self, trp):
  115. """
  116. Test graph union.
  117. """
  118. gr1 = Graph()
  119. gr2 = Graph()
  120. gr1.add(trp[0:3])
  121. gr2.add(trp[2:6])
  122. gr3 = gr1 | gr2
  123. assert len(gr3) == 5
  124. assert trp[0] in gr3
  125. assert trp[4] in gr3
  126. def test_ip_union(self, trp):
  127. """
  128. Test graph in-place union.
  129. """
  130. gr1 = Graph()
  131. gr2 = Graph()
  132. gr1.add(trp[0:3])
  133. gr2.add(trp[2:6])
  134. gr1 |= gr2
  135. assert len(gr1) == 5
  136. assert trp[0] in gr1
  137. assert trp[4] in gr1
  138. def test_addition(self, trp):
  139. """
  140. Test graph addition.
  141. """
  142. gr1 = Graph()
  143. gr2 = Graph()
  144. gr1.add(trp[0:3])
  145. gr2.add(trp[2:6])
  146. gr3 = gr1 + gr2
  147. assert len(gr3) == 5
  148. assert trp[0] in gr3
  149. assert trp[4] in gr3
  150. def test_ip_addition(self, trp):
  151. """
  152. Test graph in-place addition.
  153. """
  154. gr1 = Graph()
  155. gr2 = Graph()
  156. gr1.add(trp[0:3])
  157. gr2.add(trp[2:6])
  158. gr1 += gr2
  159. assert len(gr1) == 5
  160. assert trp[0] in gr1
  161. assert trp[4] in gr1
  162. def test_subtraction(self, trp):
  163. """
  164. Test graph addition.
  165. """
  166. gr1 = Graph()
  167. gr2 = Graph()
  168. gr1.add(trp[0:4])
  169. gr2.add(trp[2:6])
  170. gr3 = gr1 - gr2
  171. assert len(gr3) == 1
  172. assert trp[0] in gr3
  173. assert trp[1] in gr3
  174. assert trp[2] not in gr3
  175. assert trp[3] not in gr3
  176. assert trp[4] not in gr3
  177. gr3 = gr2 - gr1
  178. assert len(gr3) == 2
  179. assert trp[0] not in gr3
  180. assert trp[1] not in gr3
  181. assert trp[2] not in gr3
  182. assert trp[3] not in gr3
  183. assert trp[4] in gr3
  184. assert trp[5] in gr3
  185. def test_ip_subtraction(self, trp):
  186. """
  187. Test graph in-place addition.
  188. """
  189. gr1 = Graph()
  190. gr2 = Graph()
  191. gr1.add(trp[0:4])
  192. gr2.add(trp[2:6])
  193. gr1 -= gr2
  194. assert len(gr1) == 1
  195. assert trp[0] in gr1
  196. assert trp[1] in gr1
  197. assert trp[2] not in gr1
  198. assert trp[3] not in gr1
  199. assert trp[4] not in gr1
  200. def test_intersect(self, trp):
  201. """
  202. Test graph intersextion.
  203. """
  204. gr1 = Graph()
  205. gr2 = Graph()
  206. gr1.add(trp[0:4])
  207. gr2.add(trp[2:6])
  208. gr3 = gr1 & gr2
  209. assert len(gr3) == 2
  210. assert trp[2] in gr3
  211. assert trp[3] in gr3
  212. assert trp[0] not in gr3
  213. assert trp[5] not in gr3
  214. def test_ip_intersect(self, trp):
  215. """
  216. Test graph intersextion.
  217. """
  218. gr1 = Graph()
  219. gr2 = Graph()
  220. gr1.add(trp[0:4])
  221. gr2.add(trp[2:6])
  222. gr1 &= gr2
  223. assert len(gr1) == 2
  224. assert trp[2] in gr1
  225. assert trp[3] in gr1
  226. assert trp[0] not in gr1
  227. assert trp[5] not in gr1
  228. def test_xor(self, trp):
  229. """
  230. Test graph intersextion.
  231. """
  232. gr1 = Graph()
  233. gr2 = Graph()
  234. gr1.add(trp[0:4])
  235. gr2.add(trp[2:6])
  236. gr3 = gr1 ^ gr2
  237. assert len(gr3) == 3
  238. assert trp[2] not in gr3
  239. assert trp[3] not in gr3
  240. assert trp[0] in gr3
  241. assert trp[5] in gr3
  242. def test_ip_xor(self, trp):
  243. """
  244. Test graph intersextion.
  245. """
  246. gr1 = Graph()
  247. gr2 = Graph()
  248. gr1.add(trp[0:4])
  249. gr2.add(trp[2:6])
  250. gr1 ^= gr2
  251. assert len(gr1) == 3
  252. assert trp[2] not in gr1
  253. assert trp[3] not in gr1
  254. assert trp[0] in gr1
  255. assert trp[5] in gr1
  256. @pytest.mark.usefixtures('trp')
  257. class TestNamedGraphOps:
  258. """
  259. Test various operations on a named graph.
  260. """
  261. def test_len(self, trp):
  262. """
  263. Test the length of a graph with and without duplicates.
  264. """
  265. imr = Graph(uri='http://example.edu/imr01')
  266. assert len(imr) == 0
  267. imr.add((trp[0],))
  268. assert len(imr) == 1
  269. imr.add((trp[1],)) # Same values
  270. assert len(imr) == 1
  271. imr.add((trp[2],))
  272. assert len(imr) == 2
  273. imr.add(trp)
  274. assert len(imr) == 6
  275. def test_dup(self, trp):
  276. """
  277. Test operations with duplicate triples.
  278. """
  279. imr = Graph(uri='http://example.edu/imr01')
  280. #import pdb; pdb.set_trace()
  281. imr.add((trp[0],))
  282. assert trp[1] in imr
  283. assert trp[2] not in imr
  284. def test_remove(self, trp):
  285. """
  286. Test adding and removing triples.
  287. """
  288. imr = Graph(uri='http://example.edu/imr01')
  289. imr.add(trp)
  290. imr.remove(trp[0])
  291. assert len(imr) == 5
  292. assert trp[0] not in imr
  293. assert trp[1] not in imr
  294. # This is the duplicate triple.
  295. imr.remove(trp[1])
  296. assert len(imr) == 5
  297. # This is the triple in reverse order.
  298. imr.remove(trp[2])
  299. assert len(imr) == 4
  300. imr.remove(trp[4])
  301. assert len(imr) == 3
  302. def test_union(self, trp):
  303. """
  304. Test graph union.
  305. """
  306. gr1 = Graph(uri='http://example.edu/imr01')
  307. gr2 = Graph(uri='http://example.edu/imr02')
  308. gr1.add(trp[0:3])
  309. gr2.add(trp[2:6])
  310. gr3 = gr1 | gr2
  311. assert len(gr3) == 5
  312. assert trp[0] in gr3
  313. assert trp[4] in gr3
  314. assert gr3.uri == URIRef('http://example.edu/imr01')
  315. def test_ip_union(self, trp):
  316. """
  317. Test graph in-place union.
  318. """
  319. gr1 = Graph(uri='http://example.edu/imr01')
  320. gr2 = Graph(uri='http://example.edu/imr02')
  321. gr1.add(trp[0:3])
  322. gr2.add(trp[2:6])
  323. gr1 |= gr2
  324. assert len(gr1) == 5
  325. assert trp[0] in gr1
  326. assert trp[4] in gr1
  327. assert gr1.uri == URIRef('http://example.edu/imr01')
  328. def test_addition(self, trp):
  329. """
  330. Test graph addition.
  331. """
  332. gr1 = Graph(uri='http://example.edu/imr01')
  333. gr2 = Graph(uri='http://example.edu/imr02')
  334. gr1.add(trp[0:3])
  335. gr2.add(trp[2:6])
  336. gr3 = gr1 + gr2
  337. assert len(gr3) == 5
  338. assert trp[0] in gr3
  339. assert trp[4] in gr3
  340. assert gr3.uri == URIRef('http://example.edu/imr01')
  341. def test_ip_addition(self, trp):
  342. """
  343. Test graph in-place addition.
  344. """
  345. gr1 = Graph(uri='http://example.edu/imr01')
  346. gr2 = Graph(uri='http://example.edu/imr02')
  347. gr1.add(trp[0:3])
  348. gr2.add(trp[2:6])
  349. gr1 += gr2
  350. assert len(gr1) == 5
  351. assert trp[0] in gr1
  352. assert trp[4] in gr1
  353. assert gr1.uri == URIRef('http://example.edu/imr01')
  354. def test_subtraction(self, trp):
  355. """
  356. Test graph addition.
  357. """
  358. gr1 = Graph(uri='http://example.edu/imr01')
  359. gr2 = Graph(uri='http://example.edu/imr02')
  360. gr1.add(trp[0:4])
  361. gr2.add(trp[2:6])
  362. gr3 = gr1 - gr2
  363. assert len(gr3) == 1
  364. assert trp[0] in gr3
  365. assert trp[1] in gr3
  366. assert trp[2] not in gr3
  367. assert trp[3] not in gr3
  368. assert trp[4] not in gr3
  369. assert gr3.uri == URIRef('http://example.edu/imr01')
  370. gr3 = gr2 - gr1
  371. assert len(gr3) == 2
  372. assert trp[0] not in gr3
  373. assert trp[1] not in gr3
  374. assert trp[2] not in gr3
  375. assert trp[3] not in gr3
  376. assert trp[4] in gr3
  377. assert trp[5] in gr3
  378. assert gr3.uri == URIRef('http://example.edu/imr02')
  379. def test_ip_subtraction(self, trp):
  380. """
  381. Test graph in-place addition.
  382. """
  383. gr1 = Graph(uri='http://example.edu/imr01')
  384. gr2 = Graph(uri='http://example.edu/imr02')
  385. gr1.add(trp[0:4])
  386. gr2.add(trp[2:6])
  387. gr1 -= gr2
  388. assert len(gr1) == 1
  389. assert trp[0] in gr1
  390. assert trp[1] in gr1
  391. assert trp[2] not in gr1
  392. assert trp[3] not in gr1
  393. assert trp[4] not in gr1
  394. assert gr1.uri == URIRef('http://example.edu/imr01')
  395. def test_intersect(self, trp):
  396. """
  397. Test graph intersextion.
  398. """
  399. gr1 = Graph(uri='http://example.edu/imr01')
  400. gr2 = Graph(uri='http://example.edu/imr02')
  401. gr1.add(trp[0:4])
  402. gr2.add(trp[2:6])
  403. gr3 = gr1 & gr2
  404. assert len(gr3) == 2
  405. assert trp[2] in gr3
  406. assert trp[3] in gr3
  407. assert trp[0] not in gr3
  408. assert trp[5] not in gr3
  409. assert gr3.uri == URIRef('http://example.edu/imr01')
  410. def test_ip_intersect(self, trp):
  411. """
  412. Test graph intersextion.
  413. """
  414. gr1 = Graph(uri='http://example.edu/imr01')
  415. gr2 = Graph(uri='http://example.edu/imr02')
  416. gr1.add(trp[0:4])
  417. gr2.add(trp[2:6])
  418. gr1 &= gr2
  419. assert len(gr1) == 2
  420. assert trp[2] in gr1
  421. assert trp[3] in gr1
  422. assert trp[0] not in gr1
  423. assert trp[5] not in gr1
  424. assert gr1.uri == URIRef('http://example.edu/imr01')
  425. def test_xor(self, trp):
  426. """
  427. Test graph intersextion.
  428. """
  429. gr1 = Graph(uri='http://example.edu/imr01')
  430. gr2 = Graph(uri='http://example.edu/imr02')
  431. gr1.add(trp[0:4])
  432. gr2.add(trp[2:6])
  433. gr3 = gr1 ^ gr2
  434. assert len(gr3) == 3
  435. assert trp[2] not in gr3
  436. assert trp[3] not in gr3
  437. assert trp[0] in gr3
  438. assert trp[5] in gr3
  439. assert gr3.uri == URIRef('http://example.edu/imr01')
  440. def test_ip_xor(self, trp):
  441. """
  442. Test graph intersextion.
  443. """
  444. gr1 = Graph(uri='http://example.edu/imr01')
  445. gr2 = Graph(uri='http://example.edu/imr02')
  446. gr1.add(trp[0:4])
  447. gr2.add(trp[2:6])
  448. gr1 ^= gr2
  449. assert len(gr1) == 3
  450. assert trp[2] not in gr1
  451. assert trp[3] not in gr1
  452. assert trp[0] in gr1
  453. assert trp[5] in gr1
  454. assert gr1.uri == URIRef('http://example.edu/imr01')
  455. @pytest.mark.usefixtures('trp')
  456. class TestHybridOps:
  457. """
  458. Test operations between IMR and graph.
  459. """
  460. def test_union(self, trp):
  461. """
  462. Test hybrid IMR + graph union.
  463. """
  464. gr1 = Graph(uri='http://example.edu/imr01')
  465. gr2 = Graph()
  466. gr1.add(trp[0:3])
  467. gr2.add(trp[2:6])
  468. gr3 = gr1 | gr2
  469. assert len(gr3) == 5
  470. assert trp[0] in gr3
  471. assert trp[4] in gr3
  472. assert isinstance(gr3, Graph)
  473. assert gr3.uri == URIRef('http://example.edu/imr01')
  474. gr4 = gr2 | gr1
  475. assert isinstance(gr4, Graph)
  476. assert gr3 == gr4
  477. def test_ip_union_imr(self, trp):
  478. """
  479. Test IMR + graph in-place union.
  480. """
  481. gr1 = Graph(uri='http://example.edu/imr01')
  482. gr2 = Graph()
  483. gr1.add(trp[0:3])
  484. gr2.add(trp[2:6])
  485. gr1 |= gr2
  486. assert len(gr1) == 5
  487. assert trp[0] in gr1
  488. assert trp[4] in gr1
  489. assert gr1.uri == URIRef('http://example.edu/imr01')
  490. def test_ip_union_gr(self, trp):
  491. """
  492. Test graph + IMR in-place union.
  493. """
  494. gr1 = Graph()
  495. gr2 = Graph(uri='http://example.edu/imr01')
  496. gr1.add(trp[0:3])
  497. gr2.add(trp[2:6])
  498. gr1 |= gr2
  499. assert len(gr1) == 5
  500. assert trp[0] in gr1
  501. assert trp[4] in gr1
  502. assert isinstance(gr1, Graph)