mustrd 0.1.7__py3-none-any.whl → 0.1.8__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mustrd/README.adoc +6 -6
- mustrd/model/catalog-v001.xml +5 -0
- mustrd/model/mustrdTestOntology.ttl +51 -0
- mustrd/model/mustrdTestShapes.ttl +24 -0
- mustrd/model/ontology.ttl +2 -1
- mustrd/model/triplestoreOntology.ttl +174 -0
- mustrd/model/triplestoreshapes.ttl +42 -0
- mustrd/mustrd.py +49 -39
- mustrd/mustrdTestPlugin.py +125 -58
- mustrd/namespace.py +36 -29
- mustrd/run.py +2 -2
- mustrd/spec_component.py +11 -11
- mustrd/steprunner.py +15 -15
- mustrd/test/test_mustrd.py +5 -0
- {mustrd-0.1.7.dist-info → mustrd-0.1.8.dist-info}/METADATA +1 -1
- mustrd-0.1.8.dist-info/RECORD +31 -0
- mustrd-0.1.7.dist-info/RECORD +0 -25
- {mustrd-0.1.7.dist-info → mustrd-0.1.8.dist-info}/LICENSE +0 -0
- {mustrd-0.1.7.dist-info → mustrd-0.1.8.dist-info}/WHEEL +0 -0
- {mustrd-0.1.7.dist-info → mustrd-0.1.8.dist-info}/entry_points.txt +0 -0
mustrd/README.adoc
CHANGED
@@ -178,16 +178,16 @@ The configuration file should be serialised RDF. An example in Turtle format is
|
|
178
178
|
must:GraphDbConfig1 a must:GraphDbConfig ;
|
179
179
|
must:url "http://localhost";
|
180
180
|
must:port "7200";
|
181
|
-
must:username "test/triplestore_config/tripleStoreCredentials.toml" ;
|
182
|
-
must:password "test/triplestore_config/tripleStoreCredentials.toml" ;
|
183
181
|
must:inputGraph "http://localhost:7200/test-graph" ;
|
184
182
|
must:repository "mustrd" .
|
185
183
|
----
|
186
|
-
|
184
|
+
To avoid versioning secrets when you want to version triplestore configuration (for example in case you want to run mustrd in CI), you have to configure user/password in a different file.
|
185
|
+
This file must be named as the triple store configuration file, but with "_secrets" just before the extension. For example triplestores.ttl -> triplestores_secrets.ttl
|
186
|
+
Subjects in the two files must match, no need to redefine the type, for example:
|
187
187
|
----
|
188
|
-
|
189
|
-
|
190
|
-
|
188
|
+
@prefix must: <https://mustrd.com/model/> .
|
189
|
+
must:GraphDbConfig1 must:username 'test' ;
|
190
|
+
must:password 'test' .
|
191
191
|
----
|
192
192
|
|
193
193
|
== Additional Notes for Developers
|
@@ -0,0 +1,5 @@
|
|
1
|
+
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
2
|
+
<catalog prefer="public" xmlns="urn:oasis:names:tc:entity:xmlns:xml:catalog">
|
3
|
+
<uri id="User Entered Import Resolution" name="https://mustrd.com/triplestore/" uri="triplestoreOntology.ttl"/>
|
4
|
+
<group id="Folder Repository, directory=, recursive=true, Auto-Update=true, version=2" prefer="public" xml:base=""/>
|
5
|
+
</catalog>
|
@@ -0,0 +1,51 @@
|
|
1
|
+
@prefix : <https://mustrd.com/mustrdTest/> .
|
2
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
3
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
4
|
+
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
|
5
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
6
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
7
|
+
@prefix triplestore: <https://mustrd.com/triplestore/> .
|
8
|
+
@base <https://mustrd.com/mustrdTest/> .
|
9
|
+
|
10
|
+
<https://mustrd.com/mustrdTest/> rdf:type owl:Ontology ;
|
11
|
+
owl:imports triplestore: ;
|
12
|
+
rdfs:comment "Model user input to generate mustrd pytests" ;
|
13
|
+
rdfs:label "Mustrd test ontology" .
|
14
|
+
|
15
|
+
#################################################################
|
16
|
+
# Object Properties
|
17
|
+
#################################################################
|
18
|
+
|
19
|
+
### https://mustrd.com/mustrdTest/filterOnTripleStore
|
20
|
+
:filterOnTripleStore rdf:type owl:ObjectProperty ;
|
21
|
+
rdfs:domain :MustrdTest ;
|
22
|
+
rdfs:range triplestore:TripleStore .
|
23
|
+
|
24
|
+
|
25
|
+
#################################################################
|
26
|
+
# Data properties
|
27
|
+
#################################################################
|
28
|
+
|
29
|
+
### https://mustrd.com/mustrdTest/hasDataPath
|
30
|
+
:hasDataPath rdf:type owl:DatatypeProperty ;
|
31
|
+
rdfs:domain :MustrdTest ;
|
32
|
+
rdfs:range xsd:string .
|
33
|
+
|
34
|
+
|
35
|
+
### https://mustrd.com/mustrdTest/hasSpecPath
|
36
|
+
:hasSpecPath rdf:type owl:DatatypeProperty ;
|
37
|
+
rdfs:domain :MustrdTest ;
|
38
|
+
rdfs:range xsd:string .
|
39
|
+
|
40
|
+
|
41
|
+
#################################################################
|
42
|
+
# Classes
|
43
|
+
#################################################################
|
44
|
+
|
45
|
+
### https://mustrd.com/mustrdTest/MustrdTest
|
46
|
+
:MustrdTest rdf:type owl:Class ;
|
47
|
+
rdfs:comment "Contains user input to parameter a mustrd pytest" ;
|
48
|
+
rdfs:label "Mustrd test" .
|
49
|
+
|
50
|
+
|
51
|
+
### Generated by the OWL API (version 4.5.26.2023-07-17T20:34:13Z) https://github.com/owlcs/owlapi
|
@@ -0,0 +1,24 @@
|
|
1
|
+
@prefix : <https://mustrd.com/mustrdTest/> .
|
2
|
+
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
3
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
4
|
+
@prefix triplestore: <https://mustrd.com/triplestore/> .
|
5
|
+
@base <https://mustrd.com/mustrdTest/> .
|
6
|
+
|
7
|
+
|
8
|
+
|
9
|
+
|
10
|
+
:MustrdTestShape
|
11
|
+
a sh:NodeShape ;
|
12
|
+
sh:targetClass :MustrdTest ;
|
13
|
+
sh:property [ sh:path :hasDataPath ;
|
14
|
+
sh:datatype xsd:string ;
|
15
|
+
sh:minCount 1 ;
|
16
|
+
sh:maxCount 1 ],
|
17
|
+
[ sh:path :hasSpecPath ;
|
18
|
+
sh:datatype xsd:string ;
|
19
|
+
sh:minCount 1 ;
|
20
|
+
sh:maxCount 1 ],
|
21
|
+
[ sh:path :hasPytestPath ;
|
22
|
+
sh:datatype xsd:string ;
|
23
|
+
sh:maxCount 1 ] .
|
24
|
+
|
mustrd/model/ontology.ttl
CHANGED
@@ -0,0 +1,174 @@
|
|
1
|
+
@base <https://mustrd.com/triplestore/> .
|
2
|
+
@prefix : <https://mustrd.com/triplestore/> .
|
3
|
+
@prefix dc: <http://purl.org/dc/elements/1.1/> .
|
4
|
+
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
5
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
6
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
7
|
+
@prefix xml: <http://www.w3.org/XML/1998/namespace> .
|
8
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
9
|
+
@prefix foaf: <http://xmlns.com/foaf/spec/> .
|
10
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
11
|
+
@prefix skos: <http://www.w3.org/2004/02/skos/core#> .
|
12
|
+
#
|
13
|
+
#
|
14
|
+
# #################################################################
|
15
|
+
# #
|
16
|
+
# # Data properties
|
17
|
+
# #
|
18
|
+
# #################################################################
|
19
|
+
#
|
20
|
+
#
|
21
|
+
# https://mustrd.com/triplestore/gqeURI
|
22
|
+
#
|
23
|
+
# https://mustrd.com/triplestore/inputGraph
|
24
|
+
#
|
25
|
+
# https://mustrd.com/triplestore/outputGraph
|
26
|
+
#
|
27
|
+
# https://mustrd.com/triplestore/password
|
28
|
+
#
|
29
|
+
# https://mustrd.com/triplestore/port
|
30
|
+
#
|
31
|
+
# https://mustrd.com/triplestore/repository
|
32
|
+
#
|
33
|
+
# https://mustrd.com/triplestore/url
|
34
|
+
#
|
35
|
+
# https://mustrd.com/triplestore/username
|
36
|
+
#
|
37
|
+
#
|
38
|
+
#
|
39
|
+
# #################################################################
|
40
|
+
# #
|
41
|
+
# # Classes
|
42
|
+
# #
|
43
|
+
# #################################################################
|
44
|
+
#
|
45
|
+
#
|
46
|
+
# https://mustrd.com/triplestore/Anzo
|
47
|
+
#
|
48
|
+
# https://mustrd.com/triplestore/ExternalTripleStore
|
49
|
+
#
|
50
|
+
# https://mustrd.com/triplestore/GraphDb
|
51
|
+
#
|
52
|
+
# https://mustrd.com/triplestore/InternalTripleStore
|
53
|
+
#
|
54
|
+
# https://mustrd.com/triplestore/RdfLib
|
55
|
+
#
|
56
|
+
# https://mustrd.com/triplestore/TripleStore
|
57
|
+
#
|
58
|
+
# Generated by the OWL API (version 4.5.26.2023-07-17T20:34:13Z) https://github.com/owlcs/owlapi
|
59
|
+
|
60
|
+
<> a owl:Ontology;
|
61
|
+
rdfs:label "triple store ontology" .
|
62
|
+
|
63
|
+
:gqeURI a owl:DatatypeProperty;
|
64
|
+
rdfs:domain :Anzo;
|
65
|
+
rdfs:range xsd:string;
|
66
|
+
rdfs:label "gqeURI" .
|
67
|
+
|
68
|
+
:inputGraph a owl:DatatypeProperty;
|
69
|
+
rdfs:domain :TripleStore;
|
70
|
+
rdfs:range xsd:string;
|
71
|
+
rdfs:label "inputGraph" .
|
72
|
+
|
73
|
+
:outputGraph a owl:DatatypeProperty;
|
74
|
+
rdfs:domain :TripleStore;
|
75
|
+
rdfs:range xsd:string;
|
76
|
+
rdfs:comment """Uri of the graph where to insert/delete the triples
|
77
|
+
|
78
|
+
In some triple stores there is a default insert graph like in graphDB:
|
79
|
+
In graphDB the default insert graph is called: <http://www.openrdf.org/schema/sesame#nil>
|
80
|
+
or
|
81
|
+
<http://rdf4j.org/schema/rdf4j#nil>
|
82
|
+
|
83
|
+
Other triple stores do not define default insert graph like anzograph.
|
84
|
+
For those triple stores, this property must be mandatory""";
|
85
|
+
rdfs:label "outputGraph" .
|
86
|
+
|
87
|
+
:password a owl:DatatypeProperty;
|
88
|
+
rdfs:domain :ExternalTripleStore;
|
89
|
+
rdfs:range xsd:string;
|
90
|
+
rdfs:label "password" .
|
91
|
+
|
92
|
+
:port a owl:DatatypeProperty;
|
93
|
+
rdfs:domain :ExternalTripleStore;
|
94
|
+
rdfs:range xsd:string;
|
95
|
+
rdfs:comment "Triple store port";
|
96
|
+
rdfs:label "port" .
|
97
|
+
|
98
|
+
:repository a owl:DatatypeProperty;
|
99
|
+
rdfs:domain :GraphDb;
|
100
|
+
rdfs:range xsd:string;
|
101
|
+
rdfs:label "repository" .
|
102
|
+
|
103
|
+
:url a owl:DatatypeProperty;
|
104
|
+
rdfs:domain :ExternalTripleStore;
|
105
|
+
rdfs:range xsd:string;
|
106
|
+
rdfs:comment "triple store URL";
|
107
|
+
rdfs:label "url" .
|
108
|
+
|
109
|
+
:username a owl:DatatypeProperty;
|
110
|
+
rdfs:domain :ExternalTripleStore;
|
111
|
+
rdfs:range xsd:string;
|
112
|
+
rdfs:label "username" .
|
113
|
+
|
114
|
+
:Anzo a owl:Class;
|
115
|
+
rdfs:subClassOf :ExternalTripleStore;
|
116
|
+
rdfs:comment """TODO: model this:
|
117
|
+
|
118
|
+
definition of RDF dataset:
|
119
|
+
|
120
|
+
default graph=
|
121
|
+
RDF merge of default-graph-uri if exists
|
122
|
+
else RDF merge of FROM if exists
|
123
|
+
else all graphs in anzo graph (if you query a graphmart, default-graph-uri will be automatically set to the layers of the graphmart), if you are not sysadmin and you do not define the default graph, then the query will fail since you don't have permissions on all graphs
|
124
|
+
if default-graph-uri is defined then FROM clauses are ignored
|
125
|
+
|
126
|
+
default named graph =
|
127
|
+
RDF merge of named-graph-uri if exists
|
128
|
+
else RDF merge of FROM NAMED if exists
|
129
|
+
else default graph if exists
|
130
|
+
all graphs in anzo graph (if you query a graphmart, default-graph-uri will be automatically set to the layers of the graphmart), if you are not sysadmin and you do not define the default graph, then the query will fail since you don't have permissions on all graphs
|
131
|
+
if named-graph-uri is defined then FROM NAMED clauses are ignored
|
132
|
+
|
133
|
+
There is no default insert graph. If you try to insert/delete without graph clause, your query will fail.""";
|
134
|
+
rdfs:label "Anzo" .
|
135
|
+
|
136
|
+
:ExternalTripleStore a owl:Class;
|
137
|
+
rdfs:subClassOf :TripleStore .
|
138
|
+
|
139
|
+
:GraphDb a owl:Class;
|
140
|
+
rdfs:subClassOf :ExternalTripleStore;
|
141
|
+
rdfs:comment """TODO: model this:
|
142
|
+
|
143
|
+
Definition of RDF dataset in graphDB:
|
144
|
+
|
145
|
+
default graph (in the sense of W3C, called default dataset in graphDB) =
|
146
|
+
Virtual graph that exist only for a query and represent all triples accessible outside of a graph clause in a sparql query =
|
147
|
+
RDF merge of default-graph-uri if exists
|
148
|
+
else RDF merge of FROM if exists
|
149
|
+
else all graphs in the repository, including default insert graph
|
150
|
+
you can query default insert graph by including it (<http://www.openrdf.org/schema/sesame#nil> or <http://rdf4j.org/schema/rdf4j#nil>) in a default-graph-uri parameter or a FROM clause
|
151
|
+
If default-graph-uri is defined, then FROM clause is ignored
|
152
|
+
|
153
|
+
default named graph =
|
154
|
+
All triples accessible inside a graph clause:
|
155
|
+
RDF merge of named-graph-uri if exists
|
156
|
+
else RDF merge of FROM NAMED if exist
|
157
|
+
else all graphs in the repository, EXCLUDING default insert graph
|
158
|
+
(To be exact you can query the default insert graph only if you name it GRAPH <http://www.openrdf.org/schema/sesame#nil> or GRAPH <http://rdf4j.org/schema/rdf4j#nil>, but you won't query it with GRAPH ?graph)
|
159
|
+
default insert graph can be added to named-graph-uri or FROM NAMED
|
160
|
+
If a default-graph-uri is defined but no named-graph-uri, then default named graph = void
|
161
|
+
|
162
|
+
default insert graph (called \"The default graph\" in graphDB) =
|
163
|
+
Graph where triples are inserted / deleted when no graph clause is given in an INSERT or DELETE clause""";
|
164
|
+
rdfs:label "GraphDb" .
|
165
|
+
|
166
|
+
:InternalTripleStore a owl:Class;
|
167
|
+
rdfs:subClassOf :TripleStore .
|
168
|
+
|
169
|
+
:RdfLib a owl:Class;
|
170
|
+
rdfs:subClassOf :InternalTripleStore;
|
171
|
+
rdfs:label "RdfLib" .
|
172
|
+
|
173
|
+
:TripleStore a owl:Class;
|
174
|
+
rdfs:label "TripleStore" .
|
@@ -0,0 +1,42 @@
|
|
1
|
+
@prefix rdf: <http://www.w3.org/1999/02/22-rdf-syntax-ns#> .
|
2
|
+
@prefix sh: <http://www.w3.org/ns/shacl#> .
|
3
|
+
@prefix xsd: <http://www.w3.org/2001/XMLSchema#> .
|
4
|
+
@prefix rdfs: <http://www.w3.org/2000/01/rdf-schema#> .
|
5
|
+
@prefix ex: <http://www.example.org/#> .
|
6
|
+
@prefix owl: <http://www.w3.org/2002/07/owl#> .
|
7
|
+
@prefix triplestore: <https://mustrd.com/triplestore/> .
|
8
|
+
|
9
|
+
triplestore:ExternalTripleStoreShape
|
10
|
+
a sh:NodeShape ;
|
11
|
+
sh:targetClass triplestore:ExternalTripleStore ;
|
12
|
+
sh:property [ sh:path triplestore:url ;
|
13
|
+
sh:minCount 1 ;
|
14
|
+
sh:maxCount 1 ],
|
15
|
+
[ sh:path triplestore:port ;
|
16
|
+
sh:minCount 1 ;
|
17
|
+
sh:maxCount 1 ],
|
18
|
+
[ sh:path triplestore:username ;
|
19
|
+
sh:maxCount 1 ],
|
20
|
+
[ sh:path triplestore:password ;
|
21
|
+
sh:maxCount 1 ] .
|
22
|
+
|
23
|
+
triplestore:AnzoShape
|
24
|
+
a sh:NodeShape ;
|
25
|
+
sh:targetClass triplestore:Anzo ;
|
26
|
+
sh:property [ sh:path triplestore:gqeURI ;
|
27
|
+
sh:minCount 1 ;
|
28
|
+
sh:maxCount 1 ],
|
29
|
+
[ sh:path triplestore:outputGraph ;
|
30
|
+
sh:minCount 1 ;
|
31
|
+
sh:maxCount 1 ],
|
32
|
+
# For anzo the input graph is not really necessary if the user is sysadmin
|
33
|
+
# but querying all graphs in AZG is usually not a good idea, so for the moment this is forbidden
|
34
|
+
[ sh:path triplestore:inputGraph ;
|
35
|
+
sh:minCount 1 ] .
|
36
|
+
|
37
|
+
triplestore:GraphDbShape
|
38
|
+
a sh:NodeShape ;
|
39
|
+
sh:targetClass triplestore:GraphDb ;
|
40
|
+
sh:property [ sh:path triplestore:repository ;
|
41
|
+
sh:minCount 1 ;
|
42
|
+
sh:maxCount 1 ] .
|
mustrd/mustrd.py
CHANGED
@@ -40,13 +40,13 @@ from rdflib import Graph, URIRef, RDF, XSD, SH, Literal
|
|
40
40
|
from rdflib.compare import isomorphic, graph_diff
|
41
41
|
import pandas
|
42
42
|
|
43
|
-
from .namespace import MUST
|
43
|
+
from .namespace import MUST, TRIPLESTORE
|
44
44
|
import requests
|
45
45
|
import json
|
46
46
|
from pandas import DataFrame
|
47
47
|
|
48
48
|
from .spec_component import TableThenSpec, parse_spec_component, WhenSpec, ThenSpec
|
49
|
-
from .utils import is_json
|
49
|
+
from .utils import is_json,get_mustrd_root
|
50
50
|
from colorama import Fore, Style
|
51
51
|
from tabulate import tabulate
|
52
52
|
from collections import defaultdict
|
@@ -93,6 +93,7 @@ class Specification:
|
|
93
93
|
given: Graph
|
94
94
|
when: WhenSpec
|
95
95
|
then: ThenSpec
|
96
|
+
spec_file_name: str = "default.mustrd.ttl"
|
96
97
|
|
97
98
|
|
98
99
|
@dataclass
|
@@ -152,6 +153,7 @@ class TripleStoreConnectionError(SpecResult):
|
|
152
153
|
@dataclass
|
153
154
|
class SpecSkipped(SpecResult):
|
154
155
|
message: str
|
156
|
+
spec_file_name: str = "default.mustrd.ttl"
|
155
157
|
|
156
158
|
|
157
159
|
@dataclass
|
@@ -176,16 +178,15 @@ class UpdateSparqlQuery(SparqlAction):
|
|
176
178
|
|
177
179
|
# https://github.com/Semantic-partners/mustrd/issues/19
|
178
180
|
|
179
|
-
def validate_specs(run_config: dict, triple_stores: List, shacl_graph: Graph, ont_graph: Graph)\
|
181
|
+
def validate_specs(run_config: dict, triple_stores: List, shacl_graph: Graph, ont_graph: Graph, file_name: str = "*")\
|
180
182
|
-> Tuple[List, Graph, List]:
|
181
183
|
spec_graph = Graph()
|
182
184
|
subject_uris = set()
|
183
185
|
focus_uris = set()
|
184
186
|
invalid_specs = []
|
185
|
-
|
186
|
-
ttl_files = list(run_config['spec_path'].glob('**/*.mustrd.ttl'))
|
187
|
+
ttl_files = list(run_config['spec_path'].glob(f'**/{file_name}.mustrd.ttl'))
|
187
188
|
ttl_files.sort()
|
188
|
-
log.info(f"Found {len(ttl_files)} mustrd.ttl files in {run_config['spec_path']}")
|
189
|
+
log.info(f"Found {len(ttl_files)} {file_name}.mustrd.ttl files in {run_config['spec_path']}")
|
189
190
|
|
190
191
|
for file in ttl_files:
|
191
192
|
error_messages = []
|
@@ -233,7 +234,7 @@ def validate_specs(run_config: dict, triple_stores: List, shacl_graph: Graph, on
|
|
233
234
|
if len(error_messages) > 0:
|
234
235
|
error_messages.sort()
|
235
236
|
error_message = "\n".join(msg for msg in error_messages)
|
236
|
-
invalid_specs += [SpecSkipped(subject_uri, triple_store["type"], error_message) for triple_store in
|
237
|
+
invalid_specs += [SpecSkipped(subject_uri, triple_store["type"], error_message, file.name) for triple_store in
|
237
238
|
triple_stores]
|
238
239
|
else:
|
239
240
|
subject_uris.add(subject_uri)
|
@@ -241,13 +242,12 @@ def validate_specs(run_config: dict, triple_stores: List, shacl_graph: Graph, on
|
|
241
242
|
this_spec_graph.parse(file)
|
242
243
|
spec_uris_in_this_file = list(this_spec_graph.subjects(RDF.type, MUST.TestSpec))
|
243
244
|
for spec in spec_uris_in_this_file:
|
244
|
-
tripleToAdd = [spec, MUST.specSourceFile, Literal(file)]
|
245
245
|
# print(f"adding {tripleToAdd}")
|
246
|
-
this_spec_graph.add(
|
246
|
+
this_spec_graph.add([spec, MUST.specSourceFile, Literal(file)])
|
247
|
+
this_spec_graph.add([spec, MUST.specFileName, Literal(file.name)])
|
247
248
|
# print(f"beforeadd: {spec_graph}" )
|
248
249
|
# print(f"beforeadd: {str(this_spec_graph.serialize())}" )
|
249
250
|
spec_graph += this_spec_graph
|
250
|
-
# print(f"afteradd: {str(spec_graph.serialize())}" )
|
251
251
|
|
252
252
|
|
253
253
|
sourceFiles = list(spec_graph.subject_objects(MUST.specSourceFile))
|
@@ -276,14 +276,14 @@ def get_specs(spec_uris: List[URIRef], spec_graph: Graph, triple_stores: List[di
|
|
276
276
|
for triple_store in triple_stores:
|
277
277
|
if "error" in triple_store:
|
278
278
|
log.error(f"{triple_store['error']}. No specs run for this triple store.")
|
279
|
-
skipped_results += [SpecSkipped(spec_uri, triple_store['type'], triple_store['error']) for spec_uri in
|
279
|
+
skipped_results += [SpecSkipped(spec_uri, triple_store['type'], triple_store['error'], get_spec_file(spec_uri, spec_graph)) for spec_uri in
|
280
280
|
spec_uris]
|
281
281
|
else:
|
282
282
|
for spec_uri in spec_uris:
|
283
283
|
try:
|
284
284
|
specs += [get_spec(spec_uri, spec_graph, run_config, triple_store)]
|
285
285
|
except (ValueError, FileNotFoundError, ConnectionError) as e:
|
286
|
-
skipped_results += [SpecSkipped(spec_uri, triple_store['type'], e)]
|
286
|
+
skipped_results += [SpecSkipped(spec_uri, triple_store['type'], e, get_spec_file(spec_uri, spec_graph))]
|
287
287
|
|
288
288
|
except (BadSyntax, FileNotFoundError) as e:
|
289
289
|
template = "An exception of type {0} occurred when trying to parse the triple store configuration file. " \
|
@@ -303,11 +303,14 @@ def run_specs(specs) -> List[SpecResult]:
|
|
303
303
|
results.append(run_spec(specification))
|
304
304
|
return results
|
305
305
|
|
306
|
+
def get_spec_file(spec_uri: URIRef, spec_graph: Graph):
|
307
|
+
test = str(spec_graph.value(subject = spec_uri, predicate = MUST.specFileName, default = "default.mustrd.ttl"))
|
308
|
+
return test
|
306
309
|
|
307
310
|
def get_spec(spec_uri: URIRef, spec_graph: Graph, run_config: dict, mustrd_triple_store: dict = None) -> Specification:
|
308
311
|
try:
|
309
312
|
if mustrd_triple_store is None:
|
310
|
-
mustrd_triple_store = {"type":
|
313
|
+
mustrd_triple_store = {"type": TRIPLESTORE.RdfLib}
|
311
314
|
components = []
|
312
315
|
for predicate in MUST.given, MUST.when, MUST.then:
|
313
316
|
components.append(parse_spec_component(subject=spec_uri,
|
@@ -316,9 +319,9 @@ def get_spec(spec_uri: URIRef, spec_graph: Graph, run_config: dict, mustrd_tripl
|
|
316
319
|
run_config=run_config,
|
317
320
|
mustrd_triple_store=mustrd_triple_store))
|
318
321
|
|
319
|
-
|
322
|
+
spec_file_name = get_spec_file(spec_uri, spec_graph)
|
320
323
|
# https://github.com/Semantic-partners/mustrd/issues/92
|
321
|
-
return Specification(spec_uri, mustrd_triple_store, components[0].value, components[1], components[2])
|
324
|
+
return Specification(spec_uri, mustrd_triple_store, components[0].value, components[1], components[2], spec_file_name)
|
322
325
|
|
323
326
|
except (ValueError, FileNotFoundError) as e:
|
324
327
|
template = "An exception of type {0} occurred. Arguments:\n{1!r}"
|
@@ -354,7 +357,7 @@ def run_spec(spec: Specification) -> SpecResult:
|
|
354
357
|
log.debug(f"{given_as_turtle}")
|
355
358
|
upload_given(triple_store, spec.given)
|
356
359
|
else:
|
357
|
-
if triple_store['type'] ==
|
360
|
+
if triple_store['type'] == TRIPLESTORE.RdfLib:
|
358
361
|
return SpecSkipped(spec_uri, triple_store['type'], "Unable to run Inherited State tests on Rdflib")
|
359
362
|
try:
|
360
363
|
for when in spec.when:
|
@@ -386,57 +389,64 @@ def get_triple_store_graph(triple_store_graph_path: Path, secrets: str):
|
|
386
389
|
return Graph().parse(triple_store_graph_path).parse(data = secrets)
|
387
390
|
else:
|
388
391
|
secret_path = triple_store_graph_path.parent / Path(triple_store_graph_path.stem + "_secrets" + triple_store_graph_path.suffix)
|
389
|
-
return Graph().parse(triple_store_graph_path).parse(
|
392
|
+
return Graph().parse(triple_store_graph_path).parse(secret_path)
|
390
393
|
|
391
394
|
|
392
395
|
def get_triple_stores(triple_store_graph: Graph) -> list[dict]:
|
393
396
|
triple_stores = []
|
397
|
+
shacl_graph = Graph().parse(Path(os.path.join(get_mustrd_root(), "model/triplestoreshapes.ttl")))
|
398
|
+
ont_graph = Graph().parse(Path(os.path.join(get_mustrd_root(), "model/triplestoreOntology.ttl")))
|
399
|
+
conforms, results_graph, results_text = validate(
|
400
|
+
data_graph= triple_store_graph,
|
401
|
+
shacl_graph = shacl_graph,
|
402
|
+
ont_graph = ont_graph,
|
403
|
+
advanced= True,
|
404
|
+
inference= 'none'
|
405
|
+
)
|
406
|
+
if not conforms:
|
407
|
+
raise ValueError(f"Triple store configuration not conform to the shapes. SHACL report: {results_text}", results_graph)
|
394
408
|
for triple_store_config, rdf_type, triple_store_type in triple_store_graph.triples((None, RDF.type, None)):
|
395
409
|
triple_store = {}
|
396
|
-
|
397
|
-
|
398
|
-
triple_store["type"] = MUST.RdfLib
|
410
|
+
triple_store["type"] = triple_store_type
|
411
|
+
triple_store["uri"] = triple_store_config
|
399
412
|
# Anzo graph via anzo
|
400
|
-
|
401
|
-
triple_store["
|
402
|
-
triple_store["
|
403
|
-
triple_store["port"] = triple_store_graph.value(subject=triple_store_config, predicate=MUST.port)
|
413
|
+
if triple_store_type == TRIPLESTORE.Anzo:
|
414
|
+
triple_store["url"] = triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.url)
|
415
|
+
triple_store["port"] = triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.port)
|
404
416
|
try:
|
405
|
-
triple_store["username"] = str(triple_store_graph.value(subject=triple_store_config, predicate=
|
406
|
-
triple_store["password"] = str(triple_store_graph.value(subject=triple_store_config, predicate=
|
417
|
+
triple_store["username"] = str(triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.username))
|
418
|
+
triple_store["password"] = str(triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.password))
|
407
419
|
except (FileNotFoundError, ValueError) as e:
|
408
420
|
triple_store["error"] = e
|
409
|
-
triple_store["gqe_uri"] = triple_store_graph.value(subject=triple_store_config, predicate=
|
421
|
+
triple_store["gqe_uri"] = triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.gqeURI)
|
410
422
|
triple_store["input_graph"] = triple_store_graph.value(subject=triple_store_config,
|
411
|
-
predicate=
|
423
|
+
predicate=TRIPLESTORE.inputGraph)
|
412
424
|
triple_store["output_graph"] = triple_store_graph.value(subject=triple_store_config,
|
413
|
-
predicate=
|
425
|
+
predicate=TRIPLESTORE.outputGraph)
|
414
426
|
try:
|
415
427
|
check_triple_store_params(triple_store, ["url", "port", "username", "password", "input_graph"])
|
416
428
|
except ValueError as e:
|
417
429
|
triple_store["error"] = e
|
418
430
|
# GraphDB
|
419
|
-
elif triple_store_type ==
|
420
|
-
triple_store["
|
421
|
-
triple_store["
|
422
|
-
triple_store["port"] = triple_store_graph.value(subject=triple_store_config, predicate=MUST.port)
|
431
|
+
elif triple_store_type == TRIPLESTORE.GraphDb:
|
432
|
+
triple_store["url"] = triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.url)
|
433
|
+
triple_store["port"] = triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.port)
|
423
434
|
try:
|
424
|
-
triple_store["username"] = str(triple_store_graph.value(subject=triple_store_config, predicate=
|
425
|
-
triple_store["password"] = str(triple_store_graph.value(subject=triple_store_config, predicate=
|
435
|
+
triple_store["username"] = str(triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.username))
|
436
|
+
triple_store["password"] = str(triple_store_graph.value(subject=triple_store_config, predicate=TRIPLESTORE.password))
|
426
437
|
except (FileNotFoundError, ValueError) as e:
|
427
438
|
log.error(f"Credential retrieval failed {e}")
|
428
439
|
triple_store["error"] = e
|
429
440
|
triple_store["repository"] = triple_store_graph.value(subject=triple_store_config,
|
430
|
-
predicate=
|
441
|
+
predicate=TRIPLESTORE.repository)
|
431
442
|
triple_store["input_graph"] = triple_store_graph.value(subject=triple_store_config,
|
432
|
-
predicate=
|
443
|
+
predicate=TRIPLESTORE.inputGraph)
|
433
444
|
|
434
445
|
try:
|
435
446
|
check_triple_store_params(triple_store, ["url", "port", "repository"])
|
436
447
|
except ValueError as e:
|
437
448
|
triple_store["error"] = e
|
438
|
-
|
439
|
-
triple_store["type"] = triple_store_type
|
449
|
+
elif triple_store_type != TRIPLESTORE.RdfLib:
|
440
450
|
triple_store["error"] = f"Triple store not implemented: {triple_store_type}"
|
441
451
|
|
442
452
|
triple_stores.append(triple_store)
|
mustrd/mustrdTestPlugin.py
CHANGED
@@ -29,22 +29,30 @@ from pathlib import Path
|
|
29
29
|
from rdflib.namespace import Namespace
|
30
30
|
from rdflib import Graph, RDF
|
31
31
|
from pytest import Session
|
32
|
-
from typing import Dict
|
33
32
|
|
34
33
|
from mustrd.TestResult import ResultList, TestResult, get_result_list
|
35
34
|
from mustrd.utils import get_mustrd_root
|
36
35
|
from mustrd.mustrd import get_triple_store_graph, get_triple_stores
|
37
|
-
from mustrd.mustrd import SpecSkipped, validate_specs, get_specs, SpecPassed, run_spec
|
38
|
-
from mustrd.namespace import MUST
|
39
|
-
from
|
36
|
+
from mustrd.mustrd import Specification, SpecSkipped, validate_specs, get_specs, SpecPassed, run_spec
|
37
|
+
from mustrd.namespace import MUST, TRIPLESTORE, MUSTRDTEST
|
38
|
+
from typing import Union
|
39
|
+
from pyshacl import validate
|
40
40
|
|
41
41
|
spnamespace = Namespace("https://semanticpartners.com/data/test/")
|
42
42
|
|
43
43
|
mustrd_root = get_mustrd_root()
|
44
44
|
|
45
|
+
MUSTRD_PYTEST_PATH = "mustrd_tests/"
|
46
|
+
|
45
47
|
|
46
48
|
def pytest_addoption(parser):
|
47
|
-
group = parser.getgroup("
|
49
|
+
group = parser.getgroup("mustrd option")
|
50
|
+
group.addoption(
|
51
|
+
"--mustrd",
|
52
|
+
action="store_true",
|
53
|
+
dest="mustrd",
|
54
|
+
help="Activate/deactivate mustrd test generation.",
|
55
|
+
)
|
48
56
|
group.addoption(
|
49
57
|
"--md",
|
50
58
|
action="store",
|
@@ -59,7 +67,6 @@ def pytest_addoption(parser):
|
|
59
67
|
dest="configpath",
|
60
68
|
metavar="pathToTestConfig",
|
61
69
|
default=None,
|
62
|
-
required=True,
|
63
70
|
help="Ttl file containing the list of test to construct.",
|
64
71
|
)
|
65
72
|
group.addoption(
|
@@ -68,7 +75,6 @@ def pytest_addoption(parser):
|
|
68
75
|
dest="secrets",
|
69
76
|
metavar="Secrets",
|
70
77
|
default=None,
|
71
|
-
required=False,
|
72
78
|
help="Give the secrets by command line in order to be able to store secrets safely in CI tools",
|
73
79
|
)
|
74
80
|
return
|
@@ -76,23 +82,40 @@ def pytest_addoption(parser):
|
|
76
82
|
|
77
83
|
def pytest_configure(config) -> None:
|
78
84
|
# Read configuration file
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
85
|
+
if config.getoption("mustrd"):
|
86
|
+
test_configs = parse_config(config.getoption("configpath"))
|
87
|
+
config.pluginmanager.register(MustrdTestPlugin(config.getoption("mdpath"),
|
88
|
+
test_configs, config.getoption("secrets")))
|
89
|
+
|
90
|
+
def parse_config(config_path):
|
91
|
+
test_configs = []
|
92
|
+
config_graph = Graph().parse(config_path)
|
93
|
+
shacl_graph = Graph().parse(Path(os.path.join(mustrd_root, "model/mustrdTestShapes.ttl")))
|
94
|
+
ont_graph = Graph().parse(Path(os.path.join(mustrd_root, "model/mustrdTestOntology.ttl")))
|
95
|
+
conforms, results_graph, results_text = validate(
|
96
|
+
data_graph= config_graph,
|
97
|
+
shacl_graph = shacl_graph,
|
98
|
+
ont_graph = ont_graph,
|
99
|
+
advanced= True,
|
100
|
+
inference= 'none'
|
101
|
+
)
|
102
|
+
if not conforms:
|
103
|
+
raise ValueError(f"Mustrd test configuration not conform to the shapes. SHACL report: {results_text}", results_graph)
|
104
|
+
|
105
|
+
for test_config_subject in config_graph.subjects(predicate=RDF.type, object=MUSTRDTEST.MustrdTest):
|
106
|
+
spec_path = get_config_param(config_graph, test_config_subject, MUSTRDTEST.hasSpecPath, str)
|
107
|
+
data_path = get_config_param(config_graph, test_config_subject, MUSTRDTEST.hasDataPath, str)
|
108
|
+
triplestore_spec_path = get_config_param(config_graph, test_config_subject, MUSTRDTEST.triplestoreSpecPath, str)
|
109
|
+
pytest_path = get_config_param(config_graph, test_config_subject, MUSTRDTEST.hasPytestPath, str)
|
86
110
|
filter_on_tripleStore = list(config_graph.objects(subject=test_config_subject,
|
87
|
-
|
111
|
+
predicate=MUSTRDTEST.filterOnTripleStore))
|
88
112
|
|
89
|
-
test_configs
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
test_configs, config.getoption("secrets")))
|
113
|
+
test_configs.append(TestConfig(spec_path=spec_path, data_path=data_path,
|
114
|
+
triplestore_spec_path=triplestore_spec_path,
|
115
|
+
pytest_path = pytest_path,
|
116
|
+
filter_on_tripleStore=filter_on_tripleStore))
|
117
|
+
return test_configs
|
118
|
+
|
96
119
|
|
97
120
|
|
98
121
|
def get_config_param(config_graph, config_subject, config_param, convert_function):
|
@@ -102,65 +125,109 @@ def get_config_param(config_graph, config_subject, config_param, convert_functio
|
|
102
125
|
|
103
126
|
@dataclass
|
104
127
|
class TestConfig:
|
105
|
-
test_function: str
|
106
128
|
spec_path: str
|
107
129
|
data_path: str
|
108
130
|
triplestore_spec_path: str
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
filter_on_tripleStore: str = None):
|
113
|
-
self.test_function = test_function
|
114
|
-
self.spec_path = spec_path
|
115
|
-
self.data_path = data_path
|
116
|
-
self.triplestore_spec_path = triplestore_spec_path
|
117
|
-
self.filter_on_tripleStore = filter_on_tripleStore
|
131
|
+
pytest_path: str
|
132
|
+
filter_on_tripleStore: str = None
|
133
|
+
|
118
134
|
|
135
|
+
@dataclass
|
136
|
+
class TestParamWrapper:
|
137
|
+
test_config: TestConfig
|
138
|
+
unit_test: Union[Specification, SpecSkipped]
|
119
139
|
|
120
140
|
class MustrdTestPlugin:
|
121
141
|
md_path: str
|
122
|
-
test_configs:
|
142
|
+
test_configs: list
|
123
143
|
secrets: str
|
144
|
+
unit_tests: Union[Specification, SpecSkipped]
|
145
|
+
items: list
|
124
146
|
|
125
147
|
def __init__(self, md_path, test_configs, secrets):
|
126
148
|
self.md_path = md_path
|
127
149
|
self.test_configs = test_configs
|
128
150
|
self.secrets = secrets
|
151
|
+
self.items = []
|
152
|
+
|
153
|
+
@pytest.hookimpl(tryfirst=True)
|
154
|
+
def pytest_collection(self, session):
|
155
|
+
self.unit_tests = []
|
156
|
+
args = session.config.args
|
157
|
+
if len(args) > 0:
|
158
|
+
file_name = self.get_file_name_from_arg(args[0])
|
159
|
+
# Filter test to collect only specified path
|
160
|
+
config_to_collect = list(filter(lambda config:
|
161
|
+
# Case we want to collect everything
|
162
|
+
MUSTRD_PYTEST_PATH not in args[0]
|
163
|
+
# Case we want to collect a test or sub test
|
164
|
+
or (config.pytest_path or "") in args[0]
|
165
|
+
# Case we want to collect a whole test folder
|
166
|
+
or args[0].replace(f"./{MUSTRD_PYTEST_PATH}", "") in config.pytest_path,
|
167
|
+
self.test_configs))
|
168
|
+
|
169
|
+
# Redirect everything to test_mustrd.py, no need to filter on specified test: Only specified test will be collected anyway
|
170
|
+
session.config.args[0] = os.path.join(mustrd_root, "test/test_mustrd.py")
|
171
|
+
# Collecting only relevant tests
|
172
|
+
|
173
|
+
for one_test_config in config_to_collect:
|
174
|
+
triple_stores = self.get_triple_stores_from_file(one_test_config)
|
175
|
+
|
176
|
+
if one_test_config.filter_on_tripleStore and not triple_stores:
|
177
|
+
self.unit_tests.extend(list(map(lambda triple_store:
|
178
|
+
TestParamWrapper(test_config = one_test_config, unit_test=SpecSkipped(MUST.TestSpec, triple_store, "No triplestore found")),
|
179
|
+
one_test_config.filter_on_tripleStore)))
|
180
|
+
else:
|
181
|
+
specs = self.generate_tests_for_config({"spec_path": Path(one_test_config.spec_path),
|
182
|
+
"data_path": Path(one_test_config.data_path)},
|
183
|
+
triple_stores, file_name)
|
184
|
+
self.unit_tests.extend(list(map(lambda spec: TestParamWrapper(test_config = one_test_config, unit_test=spec),specs)))
|
185
|
+
|
186
|
+
def get_file_name_from_arg(self, arg):
|
187
|
+
if arg and len(arg) > 0 and "[" in arg and ".mustrd.ttl@" in arg:
|
188
|
+
return arg[arg.index("[") + 1: arg.index(".mustrd.ttl@")]
|
189
|
+
return None
|
190
|
+
|
191
|
+
|
192
|
+
@pytest.hookimpl(hookwrapper=True)
|
193
|
+
def pytest_pycollect_makeitem(self, collector, name, obj):
|
194
|
+
report = yield
|
195
|
+
if name == "test_unit":
|
196
|
+
items = report.get_result()
|
197
|
+
new_results = []
|
198
|
+
for item in items:
|
199
|
+
virtual_path = MUSTRD_PYTEST_PATH + (item.callspec.params["unit_tests"].test_config.pytest_path or "default")
|
200
|
+
item.fspath = Path(virtual_path)
|
201
|
+
item._nodeid = virtual_path + "::" + item.name
|
202
|
+
self.items.append(item)
|
203
|
+
new_results.append(item)
|
204
|
+
return new_results
|
205
|
+
|
129
206
|
|
130
207
|
# Hook called at collection time: reads the configuration of the tests, and generate pytests from it
|
131
208
|
def pytest_generate_tests(self, metafunc):
|
132
|
-
|
133
209
|
if len(metafunc.fixturenames) > 0:
|
134
|
-
if metafunc.function.__name__
|
135
|
-
one_test_config = self.test_configs[metafunc.function.__name__]
|
136
|
-
|
137
|
-
triple_stores = self.get_triple_stores_from_file(one_test_config)
|
138
|
-
|
139
|
-
unit_tests = []
|
140
|
-
if one_test_config.filter_on_tripleStore and not triple_stores:
|
141
|
-
unit_tests = list(map(lambda triple_store:
|
142
|
-
SpecSkipped(MUST.TestSpec, triple_store, "No triplestore found"),
|
143
|
-
one_test_config.filter_on_tripleStore))
|
144
|
-
else:
|
145
|
-
unit_tests = self.generate_tests_for_config({"spec_path": Path(one_test_config.spec_path),
|
146
|
-
"data_path": Path(one_test_config.data_path)},
|
147
|
-
triple_stores)
|
148
|
-
|
210
|
+
if metafunc.function.__name__ == "test_unit":
|
149
211
|
# Create the test in itself
|
150
|
-
if unit_tests:
|
151
|
-
metafunc.parametrize(metafunc.fixturenames[0], unit_tests,
|
212
|
+
if self.unit_tests:
|
213
|
+
metafunc.parametrize(metafunc.fixturenames[0], self.unit_tests,
|
214
|
+
ids=lambda test_param: (test_param.unit_test.spec_file_name or "") + "@" +
|
215
|
+
(test_param.test_config.pytest_path or ""))
|
152
216
|
else:
|
153
217
|
metafunc.parametrize(metafunc.fixturenames[0],
|
154
218
|
[SpecSkipped(MUST.TestSpec, None, "No triplestore found")],
|
155
219
|
ids=lambda x: "No configuration found for this test")
|
220
|
+
|
221
|
+
|
222
|
+
|
156
223
|
|
157
224
|
# Generate test for each triple store available
|
158
|
-
def generate_tests_for_config(self, config, triple_stores):
|
225
|
+
def generate_tests_for_config(self, config, triple_stores, file_name):
|
159
226
|
|
160
227
|
shacl_graph = Graph().parse(Path(os.path.join(mustrd_root, "model/mustrdShapes.ttl")))
|
161
228
|
ont_graph = Graph().parse(Path(os.path.join(mustrd_root, "model/ontology.ttl")))
|
162
229
|
valid_spec_uris, spec_graph, invalid_spec_results = validate_specs(config, triple_stores,
|
163
|
-
shacl_graph, ont_graph)
|
230
|
+
shacl_graph, ont_graph, file_name or "*")
|
164
231
|
|
165
232
|
specs, skipped_spec_results = \
|
166
233
|
get_specs(valid_spec_uris, spec_graph, triple_stores, config)
|
@@ -186,15 +253,15 @@ class MustrdTestPlugin:
|
|
186
253
|
triple_stores = get_triple_stores(get_triple_store_graph(Path(test_config.triplestore_spec_path),
|
187
254
|
self.secrets))
|
188
255
|
except Exception as e:
|
189
|
-
print(f"""
|
190
|
-
|
191
|
-
triple_stores = [{'type':
|
256
|
+
print(f"""Triplestore configuration parsing failed {test_config.triplestore_spec_path}.
|
257
|
+
Only rdflib will be executed""", e)
|
258
|
+
triple_stores = [{'type': TRIPLESTORE.RdfLib, 'uri': TRIPLESTORE.RdfLib}]
|
192
259
|
else:
|
193
260
|
print("No triple store configuration required: using embedded rdflib")
|
194
|
-
triple_stores = [{'type':
|
261
|
+
triple_stores = [{'type': TRIPLESTORE.RdfLib, 'uri': TRIPLESTORE.RdfLib}]
|
195
262
|
|
196
263
|
if test_config.filter_on_tripleStore:
|
197
|
-
triple_stores = list(filter(lambda triple_store: (triple_store["
|
264
|
+
triple_stores = list(filter(lambda triple_store: (triple_store["uri"] in test_config.filter_on_tripleStore),
|
198
265
|
triple_stores))
|
199
266
|
return triple_stores
|
200
267
|
|
mustrd/namespace.py
CHANGED
@@ -25,18 +25,10 @@ SOFTWARE.
|
|
25
25
|
from rdflib import URIRef
|
26
26
|
from rdflib.namespace import DefinedNamespace, Namespace
|
27
27
|
|
28
|
-
|
28
|
+
# Namespace for the test specifications
|
29
29
|
class MUST(DefinedNamespace):
|
30
30
|
_NS = Namespace("https://mustrd.com/model/")
|
31
|
-
|
32
|
-
# test configuration
|
33
|
-
TestConfig: URIRef
|
34
|
-
hasTestFunction: URIRef
|
35
|
-
hasSpecPath: URIRef
|
36
|
-
hasDataPath: URIRef
|
37
|
-
triplestoreSpecPath: URIRef
|
38
|
-
filterOnTripleStore: URIRef
|
39
|
-
|
31
|
+
|
40
32
|
# Specification classes
|
41
33
|
TestSpec: URIRef
|
42
34
|
SelectSparql: URIRef
|
@@ -50,8 +42,6 @@ class MUST(DefinedNamespace):
|
|
50
42
|
given: URIRef
|
51
43
|
when: URIRef
|
52
44
|
then: URIRef
|
53
|
-
inputGraph: URIRef
|
54
|
-
outputGraph: URIRef # anzo specials?
|
55
45
|
dataSource: URIRef
|
56
46
|
file: URIRef
|
57
47
|
fileName: URIRef
|
@@ -84,22 +74,10 @@ class MUST(DefinedNamespace):
|
|
84
74
|
fileSource: URIRef
|
85
75
|
loadedFromFile: URIRef
|
86
76
|
specSourceFile: URIRef
|
77
|
+
specFileName: URIRef
|
87
78
|
|
88
79
|
# Triple store config parameters
|
89
|
-
url: URIRef
|
90
|
-
port: URIRef
|
91
|
-
username: URIRef
|
92
|
-
password: URIRef
|
93
|
-
inputGraph: URIRef
|
94
|
-
repository: URIRef
|
95
|
-
|
96
|
-
# RDFLib
|
97
|
-
RdfLib: URIRef
|
98
|
-
RdfLibConfig: URIRef
|
99
|
-
|
100
80
|
# Anzo
|
101
|
-
Anzo: URIRef
|
102
|
-
AnzoConfig: URIRef
|
103
81
|
AnzoGraphmartDataset: URIRef
|
104
82
|
AnzoQueryBuilderSparqlSource: URIRef
|
105
83
|
AnzoGraphmartStepSparqlSource: URIRef
|
@@ -107,12 +85,41 @@ class MUST(DefinedNamespace):
|
|
107
85
|
AnzoGraphmartQueryDrivenTemplatedStepSparqlSource: URIRef
|
108
86
|
anzoQueryStep: URIRef
|
109
87
|
anzoGraphmartLayer: URIRef
|
110
|
-
|
111
88
|
|
112
89
|
graphmart: URIRef
|
113
90
|
layer: URIRef
|
114
|
-
gqeURI: URIRef
|
115
91
|
|
116
|
-
|
92
|
+
|
93
|
+
# FIXME: There is nothing to do that by default?
|
94
|
+
@classmethod
|
95
|
+
def get_local_name(cls, uri: URIRef):
|
96
|
+
return str(uri).split(cls._NS)[1]
|
97
|
+
|
98
|
+
# Namespace for triplestores
|
99
|
+
class TRIPLESTORE(DefinedNamespace):
|
100
|
+
_NS = Namespace("https://mustrd.com/triplestore/")
|
101
|
+
RdfLib: URIRef
|
117
102
|
GraphDb: URIRef
|
118
|
-
|
103
|
+
Anzo: URIRef
|
104
|
+
ExternalTripleStore: URIRef
|
105
|
+
InternalTripleStore: URIRef
|
106
|
+
|
107
|
+
gqeURI: URIRef
|
108
|
+
inputGraph: URIRef
|
109
|
+
outputGraph: URIRef # anzo specials? # Triple store config parameters
|
110
|
+
url: URIRef
|
111
|
+
port: URIRef
|
112
|
+
username: URIRef
|
113
|
+
password: URIRef
|
114
|
+
repository: URIRef
|
115
|
+
|
116
|
+
# namespace for pytest_mustrd config
|
117
|
+
class MUSTRDTEST(DefinedNamespace):
|
118
|
+
_NS = Namespace("https://mustrd.com/mustrdTest/")
|
119
|
+
MustrdTest: URIRef
|
120
|
+
hasSpecPath: URIRef
|
121
|
+
hasDataPath: URIRef
|
122
|
+
triplestoreSpecPath: URIRef
|
123
|
+
hasPytestPath: URIRef
|
124
|
+
filterOnTripleStore: URIRef
|
125
|
+
|
mustrd/run.py
CHANGED
@@ -29,7 +29,7 @@ import os
|
|
29
29
|
from rdflib import Graph
|
30
30
|
from .mustrd import get_triple_store_graph, run_specs, get_triple_stores, review_results, validate_specs, get_specs
|
31
31
|
from pathlib import Path
|
32
|
-
from .namespace import
|
32
|
+
from .namespace import TRIPLESTORE
|
33
33
|
from .utils import get_project_root
|
34
34
|
import logging
|
35
35
|
log = logger_setup.setup_logger(__name__)
|
@@ -68,7 +68,7 @@ def main(argv):
|
|
68
68
|
triple_stores = get_triple_stores(get_triple_store_graph(triplestore_spec_path))
|
69
69
|
else:
|
70
70
|
log.info(f"No triple store configuration added, running default configuration")
|
71
|
-
triple_stores = [{'type':
|
71
|
+
triple_stores = [{'type': TRIPLESTORE.RdfLib}]
|
72
72
|
log.info("Triple Stores: " + str(triple_stores))
|
73
73
|
if args.data:
|
74
74
|
run_config["data_path"] = Path(args.data)
|
mustrd/spec_component.py
CHANGED
@@ -37,7 +37,7 @@ import logging
|
|
37
37
|
|
38
38
|
from . import logger_setup
|
39
39
|
from .mustrdAnzo import get_queries_for_layer, get_queries_from_templated_step, get_spec_component_from_graphmart, get_query_from_querybuilder, get_query_from_step
|
40
|
-
from .namespace import MUST
|
40
|
+
from .namespace import MUST, TRIPLESTORE
|
41
41
|
from multimethods import MultiMethod, Default
|
42
42
|
|
43
43
|
log = logger_setup.setup_logger(__name__)
|
@@ -417,7 +417,7 @@ def _get_spec_component_StatementsDataset(spec_component_details: SpecComponentD
|
|
417
417
|
def _get_spec_component_AnzoGraphmartDataset(spec_component_details: SpecComponentDetails) -> SpecComponent:
|
418
418
|
spec_component = init_spec_component(spec_component_details.predicate)
|
419
419
|
|
420
|
-
if spec_component_details.mustrd_triple_store["type"] ==
|
420
|
+
if spec_component_details.mustrd_triple_store["type"] == TRIPLESTORE.Anzo:
|
421
421
|
# Get GIVEN or THEN from anzo graphmart
|
422
422
|
graphmart = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
423
423
|
predicate=MUST.graphmart)
|
@@ -428,7 +428,7 @@ def _get_spec_component_AnzoGraphmartDataset(spec_component_details: SpecCompone
|
|
428
428
|
graphmart=graphmart,
|
429
429
|
layer=layer)
|
430
430
|
else:
|
431
|
-
raise ValueError(f"You must define {
|
431
|
+
raise ValueError(f"You must define {TRIPLESTORE.Anzo} to use {MUST.AnzoGraphmartDataset}")
|
432
432
|
|
433
433
|
return spec_component
|
434
434
|
|
@@ -438,7 +438,7 @@ def _get_spec_component_AnzoQueryBuilderSparqlSource(spec_component_details: Spe
|
|
438
438
|
spec_component = init_spec_component(spec_component_details.predicate)
|
439
439
|
|
440
440
|
# Get WHEN specComponent from query builder
|
441
|
-
if spec_component_details.mustrd_triple_store["type"] ==
|
441
|
+
if spec_component_details.mustrd_triple_store["type"] == TRIPLESTORE.Anzo:
|
442
442
|
query_folder = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
443
443
|
predicate=MUST.queryFolder)
|
444
444
|
query_name = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
@@ -448,7 +448,7 @@ def _get_spec_component_AnzoQueryBuilderSparqlSource(spec_component_details: Spe
|
|
448
448
|
query_name=query_name)
|
449
449
|
# If anzo specific function is called but no anzo defined
|
450
450
|
else:
|
451
|
-
raise ValueError(f"You must define {
|
451
|
+
raise ValueError(f"You must define {TRIPLESTORE.Anzo} to use {MUST.AnzoQueryBuilderSparqlSource}")
|
452
452
|
|
453
453
|
spec_component.queryType = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
454
454
|
predicate=MUST.queryType)
|
@@ -460,14 +460,14 @@ def _get_spec_component_AnzoGraphmartStepSparqlSource(spec_component_details: Sp
|
|
460
460
|
spec_component = init_spec_component(spec_component_details.predicate)
|
461
461
|
|
462
462
|
# Get WHEN specComponent from query builder
|
463
|
-
if spec_component_details.mustrd_triple_store["type"] ==
|
463
|
+
if spec_component_details.mustrd_triple_store["type"] == TRIPLESTORE.Anzo:
|
464
464
|
query_step_uri = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
465
465
|
predicate=MUST.anzoQueryStep)
|
466
466
|
spec_component.value = get_query_from_step(triple_store=spec_component_details.mustrd_triple_store,
|
467
467
|
query_step_uri=query_step_uri)
|
468
468
|
# If anzo specific function is called but no anzo defined
|
469
469
|
else:
|
470
|
-
raise ValueError(f"You must define {
|
470
|
+
raise ValueError(f"You must define {TRIPLESTORE.Anzo} to use {MUST.AnzoGraphmartStepSparqlSource}")
|
471
471
|
|
472
472
|
spec_component.queryType = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
473
473
|
predicate=MUST.queryType)
|
@@ -478,7 +478,7 @@ def _get_spec_component_AnzoGraphmartQueryDrivenTemplatedStepSparqlSource(spec_c
|
|
478
478
|
spec_component = init_spec_component(spec_component_details.predicate, spec_component_details.mustrd_triple_store["type"] )
|
479
479
|
|
480
480
|
# Get WHEN specComponent from query builder
|
481
|
-
if spec_component_details.mustrd_triple_store["type"] ==
|
481
|
+
if spec_component_details.mustrd_triple_store["type"] == TRIPLESTORE.Anzo:
|
482
482
|
query_step_uri = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
483
483
|
predicate=MUST.anzoQueryStep)
|
484
484
|
queries = get_queries_from_templated_step(triple_store=spec_component_details.mustrd_triple_store,
|
@@ -487,7 +487,7 @@ def _get_spec_component_AnzoGraphmartQueryDrivenTemplatedStepSparqlSource(spec_c
|
|
487
487
|
spec_component.queryTemplate = queries["query_template"]
|
488
488
|
# If anzo specific function is called but no anzo defined
|
489
489
|
else:
|
490
|
-
raise ValueError(f"You must define {
|
490
|
+
raise ValueError(f"You must define {TRIPLESTORE.Anzo} to use {MUST.AnzoGraphmartQueryDrivenTemplatedStepSparqlSource}")
|
491
491
|
|
492
492
|
spec_component.queryType = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
493
493
|
predicate=MUST.queryType)
|
@@ -497,7 +497,7 @@ def _get_spec_component_AnzoGraphmartQueryDrivenTemplatedStepSparqlSource(spec_c
|
|
497
497
|
def _get_spec_component_AnzoGraphmartLayerSparqlSource(spec_component_details: SpecComponentDetails) -> list:
|
498
498
|
spec_components = []
|
499
499
|
# Get the ordered WHEN specComponents which is the transform and query driven template queries for the Layer
|
500
|
-
if spec_component_details.mustrd_triple_store["type"] ==
|
500
|
+
if spec_component_details.mustrd_triple_store["type"] == TRIPLESTORE.Anzo:
|
501
501
|
graphmart_layer_uri = spec_component_details.spec_graph.value(subject=spec_component_details.spec_component_node,
|
502
502
|
predicate=MUST.anzoGraphmartLayer)
|
503
503
|
queries = get_queries_for_layer(triple_store=spec_component_details.mustrd_triple_store,
|
@@ -529,7 +529,7 @@ def init_spec_component(predicate: URIRef, triple_store_type: URIRef = None ) ->
|
|
529
529
|
if predicate == MUST.given:
|
530
530
|
spec_component = GivenSpec()
|
531
531
|
elif predicate == MUST.when:
|
532
|
-
if triple_store_type ==
|
532
|
+
if triple_store_type == TRIPLESTORE.Anzo:
|
533
533
|
spec_component = AnzoWhenSpec()
|
534
534
|
else:
|
535
535
|
spec_component = WhenSpec()
|
mustrd/steprunner.py
CHANGED
@@ -26,7 +26,7 @@ import json
|
|
26
26
|
|
27
27
|
from . import logger_setup
|
28
28
|
from multimethods import MultiMethod, Default
|
29
|
-
from .namespace import MUST
|
29
|
+
from .namespace import MUST, TRIPLESTORE
|
30
30
|
from rdflib import Graph, URIRef
|
31
31
|
from .mustrdRdfLib import execute_select as execute_select_rdflib
|
32
32
|
from .mustrdRdfLib import execute_construct as execute_construct_rdflib
|
@@ -53,17 +53,17 @@ def dispatch_upload_given(triple_store: dict, given: Graph):
|
|
53
53
|
upload_given = MultiMethod('upload_given', dispatch_upload_given)
|
54
54
|
|
55
55
|
|
56
|
-
@upload_given.method(
|
56
|
+
@upload_given.method(TRIPLESTORE.RdfLib)
|
57
57
|
def _upload_given_rdflib(triple_store: dict, given: Graph):
|
58
58
|
triple_store["given"] = given
|
59
59
|
|
60
60
|
|
61
|
-
@upload_given.method(
|
61
|
+
@upload_given.method(TRIPLESTORE.GraphDb)
|
62
62
|
def _upload_given_graphdb(triple_store: dict, given: Graph):
|
63
63
|
upload_given_graphdb(triple_store, given)
|
64
64
|
|
65
65
|
|
66
|
-
@upload_given.method(
|
66
|
+
@upload_given.method(TRIPLESTORE.Anzo)
|
67
67
|
def _upload_given_anzo(triple_store: dict, given: Graph):
|
68
68
|
upload_given_anzo(triple_store, given)
|
69
69
|
|
@@ -78,52 +78,52 @@ def dispatch_run_when(spec_uri: URIRef, triple_store: dict, when: WhenSpec):
|
|
78
78
|
run_when = MultiMethod('run_when', dispatch_run_when)
|
79
79
|
|
80
80
|
|
81
|
-
@run_when.method((
|
81
|
+
@run_when.method((TRIPLESTORE.Anzo, MUST.UpdateSparql))
|
82
82
|
def _anzo_run_when_update(spec_uri: URIRef, triple_store: dict, when: AnzoWhenSpec):
|
83
83
|
return execute_update_anzo(triple_store, when.value, when.bindings)
|
84
84
|
|
85
85
|
|
86
|
-
@run_when.method((
|
86
|
+
@run_when.method((TRIPLESTORE.Anzo, MUST.ConstructSparql))
|
87
87
|
def _anzo_run_when_construct(spec_uri: URIRef, triple_store: dict, when: AnzoWhenSpec):
|
88
88
|
return execute_construct_anzo(triple_store, when.value, when.bindings)
|
89
89
|
|
90
90
|
|
91
|
-
@run_when.method((
|
91
|
+
@run_when.method((TRIPLESTORE.Anzo, MUST.SelectSparql))
|
92
92
|
def _anzo_run_when_select(spec_uri: URIRef, triple_store: dict, when: AnzoWhenSpec):
|
93
93
|
return execute_select_anzo(triple_store, when.value, when.bindings)
|
94
94
|
|
95
95
|
|
96
|
-
@run_when.method((
|
96
|
+
@run_when.method((TRIPLESTORE.GraphDb, MUST.UpdateSparql))
|
97
97
|
def _graphdb_run_when_update(spec_uri: URIRef, triple_store: dict, when: WhenSpec):
|
98
98
|
return execute_update_graphdb(triple_store, when.value, when.bindings)
|
99
99
|
|
100
100
|
|
101
|
-
@run_when.method((
|
101
|
+
@run_when.method((TRIPLESTORE.GraphDb, MUST.ConstructSparql))
|
102
102
|
def _graphdb_run_when_construct(spec_uri: URIRef, triple_store: dict, when: WhenSpec):
|
103
103
|
return execute_construct_graphdb(triple_store, when.value, when.bindings)
|
104
104
|
|
105
105
|
|
106
|
-
@run_when.method((
|
106
|
+
@run_when.method((TRIPLESTORE.GraphDb, MUST.SelectSparql))
|
107
107
|
def _graphdb_run_when_select(spec_uri: URIRef, triple_store: dict, when: WhenSpec):
|
108
108
|
return execute_select_graphdb(triple_store, when.value, when.bindings)
|
109
109
|
|
110
110
|
|
111
|
-
@run_when.method((
|
111
|
+
@run_when.method((TRIPLESTORE.RdfLib, MUST.UpdateSparql))
|
112
112
|
def _rdflib_run_when_update(spec_uri: URIRef, triple_store: dict, when: WhenSpec):
|
113
113
|
return execute_update_rdflib(triple_store, triple_store["given"], when.value, when.bindings)
|
114
114
|
|
115
115
|
|
116
|
-
@run_when.method((
|
116
|
+
@run_when.method((TRIPLESTORE.RdfLib, MUST.ConstructSparql))
|
117
117
|
def _rdflib_run_when_construct(spec_uri: URIRef, triple_store: dict, when: WhenSpec):
|
118
118
|
return execute_construct_rdflib(triple_store, triple_store["given"], when.value, when.bindings)
|
119
119
|
|
120
120
|
|
121
|
-
@run_when.method((
|
121
|
+
@run_when.method((TRIPLESTORE.RdfLib, MUST.SelectSparql))
|
122
122
|
def _rdflib_run_when_select(spec_uri: URIRef, triple_store: dict, when: WhenSpec):
|
123
123
|
return execute_select_rdflib(triple_store, triple_store["given"], when.value, when.bindings)
|
124
124
|
|
125
125
|
|
126
|
-
@run_when.method((
|
126
|
+
@run_when.method((TRIPLESTORE.Anzo, MUST.AnzoQueryDrivenUpdateSparql))
|
127
127
|
def _multi_run_when_anzo_query_driven_update(spec_uri: URIRef, triple_store: dict, when: AnzoWhenSpec):
|
128
128
|
# run the parameters query to obtain the values for the template step and put them into a dictionary
|
129
129
|
query_parameters = json.loads(execute_select_anzo(triple_store, when.paramQuery, None))
|
@@ -158,7 +158,7 @@ def _multi_run_when_default(spec_uri: URIRef, triple_store: dict, when: WhenSpec
|
|
158
158
|
elif when.queryType == MUST.DescribeSparql:
|
159
159
|
log.warning(f"Skipping {spec_uri}, SPARQL DESCRIBE not implemented.")
|
160
160
|
msg = "SPARQL DESCRIBE not implemented."
|
161
|
-
elif triple_store['type'] not in [
|
161
|
+
elif triple_store['type'] not in [TRIPLESTORE.Anzo, TRIPLESTORE.GraphDb, TRIPLESTORE.RdfLib]:
|
162
162
|
msg = f"{when.queryType} not implemented for {triple_store['type']}"
|
163
163
|
else:
|
164
164
|
log.warning(f"Skipping {spec_uri}, {when.queryType} is not a valid SPARQL query type.")
|
@@ -0,0 +1,31 @@
|
|
1
|
+
mustrd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
mustrd/logger_setup.py,sha256=AXTXiiyQ4E_SyqNaKlLsZlkkKr_YJfJZ0N4PEoN7d7E,1630
|
3
|
+
mustrd/model/catalog-v001.xml,sha256=jgD6VOxR6A8izzr3ZmL4AzaTZ5cVwsvt618MTuRlGBk,386
|
4
|
+
mustrd/model/mustrdShapes.ttl,sha256=BR-9fAwGpQt6glfPpDB0Xx3vFXMt_UTQwi469o6aWUo,9709
|
5
|
+
mustrd/model/mustrdTestOntology.ttl,sha256=W7IRbPKrhpYFweZvc9QH8gdjBiuZMHKETIuHBepLnYw,2034
|
6
|
+
mustrd/model/mustrdTestShapes.ttl,sha256=Bcof6p7MtzO2L6H1DWB1hibLSix7Dxo-z6HlFcG31M8,842
|
7
|
+
mustrd/model/ontology.ttl,sha256=JF6LG5-T7tbi3QfmJcEFQcFo-rQT0CTYGg7PEmuzINY,17303
|
8
|
+
mustrd/model/test-resources/resources.ttl,sha256=7z1P4qJwuqRdmHzKd_mhnUIs-aQoSQxas7yDCwKYarc,1558
|
9
|
+
mustrd/model/triplestoreOntology.ttl,sha256=87leTcKot45AgcCGfJLEwbY9rsuRGHbYbnTFeijrzOk,6199
|
10
|
+
mustrd/model/triplestoreshapes.ttl,sha256=qiLzbclGDzueH5GCKANEwMM9VxOmswu42FiSnITATeQ,1876
|
11
|
+
mustrd/mustrd.py,sha256=-obRBvgFU5QiI5k4zTaf473aHkgvl3ZHQ2xVkdSxS8c,35099
|
12
|
+
mustrd/mustrdAnzo.py,sha256=bQ-IHCnsEK7paJ31GgS9IH3hGd4o_5zeNrpn0Sb8WIk,11822
|
13
|
+
mustrd/mustrdGraphDb.py,sha256=KNXXYyZjYm_IZaeuuxlPBP-XyX9hZ5UvrdxshKnZhwo,5599
|
14
|
+
mustrd/mustrdRdfLib.py,sha256=LeS-uArlxQwsM-7lrJyp8O8m-6VgxsR1BlpxsOCNePs,2129
|
15
|
+
mustrd/mustrdTestPlugin.py,sha256=SsTkwrs0n1lvHvuiyQs-z4dsXnjB7p3d6aFWR8_jLV8,15035
|
16
|
+
mustrd/namespace.py,sha256=3zJbdWEji_2SkhasHK3J2UO3am_phNKDwAFk2htXRYM,3765
|
17
|
+
mustrd/README.adoc,sha256=56W59hX4xyttspTXUXRJAgqemBSVavWHpfs6Lar_-qo,11995
|
18
|
+
mustrd/run.py,sha256=r3FS_iAuXYpENbbrLfgymGUP4dx-ZGJ_Y2ZvnZdL9dg,4380
|
19
|
+
mustrd/spec_component.py,sha256=0D81UlZEpUGk9FZfzUElp8a6kEoFsfkr7bGasKDTdSU,32546
|
20
|
+
mustrd/steprunner.py,sha256=n3k4O2SjsLUEG5QOxLG8Z8D3iH9PJzzR63dIV2KHcBE,7555
|
21
|
+
mustrd/templates/md_ResultList_leaf_template.jinja,sha256=un1XMeNO9xLcry-DmTQ2QoWoTM5Q5CkVUV_LS4O7sHM,526
|
22
|
+
mustrd/templates/md_ResultList_template.jinja,sha256=RrTaPN1obsTEpG5BjQp7BV9iBFzZOXHwslgvyC0hDKY,211
|
23
|
+
mustrd/templates/md_stats_template.jinja,sha256=DlNfH9eoEFVHQmvp6QNbQv36cqRLyBkqG1ITOHb_Yu8,157
|
24
|
+
mustrd/test/test_mustrd.py,sha256=Q2qTTY--I0wfhgHW7hnkIoV3t_sUTXm8xMmirJaFc7o,129
|
25
|
+
mustrd/TestResult.py,sha256=q5BnvRxhfCEEY062rHasnA61AeKR4oXXs5z8lASvx1o,4986
|
26
|
+
mustrd/utils.py,sha256=fuvdLE20MdkJtY5atBiU8-u7sVcq1mzIYF0gTcw1UMk,1424
|
27
|
+
mustrd-0.1.8.dist-info/entry_points.txt,sha256=v7V7sN0_L1aB4Ug_9io5axlQSeJ1C0tNrQWwdXdV58s,50
|
28
|
+
mustrd-0.1.8.dist-info/LICENSE,sha256=OwjAcbL4HsENdMen1iYR23HH7OEn899oCt100xUo0Zo,1099
|
29
|
+
mustrd-0.1.8.dist-info/METADATA,sha256=lxU94amogEOoqPHnF1cdKqK8ceXahLbgpXudBQ3pGCg,4130
|
30
|
+
mustrd-0.1.8.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
31
|
+
mustrd-0.1.8.dist-info/RECORD,,
|
mustrd-0.1.7.dist-info/RECORD
DELETED
@@ -1,25 +0,0 @@
|
|
1
|
-
mustrd/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
mustrd/logger_setup.py,sha256=AXTXiiyQ4E_SyqNaKlLsZlkkKr_YJfJZ0N4PEoN7d7E,1630
|
3
|
-
mustrd/model/mustrdShapes.ttl,sha256=BR-9fAwGpQt6glfPpDB0Xx3vFXMt_UTQwi469o6aWUo,9709
|
4
|
-
mustrd/model/ontology.ttl,sha256=6xhmOF02gjP4nlOh6rnF5EWCaxWOdexQFn8YndGebck,17226
|
5
|
-
mustrd/model/test-resources/resources.ttl,sha256=7z1P4qJwuqRdmHzKd_mhnUIs-aQoSQxas7yDCwKYarc,1558
|
6
|
-
mustrd/mustrd.py,sha256=kAudCpk7NLoS2Y555l5Q2jhKbxR-D_sSPLa0Z3yP42w,34109
|
7
|
-
mustrd/mustrdAnzo.py,sha256=bQ-IHCnsEK7paJ31GgS9IH3hGd4o_5zeNrpn0Sb8WIk,11822
|
8
|
-
mustrd/mustrdGraphDb.py,sha256=KNXXYyZjYm_IZaeuuxlPBP-XyX9hZ5UvrdxshKnZhwo,5599
|
9
|
-
mustrd/mustrdRdfLib.py,sha256=LeS-uArlxQwsM-7lrJyp8O8m-6VgxsR1BlpxsOCNePs,2129
|
10
|
-
mustrd/mustrdTestPlugin.py,sha256=k7osmdgMIoHbVryrKxBqeDXYsE84Q_D5E2HEGhcOaSs,11784
|
11
|
-
mustrd/namespace.py,sha256=pCvLXkD_n_tS23oIizO52ylVwXGC1xFP8cHx4Mml0Ro,3326
|
12
|
-
mustrd/README.adoc,sha256=DwXeoMy2yMgAoLvyjZHp3HQW8NBIn8wCSaNo1ixHvFo,11803
|
13
|
-
mustrd/run.py,sha256=Ez00qZrl0Qb7P374miD8hEVucRKt_PYWdr4aorigltg,4366
|
14
|
-
mustrd/spec_component.py,sha256=l2CP8dszFENDkUsMIC065KNMeU8tNPPMMfCyQ4a1gHc,32487
|
15
|
-
mustrd/steprunner.py,sha256=bpa0K_WCapsH-3tbdzQkCYNQI3NnfTXy71w8Pl0-8aA,7430
|
16
|
-
mustrd/templates/md_ResultList_leaf_template.jinja,sha256=un1XMeNO9xLcry-DmTQ2QoWoTM5Q5CkVUV_LS4O7sHM,526
|
17
|
-
mustrd/templates/md_ResultList_template.jinja,sha256=RrTaPN1obsTEpG5BjQp7BV9iBFzZOXHwslgvyC0hDKY,211
|
18
|
-
mustrd/templates/md_stats_template.jinja,sha256=DlNfH9eoEFVHQmvp6QNbQv36cqRLyBkqG1ITOHb_Yu8,157
|
19
|
-
mustrd/TestResult.py,sha256=q5BnvRxhfCEEY062rHasnA61AeKR4oXXs5z8lASvx1o,4986
|
20
|
-
mustrd/utils.py,sha256=fuvdLE20MdkJtY5atBiU8-u7sVcq1mzIYF0gTcw1UMk,1424
|
21
|
-
mustrd-0.1.7.dist-info/entry_points.txt,sha256=v7V7sN0_L1aB4Ug_9io5axlQSeJ1C0tNrQWwdXdV58s,50
|
22
|
-
mustrd-0.1.7.dist-info/LICENSE,sha256=OwjAcbL4HsENdMen1iYR23HH7OEn899oCt100xUo0Zo,1099
|
23
|
-
mustrd-0.1.7.dist-info/METADATA,sha256=wHFv9uJO64la0-lEtXel4KusPEvXTDPqLyQdHtLX5vk,4130
|
24
|
-
mustrd-0.1.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
|
25
|
-
mustrd-0.1.7.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|