-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathlibreasoner.py
120 lines (99 loc) · 4.44 KB
/
libreasoner.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
#!/usr/bin/env python
"""
libreasoner.py: Library of functions for communicating with the Reasoner Java executable.
"""
import os
import subprocess
import xml.sax
import rdflib
from rdflib.namespace import RDF
def exec_reasoner(cmdline=None, stdin=""):
"""Send those command line arguments to reasoner.class.
Returns: (exitcode, output, error)
"""
cmdline = cmdline or [] # Use provided command line or an empty array
environment = os.environ
starts_with = ["java", "-jar", "tests/reasoner/target/reasoner-0.1-SNAPSHOT.jar"]
# Based on http://stackoverflow.com/a/1996540/27310
print starts_with
print cmdline
process = subprocess.Popen(
starts_with + cmdline,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
env=environment)
stdout, stderr = process.communicate(stdin)
# print stdout
print stderr
return (process.returncode, stdout, stderr)
def validate_with_reasoner(tree_path, phyloref_path):
""" Run the reasoner over the treePath and the phylorefPath, and
then check to see if every class named 'X_expected' has the same
set of individuals as 'X'.
- treePath: The path to the tree, as OWL
- phylorefPath: The path to the phyloreference, in Manchester syntax
- expect_valid: if True, that means we're expecting a success; if
False, that means that the OWL file is incorrect and we're
expecting a failure.
"""
(return_code, stdout, stderr) = exec_reasoner([tree_path, phyloref_path])
assert return_code == 0
# stdout should always be an ntriples document.
graph = rdflib.Graph()
try:
graph.parse(format='n3', data=stdout)
except xml.sax.SAXParseException as exception:
print "SAXParseException parsing '{0}': {1}".format(stdout, exception)
assert False
# Identify all '_expected' classes, which we can test.
all_classes = set(graph.objects(None, RDF.type))
expected_classes = [cls for cls in all_classes if cls.endswith(u'_expected')]
# Make sure we have at least one expected class.
assert expected_classes, "Must have at least one expected class"
# Running these tests are time-consuming, so it's best if we test all
# expected classes, then report an overall success or failure. Details
# go to stdout, which py.test captures.
tests_failed = False
for expected_class in expected_classes:
test_succeeded = True
# For every 'X_expected' class, identify the 'X' class with
# observed values.
observed_class = rdflib.URIRef(expected_class[:-9])
# Obtain the list (not the set!) of all individuals belonging
# to these two classes.
expected_individuals = sorted(list(graph.subjects(RDF.type, expected_class)))
observed_individuals = sorted(list(graph.subjects(RDF.type, observed_class)))
# For debugging, write out the two lists.
print "Comparing classes '%s' and '%s'." % (expected_class, observed_class)
# Make sure neither class is empty
if not expected_individuals:
print " - TEST FAILED: expected class is empty."
test_succeeded = False
if not observed_individuals:
print " - TEST FAILED: observed class is empty."
test_succeeded = False
# Test that these two lists are identical.
if len(expected_individuals) != len(observed_individuals):
print " - TEST FAILED: " \
+ "expected and observed classes have different numbers of individuals."
test_succeeded = False
else:
for index, expected in enumerate(expected_individuals):
observed = observed_individuals[index]
if expected != observed:
print " - TEST FAILED: at index {0}, expected '{1}', observed '{2}'".format(
index, expected, observed
)
test_succeeded = False
# If the test failed, list all individuals.
if test_succeeded:
print " - Test succeeded."
else:
tests_failed = True
print " - " + expected_class + ":\n - " + "\n - ".join(expected_individuals)
print " - " + observed_class + ":\n - " + "\n - ".join(observed_individuals)
# Insert a newline before the next test.
print ""
if tests_failed:
assert False, "See output for details."