001: /*
002: * Copyright Aduna (http://www.aduna-software.com/) (c) 1997-2006.
003: *
004: * Licensed under the Aduna BSD-style license.
005: */
006: package org.openrdf.sail;
007:
008: import java.io.File;
009: import java.io.FileOutputStream;
010: import java.io.InputStream;
011: import java.io.OutputStream;
012: import java.util.Collection;
013: import java.util.HashSet;
014:
015: import junit.framework.Test;
016: import junit.framework.TestCase;
017: import junit.framework.TestSuite;
018:
019: import info.aduna.iteration.Iterations;
020:
021: import org.openrdf.model.Statement;
022: import org.openrdf.model.util.ModelUtil;
023: import org.openrdf.repository.Repository;
024: import org.openrdf.repository.RepositoryConnection;
025: import org.openrdf.repository.sail.SailRepository;
026: import org.openrdf.repository.util.RepositoryUtil;
027: import org.openrdf.rio.RDFFormat;
028: import org.openrdf.rio.RDFWriter;
029: import org.openrdf.rio.Rio;
030: import org.openrdf.sail.memory.MemoryStore;
031:
032: public class InferencingTest extends TestCase {
033:
034: /*-----------*
035: * Constants *
036: *-----------*/
037:
038: public static final String TEST_DIR_PREFIX = "/testcases/rdf-mt-inferencing";
039:
040: /*-----------*
041: * Variables *
042: *-----------*/
043:
044: protected Sail sailStack;
045:
046: protected String inputData;
047:
048: protected String outputData;
049:
050: protected boolean isPositiveTest;
051:
052: protected String name;
053:
054: /*--------------*
055: * Constructors *
056: *--------------*/
057:
058: /**
059: * Creates a new inferencing test. This test can either be positive or
060: * negative. For positive tests, all triples from <tt>outputData</tt>
061: * should be present in the triples returned by the supplied
062: * RdfSchemaRepository after the triples from <tt>intputData</tt> have been
063: * added to it. For negative tests, none of the triples from
064: * <tt>outputData</tt> should be present in the returned triples.
065: *
066: * @param name
067: * The name of the test.
068: * @param rss
069: * The RdfSchemaRepository to test.
070: * @param inputData
071: * The URL of the (N-Triples) data containing the triples that should
072: * be added to the RdfSchemaRepository.
073: * @param outputData
074: * The URL of the (N-Triples) data containing the triples that should
075: * or should not (depending on the value of <tt>isPositiveTest</tt>
076: * be present in the statements returned by the RdfSchemaRepository.
077: * @param isPositiveTest
078: * Flag indicating whether this is a positive or a negative
079: * inferencing test; <tt>true</tt> for a positive test,
080: * <tt>false</tt> for a negative test.
081: */
082: public InferencingTest(String name, Sail sailStack,
083: String inputData, String outputData, boolean isPositiveTest) {
084: super (name);
085: int slashLoc = name.lastIndexOf('/');
086: this .name = name.substring(0, slashLoc) + "-"
087: + name.substring(slashLoc + 1);
088:
089: this .sailStack = sailStack;
090: this .inputData = inputData;
091: this .outputData = outputData;
092: this .isPositiveTest = isPositiveTest;
093: }
094:
095: /*---------*
096: * Methods *
097: *---------*/
098:
099: @Override
100: protected void runTest() throws Exception {
101: Collection<? extends Statement> entailedStatements = null;
102: Collection<? extends Statement> expectedStatements = null;
103:
104: Repository repository = new SailRepository(sailStack);
105: repository.initialize();
106:
107: RepositoryConnection con = repository.getConnection();
108: con.setAutoCommit(false);
109:
110: // clear the input store
111: con.clear();
112: con.commit();
113:
114: // Upload input data
115: InputStream stream = getClass().getResourceAsStream(inputData);
116: try {
117: con.add(stream, inputData, RDFFormat.NTRIPLES);
118: con.commit();
119:
120: entailedStatements = Iterations.addAll(con.getStatements(
121: null, null, null, true), new HashSet<Statement>());
122: } finally {
123: stream.close();
124: con.close();
125: }
126:
127: // Upload output data
128: Repository outputRepository = new SailRepository(
129: new MemoryStore());
130: outputRepository.initialize();
131: con = outputRepository.getConnection();
132: con.setAutoCommit(false);
133:
134: stream = getClass().getResourceAsStream(outputData);
135: try {
136: con.add(stream, outputData, RDFFormat.NTRIPLES);
137: con.commit();
138:
139: expectedStatements = Iterations.addAll(con.getStatements(
140: null, null, null, false), new HashSet<Statement>());
141: } finally {
142: stream.close();
143: con.close();
144: outputRepository.shutDown();
145: repository.shutDown();
146: }
147:
148: // Check whether all expected statements are present in the entailment
149: // closure set.
150: boolean outputEntailed = ModelUtil.isSubset(expectedStatements,
151: entailedStatements);
152:
153: if (isPositiveTest && !outputEntailed) {
154: File dumpFile = dumpStatements(RepositoryUtil.difference(
155: expectedStatements, entailedStatements));
156:
157: fail("Incomplete entailment, difference between expected and entailed dumped to file "
158: + dumpFile);
159: } else if (!isPositiveTest && outputEntailed) {
160: File dumpFile = dumpStatements(expectedStatements);
161: fail("Erroneous entailment, unexpected statements dumped to file "
162: + dumpFile);
163: }
164: }
165:
166: private File dumpStatements(
167: Collection<? extends Statement> statements)
168: throws Exception {
169: // Dump results to tmp file for debugging
170: String tmpDir = System.getProperty("java.io.tmpdir");
171: File tmpFile = new File(tmpDir, "junit-" + name + ".nt");
172:
173: OutputStream export = new FileOutputStream(tmpFile);
174: try {
175: RDFWriter writer = Rio.createWriter(RDFFormat.NTRIPLES,
176: export);
177:
178: writer.startRDF();
179: for (Statement st : statements) {
180: writer.handleStatement(st);
181: }
182: writer.endRDF();
183: } finally {
184: export.close();
185: }
186:
187: return tmpFile;
188: }
189:
190: /*----------------*
191: * Static methods *
192: *----------------*/
193:
194: public static Test suite(Sail sailStack) {
195: TestSuite suite = new TestSuite();
196:
197: suite.addTest(createTestCase(sailStack, "subclassof",
198: "test001", true));
199: suite.addTest(createTestCase(sailStack, "subclassof",
200: "test002", true));
201: suite.addTest(createTestCase(sailStack, "subclassof",
202: "test003", true));
203: suite.addTest(createTestCase(sailStack, "subclassof",
204: "error001", false));
205: suite.addTest(createTestCase(sailStack, "subpropertyof",
206: "test001", true));
207: suite.addTest(createTestCase(sailStack, "subpropertyof",
208: "test002", true));
209: suite.addTest(createTestCase(sailStack, "subpropertyof",
210: "test003", true));
211: suite.addTest(createTestCase(sailStack, "subpropertyof",
212: "error001", false));
213: suite.addTest(createTestCase(sailStack, "domain", "test001",
214: true));
215: suite.addTest(createTestCase(sailStack, "domain", "error001",
216: false));
217: suite.addTest(createTestCase(sailStack, "range", "test001",
218: true));
219: suite.addTest(createTestCase(sailStack, "range", "error001",
220: false));
221: suite
222: .addTest(createTestCase(sailStack, "type", "test001",
223: true));
224: suite
225: .addTest(createTestCase(sailStack, "type", "test002",
226: true));
227: suite
228: .addTest(createTestCase(sailStack, "type", "test003",
229: true));
230: suite
231: .addTest(createTestCase(sailStack, "type", "test004",
232: true));
233: suite
234: .addTest(createTestCase(sailStack, "type", "test005",
235: true));
236: suite.addTest(createTestCase(sailStack, "type", "error001",
237: false));
238: suite.addTest(createTestCase(sailStack, "type", "error002",
239: false));
240:
241: return suite;
242: }
243:
244: private static TestCase createTestCase(Sail sailStack,
245: String subdir, String testName, boolean isPositiveTest) {
246: return new InferencingTest(subdir + "/" + testName, sailStack,
247: TEST_DIR_PREFIX + "/" + subdir + "/" + testName
248: + "-in.nt", TEST_DIR_PREFIX + "/" + subdir
249: + "/" + testName + "-out.nt", isPositiveTest);
250: }
251: }
|