KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > hp > hpl > jena > reasoner > test > ReasonerTester


1 /******************************************************************
2  * File: QueryTester.java
3  * Created by: Dave Reynolds
4  * Created on: 19-Jan-03
5  *
6  * (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
7  * [See end of file]
8  * $Id: ReasonerTester.java,v 1.26 2005/02/21 12:18:15 andy_seaborne Exp $
9  *****************************************************************/

10 package com.hp.hpl.jena.reasoner.test;
11
12 import com.hp.hpl.jena.rdf.model.*;
13 import com.hp.hpl.jena.graph.*;
14 import com.hp.hpl.jena.rdf.model.impl.*;
15 import com.hp.hpl.jena.mem.GraphMem;
16 import com.hp.hpl.jena.reasoner.*;
17 import com.hp.hpl.jena.reasoner.rulesys.Node_RuleVariable;
18 import com.hp.hpl.jena.vocabulary.RDF;
19
20 import com.hp.hpl.jena.shared.*;
21
22 import junit.framework.TestCase;
23 import org.apache.commons.logging.Log;
24 import org.apache.commons.logging.LogFactory;
25
26 import java.util.*;
27 import java.io.*;
28
29 /**
30  * A utility for loading a set of test reasoner problems and running defined
31  * sets of listStatement operations and checking the results.
32  * <p>
33  * Each of the source, query and result models are specified in
34  * different files. The files can be of type .rdf, .nt or .n3.</p>
35  * <p>
36  * A single manifest file defines the set of tests to run. Each test
37  * specifies a name, source tbox file, source data file, query file and result file using
38  * the properties "name", "source", "query" and "result" in the namespace
39  * "http://www.hpl.hp.com/semweb/2003/query_tester#". The file names are
40  * given as strings instead of URIs because the base directory for the test
41  * files is subject to change. </p>
42  * <p>
43  * Within the query file each triple is treated as a triple pattern
44  * to be searched for. Variables are indicated by resources in of the
45  * form "var:x".</p>
46  *
47  * @author <a HREF="mailto:der@hplb.hpl.hp.com">Dave Reynolds</a>
48  * @version $Revision: 1.26 $ on $Date: 2005/02/21 12:18:15 $
49  */

