class TestGraphSet(unittest.TestCase): resp_agent = 'http://resp_agent.test/' def setUp(self): self.graph_set = GraphSet("http://test/", "./info_dir/", "", False) def test_get_entity(self): ar = self.graph_set.add_ar(self.resp_agent) ref = ar.res result = self.graph_set.get_entity(ref) self.assertIsNotNone(result) self.assertIs(result, ar) def test_add_an(self): an = self.graph_set.add_an(self.resp_agent) self.assertIsNotNone(an) self.assertIsInstance(an, ReferenceAnnotation) self.assertEqual(str(an.g.identifier), self.graph_set.g_an) def test_add_ar(self): ar = self.graph_set.add_ar(self.resp_agent) self.assertIsNotNone(ar) self.assertIsInstance(ar, AgentRole) self.assertEqual(str(ar.g.identifier), self.graph_set.g_ar) def test_add_be(self): be = self.graph_set.add_be(self.resp_agent) self.assertIsNotNone(be) self.assertIsInstance(be, BibliographicReference) self.assertEqual(str(be.g.identifier), self.graph_set.g_be) def test_add_br(self): br = self.graph_set.add_br(self.resp_agent) self.assertIsNotNone(br) self.assertIsInstance(br, BibliographicResource) self.assertEqual(str(br.g.identifier), self.graph_set.g_br) def test_add_ci(self): ci = self.graph_set.add_ci(self.resp_agent) self.assertIsNotNone(ci) self.assertIsInstance(ci, Citation) self.assertEqual(str(ci.g.identifier), self.graph_set.g_ci) def test_add_de(self): de = self.graph_set.add_de(self.resp_agent) self.assertIsNotNone(de) self.assertIsInstance(de, DiscourseElement) self.assertEqual(str(de.g.identifier), self.graph_set.g_de) def test_add_id(self): identifier = self.graph_set.add_id(self.resp_agent) self.assertIsNotNone(identifier) self.assertIsInstance(identifier, Identifier) self.assertEqual(str(identifier.g.identifier), self.graph_set.g_id) def test_add_pl(self): pl = self.graph_set.add_pl(self.resp_agent) self.assertIsNotNone(pl) self.assertIsInstance(pl, PointerList) self.assertEqual(str(pl.g.identifier), self.graph_set.g_pl) def test_add_rp(self): rp = self.graph_set.add_rp(self.resp_agent) self.assertIsNotNone(rp) self.assertIsInstance(rp, ReferencePointer) self.assertEqual(str(rp.g.identifier), self.graph_set.g_rp) def test_add_ra(self): ra = self.graph_set.add_ra(self.resp_agent) self.assertIsNotNone(ra) self.assertIsInstance(ra, ResponsibleAgent) self.assertEqual(str(ra.g.identifier), self.graph_set.g_ra) def test_add_re(self): re = self.graph_set.add_re(self.resp_agent) self.assertIsNotNone(re) self.assertIsInstance(re, ResourceEmbodiment) self.assertEqual(str(re.g.identifier), self.graph_set.g_re) def test_graphs(self): count = 10 for i in range(count): self.graph_set.add_ar(self.resp_agent) result = self.graph_set.graphs() self.assertIsNotNone(result) self.assertEqual(len(result), count) for graph in result: self.assertIsInstance(graph, Graph) def test_get_graph_iri(self): ar = self.graph_set.add_ar(self.resp_agent) iri = str(ar.g.identifier) result = GraphSet.get_graph_iri(ar.g) self.assertIsNotNone(result) self.assertEqual(iri, result) def test_get_orphans(self): br = self.graph_set.add_br(self.resp_agent) ar = self.graph_set.add_ar(self.resp_agent) ra = self.graph_set.add_ra(self.resp_agent) with self.subTest("subtest 1"): orphans = self.graph_set.get_orphans() self.assertIsNotNone(orphans) orphans_set = {o.res for o in orphans} self.assertSetEqual({br.res, ar.res, ra.res}, orphans_set) with self.subTest("subtest 2"): # Here we link br and ar: br.has_contributor(ar) orphans = self.graph_set.get_orphans() self.assertIsNotNone(orphans) orphans_set = {o.res for o in orphans} self.assertSetEqual({br.res, ra.res}, orphans_set) with self.subTest("subtest 3"): # Here we link ar and ra: ar.is_held_by(ra) orphans = self.graph_set.get_orphans() self.assertIsNotNone(orphans) orphans_set = {o.res for o in orphans} self.assertSetEqual({br.res}, orphans_set)
class TestProvSet(unittest.TestCase): resp_agent = 'http://resp_agent.test/' def setUp(self): self.graph_set = GraphSet("http://test/", "./info_dir/", "", False) self.prov_set = ProvSet(self.graph_set, "http://test/", "./info_dir/", False) def test_add_se(self): prov_subj = self.graph_set.add_br(self.resp_agent) se = self.prov_set.add_se(prov_subj) self.assertIsNotNone(se) self.assertIsInstance(se, SnapshotEntity) self.assertEqual(str(se.g.identifier), str(prov_subj.res) + "/prov/") def test_generate_provenance(self): cur_time = 1607375859.846196 cur_time_str = '2020-12-07T22:17:39' with self.subTest('Creation [Merged entity]'): a = self.graph_set.add_br(self.resp_agent) b = self.graph_set.add_br(self.resp_agent) a.merge(b) result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) se_a = self.prov_set.get_entity(URIRef(a.res + '/prov/se/1')) self.assertIsNotNone(se_a) self.assertIsInstance(se_a, SnapshotEntity) self.assertEqual(a.res, se_a.get_is_snapshot_of()) self.assertEqual(cur_time_str, se_a.get_generation_time()) if a.source is not None: self.assertEqual(a.source, str(se_a.get_primary_source())) if a.resp_agent is not None: self.assertEqual(a.resp_agent, str(se_a.get_resp_agent())) self.assertEqual(f"The entity '{a.res}' has been created.", se_a.get_description()) with self.subTest('No snapshot [Merged entity]'): a = self.graph_set.add_br(self.resp_agent) b = self.graph_set.add_br(self.resp_agent) a.merge(b) se_a_1 = self.prov_set.add_se(a) # This avoids that the presence of the mandatory rdf:type gets interpreted # as a modification with respect to an empty preexisting_graph: a.remove_every_triple() result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) se_a_2 = self.prov_set.get_entity(URIRef(a.res + '/prov/se/2')) self.assertIsNone(se_a_2) with self.subTest('Modification [Merged entity]'): title = "TEST TITLE" a = self.graph_set.add_br(self.resp_agent) b = self.graph_set.add_br(self.resp_agent) b.has_title(title) a.merge(b) se_a_1 = self.prov_set.add_se(a) result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) self.assertEqual(cur_time_str, se_a_1.get_invalidation_time()) se_a_2 = self.prov_set.get_entity(URIRef(a.res + '/prov/se/2')) self.assertIsNotNone(se_a_2) self.assertIsInstance(se_a_2, SnapshotEntity) self.assertEqual(a.res, se_a_2.get_is_snapshot_of()) self.assertEqual(cur_time_str, se_a_2.get_generation_time()) if a.source is not None: self.assertEqual(a.source, str(se_a_2.get_primary_source())) if a.resp_agent is not None: self.assertEqual(a.resp_agent, str(se_a_2.get_resp_agent())) self.assertSetEqual({se_a_1}, set(se_a_2.get_derives_from())) self.assertIsNotNone(se_a_2.get_update_action()) self.assertEqual(f"The entity '{a.res}' has been modified.", se_a_2.get_description()) with self.subTest('Merge [Merged entity]'): a = self.graph_set.add_br(self.resp_agent) b = self.graph_set.add_br(self.resp_agent) c = self.graph_set.add_br(self.resp_agent) a.merge(b) a.merge(c) se_a_1 = self.prov_set.add_se(a) se_b_1 = self.prov_set.add_se(b) result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) self.assertEqual(cur_time_str, se_a_1.get_invalidation_time()) se_a_2 = self.prov_set.get_entity(URIRef(a.res + '/prov/se/2')) self.assertIsNotNone(se_a_2) self.assertIsInstance(se_a_2, SnapshotEntity) self.assertEqual(a.res, se_a_2.get_is_snapshot_of()) self.assertEqual(cur_time_str, se_a_2.get_generation_time()) if a.source is not None: self.assertEqual(a.source, str(se_a_2.get_primary_source())) if a.resp_agent is not None: self.assertEqual(a.resp_agent, str(se_a_2.get_resp_agent())) self.assertSetEqual({se_a_1, se_b_1}, set(se_a_2.get_derives_from())) self.assertEqual( f"The entity '{a.res}' has been merged with '{b.res}'.", se_a_2.get_description()) with self.subTest('Creation [Non-Merged entity]'): a = self.graph_set.add_br(self.resp_agent) result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) se_a = self.prov_set.get_entity(URIRef(a.res + '/prov/se/1')) self.assertIsNotNone(se_a) self.assertIsInstance(se_a, SnapshotEntity) self.assertEqual(a.res, se_a.get_is_snapshot_of()) self.assertEqual(cur_time_str, se_a.get_generation_time()) if a.source is not None: self.assertEqual(a.source, str(se_a.get_primary_source())) if a.resp_agent is not None: self.assertEqual(a.resp_agent, str(se_a.get_resp_agent())) self.assertEqual(f"The entity '{a.res}' has been created.", se_a.get_description()) with self.subTest('No snapshot [Non-Merged entity] (Scenario 1)'): a = self.graph_set.add_br(self.resp_agent) a.mark_as_to_be_deleted() result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) se_a = self.prov_set.get_entity(URIRef(a.res + '/prov/se/1')) self.assertIsNone(se_a) with self.subTest('No snapshot [Merged entity] (Scenario 2)'): a = self.graph_set.add_br(self.resp_agent) se_a_1 = self.prov_set.add_se(a) # This avoids that the presence of the mandatory rdf:type gets interpreted # as a modification with respect to an empty preexisting_graph: a.remove_every_triple() result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) se_a_2 = self.prov_set.get_entity(URIRef(a.res + '/prov/se/2')) self.assertIsNone(se_a_2) with self.subTest('Deletion [Non-Merged entity]'): a = self.graph_set.add_br(self.resp_agent) se_a_1 = self.prov_set.add_se(a) a.has_title('ciao') a.mark_as_to_be_deleted() result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) self.assertEqual(cur_time_str, se_a_1.get_invalidation_time()) se_a_2 = self.prov_set.get_entity(URIRef(a.res + '/prov/se/2')) self.assertIsNotNone(se_a_2) self.assertIsInstance(se_a_2, SnapshotEntity) self.assertEqual(a.res, se_a_2.get_is_snapshot_of()) self.assertEqual(cur_time_str, se_a_2.get_generation_time()) if a.source is not None: self.assertEqual(a.source, str(se_a_2.get_primary_source())) if a.resp_agent is not None: self.assertEqual(a.resp_agent, str(se_a_2.get_resp_agent())) self.assertSetEqual({se_a_1}, set(se_a_2.get_derives_from())) self.assertEqual(f"The entity '{a.res}' has been deleted.", se_a_2.get_description()) with self.subTest('Modification [Non-Merged entity]'): title = "TEST TITLE" a = self.graph_set.add_br(self.resp_agent) se_a_1 = self.prov_set.add_se(a) a.has_title(title) result = self.prov_set.generate_provenance(cur_time) self.assertIsNone(result) self.assertEqual(cur_time_str, se_a_1.get_invalidation_time()) se_a_2 = self.prov_set.get_entity(URIRef(a.res + '/prov/se/2')) self.assertIsNotNone(se_a_2) self.assertIsInstance(se_a_2, SnapshotEntity) self.assertEqual(a.res, se_a_2.get_is_snapshot_of()) self.assertEqual(cur_time_str, se_a_2.get_generation_time()) if a.source is not None: self.assertEqual(a.source, str(se_a_2.get_primary_source())) if a.resp_agent is not None: self.assertEqual(a.resp_agent, str(se_a_2.get_resp_agent())) self.assertSetEqual({se_a_1}, set(se_a_2.get_derives_from())) self.assertIsNotNone(se_a_2.get_update_action()) self.assertEqual(f"The entity '{a.res}' has been modified.", se_a_2.get_description()) def test_retrieve_last_snapshot(self): br = self.graph_set.add_br(self.resp_agent) br_res = br.res result = self.prov_set._retrieve_last_snapshot(br_res) self.assertIsNone(result) se = self.prov_set.add_se(br) result = self.prov_set._retrieve_last_snapshot(br_res) self.assertIsNotNone(result) self.assertEqual(str(result), str(se)) prov_subject = URIRef('https://w3id.org/oc/corpus/br/0') self.assertRaises(ValueError, self.prov_set._retrieve_last_snapshot, prov_subject) prov_subject = URIRef('https://w3id.org/oc/corpus/br/-1') self.assertRaises(ValueError, self.prov_set._retrieve_last_snapshot, prov_subject) prov_subject = URIRef('https://w3id.org/oc/corpus/br/abc') self.assertRaises(ValueError, self.prov_set._retrieve_last_snapshot, prov_subject)
def import_entities_from_graph(g_set: GraphSet, graph: Graph, resp_agent: str, enable_validation: bool = False, closed: bool = False) -> List[GraphEntity]: if enable_validation: graph = Reader.graph_validation(graph, closed) imported_entities: List[GraphEntity] = [] for subject in Reader._extract_subjects(graph): types: List[term] = [] for o in graph.objects(subject, RDF.type): types.append(o) # ReferenceAnnotation if GraphEntity.iri_note in types: imported_entities.append( g_set.add_an( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # AgentRole elif GraphEntity.iri_role_in_time in types: imported_entities.append( g_set.add_ar( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # BibliographicReference elif GraphEntity.iri_bibliographic_reference in types: imported_entities.append( g_set.add_be( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # BibliographicResource elif GraphEntity.iri_expression in types: imported_entities.append( g_set.add_br( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # Citation elif GraphEntity.iri_citation in types: imported_entities.append( g_set.add_ci( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # DiscourseElement elif GraphEntity.iri_discourse_element in types: imported_entities.append( g_set.add_de( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # Identifier elif GraphEntity.iri_identifier in types: imported_entities.append( g_set.add_id( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # PointerList elif GraphEntity.iri_singleloc_pointer_list in types: imported_entities.append( g_set.add_pl( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # ResponsibleAgent elif GraphEntity.iri_agent in types: imported_entities.append( g_set.add_ra( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # ResourceEmbodiment elif GraphEntity.iri_manifestation in types: imported_entities.append( g_set.add_re( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) # ReferencePointer elif GraphEntity.iri_intextref_pointer in types: imported_entities.append( g_set.add_rp( resp_agent=resp_agent, res=subject, preexisting_graph=Reader.get_graph_from_subject( graph, subject))) return imported_entities
class TestSupport(unittest.TestCase): resp_agent = 'http://resp_agent.test/' pro = Namespace("http://purl.org/spar/pro/") def setUp(self): self.graph_set = GraphSet("http://test/", "./info_dir/", "", False) self.prov_set = ProvSet(self.graph_set, "http://test/", "./info_dir/", False) self.br = self.graph_set.add_br(self.resp_agent) def _prepare_ordered_authors_list(self, list_len): # First of all, we must cleanup the GraphSet: self.br.remove_contributor() for ar in self.graph_set.get_ar(): del self.graph_set.res_to_entity[ar.res] for ra in self.graph_set.get_ra(): del self.graph_set.res_to_entity[ra.res] # Then, we initialize a new well-formed linked list of authors: ar_ordered_list = [] for i in range(list_len): ra = self.graph_set.add_ra(self.resp_agent) ar = self.graph_set.add_ar(self.resp_agent) ar.create_author() ar.is_held_by(ra) self.br.has_contributor(ar) ar_ordered_list.append(ar) # Here each node of the list gets linked to the next one: for i in range(list_len - 1): ar_ordered_list[i].has_next(ar_ordered_list[i + 1]) return ar_ordered_list @staticmethod def _extract_ra_list(ar_list): # Here the RA list is built and returned: ra_list = [] for i in range(len(ar_list)): ra = ar_list[i].get_is_held_by() if ra is not None: ra_list.append(ra) return ra_list def test_get_ordered_contributors_from_br(self): list_len = 100 with self.subTest("Empty linked list"): result = get_ordered_contributors_from_br(self.br, self.pro.author) self.assertIsNotNone(result) self.assertListEqual([], result) with self.subTest("Well-formed linked list"): correct_list = self._prepare_ordered_authors_list(list_len) result = get_ordered_contributors_from_br(self.br, self.pro.author) self.assertIsNotNone(result) ar_list = self._extract_ra_list(correct_list) self.assertListEqual(ar_list, result) with self.subTest("Linked list with a loop"): correct_list = self._prepare_ordered_authors_list(list_len) # Here we corrupt the well-formed linked list introducing a loop: correct_list[80].has_next(correct_list[50]) self.assertRaises(ValueError, get_ordered_contributors_from_br, self.br, self.pro.author) with self.subTest("Linked list split in two sub-lists"): correct_list = self._prepare_ordered_authors_list(list_len) # Here we corrupt the well-formed linked list introducing a loop: correct_list[64].remove_next() self.assertRaises(ValueError, get_ordered_contributors_from_br, self.br, self.pro.author)