/* * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.jena.reasoner.test; import java.io.*; import java.util.Iterator; import junit.framework.TestCase; import junit.framework.TestSuite; import org.apache.jena.rdf.model.* ; import org.apache.jena.reasoner.* ; import org.apache.jena.reasoner.ValidityReport.Report ; import org.apache.jena.reasoner.rulesys.RDFSFBRuleReasonerFactory ; import org.apache.jena.reasoner.rulesys.RDFSRuleReasonerFactory ; import org.apache.jena.vocabulary.* ; import org.slf4j.Logger; import org.slf4j.LoggerFactory; /** * Test the set of admissable RDFS reasoners. */ public class TestRDFSReasoners extends ReasonerTestBase { /** Base URI for the test names */ public static final String NAMESPACE = "http://www.hpl.hp.com/semweb/2003/query_tester/"; protected static Logger logger = LoggerFactory.getLogger(TestReasoners.class); /** * Boilerplate for junit */ public TestRDFSReasoners( String name ) { super( name ); } /** * Boilerplate for junit. * This is its own test suite */ public static TestSuite suite() { TestSuite suite = new TestSuite(); try { // FB reasoner doesn't support validation so the full set of wg tests are // commented out // constructRDFWGtests(suite, RDFSFBRuleReasonerFactory.theInstance(), null); constructQuerytests(suite, "rdfs/manifest-nodirect-noresource.rdf", RDFSFBRuleReasonerFactory.theInstance(), null); Resource config = newResource().addProperty(ReasonerVocabulary.PROPenableCMPScan, "true" ); // TODO make boolean value work // config.addProperty(ReasonerVocabulary.PROPtraceOn, true); constructRDFWGtests(suite, RDFSRuleReasonerFactory.theInstance(), null); constructQuerytests(suite, "rdfs/manifest-standard.rdf", RDFSRuleReasonerFactory.theInstance(), config); suite.addTest(new TestRDFSMisc(RDFSRuleReasonerFactory.theInstance(), null)); Resource configFull = newResource().addProperty(ReasonerVocabulary.PROPsetRDFSLevel, ReasonerVocabulary.RDFS_FULL); constructQuerytests(suite, "rdfs/manifest.rdf", RDFSRuleReasonerFactory.theInstance(), configFull); // This test was needed for the brief time the rdfs12 rules might have been in the standard // That's no longer true but left comment out because we might want them for OWL someday // constructQuerytests(suite, "rdfs/manifest-rdfs12.rdf", RDFSRuleReasonerFactory.theInstance(), configFull); Resource configSimple = newResource().addProperty(ReasonerVocabulary.PROPsetRDFSLevel, ReasonerVocabulary.RDFS_SIMPLE); constructQuerytests(suite, "rdfs/manifest-simple.rdf", RDFSRuleReasonerFactory.theInstance(), configSimple); // Single test case used in debugging, subsumed by above // constructSingleQuerytests(suite, // "rdfs/manifest.rdf", // "http://www.hpl.hp.com/semweb/2003/query_tester/rdfs/test13", // RDFSRuleReasonerFactory.theInstance(), // configFull); } catch (IOException e) { // failed to even built the test harness logger.error("Failed to construct RDFS test harness", e); } return suite; } /** * Build a single named query test */ private static void constructSingleQuerytests(TestSuite suite, String manifest, String test, ReasonerFactory rf, Resource config) throws IOException { ReasonerTester tester = new ReasonerTester(manifest); Reasoner r = rf.create(config); suite.addTest(new TestReasonerFromManifest(tester, test, r)); } /** * Build the query tests for the given reasoner. */ private static void constructQuerytests(TestSuite suite, String manifest, ReasonerFactory rf, Resource config) throws IOException { ReasonerTester tester = new ReasonerTester(manifest); Reasoner r = rf.create(config); for ( String test : tester.listTests() ) { suite.addTest( new TestReasonerFromManifest( tester, test, r ) ); } } /** * Build the working group tests for the given reasoner. */ private static void constructRDFWGtests(TestSuite suite, ReasonerFactory rf, Resource config) throws IOException { WGReasonerTester tester = new WGReasonerTester("Manifest.rdf"); for ( String test : tester.listTests() ) { suite.addTest( new TestReasonerWG( tester, test, rf, config ) ); } } /** * Build the query tests for the given reasoner. */ public static void constructQuerytests(TestSuite suite, String manifest, Reasoner reasoner) throws IOException { ReasonerTester tester = new ReasonerTester(manifest); for ( String test : tester.listTests() ) { suite.addTest( new TestReasonerFromManifest( tester, test, reasoner ) ); } } /** * Inner class defining a test framework for invoking a single locally * defined query-over-inference test. */ static class TestReasonerFromManifest extends TestCase { /** The tester which already has the test manifest loaded */ ReasonerTester tester; /** The name of the specific test to run */ String test; /** The factory for the reasoner type under test */ Reasoner reasoner; /** Constructor */ TestReasonerFromManifest(ReasonerTester tester, String test, Reasoner reasoner) { super(test); this.tester = tester; this.test = test; this.reasoner = reasoner; } /** * The test runner */ @Override public void runTest() throws IOException { tester.runTest(test, reasoner, this); } } /** * Inner class defining a test framework for invoking a single * RDFCore working group test. */ static class TestReasonerWG extends TestCase { /** The tester which already has the test manifest loaded */ WGReasonerTester tester; /** The name of the specific test to run */ String test; /** The factory for the reasoner type under test */ ReasonerFactory reasonerFactory; /** An optional configuration model */ Resource config; /** Constructor */ TestReasonerWG(WGReasonerTester tester, String test, ReasonerFactory reasonerFactory, Resource config) { super(test); this.tester = tester; this.test = test; this.reasonerFactory = reasonerFactory; this.config = config; } /** * The test runner */ @Override public void runTest() throws IOException { tester.runTest(test, reasonerFactory, this, config); } } /** * Inner class defining the misc extra tests needed to check out a * candidate RDFS reasoner. */ static class TestRDFSMisc extends TestCase { /** The factory for the reasoner type under test */ ReasonerFactory reasonerFactory; /** An optional configuration model */ Resource config; /** Constructor */ TestRDFSMisc(ReasonerFactory reasonerFactory, Resource config) { super("TestRDFSMisc"); this.reasonerFactory = reasonerFactory; this.config = config; } /** * The test runner */ @Override public void runTest() throws IOException { ReasonerTester tester = new ReasonerTester("rdfs/manifest.rdf"); // Test effect of switching off property scan - should break container property test case Resource configuration = newResource(); if (config != null) { for (StmtIterator i = config.listProperties(); i.hasNext();) { Statement s = i.nextStatement(); configuration.addProperty(s.getPredicate(), s.getObject()); } } configuration.addProperty(ReasonerVocabulary.PROPenableCMPScan, "false"); assertTrue("scanproperties off", !tester.runTest(NAMESPACE + "rdfs/test17", reasonerFactory, null, configuration)); // Check capabilities description Reasoner r = reasonerFactory.create(null); assertTrue(r.supportsProperty(RDFS.subClassOf)); assertTrue(r.supportsProperty(RDFS.domain)); assertTrue(r.supportsProperty(RDFS.range)); // Datatype tests assertTrue( ! doTestRDFSDTRange("dttest1.nt", reasonerFactory)); assertTrue( ! doTestRDFSDTRange("dttest2.nt", reasonerFactory)); assertTrue( doTestRDFSDTRange("dttest3.nt", reasonerFactory)); } /** * Helper for dt range testing - loads a file, validates it using RDFS/DT * and returns error status of the result */ private boolean doTestRDFSDTRange(String file, ReasonerFactory rf) throws IOException { String langType = "RDF/XML"; if (file.endsWith(".nt")) { langType = "N-TRIPLE"; } else if (file.endsWith("n3")) { langType = "N3"; } Model m = ModelFactory.createDefaultModel(); Reader reader = new BufferedReader(new FileReader("testing/reasoners/rdfs/"+file)); m.read(reader, WGReasonerTester.BASE_URI + file, langType); InfGraph g = rf.create(null).bind(m.getGraph()); ValidityReport report = g.validate(); if (!report.isValid()) { logger.debug("Validation error report:"); for (Iterator<Report> i = report.getReports(); i.hasNext(); ) { logger.debug(i.next().toString()); } } return report.isValid(); } } }