50 public class ReasonerTester {
51
52     /** The namespace for the test specification schema */
53     public static final String JavaDoc NS = "http://www.hpl.hp.com/semweb/2003/query_tester#";
54     
55     /** The base URI in which the files are purported to reside */
56     public static final String JavaDoc BASE_URI = "http://www.hpl.hp.com/semweb/2003/query_tester/";
57     
58     /** The rdf class to which all tests belong */
59     public static final Resource testClass;
60     
61     /** The predicate defining the description of the test */
62     public static final Property descriptionP;
63     
64     /** The predicate defining the source tbox file for the test */
65     public static final Property tboxP;
66     
67     /** The predicate defining the source data file for the test */
68     public static final Property dataP;
69     
70     /** The predicate defining the query file for the test */
71     public static final Property queryP;
72     
73     /** The predicate defining the result file for the test */
74     public static final Property resultP;
75     
76     /** The base directory in which the test data is stored */
77     public static final String JavaDoc baseDir = "testing/reasoners/";
78     
79     // Static initializer for the predicates
80
static {
81         descriptionP = new PropertyImpl(NS, "description");
82         tboxP = new PropertyImpl(NS, "tbox");
83         dataP = new PropertyImpl(NS, "data");
84         queryP = new PropertyImpl(NS, "query");
85         resultP = new PropertyImpl(NS, "result");
86         testClass = new ResourceImpl(NS, "Test");
87     }
88     
89     /** The rdf defining all the tests to be run */
90     protected Model testManifest;
91     
92     /** A cache of loaded source files, map from source name to Model */
93     protected Map sourceCache = new HashMap();
94     
95     protected static Log logger = LogFactory.getLog(ReasonerTester.class);
96     
97     /**
98      * Constructor.
99      * @param manifest the name of the manifest file defining these
100      * tests - relative to baseDir
101      */

102     public ReasonerTester(String JavaDoc manifest) throws IOException {
103         testManifest = loadFile(manifest, false);
104     }
105     
106     /**
107      * Utility to load a file in rdf/nt/n3 format as a Model.
108      * @param file the file name, relative to baseDir
109      * @param cache set to true if the file could be usefully cached
110      * @return the loaded Model
111      */

112     public Model loadFile(String JavaDoc file, boolean cache) throws IOException {
113         if (cache && sourceCache.keySet().contains(file)) {
114             return (Model)sourceCache.get(file);
115         }
116         String JavaDoc langType = "RDF/XML";
117         if (file.endsWith(".nt")) {
118             langType = "N-TRIPLE";
119         } else if (file.endsWith("n3")) {
120             langType = "N3";
121         }
122         Model result = ModelFactory.createDefaultModel();
123         Reader reader = new BufferedReader(new FileReader(baseDir + file));
124         result.read(reader, BASE_URI + file, langType);
125         if (cache) {
126             sourceCache.put(file, result);
127         }
128         return result;
129     }
130     
131     /**
132      * Load the datafile given by the property name.
133      * @param test the test being processed
134      * @param predicate the property of the test giving the file name to load
135      * @return a graph containing the file contents or an empty graph if the property
136      * is not present
137      * @throws IOException if the property is present but the file can't be found
138      */

139     public Graph loadTestFile(Resource test, Property predicate) throws IOException {
140         if (test.hasProperty(predicate)) {
141             String JavaDoc fileName = test.getRequiredProperty(predicate).getObject().toString();
142             boolean cache = predicate.equals(tboxP) || predicate.equals(dataP);
143             return loadFile(fileName, cache).getGraph();
144         } else {
145             return new GraphMem();
146         }
147     }
148     
149     /**
150      * Convert a triple into a triple pattern by converting var resources into
151      * wildcard variables.
152      */

153     public static TriplePattern tripleToPattern(Triple t) {
154         return new TriplePattern(
155                         nodeToPattern(t.getSubject()),
156                         nodeToPattern(t.getPredicate()),
157                         nodeToPattern(t.getObject()));
158     }
159     
160     /**
161      * Convert a node into a pattern node by converting var resources into wildcard
162      * variables.
163      */

164     public static Node nodeToPattern(Node n) {
165         if (n.isURI() && n.toString().startsWith("var:")) {
166             return Node_RuleVariable.WILD;
167 // return Node.ANY;
168
} else {
169             return n;
170         }
171     }
172     
173     /**
174      * Run all the tests in the manifest
175      * @param reasonerF the factory for the reasoner to be tested
176      * @param testcase the JUnit test case which is requesting this test
177      * @param configuration optional configuration information
178      * @return true if all the tests pass
179      * @throws IOException if one of the test files can't be found
180      * @throws RDFException if the test can't be found or fails internally
181      */

182     public boolean runTests(ReasonerFactory reasonerF, TestCase testcase, Resource configuration) throws IOException {
183         for (Iterator i = listTests().iterator(); i.hasNext(); ) {
184             String JavaDoc test = (String JavaDoc)i.next();
185             if (!runTest(test, reasonerF, testcase, configuration)) return false;
186         }
187         return true;
188     }
189     
190     /**
191      * Run all the tests in the manifest
192      * @param reasoner the reasoner to be tested
193      * @param testcase the JUnit test case which is requesting this test
194      * @return true if all the tests pass
195      * @throws IOException if one of the test files can't be found
196      * @throws RDFException if the test can't be found or fails internally
197      */

198     public boolean runTests(Reasoner reasoner, TestCase testcase) throws IOException {
199         for (Iterator i = listTests().iterator(); i.hasNext(); ) {
200             String JavaDoc test = (String JavaDoc)i.next();
201             if (!runTest(test, reasoner, testcase)) return false;
202         }
203         return true;
204     }
205     
206     /**
207      * Return a list of all test names defined in the manifest for this test harness.
208      */

209     public List listTests() {
210         List testList = new ArrayList();
211         ResIterator tests = testManifest.listSubjectsWithProperty(RDF.type, testClass);
212         while (tests.hasNext()) {
213             testList.add(tests.next().toString());
214         }
215         return testList;
216     }
217     
218     
219     /**
220      * Run a single designated test.
221      * @param uri the uri of the test, as defined in the manifest file
222      * @param reasonerF the factory for the reasoner to be tested
223      * @param testcase the JUnit test case which is requesting this test
224      * @param configuration optional configuration information
225      * @return true if the test passes
226      * @throws IOException if one of the test files can't be found
227      * @throws RDFException if the test can't be found or fails internally
228      */

229     public boolean runTest(String JavaDoc uri, ReasonerFactory reasonerF, TestCase testcase, Resource configuration) throws IOException {
230         Reasoner reasoner = reasonerF.create(configuration);
231         return runTest(uri, reasoner, testcase);
232     }
233     
234     /**
235      * Run a single designated test.
236      * @param uri the uri of the test, as defined in the manifest file
237      * @param reasoner the reasoner to be tested
238      * @param testcase the JUnit test case which is requesting this test
239      * @return true if the test passes
240      * @throws IOException if one of the test files can't be found
241      * @throws RDFException if the test can't be found or fails internally
242      */

243     public boolean runTest(String JavaDoc uri, Reasoner reasoner, TestCase testcase) throws IOException {
244         // Find the specification for the named test
245
Resource test = testManifest.getResource(uri);
246         if (!test.hasProperty(RDF.type, testClass)) {
247             throw new JenaException("Can't find test: " + uri);
248         }
249
250         String JavaDoc description = test.getRequiredProperty(descriptionP).getObject().toString();
251         logger.debug("Reasoner test " + test.getURI() + " - " + description);
252         
253         // Construct the inferred graph
254
Graph tbox = loadTestFile(test, tboxP);
255         Graph data = loadTestFile(test, dataP);
256         InfGraph graph = reasoner.bindSchema(tbox).bind(data);
257         
258         // Run each query triple and accumulate the results
259
Graph queryG = loadTestFile(test, queryP);
260         Graph resultG = new GraphMem();
261
262         Iterator queries = queryG.find(null, null, null);
263         while (queries.hasNext()) {
264             TriplePattern query = tripleToPattern((Triple)queries.next());
265             logger.debug("Query: " + query);
266             Iterator answers = graph.find(query.asTripleMatch());
267             while (answers.hasNext()) {
268                 Triple ans = (Triple)answers.next();
269                 logger.debug("ans: " + TriplePattern.simplePrintString(ans));
270                 resultG.add(ans);
271             }
272         }
273         
274         // Check the total result set against the correct answer
275
Graph correctG = loadTestFile(test, resultP);
276         boolean correct = correctG.isIsomorphicWith(resultG);
277         // Used in debugging the tests ...
278
// Can't just leave it as a logger.debug because there are unit tests to which are supposed to given
279
// a test failure which would then problem unwanted output.
280
/*
281         System.out.println("Reasoner test " + test.getURI() + " - " + description);
282         if (!correct) {
283             System.out.println("Missing triples:");
284             for (Iterator i = correctG.find(null, null, null); i.hasNext(); ) {
285                 Triple t = (Triple) i.next();
286                 if (!resultG.contains(t)) {
287                     System.out.println(" " + t);
288                 }
289             }
290             System.out.println("Extra triples:");
291             for (Iterator i = resultG.find(null, null, null); i.hasNext(); ) {
292                 Triple t = (Triple) i.next();
293                 if (!correctG.contains(t)) {
294                     System.out.println(" - " + t);
295                 }
296             }
297             
298         }
299         */

300         // ... end of debugging hack
301
if (testcase != null) {
302             TestCase.assertTrue(description, correct);
303         }
304         return correct;
305     }
306     
307 }
308
309 /*
310     (c) Copyright 2003, 2004, 2005 Hewlett-Packard Development Company, LP
311     All rights reserved.
312
313     Redistribution and use in source and binary forms, with or without
314     modification, are permitted provided that the following conditions
315     are met:
316
317     1. Redistributions of source code must retain the above copyright
318        notice, this list of conditions and the following disclaimer.
319
320     2. Redistributions in binary form must reproduce the above copyright
321        notice, this list of conditions and the following disclaimer in the
322        documentation and/or other materials provided with the distribution.
323
324     3. The name of the author may not be used to endorse or promote products
325        derived from this software without specific prior written permission.
326
327     THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
328     IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
329     OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
330     IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
331     INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
332     NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
333     DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
334     THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
335     (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
336     THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
337 */

338
339
Popular Tags