blob: 6a6a53c4286d79d45913d96e55f60f550bed7eaf [file] [log] [blame]
/*
* 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");
}
}