RDFSchemaRepositoryConnectionTest.java
/*******************************************************************************
* Copyright (c) 2015 Eclipse RDF4J contributors, Aduna, and others.
*
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Distribution License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/org/documents/edl-v10.php.
*
* SPDX-License-Identifier: BSD-3-Clause
*******************************************************************************/
package org.eclipse.rdf4j.testsuite.repository;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;
import org.eclipse.rdf4j.common.transaction.IsolationLevel;
import org.eclipse.rdf4j.common.transaction.IsolationLevels;
import org.eclipse.rdf4j.model.IRI;
import org.eclipse.rdf4j.model.Resource;
import org.eclipse.rdf4j.model.Statement;
import org.eclipse.rdf4j.model.vocabulary.FOAF;
import org.eclipse.rdf4j.model.vocabulary.RDF;
import org.eclipse.rdf4j.model.vocabulary.RDFS;
import org.eclipse.rdf4j.repository.RepositoryResult;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.EnumSource;
import org.junit.jupiter.params.provider.MethodSource;
/**
* @author jeen
* @author Arjohn Kampman
*/
public abstract class RDFSchemaRepositoryConnectionTest extends RepositoryConnectionTest {
public static IsolationLevel[] parameters() {
return new IsolationLevel[] { IsolationLevels.NONE, IsolationLevels.READ_COMMITTED,
IsolationLevels.SNAPSHOT_READ,
IsolationLevels.SNAPSHOT, IsolationLevels.SERIALIZABLE };
}
private IRI woman;
private IRI man;
@Override
protected void setupTest(IsolationLevel level) {
super.setupTest(level);
woman = vf.createIRI("http://example.org/Woman");
man = vf.createIRI("http://example.org/Man");
}
@ParameterizedTest
@MethodSource("parameters")
public void testDomainInference(IsolationLevel level) {
setupTest(level);
testCon.begin();
testCon.add(name, RDFS.DOMAIN, FOAF.PERSON);
testCon.add(bob, name, nameBob);
testCon.commit();
assertTrue(testCon.hasStatement(bob, RDF.TYPE, FOAF.PERSON, true));
}
@ParameterizedTest
@MethodSource("parameters")
public void testSubClassInference(IsolationLevel level) {
setupTest(level);
testCon.begin();
testCon.add(woman, RDFS.SUBCLASSOF, FOAF.PERSON);
testCon.add(man, RDFS.SUBCLASSOF, FOAF.PERSON);
testCon.add(alice, RDF.TYPE, woman);
testCon.commit();
assertTrue(testCon.hasStatement(alice, RDF.TYPE, FOAF.PERSON, true));
}
@ParameterizedTest
@MethodSource("parameters")
/**
* See https://github.com/eclipse/rdf4j/issues/1685
*/
public void testSubClassInferenceAfterRemoval(IsolationLevel level) {
setupTest(level);
IRI mother = vf.createIRI("http://example.org/Mother");
testCon.begin();
testCon.add(FOAF.PERSON, RDFS.SUBCLASSOF, FOAF.AGENT);
testCon.add(woman, RDFS.SUBCLASSOF, FOAF.PERSON);
testCon.add(mother, RDFS.SUBCLASSOF, woman);
testCon.commit();
assertTrue(testCon.hasStatement(mother, RDFS.SUBCLASSOF, FOAF.AGENT, true));
assertTrue(testCon.hasStatement(woman, RDFS.SUBCLASSOF, FOAF.AGENT, true));
testCon.begin();
testCon.remove(mother, RDFS.SUBCLASSOF, woman);
testCon.commit();
assertFalse(testCon.hasStatement(mother, RDFS.SUBCLASSOF, FOAF.AGENT, true));
assertTrue(testCon.hasStatement(woman, RDFS.SUBCLASSOF, FOAF.AGENT, true));
}
@ParameterizedTest
@MethodSource("parameters")
public void testMakeExplicit(IsolationLevel level) {
setupTest(level);
testCon.begin();
testCon.add(woman, RDFS.SUBCLASSOF, FOAF.PERSON);
testCon.add(alice, RDF.TYPE, woman);
testCon.commit();
assertTrue(testCon.hasStatement(alice, RDF.TYPE, FOAF.PERSON, true));
testCon.begin();
testCon.add(alice, RDF.TYPE, FOAF.PERSON);
testCon.commit();
assertTrue(testCon.hasStatement(alice, RDF.TYPE, FOAF.PERSON, true));
}
@ParameterizedTest
@MethodSource("parameters")
public void testExplicitFlag(IsolationLevel level) {
setupTest(level);
RepositoryResult<Statement> result = testCon.getStatements(RDF.TYPE, RDF.TYPE, null, true);
try {
assertTrue(result.hasNext(), "result should not be empty");
} finally {
result.close();
}
result = testCon.getStatements(RDF.TYPE, RDF.TYPE, null, false);
try {
assertFalse(result.hasNext(), "result should be empty");
} finally {
result.close();
}
}
@ParameterizedTest
@MethodSource("parameters")
public void testInferencerUpdates(IsolationLevel level) {
setupTest(level);
testCon.begin(IsolationLevels.READ_COMMITTED);
testCon.add(bob, name, nameBob);
testCon.remove(bob, name, nameBob);
testCon.commit();
assertFalse(testCon.hasStatement(bob, RDF.TYPE, RDFS.RESOURCE, true));
}
@ParameterizedTest
@MethodSource("parameters")
public void testInferencerQueryDuringTransaction(IsolationLevel level) {
setupTest(level);
testCon.begin();
testCon.add(bob, name, nameBob);
assertTrue(testCon.hasStatement(bob, RDF.TYPE, RDFS.RESOURCE, true));
testCon.commit();
}
@ParameterizedTest
@EnumSource(IsolationLevels.class)
public void testInferencerTransactionIsolation(IsolationLevel level) {
setupTest(level);
if (IsolationLevels.NONE.isCompatibleWith(level)) {
return;
}
testCon.begin();
testCon.add(bob, name, nameBob);
assertTrue(testCon.hasStatement(bob, RDF.TYPE, RDFS.RESOURCE, true));
assertFalse(testCon2.hasStatement(bob, RDF.TYPE, RDFS.RESOURCE, true));
testCon.commit();
assertTrue(testCon.hasStatement(bob, RDF.TYPE, RDFS.RESOURCE, true));
assertTrue(testCon2.hasStatement(bob, RDF.TYPE, RDFS.RESOURCE, true));
}
@ParameterizedTest
@MethodSource("parameters")
public void testContextStatementsNotDuplicated(IsolationLevel level) {
setupTest(level);
testCon.add(bob, RDF.TYPE, FOAF.PERSON, RDF.FIRST);
// TODO this test currently assumes that inferred triples are added to the null context. If we extend
// the reasoner to support usage of other contexts, this will have to be amended.
assertTrue(testCon.hasStatement(bob, RDF.TYPE, RDFS.RESOURCE, true, (Resource) null),
"inferred triple should have been added to null context");
// It used to expected behaviour that all inferred statements be added to the null context except those that already existed in some other context. There is no longer a check for if an inferred statement exists in other contexts.
// assertFalse("input triple should not have been re-added as inferred",
// testCon.hasStatement(bob, RDF.TYPE, FOAF.PERSON, true, (Resource) null));
}
@ParameterizedTest
@MethodSource("parameters")
public void testContextStatementsNotDuplicated2(IsolationLevel level) {
setupTest(level);
testCon.add(FOAF.PERSON, RDF.TYPE, RDFS.CLASS, RDF.FIRST);
testCon.add(FOAF.PERSON, RDFS.SUBCLASSOF, FOAF.AGENT, RDF.FIRST);
// TODO this test currently assumes that inferred triples are added to the null context. If we extend
// the reasoner to support usage of other contexts, this will have to be amended.
assertTrue(testCon.hasStatement(FOAF.AGENT, RDF.TYPE, RDFS.CLASS, true, (Resource) null),
"inferred triple should have been added to null context");
// It used to expected behaviour that all inferred statements be added to the null context except those that
// already existed in some other context. There is no longer a check for if an inferred statement exists in
// other contexts.
// assertFalse("input triple should not have been re-added as inferred", testCon.hasStatement(FOAF.PERSON,
// RDF.TYPE, RDFS.CLASS, true, (Resource) null));
// assertFalse("input triple should not have been re-added as inferred", testCon.hasStatement(FOAF.PERSON,
// RDFS.SUBCLASSOF, FOAF.AGENT, true, (Resource) null));
assertTrue(testCon.hasStatement(FOAF.PERSON, RDFS.SUBCLASSOF, FOAF.AGENT, false),
"input triple should be explicitly present");
assertTrue(testCon.hasStatement(FOAF.PERSON, RDF.TYPE, RDFS.CLASS, false),
"input triple should be explicitly present");
}
}