| /* |
| * 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.rya.accumulo.mr.merge; |
| |
| import static org.apache.rya.accumulo.mr.merge.util.TestUtils.YESTERDAY; |
| import static org.apache.rya.accumulo.mr.merge.util.ToolConfigUtils.makeArgument; |
| |
| import java.io.File; |
| import java.util.Arrays; |
| import java.util.HashMap; |
| import java.util.HashSet; |
| import java.util.List; |
| import java.util.Map; |
| import java.util.Set; |
| |
| import org.apache.accumulo.core.client.Connector; |
| import org.apache.hadoop.conf.Configuration; |
| import org.apache.log4j.Logger; |
| import org.apache.rya.accumulo.AccumuloRdfConfiguration; |
| import org.apache.rya.accumulo.AccumuloRyaDAO; |
| import org.apache.rya.accumulo.mr.MRUtils; |
| import org.apache.rya.accumulo.mr.merge.common.InstanceType; |
| import org.apache.rya.accumulo.mr.merge.demo.util.DemoUtilities; |
| import org.apache.rya.accumulo.mr.merge.demo.util.DemoUtilities.LoggingDetail; |
| import org.apache.rya.accumulo.mr.merge.driver.AccumuloDualInstanceDriver; |
| import org.apache.rya.accumulo.mr.merge.util.AccumuloRyaUtils; |
| import org.apache.rya.accumulo.mr.merge.util.TestUtils; |
| import org.apache.rya.api.RdfCloudTripleStoreConfiguration; |
| import org.apache.rya.api.domain.RyaStatement; |
| import org.apache.rya.api.domain.RyaType; |
| import org.apache.rya.api.domain.RyaURI; |
| import org.apache.rya.api.persist.RyaDAOException; |
| import org.apache.rya.api.resolver.RyaToRdfConversions; |
| import org.apache.rya.indexing.accumulo.ConfigUtils; |
| import org.apache.rya.sail.config.RyaSailFactory; |
| import org.eclipse.rdf4j.common.iteration.CloseableIteration; |
| import org.eclipse.rdf4j.model.IRI; |
| import org.eclipse.rdf4j.model.Namespace; |
| import org.eclipse.rdf4j.model.Statement; |
| import org.eclipse.rdf4j.model.ValueFactory; |
| import org.eclipse.rdf4j.model.impl.SimpleValueFactory; |
| import org.eclipse.rdf4j.model.vocabulary.OWL; |
| import org.eclipse.rdf4j.model.vocabulary.RDF; |
| import org.eclipse.rdf4j.model.vocabulary.RDFS; |
| import org.eclipse.rdf4j.model.vocabulary.XMLSchema; |
| import org.eclipse.rdf4j.query.BindingSet; |
| import org.eclipse.rdf4j.query.QueryLanguage; |
| import org.eclipse.rdf4j.query.QueryResultHandlerException; |
| import org.eclipse.rdf4j.query.TupleQuery; |
| import org.eclipse.rdf4j.query.TupleQueryResultHandler; |
| import org.eclipse.rdf4j.query.TupleQueryResultHandlerException; |
| import org.eclipse.rdf4j.repository.sail.SailRepository; |
| import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection; |
| import org.eclipse.rdf4j.sail.Sail; |
| import org.junit.After; |
| import org.junit.AfterClass; |
| import org.junit.Before; |
| import org.junit.BeforeClass; |
| import org.junit.Test; |
| |
| import junit.framework.Assert; |
| |
| public class RulesetCopyIT { |
| private static final Logger log = Logger.getLogger(RulesetCopyIT.class); |
| |
| private static final ValueFactory VF = SimpleValueFactory.getInstance(); |
| |
| private static final boolean IS_MOCK = false; |
| private static final String CHILD_SUFFIX = MergeTool.CHILD_SUFFIX; |
| |
| private static final String PARENT_PASSWORD = AccumuloDualInstanceDriver.PARENT_PASSWORD; |
| private static final String PARENT_INSTANCE = AccumuloDualInstanceDriver.PARENT_INSTANCE; |
| private static final String PARENT_TABLE_PREFIX = AccumuloDualInstanceDriver.PARENT_TABLE_PREFIX; |
| private static final String PARENT_TOMCAT_URL = "http://rya-example-box:8080"; |
| |
| private static final String CHILD_PASSWORD = AccumuloDualInstanceDriver.CHILD_PASSWORD; |
| private static final String CHILD_INSTANCE = AccumuloDualInstanceDriver.CHILD_INSTANCE; |
| private static final String CHILD_TABLE_PREFIX = AccumuloDualInstanceDriver.CHILD_TABLE_PREFIX; |
| private static final String CHILD_TOMCAT_URL = "http://localhost:8080"; |
| |
| private static final String QUERY_PREFIXES; |
| |
| private static AccumuloRdfConfiguration parentConfig; |
| private static AccumuloRdfConfiguration childConfig; |
| |
| private static AccumuloDualInstanceDriver accumuloDualInstanceDriver; |
| private static CopyTool rulesetTool = null; |
| private static AccumuloRyaDAO parentDao; |
| |
| private static Map<String, String> prefixes = new HashMap<>(); |
| static { |
| prefixes.put("test:", "http://example.com#"); |
| prefixes.put("alt:", "http://example.com/alternate#"); |
| prefixes.put("time:", "http://www.w3.org/2006/time#"); |
| prefixes.put("geo:", "http://www.opengis.net/ont/geosparql#"); |
| prefixes.put("fts:", "http://rdf.useekm.com/fts#"); |
| prefixes.put("tempo:", "tag:rya-rdf.org,2015:temporal#"); |
| prefixes.put("rdf:", RDF.NAMESPACE); |
| prefixes.put("rdfs:", RDFS.NAMESPACE); |
| prefixes.put("owl:", OWL.NAMESPACE); |
| final StringBuilder sb = new StringBuilder(); |
| for (final String prefix : prefixes.keySet()) { |
| sb.append("PREFIX " + prefix + " <" + prefixes.get(prefix) + ">\n"); |
| } |
| QUERY_PREFIXES = sb.toString(); |
| } |
| |
| private static RyaURI substitute(final String uri) { |
| for (final String prefix : prefixes.keySet()) { |
| if (uri.startsWith(prefix)) { |
| return new RyaURI(uri.replace(prefix, prefixes.get(prefix))); |
| } |
| } |
| return new RyaURI(uri); |
| } |
| |
| private static RyaStatement statement(final String s, final String p, final RyaType o) { |
| final RyaStatement ryaStatement = new RyaStatement(substitute(s), substitute(p), o); |
| ryaStatement.setTimestamp(YESTERDAY.getTime()); |
| return ryaStatement; |
| } |
| |
| private static RyaStatement statement(final String s, final String p, final String o) { |
| return statement(s, p, substitute(o)); |
| } |
| |
| private static RyaType literal(final String lit) { |
| return new RyaType(lit); |
| } |
| |
| private static RyaType literal(final String lit, final IRI type) { |
| return new RyaType(type, lit); |
| } |
| |
| public static String getProjectRootDir() { |
| String rootDir = System.getProperty("basedir"); |
| if(rootDir == null) { |
| rootDir = System.getProperty("user.dir"); |
| } |
| if(rootDir == null) { |
| throw new RuntimeException("Expected user.dir to contain a value"); |
| } |
| return rootDir; |
| } |
| |
| private static File getUnitTestScratchDirectory(final String testName) { |
| final File dir = new File(getProjectRootDir() + File.separator + "target" |
| + File.separator + "TestScratch" + File.separator |
| + testName+ "-" + System.currentTimeMillis()); |
| Assert.assertTrue("Unable to make TestScratchDirectory:"+ dir.getAbsolutePath(), dir.mkdirs()); |
| return dir; |
| } |
| |
| @BeforeClass |
| public static void setUpPerClass() throws Exception { |
| DemoUtilities.setupLogging(LoggingDetail.LIGHT); |
| accumuloDualInstanceDriver = new AccumuloDualInstanceDriver(IS_MOCK, true, true, false, false); |
| accumuloDualInstanceDriver.setUpInstances(); |
| } |
| |
| @Before |
| public void setUpPerTest() throws Exception { |
| accumuloDualInstanceDriver.setUpConfigs(); |
| accumuloDualInstanceDriver.setUpTables(); |
| accumuloDualInstanceDriver.setUpDaos(); |
| parentConfig = accumuloDualInstanceDriver.getParentConfig(); |
| childConfig = accumuloDualInstanceDriver.getChildConfig(); |
| parentDao = accumuloDualInstanceDriver.getParentDao(); |
| } |
| |
| @After |
| public void tearDownPerTest() throws Exception { |
| log.info("tearDownPerTest(): tearing down now."); |
| accumuloDualInstanceDriver.tearDownTables(); |
| accumuloDualInstanceDriver.tearDownDaos(); |
| if (rulesetTool != null) { |
| rulesetTool.shutdown(); |
| } |
| } |
| |
| @AfterClass |
| public static void tearDownPerClass() throws Exception { |
| accumuloDualInstanceDriver.tearDown(); |
| } |
| |
| private AccumuloRyaDAO runRulesetCopyTest(final RyaStatement[] solutionStatements, final RyaStatement[] copyStatements, |
| final RyaStatement[] irrelevantStatements, final String query, final int numSolutions, final boolean infer) throws Exception { |
| log.info("Adding data to parent..."); |
| parentDao.add(Arrays.asList(solutionStatements).iterator()); |
| parentDao.add(Arrays.asList(copyStatements).iterator()); |
| parentDao.add(Arrays.asList(irrelevantStatements).iterator()); |
| |
| log.info("Copying from parent tables:"); |
| for (final String table : accumuloDualInstanceDriver.getParentTableList()) { |
| AccumuloRyaUtils.printTablePretty(table, parentConfig, false); |
| } |
| |
| parentConfig.set(RdfCloudTripleStoreConfiguration.CONF_INFER, Boolean.toString(infer)); |
| childConfig.set(RdfCloudTripleStoreConfiguration.CONF_INFER, Boolean.toString(infer)); |
| |
| rulesetTool = new CopyTool(); |
| rulesetTool.setupAndRun(new String[] { |
| makeArgument(MRUtils.AC_MOCK_PROP, Boolean.toString(IS_MOCK)), |
| makeArgument(MRUtils.AC_INSTANCE_PROP, PARENT_INSTANCE), |
| makeArgument(MRUtils.AC_USERNAME_PROP, accumuloDualInstanceDriver.getParentUser()), |
| makeArgument(MRUtils.AC_PWD_PROP, PARENT_PASSWORD), |
| makeArgument(MRUtils.TABLE_PREFIX_PROPERTY, PARENT_TABLE_PREFIX), |
| makeArgument(MRUtils.AC_AUTH_PROP, accumuloDualInstanceDriver.getParentAuth()), |
| makeArgument(MRUtils.AC_ZK_PROP, accumuloDualInstanceDriver.getParentZooKeepers()), |
| makeArgument(CopyTool.PARENT_TOMCAT_URL_PROP, PARENT_TOMCAT_URL), |
| makeArgument(MRUtils.AC_MOCK_PROP + CHILD_SUFFIX, Boolean.toString(IS_MOCK)), |
| makeArgument(MRUtils.AC_INSTANCE_PROP + CHILD_SUFFIX, CHILD_INSTANCE), |
| makeArgument(MRUtils.AC_USERNAME_PROP + CHILD_SUFFIX, accumuloDualInstanceDriver.getChildUser()), |
| makeArgument(MRUtils.AC_PWD_PROP + CHILD_SUFFIX, CHILD_PASSWORD), |
| makeArgument(MRUtils.TABLE_PREFIX_PROPERTY + CHILD_SUFFIX, CHILD_TABLE_PREFIX), |
| makeArgument(MRUtils.AC_AUTH_PROP + CHILD_SUFFIX, accumuloDualInstanceDriver.getChildAuth()), |
| makeArgument(MRUtils.AC_ZK_PROP + CHILD_SUFFIX, accumuloDualInstanceDriver.getChildZooKeepers() != null ? accumuloDualInstanceDriver.getChildZooKeepers() : "localhost"), |
| makeArgument(CopyTool.CHILD_TOMCAT_URL_PROP, CHILD_TOMCAT_URL), |
| makeArgument(CopyTool.CREATE_CHILD_INSTANCE_TYPE_PROP, (IS_MOCK ? InstanceType.MOCK : InstanceType.MINI).toString()), |
| makeArgument(CopyTool.QUERY_STRING_PROP, query), |
| makeArgument(CopyTool.USE_COPY_QUERY_SPARQL, "true"), |
| makeArgument(RdfCloudTripleStoreConfiguration.CONF_INFER, Boolean.toString(infer)), |
| makeArgument("hadoop.tmp.dir", getUnitTestScratchDirectory(RulesetCopyIT.class.getSimpleName()).getAbsolutePath()) |
| }); |
| |
| final Configuration toolConfig = rulesetTool.getConf(); |
| final String zooKeepers = toolConfig.get(MRUtils.AC_ZK_PROP + CHILD_SUFFIX); |
| MergeTool.setDuplicateKeysForProperty(childConfig, MRUtils.AC_ZK_PROP, zooKeepers); |
| |
| log.info("Finished running tool."); |
| |
| // Child instance has now been created |
| final Connector childConnector = ConfigUtils.getConnector(childConfig); |
| accumuloDualInstanceDriver.getChildAccumuloInstanceDriver().setConnector(childConnector); |
| accumuloDualInstanceDriver.getChildAccumuloInstanceDriver().setUpTables(); |
| accumuloDualInstanceDriver.getChildAccumuloInstanceDriver().setUpDao(); |
| final AccumuloRyaDAO childDao = accumuloDualInstanceDriver.getChildDao(); |
| |
| log.info("Resulting child tables:"); |
| for (final String table : accumuloDualInstanceDriver.getChildTableList()) { |
| AccumuloRyaUtils.printTablePretty(table, childConfig, false); |
| } |
| |
| for (final RyaStatement solution : solutionStatements) { |
| final Statement stmt = RyaToRdfConversions.convertStatement(solution); |
| TestUtils.assertStatementInInstance("Child missing solution statement " + stmt, |
| 1, solution, childDao, childConfig); |
| } |
| for (final RyaStatement copied : copyStatements) { |
| final Statement stmt = RyaToRdfConversions.convertStatement(copied); |
| TestUtils.assertStatementInInstance("Child missing relevant statement " + stmt, |
| 1, copied, childDao, childConfig); |
| } |
| for (final RyaStatement irrelevant : irrelevantStatements) { |
| final Statement stmt = RyaToRdfConversions.convertStatement(irrelevant); |
| TestUtils.assertStatementInInstance("Should not have copied irrelevant statement " + stmt, |
| 0, irrelevant, childDao, childConfig); |
| } |
| |
| final Set<BindingSet> parentSolutions = runQuery(query, parentConfig); |
| if (parentSolutions.isEmpty()) { |
| log.info("No solutions to query in parent"); |
| } |
| else { |
| for (final BindingSet bs : parentSolutions) { |
| log.info("Parent yields query solution: " + bs); |
| } |
| } |
| final Set<BindingSet> childSolutions = runQuery(query, childConfig); |
| if (childSolutions.isEmpty()) { |
| log.info("No solutions to query in child"); |
| } |
| else { |
| for (final BindingSet bs : childSolutions) { |
| log.info("Child yields query solution: " + bs); |
| } |
| } |
| Assert.assertEquals("Query results should be the same:", parentSolutions, childSolutions); |
| Assert.assertEquals("Incorrect number of solutions:", numSolutions, childSolutions.size()); |
| return childDao; |
| } |
| |
| private Set<BindingSet> runQuery(final String query, final Configuration conf) throws Exception { |
| SailRepository repository = null; |
| SailRepositoryConnection conn = null; |
| try { |
| final Sail extSail = RyaSailFactory.getInstance(conf); |
| repository = new SailRepository(extSail); |
| conn = repository.getConnection(); |
| final ResultHandler handler = new ResultHandler(); |
| final TupleQuery tq = conn.prepareTupleQuery(QueryLanguage.SPARQL, query); |
| tq.evaluate(handler); |
| return handler.getSolutions(); |
| } |
| finally { |
| if (conn != null) { |
| conn.close(); |
| } |
| if (repository != null) { |
| repository.shutDown(); |
| } |
| } |
| } |
| |
| private static class ResultHandler implements TupleQueryResultHandler { |
| private final Set<BindingSet> solutions = new HashSet<>(); |
| public Set<BindingSet> getSolutions() { |
| return solutions; |
| } |
| @Override |
| public void startQueryResult(final List<String> arg0) throws TupleQueryResultHandlerException { |
| } |
| @Override |
| public void handleSolution(final BindingSet arg0) throws TupleQueryResultHandlerException { |
| solutions.add(arg0); |
| } |
| @Override |
| public void endQueryResult() throws TupleQueryResultHandlerException { |
| } |
| @Override |
| public void handleBoolean(final boolean arg0) throws QueryResultHandlerException { |
| } |
| @Override |
| public void handleLinks(final List<String> arg0) throws QueryResultHandlerException { |
| } |
| } |
| |
| @Test |
| public void testRulesetCopyTool() throws Exception { |
| // Should be copied and are involved in the solution: |
| final RyaStatement[] solutionStatements = { |
| statement("test:FullProfessor1", "rdf:type", "test:FullProfessor"), |
| statement("test:GraduateStudent1", "test:advisor", "test:FullProfessor1"), |
| statement("test:FullProfessor1", "test:telephone", literal("123-456-7890")), |
| statement("test:University1", "test:telephone", literal("555")), |
| statement("test:FullProfessor1", "test:worksFor", "test:University1"), |
| statement("test:FullProfessor1", "test:hired", literal("2001-01-01T04:01:02.000Z", XMLSchema.DATETIME)), |
| statement("test:University1", "geo:asWKT", literal("Point(-77.03524 38.889468)", VF.createIRI("http://www.opengis.net/ont/geosparql#wktLiteral"))) |
| }; |
| // These aren't solutions but should be copied: |
| final RyaStatement[] copyStatements = { |
| statement("test:FullProfessor2", "rdf:type", "test:FullProfessor"), |
| statement("test:GraduateStudent1", "test:advisor", "test:AssistantProfessor1"), |
| statement("test:GraduateStudent1", "test:telephone", literal("555-123-4567")), |
| statement("test:FullProfessor1", "test:telephone", literal("567-8901")), |
| statement("test:University1", "test:telephone", literal("800-123-4567")) |
| }; |
| // Should not be copied: |
| final RyaStatement[] irrelevantStatements = { |
| statement("test:GraduateStudent2", "test:advisor", "test:FullProfessor1"), |
| statement("test:UndergraduateStudent1", "rdf:type", "test:UndergraduateStudent"), |
| statement("test:UndergraduateStudent2", "rdf:type", "test:UndergraduateStudent"), |
| statement("test:GraduateStudent1", "rdf:type", "test:GraduateStudent"), |
| statement("test:GraduateStudent1", "test:name", literal("GraduateStudent1")), |
| statement("test:UndergraduateStudent2", "test:name", literal("UndergraduateStudent2")), |
| statement("test:Course1", "test:name", literal("Course1")), |
| statement("test:GraduateStudent1", "test:emailAddress", literal("GraduateStudent1@Department0.University0.edu")), |
| statement("test:GraduateStudent1", "test:teachingAssistantOf", "test:Course1"), |
| statement("test:GraduateStudent2", "test:undergraduateDegreeFrom", "test:University1"), |
| statement("test:AssistantProfessor1", "test:teacherOf", "test:Course1"), |
| statement("test:FullProfessor1", "test:telephone", literal("xxx-xxx-xxxx")), |
| statement("test:University1", "test:telephone", literal("0000")), |
| // If inferencing is disabled, these shouldn't matter: |
| statement("test:employs", "owl:inverseOf", "test:worksFor"), |
| statement("test:University1", "test:employs", "test:FullProfessor2") |
| }; |
| |
| final String query = QUERY_PREFIXES + "SELECT * {\n" |
| + " test:GraduateStudent1 test:advisor ?person .\n" |
| + " ?person rdf:type test:FullProfessor .\n" |
| + " ?person test:telephone ?number .\n" |
| + " ?person test:worksFor ?university .\n" |
| + " FILTER regex(?number, \"...-...-....\")\n" |
| + " ?university geo:asWKT ?place .\n" |
| + " FILTER regex(?number, \"^[0-9]\")\n" |
| + " ?university test:telephone ?universityNumber\n" |
| + " FILTER regex(?universityNumber, \"^5\")\n" |
| // Would be good to test index functions, but indexing is unreliable (see RYA-72): |
| + " ?person test:hired ?time .\n" |
| // + " FILTER(tempo:after(?time, '2000-01-01T01:01:03-08:00'))\n" |
| + "}"; |
| |
| final int parentNamespaceCount = 2; |
| int childNamespaceCount = 0; |
| parentDao.addNamespace("ns1", "http://www.example.com/ns1#"); |
| parentDao.addNamespace("ns2", "http://www.example.com/ns2#"); |
| // Run the test |
| final AccumuloRyaDAO childDao = runRulesetCopyTest(solutionStatements, copyStatements, irrelevantStatements, query, 1, false); |
| // Verify namespaces were copied |
| final CloseableIteration<Namespace, RyaDAOException> nsIter = childDao.iterateNamespace(); |
| while (nsIter.hasNext()) { |
| childNamespaceCount++; |
| nsIter.next(); |
| } |
| Assert.assertEquals("Incorrect number of namespaces copied to child:", parentNamespaceCount, childNamespaceCount); |
| log.info("DONE"); |
| } |
| |
| /* |
| * Tests subclass and subproperty inference. Based on standard LUBM query #5. |
| */ |
| @Test |
| public void testRulesetCopyHierarchy() throws Exception { |
| final RyaStatement[] solutionStatements = { |
| statement("test:p1", "rdf:type", "test:Professor"), |
| statement("test:p1", "test:worksFor", "test:Department0"), |
| statement("test:p2", "rdf:type", "test:FullProfessor"), |
| statement("test:p2", "test:headOf", "test:Department0"), |
| }; |
| final RyaStatement[] copyStatements = { |
| // schema: |
| statement("test:Professor", "rdfs:subClassOf", "test:Person"), |
| statement("test:Student", "rdfs:subClassOf", "test:Person"), |
| statement("test:GraduateStudent", "rdfs:subClassOf", "test:Student"), |
| statement("test:FullProfessor", "rdfs:subClassOf", "test:Professor"), |
| statement("test:AssistantProfessor", "rdfs:subClassOf", "test:Professor"), |
| statement("test:worksFor", "rdfs:subPropertyOf", "test:memberOf"), |
| statement("test:headOf", "rdfs:subPropertyOf", "test:worksFor"), |
| // data: |
| statement("test:s1", "rdf:type", "test:Student"), |
| statement("test:ap1", "rdf:type", "test:AssistantProfessor"), |
| statement("test:gs1", "rdf:type", "test:GraduateStudent"), |
| }; |
| final RyaStatement[] otherStatements = { |
| // schema: |
| statement("test:worksFor", "rdfs:subPropertyOf", "test:affiliatedWith"), |
| statement("test:Person", "rdfs:subClassOf", "test:Animal"), |
| // data: |
| statement("test:University0", "test:hasSubOrganizationOf", "test:Department0"), |
| statement("test:a1", "rdf:type", "test:Animal") |
| }; |
| final String query = QUERY_PREFIXES + "SELECT * {\n" |
| + " ?X rdf:type test:Person .\n" |
| + " ?X test:memberOf test:Department0 .\n" |
| + "}"; |
| runRulesetCopyTest(solutionStatements, copyStatements, otherStatements, query, 2, true); |
| log.info("DONE"); |
| } |
| |
| /** |
| * Test the ruleset copy with owl:sameAs inference |
| */ |
| @Test |
| public void testRulesetCopySameAs() throws Exception { |
| final String query = QUERY_PREFIXES + "SELECT * {\n" |
| + " {\n" |
| + " ?X test:worksFor test:Department0 .\n" |
| + " ?X rdf:type test:Student\n" |
| + " } UNION {\n" |
| + " test:p1 rdf:type test:Professor .\n" |
| + " test:p1 test:worksFor test:CSDept .\n" |
| + " }\n" |
| + "}"; |
| final RyaStatement[] solutionStatements = { |
| statement("test:s1", "test:worksFor", "test:CSDept"), |
| statement("test:s1", "rdf:type", "test:Student"), |
| statement("test:p1", "rdf:type", "test:Professor"), |
| statement("alt:p1", "test:worksFor", "test:CSDept"), |
| statement("test:CSDept", "owl:sameAs", "test:Department0"), |
| statement("test:p1", "owl:sameAs", "alt:p1"), |
| statement("test:JohnDoe", "owl:sameAs", "alt:p1") |
| }; |
| final RyaStatement[] copyStatements = { |
| statement("test:s2", "rdf:type", "test:Student"), |
| statement("alt:s2", "test:worksFor", "test:CSDept"), |
| statement("test:s3", "test:worksFor", "test:CSDept") |
| }; |
| final RyaStatement[] otherStatements = { |
| // sameAs inference only expands constants: |
| statement("test:s2", "owl:sameAs", "alt:s2"), |
| // sameAs inference not applied to rdf:type statements: |
| statement("alt:p1", "rdf:type", "test:Professor"), |
| statement("test:s3", "rdf:type", "alt:Student"), |
| statement("test:Student", "owl:sameAs", "alt:Student") |
| }; |
| runRulesetCopyTest(solutionStatements, copyStatements, otherStatements, query, 2, true); |
| log.info("DONE"); |
| } |
| |
| /** |
| * Test the ruleset copy with owl:TransitiveProperty inference. |
| * Based on LUBM test query #11. |
| */ |
| @Test |
| public void testRulesetCopyTransitive() throws Exception { |
| final String query = QUERY_PREFIXES + "SELECT * {\n" |
| // Note: we get spurious results if the order of these are switched (see RYA-71): |
| + " ?X test:subOrganizationOf test:University0 .\n" |
| + " ?X rdf:type test:ResearchGroup .\n" |
| + "}"; |
| final RyaStatement[] solutionStatements = { |
| statement("test:subOrganizationOf", "rdf:type", "owl:TransitiveProperty"), |
| statement("test:ResearchGroup0", "rdf:type", "test:ResearchGroup"), |
| statement("test:ResearchGroup0", "test:subOrganizationOf", "test:Department0"), |
| statement("test:Department0", "test:subOrganizationOf", "test:University0"), |
| statement("test:Subgroup0", "rdf:type", "test:ResearchGroup"), |
| statement("test:Subgroup0", "test:subOrganizationOf", "test:ResearchGroup0") |
| }; |
| final RyaStatement[] copyStatements = { |
| statement("test:ResearchGroupA", "rdf:type", "test:ResearchGroup"), |
| statement("test:ResearchGroupA", "test:subOrganizationOf", "test:DepartmentA"), |
| statement("test:DepartmentA", "test:subOrganizationOf", "test:UniversityA"), |
| statement("test:OtherGroup0", "test:subOrganizationOf", "test:Department0"), |
| statement("test:Department1", "test:subOrganizationOf", "test:University0") |
| }; |
| final RyaStatement[] otherStatements = { |
| statement("test:University0", "rdf:type", "test:University"), |
| statement("test:Department0", "test:affiliatedWith", "test:University0") |
| }; |
| runRulesetCopyTest(solutionStatements, copyStatements, otherStatements, query, 2, true); |
| log.info("DONE"); |
| } |
| |
| /** |
| * Test the ruleset copy with owl:inverseOf and owl:subPropertyOf inference. |
| * Based on LUBM test query #13. |
| */ |
| @Test |
| public void testRulesetCopyInverse() throws Exception { |
| final String query = QUERY_PREFIXES + "SELECT * {\n" |
| + " ?X rdf:type test:Person .\n" |
| + " test:University0 test:hasAlumnus ?X .\n" |
| + "}"; |
| final RyaStatement[] solutionStatements = { |
| statement("test:s1", "rdf:type", "test:Person"), |
| statement("test:p1", "rdf:type", "test:Person"), |
| statement("test:s1", "test:undergraduateDegreeFrom", "test:University0"), |
| statement("test:p1", "test:doctoralDegreeFrom", "test:University0"), |
| statement("test:undergraduateDegreeFrom", "rdfs:subPropertyOf", "test:degreeFrom"), |
| statement("test:doctoralDegreeFrom", "rdfs:subPropertyOf", "test:degreeFrom"), |
| statement("test:hasAlumnus", "owl:inverseOf", "test:degreeFrom") |
| }; |
| final RyaStatement[] copyStatements = { |
| statement("test:mastersDegreeFrom", "rdfs:subPropertyOf", "test:degreeFrom"), |
| statement("test:s2", "test:mastersDegreeFrom", "test:University0"), |
| }; |
| final RyaStatement[] otherStatements = { |
| statement("test:p1", "test:mastersDegreeFrom", "test:University1"), |
| }; |
| runRulesetCopyTest(solutionStatements, copyStatements, otherStatements, query, 2, true); |
| log.info("DONE"); |
| } |
| |
| /** |
| * Test the ruleset copy with owl:SymmetricProperty inference, combined with rdfs:subPropertyOf. |
| */ |
| @Test |
| public void testRulesetCopySymmetry() throws Exception { |
| final String query = QUERY_PREFIXES + "SELECT * {\n" |
| + " ?X rdf:type test:Person .\n" |
| + " ?X test:knows test:Alice .\n" |
| + "}"; |
| final RyaStatement[] solutionStatements = { |
| statement("test:Alice", "test:knows", "test:Bob"), |
| statement("test:Alice", "test:friendsWith", "test:Carol"), |
| statement("test:Bob", "rdf:type", "test:Person"), |
| statement("test:Carol", "rdf:type", "test:Person"), |
| statement("test:friendsWith", "rdfs:subPropertyOf", "test:knows"), |
| statement("test:knows", "rdf:type", "owl:SymmetricProperty") |
| }; |
| final RyaStatement[] copyStatements = { |
| statement("test:Alice", "rdf:type", "test:Person"), |
| statement("test:Eve", "rdf:type", "test:Person") |
| }; |
| final RyaStatement[] otherStatements = { |
| statement("test:Carol", "test:knows", "test:Eve"), |
| statement("test:Bob", "test:friendsWith", "test:Carol") |
| }; |
| runRulesetCopyTest(solutionStatements, copyStatements, otherStatements, query, 2, true); |
| log.info("DONE"); |
| } |
| } |