bNodeMapping) {
+
+ if (bs1.size() != bs2.size()) {
+ return false;
+ }
+
+ for (Binding binding1 : bs1) {
+ Value value1 = binding1.getValue();
+ Value value2 = bs2.getValue(binding1.getName());
+
+ if (value1 == null && value2 != null) {
+ return false;
+ }
+ else if (value1 != null && value2 == null) {
+ return false;
+ }
+ else if (value1 != null && value2 != null) {
+ if (!equals(value1, value2) && !value1.stringValue().equals(value2.stringValue())) {
+ return false;
+ }
+ }
+ }
+
+ return true;
+ }
+
+ protected static boolean equals(Value value1, Value value2)
+ {
+ try {
+ return QueryEvaluationUtil.compare(value1, value2, Compare.CompareOp.EQ);
+ }
+ catch (ValueExprEvaluationException e) {
+ return false;
+ }
+ }
+
+}
diff --git a/compliance/queryresultio/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVCustomTest.java b/compliance/queryresultio/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVCustomTest.java
new file mode 100644
index 00000000000..14a461488f2
--- /dev/null
+++ b/compliance/queryresultio/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVCustomTest.java
@@ -0,0 +1,83 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.resultio.text.tsv;
+
+import static org.junit.Assert.*;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.Arrays;
+import java.util.List;
+
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
+import org.eclipse.rdf4j.query.QueryEvaluationException;
+import org.eclipse.rdf4j.query.TupleQueryResult;
+import org.eclipse.rdf4j.query.TupleQueryResultHandlerException;
+import org.eclipse.rdf4j.query.impl.IteratingTupleQueryResult;
+import org.eclipse.rdf4j.query.impl.ListBindingSet;
+import org.eclipse.rdf4j.query.resultio.QueryResultIO;
+import org.eclipse.rdf4j.query.resultio.TupleQueryResultFormat;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Custom tests for the SPARQL TSV writer.
+ *
+ * @author Peter Ansell
+ */
+public class SPARQLTSVCustomTest {
+
+ /**
+ * Only Literals with the XML Schema numeric types should be simplified.
+ *
+ * NOTE: This will fail when using RDF-1.1, as the datatype
+ * {@link XMLSchema#STRING} is implied and hence is not generally
+ * represented.
+ *
+ * @throws Exception
+ */
+ @Ignore("This test does not work with RDF-1.1")
+ @Test
+ public void testSES2126QuotedLiteralIntegerAsStringExplicitType()
+ throws Exception
+ {
+ List bindingNames = Arrays.asList("test");
+ TupleQueryResult tqr = new IteratingTupleQueryResult(bindingNames, Arrays.asList(new ListBindingSet(
+ bindingNames, SimpleValueFactory.getInstance().createLiteral("1", XMLSchema.STRING))));
+ String result = writeTupleResult(tqr);
+ assertEquals("?test\n\"1\"^^\n", result);
+ }
+
+ /**
+ * Only Literals with the XML Schema numeric types should be simplified.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testSES2126QuotedLiteralIntegerAsStringImplicitType()
+ throws Exception
+ {
+ List bindingNames = Arrays.asList("test");
+ TupleQueryResult tqr = new IteratingTupleQueryResult(bindingNames, Arrays.asList(new ListBindingSet(
+ bindingNames, SimpleValueFactory.getInstance().createLiteral("1"))));
+ String result = writeTupleResult(tqr);
+ assertEquals("?test\n\"1\"\n", result);
+ }
+
+ private String writeTupleResult(TupleQueryResult tqr)
+ throws IOException, TupleQueryResultHandlerException, QueryEvaluationException
+ {
+ ByteArrayOutputStream output = new ByteArrayOutputStream();
+ QueryResultIO.writeTuple(tqr, TupleQueryResultFormat.TSV, output);
+ String result = new String(output.toByteArray(), Charset.forName("UTF-8"));
+ return result;
+ }
+
+}
diff --git a/compliance/queryresultio/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVTupleTest.java b/compliance/queryresultio/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVTupleTest.java
new file mode 100644
index 00000000000..1248a84905c
--- /dev/null
+++ b/compliance/queryresultio/src/test/java/org/eclipse/rdf4j/query/resultio/text/tsv/SPARQLTSVTupleTest.java
@@ -0,0 +1,130 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.resultio.text.tsv;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.ByteArrayOutputStream;
+import java.io.UnsupportedEncodingException;
+import java.util.Arrays;
+import java.util.regex.Pattern;
+
+import org.eclipse.rdf4j.query.QueryEvaluationException;
+import org.eclipse.rdf4j.query.QueryResultHandlerException;
+import org.eclipse.rdf4j.query.QueryResults;
+import org.eclipse.rdf4j.query.TupleQueryResult;
+import org.eclipse.rdf4j.query.TupleQueryResultHandlerException;
+import org.eclipse.rdf4j.query.impl.MutableTupleQueryResult;
+import org.eclipse.rdf4j.query.resultio.AbstractQueryResultIOTupleTest;
+import org.eclipse.rdf4j.query.resultio.BooleanQueryResultFormat;
+import org.eclipse.rdf4j.query.resultio.QueryResultIO;
+import org.eclipse.rdf4j.query.resultio.TupleQueryResultFormat;
+import org.eclipse.rdf4j.query.resultio.TupleQueryResultWriter;
+import org.junit.Test;
+
+/**
+ * @author Peter Ansell
+ * @author James Leigh
+ */
+public class SPARQLTSVTupleTest extends AbstractQueryResultIOTupleTest {
+
+ @Override
+ protected String getFileName() {
+ return "test.tsv";
+ }
+
+ @Override
+ protected TupleQueryResultFormat getTupleFormat() {
+ return TupleQueryResultFormat.TSV;
+ }
+
+ @Override
+ protected BooleanQueryResultFormat getMatchingBooleanFormatOrNull() {
+ return null;
+ }
+
+ @Test
+ public void testEndOfLine()
+ throws Exception
+ {
+ assertEquals("\n", toString(createTupleNoBindingSets()).replaceAll("\\S+|\t", ""));
+ }
+
+ @Test
+ public void testEmptyResults()
+ throws Exception
+ {
+ assertRegex("\\?a\t\\?b\t\\?c\n?", toString(createTupleNoBindingSets()));
+ }
+
+ @Test
+ public void testSingleVarResults()
+ throws Exception
+ {
+ assertRegex("\\?a\n" + "\n" + "(2.0(E0)?|\"2.0\"\\^\\^)\n"
+ + "_:bnode3\n" + "\"''single-quoted string\"(\\^\\^)?\n"
+ + "\"\\\\\"\\\\\"double-quoted string\"(\\^\\^)?\n"
+ + "\"space at the end \"(\\^\\^)?\n"
+ + "\"space at the end \"(\\^\\^)?\n"
+ + "\"\\\\\"\\\\\"double-quoted string with no datatype\"(\\^\\^)?\n"
+ + "\"newline at the end \\\\n\"(\\^\\^)?\n?",
+ toString(createTupleSingleVarMultipleBindingSets()));
+ }
+
+ @Test
+ public void testmultipleVarResults()
+ throws Exception
+ {
+ assertRegex(
+ "\\?a\t\\?b\t\\?c\n"
+ + "\t_:bnode\t\"baz\"(\\^\\^)?\n"
+ + "(1|\"1\"\\^\\^)\t\t\"Hello World!\"@en\n"
+ + "\t\"http://example.com/other/ns/bindingB\"(\\^\\^)?\t\n"
+ + "\"string with newline at the end \\\\n\"(\\^\\^)?\t\"string with space at the end \"(\\^\\^)?\t\" \"(\\^\\^)?\n"
+ + "\"''single-quoted string\"(\\^\\^)?\t\"\\\\\"\\\\\"double-quoted string\"(\\^\\^)?\t\"\\\\t\\\\tunencoded tab characters followed by encoded \\\\t\\\\t\"(\\^\\^)?\n?",
+ toString(createTupleMultipleBindingSets()));
+ }
+
+ private String toString(TupleQueryResult results)
+ throws QueryResultHandlerException, TupleQueryResultHandlerException, QueryEvaluationException,
+ UnsupportedEncodingException
+ {
+ TupleQueryResultFormat format = getTupleFormat();
+ ByteArrayOutputStream out = new ByteArrayOutputStream(4096);
+ TupleQueryResultWriter writer = QueryResultIO.createTupleWriter(format, out);
+ writer.startDocument();
+ writer.startHeader();
+ writer.handleLinks(Arrays. asList());
+ QueryResults.report(results, writer);
+
+ return out.toString("UTF-8");
+ }
+
+ private void assertRegex(String pattern, String actual) {
+ if (!Pattern.compile(pattern, Pattern.DOTALL).matcher(actual).matches()) {
+ assertEquals(pattern, actual);
+ }
+ }
+
+ protected void assertQueryResultsEqual(TupleQueryResult expected, TupleQueryResult output)
+ throws QueryEvaluationException, TupleQueryResultHandlerException, QueryResultHandlerException,
+ UnsupportedEncodingException
+ {
+ MutableTupleQueryResult r1 = new MutableTupleQueryResult(expected);
+ MutableTupleQueryResult r2 = new MutableTupleQueryResult(output);
+ if (!QueryResults.equals(r1, r2)) {
+ r1.beforeFirst();
+ r2.beforeFirst();
+ assertEquals(toString(r1), toString(r2));
+ r2.beforeFirst();
+ fail(toString(r2));
+ }
+ }
+
+}
diff --git a/compliance/queryresultio/src/test/resources/logback-test.xml b/compliance/queryresultio/src/test/resources/logback-test.xml
new file mode 100644
index 00000000000..86b31ec4b71
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/logback-test.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %msg%n
+
+
+
+
+
+
+
+
+
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/bindings1.srj b/compliance/queryresultio/src/test/resources/sparqljson/bindings1.srj
new file mode 100644
index 00000000000..a7045c76481
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/bindings1.srj
@@ -0,0 +1,36 @@
+{
+ "head": { "vars": [ "book" , "title" ]
+ } ,
+ "results": {
+ "bindings": [
+ {
+ "book": { "type": "uri" , "value": "http://example.org/book/book6" } ,
+ "title": { "type": "literal" , "value": "Harry Potter and the Half-Blood Prince" }
+ } ,
+ {
+ "book": { "type": "uri" , "value": "http://example.org/book/book7" } ,
+ "title": { "type": "literal" , "value": "Harry Potter and the Deathly Hallows" }
+ } ,
+ {
+ "book": { "type": "uri" , "value": "http://example.org/book/book5" } ,
+ "title": { "type": "literal" , "value": "Harry Potter and the Order of the Phoenix" }
+ } ,
+ {
+ "book": { "type": "uri" , "value": "http://example.org/book/book4" } ,
+ "title": { "type": "literal" , "value": "Harry Potter and the Goblet of Fire" }
+ } ,
+ {
+ "book": { "type": "uri" , "value": "http://example.org/book/book2" } ,
+ "title": { "type": "literal" , "value": "Harry Potter and the Chamber of Secrets" }
+ } ,
+ {
+ "book": { "type": "uri" , "value": "http://example.org/book/book3" } ,
+ "title": { "type": "literal" , "value": "Harry Potter and the Prisoner Of Azkaban" }
+ } ,
+ {
+ "book": { "type": "uri" , "value": "http://example.org/book/book1" } ,
+ "title": { "type": "literal" , "value": "Harry Potter and the Philosopher's Stone" }
+ }
+ ]
+ }
+}
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/bindings2.srj b/compliance/queryresultio/src/test/resources/sparqljson/bindings2.srj
new file mode 100644
index 00000000000..29de29569d3
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/bindings2.srj
@@ -0,0 +1,39 @@
+{
+ "head": {
+ "link": [
+ "http://www.w3.org/TR/2013/REC-sparql11-results-json-20130321/#example"
+ ],
+ "vars": [
+ "x",
+ "hpage",
+ "name",
+ "mbox",
+ "age",
+ "blurb",
+ "friend"
+ ]
+ },
+ "results": {
+ "bindings": [
+ {
+ "x" : { "type": "bnode", "value": "r1" },
+ "hpage" : { "type": "uri", "value": "http://work.example.org/alice/" },
+ "name" : { "type": "literal", "value": "Alice" } ,
+ "mbox" : { "type": "literal", "value": "" } ,
+ "blurb" : {
+ "datatype": "http://www.w3.org/1999/02/22-rdf-syntax-ns#XMLLiteral",
+ "type": "literal",
+ "value": "My name is alice
"
+ },
+ "friend" : { "type": "bnode", "value": "r2" }
+ },
+ {
+ "x" : { "type": "bnode", "value": "r2" },
+ "hpage" : { "type": "uri", "value": "http://work.example.org/bob/" },
+ "name" : { "type": "literal", "value": "Bob", "xml:lang": "en" },
+ "mbox" : { "type": "uri", "value": "mailto:bob@work.example.org" },
+ "friend" : { "type": "bnode", "value": "r1" }
+ }
+ ]
+ }
+}
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/boolean1.srj b/compliance/queryresultio/src/test/resources/sparqljson/boolean1.srj
new file mode 100644
index 00000000000..4a70b7489b7
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/boolean1.srj
@@ -0,0 +1,3 @@
+{
+ "boolean": true
+}
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/boolean2.srj b/compliance/queryresultio/src/test/resources/sparqljson/boolean2.srj
new file mode 100644
index 00000000000..91b69eabc24
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/boolean2.srj
@@ -0,0 +1,3 @@
+{
+ "boolean": "true"
+}
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/boolean3.srj b/compliance/queryresultio/src/test/resources/sparqljson/boolean3.srj
new file mode 100644
index 00000000000..f4d94926ea6
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/boolean3.srj
@@ -0,0 +1,3 @@
+{
+ "boolean": false
+}
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/boolean4.srj b/compliance/queryresultio/src/test/resources/sparqljson/boolean4.srj
new file mode 100644
index 00000000000..06a2bc2be02
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/boolean4.srj
@@ -0,0 +1,3 @@
+{
+ "boolean": "false"
+}
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/non-standard-distinct-ordered.srj b/compliance/queryresultio/src/test/resources/sparqljson/non-standard-distinct-ordered.srj
new file mode 100644
index 00000000000..64f4c9182f8
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/non-standard-distinct-ordered.srj
@@ -0,0 +1,102 @@
+{ "head": { "link": [], "vars": ["Concept"] },
+ "results": { "distinct": false, "ordered": true, "bindings": [
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Thing" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Class" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#ObjectProperty" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Ontology" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#FunctionalProperty" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#DatatypeProperty" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Company" }},
+ { "Concept": { "type": "uri", "value": "http://xmlns.com/foaf/0.1/Person" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Activity" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Person" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Language" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Software" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/School" }},
+ { "Concept": { "type": "uri", "value": "http://purl.org/ontology/bibo/Book" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Name" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Actor" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Place" }},
+ { "Concept": { "type": "uri", "value": "http://www.opengis.net/gml/_Feature" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/OfficeHolder" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TennisPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Organisation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MilitaryPerson" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BaseballPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ProgrammingLanguage" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ChemicalCompound" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ArchitecturalStructure" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Infrastructure" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/CelestialBody" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AutomobileEngine" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AcademicJournal" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Broadcaster" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TelevisionStation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RailwayTunnel" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/GovernmentAgency" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Biomolecule" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RailwayLine" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MartialArtist" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RecordLabel" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AmericanFootballTeam" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/PublicTransitSystem" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BaseballLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/HistoricPlace" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RugbyLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/HistoricBuilding" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/OlympicResult" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/FootballMatch" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Language" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/MusicGroup" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/RiverBodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/SportsTeam" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/LakeBodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/MusicAlbum" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Mountain" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/StadiumOrArena" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Canal" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Hospital" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/LandmarksOrHistoricalBuildings" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/SportsEvent" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Festival" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/CanadianFootballLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RugbyPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TelevisionEpisode" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/GaelicGamesPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SnookerPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TennisLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RoadJunction" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SnookerChamp" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Book" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Work" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Philosopher" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Agent" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Award" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Film" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Song" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SpaceMission" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Event" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/City" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Band" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/FictionalCharacter" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Plant" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Saint" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Sport" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Fish" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Game" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Town" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/River" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/NaturalPlace" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Non-ProfitOrganisation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ChemicalSubstance" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BritishRoyalty" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Drug" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SportsTeamMember" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SportsLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MeanOfTransportation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Lake" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BroadcastNetwork" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Play" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Album" }} ] } }
\ No newline at end of file
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/non-standard-distinct.srj b/compliance/queryresultio/src/test/resources/sparqljson/non-standard-distinct.srj
new file mode 100644
index 00000000000..f7d27d01be2
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/non-standard-distinct.srj
@@ -0,0 +1,102 @@
+{ "head": { "link": [], "vars": ["Concept"] },
+ "results": { "distinct": false, "bindings": [
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Thing" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Class" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#ObjectProperty" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Ontology" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#FunctionalProperty" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#DatatypeProperty" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Company" }},
+ { "Concept": { "type": "uri", "value": "http://xmlns.com/foaf/0.1/Person" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Activity" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Person" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Language" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Software" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/School" }},
+ { "Concept": { "type": "uri", "value": "http://purl.org/ontology/bibo/Book" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Name" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Actor" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Place" }},
+ { "Concept": { "type": "uri", "value": "http://www.opengis.net/gml/_Feature" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/OfficeHolder" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TennisPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Organisation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MilitaryPerson" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BaseballPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ProgrammingLanguage" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ChemicalCompound" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ArchitecturalStructure" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Infrastructure" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/CelestialBody" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AutomobileEngine" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AcademicJournal" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Broadcaster" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TelevisionStation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RailwayTunnel" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/GovernmentAgency" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Biomolecule" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RailwayLine" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MartialArtist" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RecordLabel" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AmericanFootballTeam" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/PublicTransitSystem" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BaseballLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/HistoricPlace" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RugbyLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/HistoricBuilding" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/OlympicResult" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/FootballMatch" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Language" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/MusicGroup" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/RiverBodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/SportsTeam" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/LakeBodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/MusicAlbum" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Mountain" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/StadiumOrArena" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Canal" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Hospital" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/LandmarksOrHistoricalBuildings" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/SportsEvent" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Festival" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/CanadianFootballLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RugbyPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TelevisionEpisode" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/GaelicGamesPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SnookerPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TennisLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RoadJunction" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SnookerChamp" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Book" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Work" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Philosopher" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Agent" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Award" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Film" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Song" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SpaceMission" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Event" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/City" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Band" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/FictionalCharacter" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Plant" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Saint" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Sport" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Fish" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Game" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Town" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/River" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/NaturalPlace" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Non-ProfitOrganisation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ChemicalSubstance" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BritishRoyalty" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Drug" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SportsTeamMember" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SportsLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MeanOfTransportation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Lake" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BroadcastNetwork" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Play" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Album" }} ] } }
\ No newline at end of file
diff --git a/compliance/queryresultio/src/test/resources/sparqljson/non-standard-ordered.srj b/compliance/queryresultio/src/test/resources/sparqljson/non-standard-ordered.srj
new file mode 100644
index 00000000000..4a6a0a3276b
--- /dev/null
+++ b/compliance/queryresultio/src/test/resources/sparqljson/non-standard-ordered.srj
@@ -0,0 +1,102 @@
+{ "head": { "link": [], "vars": ["Concept"] },
+ "results": { "ordered": true, "bindings": [
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Thing" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Class" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#ObjectProperty" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/1999/02/22-rdf-syntax-ns#Property" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#Ontology" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#FunctionalProperty" }},
+ { "Concept": { "type": "uri", "value": "http://www.w3.org/2002/07/owl#DatatypeProperty" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Company" }},
+ { "Concept": { "type": "uri", "value": "http://xmlns.com/foaf/0.1/Person" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Activity" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Person" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Language" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Software" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/School" }},
+ { "Concept": { "type": "uri", "value": "http://purl.org/ontology/bibo/Book" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Name" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Actor" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Place" }},
+ { "Concept": { "type": "uri", "value": "http://www.opengis.net/gml/_Feature" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/OfficeHolder" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TennisPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Organisation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MilitaryPerson" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BaseballPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ProgrammingLanguage" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ChemicalCompound" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ArchitecturalStructure" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Infrastructure" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/CelestialBody" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AutomobileEngine" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AcademicJournal" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Broadcaster" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TelevisionStation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RailwayTunnel" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/GovernmentAgency" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Biomolecule" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RailwayLine" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MartialArtist" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RecordLabel" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/AmericanFootballTeam" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/PublicTransitSystem" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BaseballLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/HistoricPlace" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RugbyLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/HistoricBuilding" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/OlympicResult" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/FootballMatch" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Language" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/MusicGroup" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/RiverBodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/SportsTeam" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/LakeBodyOfWater" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/MusicAlbum" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Mountain" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/StadiumOrArena" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Canal" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Hospital" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/LandmarksOrHistoricalBuildings" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/SportsEvent" }},
+ { "Concept": { "type": "uri", "value": "http://schema.org/Festival" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/CanadianFootballLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RugbyPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TelevisionEpisode" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/GaelicGamesPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SnookerPlayer" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/TennisLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/RoadJunction" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SnookerChamp" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Book" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Work" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Philosopher" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Agent" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Award" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Film" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Song" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SpaceMission" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Event" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/City" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Band" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/FictionalCharacter" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Plant" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Saint" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Sport" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Fish" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Game" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Town" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/River" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/NaturalPlace" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Non-ProfitOrganisation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/ChemicalSubstance" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BritishRoyalty" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Drug" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SportsTeamMember" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/SportsLeague" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/MeanOfTransportation" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Lake" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/BroadcastNetwork" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Play" }},
+ { "Concept": { "type": "uri", "value": "http://dbpedia.org/ontology/Album" }} ] } }
\ No newline at end of file
diff --git a/compliance/rio/pom.xml b/compliance/rio/pom.xml
new file mode 100644
index 00000000000..9d800fee5db
--- /dev/null
+++ b/compliance/rio/pom.xml
@@ -0,0 +1,170 @@
+
+
+ 4.0.0
+
+
+ org.eclipse.rdf4j
+ rdf4j-compliance
+ 4.1.0-SNAPSHOT
+
+
+ rdf4j-rio-compliance
+
+ RDF4J Rio compliance tests
+ Tests for parsers and writers of various RDF file formats.
+
+
+
+ ${project.groupId}
+ rdf4j-runtime
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-sail
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sail-memory
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-testsuite
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-datatypes
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-languages
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-rdfxml
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-ntriples
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-nquads
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-turtle
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-trig
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-binary
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-rdfjson
+ ${project.version}
+
+
+
+ xml-security
+ xmlsec
+ 1.3.0
+
+
+
+
+ xalan
+ xalan
+ 2.6.0
+
+
+
+ junit
+ junit
+ test
+
+
+
+ ch.qos.logback
+ logback-classic
+ test
+
+
+ org.slf4j
+ jcl-over-slf4j
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+ 1
+ false
+ -Xmx512M -XX:MaxPermSize=256M
+
+ **/*Test.java
+
+
+ **/N3ParserTest.java
+ **/TestServer.java
+
+
+
+
+ integration-tests
+ integration-test
+
+ integration-test
+
+
+
+ verify
+ verify
+
+ verify
+
+
+
+
+
+
+
+
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/binary/BinaryHandlingTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/binary/BinaryHandlingTest.java
new file mode 100644
index 00000000000..a079d839a48
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/binary/BinaryHandlingTest.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.binary;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.rio.AbstractParserHandlingTest;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.binary.BinaryRDFParser;
+import org.eclipse.rdf4j.rio.binary.BinaryRDFWriter;
+
+/**
+ * Test for error handling by Binary Parser.
+ *
+ * @author Peter Ansell
+ */
+public class BinaryHandlingTest extends AbstractParserHandlingTest {
+
+ @Override
+ protected InputStream getUnknownDatatypeStream(Model unknownDatatypeStatements)
+ throws Exception
+ {
+ return writeBinary(unknownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getKnownDatatypeStream(Model knownDatatypeStatements)
+ throws Exception
+ {
+ return writeBinary(knownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getUnknownLanguageStream(Model unknownLanguageStatements)
+ throws Exception
+ {
+ return writeBinary(unknownLanguageStatements);
+ }
+
+ @Override
+ protected InputStream getKnownLanguageStream(Model knownLanguageStatements)
+ throws Exception
+ {
+ return writeBinary(knownLanguageStatements);
+ }
+
+ @Override
+ protected RDFParser getParser() {
+ return new BinaryRDFParser();
+ }
+
+ /**
+ * Helper method to write the given model to N-Triples and return an
+ * InputStream containing the results.
+ *
+ * @param statements
+ * @return An {@link InputStream} containing the results.
+ * @throws RDFHandlerException
+ */
+ private InputStream writeBinary(Model statements)
+ throws RDFHandlerException
+ {
+ ByteArrayOutputStream output = new ByteArrayOutputStream(8096);
+
+ RDFWriter binaryWriter = new BinaryRDFWriter(output);
+ binaryWriter.startRDF();
+ for (Statement nextStatement : statements) {
+ binaryWriter.handleStatement(nextStatement);
+ }
+ binaryWriter.endRDF();
+
+ return new ByteArrayInputStream(output.toByteArray());
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/binary/BinaryRDFWriterTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/binary/BinaryRDFWriterTest.java
new file mode 100644
index 00000000000..1ece3be42f3
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/binary/BinaryRDFWriterTest.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.binary;
+
+import org.eclipse.rdf4j.rio.RDFWriterTest;
+import org.eclipse.rdf4j.rio.binary.BinaryRDFParserFactory;
+import org.eclipse.rdf4j.rio.binary.BinaryRDFWriterFactory;
+
+/**
+ * @author Arjohn Kampman
+ */
+public class BinaryRDFWriterTest extends RDFWriterTest {
+
+ public BinaryRDFWriterTest() {
+ super(new BinaryRDFWriterFactory(), new BinaryRDFParserFactory());
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/DBPediaCelsiusDatatypeHandlerTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/DBPediaCelsiusDatatypeHandlerTest.java
new file mode 100644
index 00000000000..fd52035a3ed
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/DBPediaCelsiusDatatypeHandlerTest.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.datatypes;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
+import org.eclipse.rdf4j.rio.DatatypeHandler;
+import org.eclipse.rdf4j.rio.datatypes.AbstractDatatypeHandlerTest;
+import org.eclipse.rdf4j.rio.datatypes.DBPediaDatatypeHandler;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Test for {@link DBPediaDatatypeHandler} with
+ * http://dbpedia.org/datatype/degreeCelsius .
+ *
+ * @author Peter Ansell
+ */
+public class DBPediaCelsiusDatatypeHandlerTest extends AbstractDatatypeHandlerTest {
+
+ @Ignore("DBPedia datatypes are not currently verified")
+ @Test
+ @Override
+ public void testVerifyDatatypeInvalidValue()
+ throws Exception
+ {
+ }
+
+ @Ignore("DBPedia datatypes are not currently normalised")
+ @Test
+ @Override
+ public void testNormalizeDatatypeInvalidValue()
+ throws Exception
+ {
+ }
+
+ // -------------------------------------
+ // RDF LangString specific methods
+ // -------------------------------------
+
+ @Override
+ protected IRI getRecognisedDatatypeUri() {
+ return SimpleValueFactory.getInstance().createIRI("http://dbpedia.org/datatype/", "degreeCelsius");
+ }
+
+ @Override
+ protected String getValueMatchingRecognisedDatatypeUri() {
+ return "1.0";
+ }
+
+ @Override
+ protected String getValueNotMatchingRecognisedDatatypeUri() {
+ return "Not a degrees celsius value.";
+ }
+
+ @Override
+ protected Literal getNormalisedLiteralForRecognisedDatatypeAndValue() {
+ return SimpleValueFactory.getInstance().createLiteral("1.0",
+ SimpleValueFactory.getInstance().createIRI("http://dbpedia.org/datatype/", "degreeCelsius"));
+ }
+
+ // -------------------------------------
+ // Common methods
+ // -------------------------------------
+
+ @Override
+ protected DatatypeHandler getNewDatatypeHandler() {
+ return new DBPediaDatatypeHandler();
+ }
+
+ @Override
+ protected ValueFactory getValueFactory() {
+ return SimpleValueFactory.getInstance();
+ }
+
+ @Override
+ protected IRI getUnrecognisedDatatypeUri() {
+ return XMLSchema.DOUBLE;
+ }
+
+ @Override
+ protected String getExpectedKey() {
+ return DatatypeHandler.DBPEDIA;
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/RDFLangStringDatatypeHandlerTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/RDFLangStringDatatypeHandlerTest.java
new file mode 100644
index 00000000000..0baf659d821
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/RDFLangStringDatatypeHandlerTest.java
@@ -0,0 +1,101 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.datatypes;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
+import org.eclipse.rdf4j.rio.DatatypeHandler;
+import org.eclipse.rdf4j.rio.datatypes.AbstractDatatypeHandlerTest;
+import org.eclipse.rdf4j.rio.datatypes.RDFDatatypeHandler;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Test for {@link RDFDatatypeHandler} with {@link RDF#LANGSTRING}.
+ *
+ * @author Peter Ansell
+ */
+public class RDFLangStringDatatypeHandlerTest extends AbstractDatatypeHandlerTest {
+
+ @Ignore("There are no invalid values for RDF LangString other than null, which is tested seperately")
+ @Test
+ @Override
+ public void testVerifyDatatypeInvalidValue()
+ throws Exception
+ {
+ }
+
+ @Ignore("There are no invalid values for RDF LangString other than null, which is tested seperately")
+ @Test
+ @Override
+ public void testNormalizeDatatypeInvalidValue()
+ throws Exception
+ {
+ }
+
+ @Ignore("This test relies on a null language, which is not allowed for RDF.LANGSTRING")
+ @Test
+ @Override
+ public void testNormalizeDatatypeValidValue()
+ throws Exception
+ {
+ }
+
+ // -------------------------------------
+ // RDF LangString specific methods
+ // -------------------------------------
+
+ @Override
+ protected IRI getRecognisedDatatypeUri() {
+ return RDF.LANGSTRING;
+ }
+
+ @Override
+ protected String getValueMatchingRecognisedDatatypeUri() {
+ return "This is a string";
+ }
+
+ @Override
+ protected String getValueNotMatchingRecognisedDatatypeUri() {
+ return "Everything is a lang string.";
+ }
+
+ @Override
+ protected Literal getNormalisedLiteralForRecognisedDatatypeAndValue() {
+ return SimpleValueFactory.getInstance().createLiteral("This is a string", RDF.LANGSTRING);
+ }
+
+ // -------------------------------------
+ // Common methods
+ // -------------------------------------
+
+ @Override
+ protected DatatypeHandler getNewDatatypeHandler() {
+ return new RDFDatatypeHandler();
+ }
+
+ @Override
+ protected ValueFactory getValueFactory() {
+ return SimpleValueFactory.getInstance();
+ }
+
+ @Override
+ protected IRI getUnrecognisedDatatypeUri() {
+ return XMLSchema.DOUBLE;
+ }
+
+ @Override
+ protected String getExpectedKey() {
+ return DatatypeHandler.RDFDATATYPES;
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/VirtuosoGeometryPointDatatypeHandlerTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/VirtuosoGeometryPointDatatypeHandlerTest.java
new file mode 100644
index 00000000000..dfe3c220a52
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/VirtuosoGeometryPointDatatypeHandlerTest.java
@@ -0,0 +1,78 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.datatypes;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.rio.DatatypeHandler;
+import org.eclipse.rdf4j.rio.datatypes.AbstractDatatypeHandlerTest;
+import org.eclipse.rdf4j.rio.datatypes.VirtuosoGeometryDatatypeHandler;
+
+/**
+ * Test for {@link VirtuosoDatatypeHandler} with
+ * http://www.openlinksw.com/schemas/virtrdf#Geometry .
+ *
+ * @author Peter Ansell
+ */
+public class VirtuosoGeometryPointDatatypeHandlerTest extends AbstractDatatypeHandlerTest {
+
+ // -------------------------------------
+ // XMLSchema Double specific methods
+ // -------------------------------------
+
+ @Override
+ protected IRI getRecognisedDatatypeUri() {
+ return SimpleValueFactory.getInstance().createIRI("http://www.openlinksw.com/schemas/virtrdf#",
+ "Geometry");
+ }
+
+ @Override
+ protected String getValueMatchingRecognisedDatatypeUri() {
+ return "POINT(123.0000 143.000)";
+ }
+
+ @Override
+ protected String getValueNotMatchingRecognisedDatatypeUri() {
+ return "POINT(This is not a point)";
+ }
+
+ @Override
+ protected Literal getNormalisedLiteralForRecognisedDatatypeAndValue() {
+ return SimpleValueFactory.getInstance().createLiteral(
+ "POINT(123.0000 143.000)",
+ SimpleValueFactory.getInstance().createIRI("http://www.openlinksw.com/schemas/virtrdf#", "Geometry"));
+ }
+
+ // -------------------------------------
+ // Common methods
+ // -------------------------------------
+
+ @Override
+ protected DatatypeHandler getNewDatatypeHandler() {
+ return new VirtuosoGeometryDatatypeHandler();
+ }
+
+ @Override
+ protected ValueFactory getValueFactory() {
+ return SimpleValueFactory.getInstance();
+ }
+
+ @Override
+ protected IRI getUnrecognisedDatatypeUri() {
+ return RDF.LANGSTRING;
+ }
+
+ @Override
+ protected String getExpectedKey() {
+ return DatatypeHandler.VIRTUOSOGEOMETRY;
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/XMLSchemaDoubleDatatypeHandlerTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/XMLSchemaDoubleDatatypeHandlerTest.java
new file mode 100644
index 00000000000..ad199ef3250
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/datatypes/XMLSchemaDoubleDatatypeHandlerTest.java
@@ -0,0 +1,75 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.datatypes;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
+import org.eclipse.rdf4j.rio.DatatypeHandler;
+import org.eclipse.rdf4j.rio.datatypes.AbstractDatatypeHandlerTest;
+import org.eclipse.rdf4j.rio.datatypes.XMLSchemaDatatypeHandler;
+
+/**
+ * Test for {@link XMLSchemaDatatypeHandler} with {@link XMLSchema#DOUBLE}.
+ *
+ * @author Peter Ansell
+ */
+public class XMLSchemaDoubleDatatypeHandlerTest extends AbstractDatatypeHandlerTest {
+
+ // -------------------------------------
+ // XMLSchema Double specific methods
+ // -------------------------------------
+
+ @Override
+ protected IRI getRecognisedDatatypeUri() {
+ return XMLSchema.DOUBLE;
+ }
+
+ @Override
+ protected String getValueMatchingRecognisedDatatypeUri() {
+ return "123.0000";
+ }
+
+ @Override
+ protected String getValueNotMatchingRecognisedDatatypeUri() {
+ return "This is not a double";
+ }
+
+ @Override
+ protected Literal getNormalisedLiteralForRecognisedDatatypeAndValue() {
+ return SimpleValueFactory.getInstance().createLiteral("1.23E2", XMLSchema.DOUBLE);
+ }
+
+ // -------------------------------------
+ // Common methods
+ // -------------------------------------
+
+ @Override
+ protected DatatypeHandler getNewDatatypeHandler() {
+ return new XMLSchemaDatatypeHandler();
+ }
+
+ @Override
+ protected ValueFactory getValueFactory() {
+ return SimpleValueFactory.getInstance();
+ }
+
+ @Override
+ protected IRI getUnrecognisedDatatypeUri() {
+ return RDF.LANGSTRING;
+ }
+
+ @Override
+ protected String getExpectedKey() {
+ return DatatypeHandler.XMLSCHEMA;
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/helpers/RDFParserHelperTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/helpers/RDFParserHelperTest.java
new file mode 100644
index 00000000000..aef4771e061
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/helpers/RDFParserHelperTest.java
@@ -0,0 +1,371 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.helpers;
+
+import static org.junit.Assert.*;
+
+import java.util.Collections;
+import java.util.HashSet;
+
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
+import org.eclipse.rdf4j.rio.DatatypeHandler;
+import org.eclipse.rdf4j.rio.LanguageHandler;
+import org.eclipse.rdf4j.rio.ParseErrorListener;
+import org.eclipse.rdf4j.rio.ParserConfig;
+import org.eclipse.rdf4j.rio.RDFParseException;
+import org.eclipse.rdf4j.rio.RioSetting;
+import org.eclipse.rdf4j.rio.helpers.BasicParserSettings;
+import org.eclipse.rdf4j.rio.helpers.ParseErrorCollector;
+import org.eclipse.rdf4j.rio.helpers.RDFParserHelper;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+
+/**
+ * Tests for {@link RDFParserHelper} methods.
+ *
+ * @author Peter Ansell
+ */
+public class RDFParserHelperTest {
+
+ private static final String TEST_MESSAGE_FOR_FAILURE = "Test message for failure.";
+
+ @Rule
+ public ExpectedException thrown = ExpectedException.none();
+
+ private static final String LABEL_TESTA = "test-a";
+
+ private static final String LANG_EN = "en";
+
+ private ParserConfig parserConfig;
+
+ private ParseErrorCollector errListener;
+
+ private ValueFactory valueFactory;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp()
+ throws Exception
+ {
+ parserConfig = new ParserConfig();
+ // By default we wipe out the SPI loaded datatype and language handlers
+ parserConfig.set(BasicParserSettings.DATATYPE_HANDLERS, Collections. emptyList());
+ parserConfig.set(BasicParserSettings.LANGUAGE_HANDLERS, Collections. emptyList());
+ // Ensure that the set of non-fatal errors is empty by default
+ parserConfig.setNonFatalErrors(new HashSet>());
+ errListener = new ParseErrorCollector();
+ valueFactory = SimpleValueFactory.getInstance();
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown()
+ throws Exception
+ {
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#createLiteral(java.lang.String, java.lang.String, org.eclipse.rdf4j.model.URI, org.eclipse.rdf4j.rio.ParserConfig, org.eclipse.rdf4j.rio.ParseErrorListener, org.eclipse.rdf4j.model.ValueFactory)}
+ * .
+ */
+ @Test
+ public final void testCreateLiteralLabelNull()
+ throws Exception
+ {
+ thrown.expect(NullPointerException.class);
+ thrown.expectMessage("Cannot create a literal using a null label");
+ RDFParserHelper.createLiteral(null, null, null, parserConfig, errListener, valueFactory);
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#createLiteral(java.lang.String, java.lang.String, org.eclipse.rdf4j.model.URI, org.eclipse.rdf4j.rio.ParserConfig, org.eclipse.rdf4j.rio.ParseErrorListener, org.eclipse.rdf4j.model.ValueFactory)}
+ * .
+ */
+ @Test
+ public final void testCreateLiteralLabelOnly()
+ throws Exception
+ {
+ Literal literal = RDFParserHelper.createLiteral(LABEL_TESTA, null, null, parserConfig, errListener,
+ valueFactory);
+
+ assertEquals(LABEL_TESTA, literal.getLabel());
+ assertFalse(literal.getLanguage().isPresent());
+ assertEquals(XMLSchema.STRING, literal.getDatatype());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#createLiteral(java.lang.String, java.lang.String, org.eclipse.rdf4j.model.URI, org.eclipse.rdf4j.rio.ParserConfig, org.eclipse.rdf4j.rio.ParseErrorListener, org.eclipse.rdf4j.model.ValueFactory)}
+ * .
+ */
+ @Test
+ public final void testCreateLiteralLabelAndLanguage()
+ throws Exception
+ {
+ Literal literal = RDFParserHelper.createLiteral(LABEL_TESTA, LANG_EN, null, parserConfig, errListener,
+ valueFactory);
+
+ assertEquals(LABEL_TESTA, literal.getLabel());
+ assertEquals(LANG_EN, literal.getLanguage().orElse(null));
+ assertEquals(RDF.LANGSTRING, literal.getDatatype());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#createLiteral(java.lang.String, java.lang.String, org.eclipse.rdf4j.model.URI, org.eclipse.rdf4j.rio.ParserConfig, org.eclipse.rdf4j.rio.ParseErrorListener, org.eclipse.rdf4j.model.ValueFactory)}
+ * .
+ */
+ @Test
+ public final void testCreateLiteralLabelAndDatatype()
+ throws Exception
+ {
+ Literal literal = RDFParserHelper.createLiteral(LABEL_TESTA, null, XMLSchema.STRING, parserConfig,
+ errListener, valueFactory);
+
+ assertEquals(LABEL_TESTA, literal.getLabel());
+ assertFalse(literal.getLanguage().isPresent());
+ assertEquals(XMLSchema.STRING, literal.getDatatype());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#createLiteral(java.lang.String, java.lang.String, org.eclipse.rdf4j.model.URI, org.eclipse.rdf4j.rio.ParserConfig, org.eclipse.rdf4j.rio.ParseErrorListener, org.eclipse.rdf4j.model.ValueFactory)}
+ * .
+ *
+ * SES-1803 : Temporary decision to ensure RDF-1.0 backwards compatibility
+ * for Literals created by this method in cases where {@link RDF#LANGSTRING}
+ * is given and there is a language.
+ */
+ @Test
+ public final void testCreateLiteralLabelAndLanguageWithRDFLangString()
+ throws Exception
+ {
+ Literal literal = RDFParserHelper.createLiteral(LABEL_TESTA, LANG_EN, RDF.LANGSTRING, parserConfig,
+ errListener, valueFactory);
+
+ assertEquals(LABEL_TESTA, literal.getLabel());
+ assertEquals(LANG_EN, literal.getLanguage().orElse(null));
+ assertEquals(RDF.LANGSTRING, literal.getDatatype());
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#createLiteral(java.lang.String, java.lang.String, org.eclipse.rdf4j.model.URI, org.eclipse.rdf4j.rio.ParserConfig, org.eclipse.rdf4j.rio.ParseErrorListener, org.eclipse.rdf4j.model.ValueFactory)}
+ * .
+ *
+ * SES-1803 : Temporary decision to ensure RDF-1.0 backwards compatibility
+ * for Literals created by this method in cases where {@link RDF#LANGSTRING}
+ * is given and there is NO given language.
+ *
+ * SES-2203 : This was inconsistent, so has been changed to verify failure.
+ */
+ @Test
+ public final void testCreateLiteralLabelNoLanguageWithRDFLangString()
+ throws Exception
+ {
+ thrown.expect(RDFParseException.class);
+ RDFParserHelper.createLiteral(LABEL_TESTA, null, RDF.LANGSTRING, parserConfig,
+ errListener, valueFactory);
+ }
+
+ @Test
+ public final void testReportErrorStringFatalActive()
+ throws Exception
+ {
+ parserConfig.set(BasicParserSettings.VERIFY_DATATYPE_VALUES, true);
+ assertTrue(parserConfig.get(BasicParserSettings.VERIFY_DATATYPE_VALUES));
+ thrown.expect(RDFParseException.class);
+ thrown.expectMessage(TEST_MESSAGE_FOR_FAILURE);
+ try {
+ RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, BasicParserSettings.VERIFY_DATATYPE_VALUES,
+ parserConfig, errListener);
+ }
+ finally {
+ assertErrorListener(0, 1, 0);
+ }
+ }
+
+ @Test
+ public final void testReportErrorStringNonFatalActive()
+ throws Exception
+ {
+ parserConfig.set(BasicParserSettings.VERIFY_DATATYPE_VALUES, true);
+ assertTrue(parserConfig.get(BasicParserSettings.VERIFY_DATATYPE_VALUES));
+ parserConfig.addNonFatalError(BasicParserSettings.VERIFY_DATATYPE_VALUES);
+ RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, BasicParserSettings.VERIFY_DATATYPE_VALUES,
+ parserConfig, errListener);
+ assertErrorListener(0, 1, 0);
+ }
+
+ @Test
+ public final void testReportErrorStringFatalInactive()
+ throws Exception
+ {
+ assertFalse(parserConfig.get(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES));
+ RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES,
+ parserConfig, errListener);
+ assertErrorListener(0, 0, 0);
+ }
+
+ @Test
+ public final void testReportErrorStringNonFatalInactive()
+ throws Exception
+ {
+ assertFalse(parserConfig.get(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES));
+ parserConfig.addNonFatalError(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES);
+ RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES,
+ parserConfig, errListener);
+ assertErrorListener(0, 0, 0);
+ }
+
+ @Test
+ public final void testReportErrorStringIntIntFatalActive()
+ throws Exception
+ {
+ parserConfig.set(BasicParserSettings.VERIFY_DATATYPE_VALUES, true);
+ assertTrue(parserConfig.get(BasicParserSettings.VERIFY_DATATYPE_VALUES));
+ thrown.expect(RDFParseException.class);
+ thrown.expectMessage(TEST_MESSAGE_FOR_FAILURE);
+ try {
+ RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, 1, 1,
+ BasicParserSettings.VERIFY_DATATYPE_VALUES, parserConfig, errListener);
+ }
+ finally {
+ assertErrorListener(0, 1, 0);
+ }
+ }
+
+ @Test
+ public final void testReportErrorStringIntIntNonFatalActive()
+ throws Exception
+ {
+ parserConfig.set(BasicParserSettings.VERIFY_DATATYPE_VALUES, true);
+ assertTrue(parserConfig.get(BasicParserSettings.VERIFY_DATATYPE_VALUES));
+ parserConfig.addNonFatalError(BasicParserSettings.VERIFY_DATATYPE_VALUES);
+ RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, 1, 1, BasicParserSettings.VERIFY_DATATYPE_VALUES,
+ parserConfig, errListener);
+ assertErrorListener(0, 1, 0);
+ }
+
+ @Test
+ public final void testReportErrorStringIntIntFatalInactive()
+ throws Exception
+ {
+ assertFalse(parserConfig.get(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES));
+ RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, 1, 1,
+ BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, parserConfig, errListener);
+ assertErrorListener(0, 0, 0);
+ }
+
+ @Test
+ public final void testReportErrorStringIntIntNonFatalInactive()
+ throws Exception
+ {
+ assertFalse(parserConfig.get(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES));
+ parserConfig.addNonFatalError(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES);
+ RDFParserHelper.reportError(TEST_MESSAGE_FOR_FAILURE, 1, 1,
+ BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, parserConfig, errListener);
+ assertErrorListener(0, 0, 0);
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#reportError(java.lang.Exception, int, int, org.eclipse.rdf4j.rio.RioSetting, org.eclipse.rdf4j.rio.ParserConfig, org.eclipse.rdf4j.rio.ParseErrorListener)}
+ * .
+ */
+ @Ignore
+ @Test
+ public final void testReportErrorExceptionIntInt()
+ throws Exception
+ {
+ fail("Not yet implemented"); // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#reportFatalError(java.lang.String, org.eclipse.rdf4j.rio.ParseErrorListener)}
+ * .
+ */
+ @Ignore
+ @Test
+ public final void testReportFatalErrorString()
+ throws Exception
+ {
+ fail("Not yet implemented"); // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#reportFatalError(java.lang.String, int, int, org.eclipse.rdf4j.rio.ParseErrorListener)}
+ * .
+ */
+ @Ignore
+ @Test
+ public final void testReportFatalErrorStringIntInt()
+ throws Exception
+ {
+ fail("Not yet implemented"); // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#reportFatalError(java.lang.Exception, org.eclipse.rdf4j.rio.ParseErrorListener)}
+ * .
+ */
+ @Ignore
+ @Test
+ public final void testReportFatalErrorException()
+ throws Exception
+ {
+ fail("Not yet implemented"); // TODO
+ }
+
+ /**
+ * Test method for
+ * {@link org.eclipse.rdf4j.rio.helpers.RDFParserHelper#reportFatalError(java.lang.Exception, int, int, org.eclipse.rdf4j.rio.ParseErrorListener)}
+ * .
+ */
+ @Ignore
+ @Test
+ public final void testReportFatalErrorExceptionIntInt()
+ throws Exception
+ {
+ fail("Not yet implemented"); // TODO
+ }
+
+ /**
+ * Private method for verifying the number of errors that were logged to the
+ * {@link ParseErrorListener}.
+ *
+ * @param fatalErrors
+ * Expected number of fatal errors logged by error listener.
+ * @param errors
+ * Expected number of errors logged by error listener.
+ * @param warnings
+ * Expected number of warnings logged by error listener.
+ */
+ private void assertErrorListener(int fatalErrors, int errors, int warnings) {
+ assertEquals(fatalErrors, errListener.getFatalErrors().size());
+ assertEquals(errors, errListener.getErrors().size());
+ assertEquals(warnings, errListener.getWarnings().size());
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParserHandlerTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParserHandlerTest.java
new file mode 100644
index 00000000000..f027f871676
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/jsonld/JSONLDParserHandlerTest.java
@@ -0,0 +1,94 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.jsonld;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Namespace;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.rio.AbstractParserHandlingTest;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.jsonld.JSONLDParser;
+import org.eclipse.rdf4j.rio.jsonld.JSONLDWriter;
+
+/**
+ * Unit tests for {@link JSONLDParser} related to handling of datatypes and
+ * languages.
+ *
+ * @author Peter Ansell
+ */
+public class JSONLDParserHandlerTest extends AbstractParserHandlingTest {
+
+ @Override
+ protected InputStream getUnknownDatatypeStream(Model unknownDatatypeStatements)
+ throws Exception
+ {
+ return writeJSONLD(unknownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getKnownDatatypeStream(Model knownDatatypeStatements)
+ throws Exception
+ {
+ return writeJSONLD(knownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getUnknownLanguageStream(Model unknownLanguageStatements)
+ throws Exception
+ {
+ return writeJSONLD(unknownLanguageStatements);
+ }
+
+ @Override
+ protected InputStream getKnownLanguageStream(Model knownLanguageStatements)
+ throws Exception
+ {
+ return writeJSONLD(knownLanguageStatements);
+ }
+
+ @Override
+ protected RDFParser getParser() {
+ return new JSONLDParser();
+ }
+
+ /**
+ * Helper method to write the given model to JSON-LD and return an
+ * InputStream containing the results.
+ *
+ * @param statements
+ * @return An {@link InputStream} containing the results.
+ * @throws RDFHandlerException
+ */
+ private InputStream writeJSONLD(Model statements)
+ throws RDFHandlerException
+ {
+ final StringWriter writer = new StringWriter();
+
+ final RDFWriter jsonldWriter = new JSONLDWriter(writer);
+ jsonldWriter.startRDF();
+ for (final Namespace prefix : statements.getNamespaces()) {
+ jsonldWriter.handleNamespace(prefix.getPrefix(), prefix.getName());
+ }
+ for (final Statement nextStatement : statements) {
+ jsonldWriter.handleStatement(nextStatement);
+ }
+ jsonldWriter.endRDF();
+
+ // System.out.println(writer.toString());
+
+ return new ByteArrayInputStream(writer.toString().getBytes(Charset.forName("UTF-8")));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/jsonld/JSONLDWriterTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/jsonld/JSONLDWriterTest.java
new file mode 100644
index 00000000000..13b5ad8ea73
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/jsonld/JSONLDWriterTest.java
@@ -0,0 +1,110 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.jsonld;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.impl.LinkedHashModel;
+import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
+import org.eclipse.rdf4j.rio.ParserConfig;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParseException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.RDFWriterTest;
+import org.eclipse.rdf4j.rio.WriterConfig;
+import org.eclipse.rdf4j.rio.helpers.BasicParserSettings;
+import org.eclipse.rdf4j.rio.helpers.JSONLDMode;
+import org.eclipse.rdf4j.rio.helpers.JSONLDSettings;
+import org.eclipse.rdf4j.rio.helpers.StatementCollector;
+import org.eclipse.rdf4j.rio.jsonld.JSONLDParserFactory;
+import org.eclipse.rdf4j.rio.jsonld.JSONLDWriterFactory;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * @author Peter Ansell
+ */
+public class JSONLDWriterTest extends RDFWriterTest {
+
+ public JSONLDWriterTest() {
+ super(new JSONLDWriterFactory(), new JSONLDParserFactory());
+ }
+
+ @Override
+ protected void setupWriterConfig(WriterConfig config) {
+ super.setupWriterConfig(config);
+ config.set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT);
+ }
+
+ @Override
+ protected void setupParserConfig(ParserConfig config) {
+ super.setupParserConfig(config);
+ config.set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true);
+ config.set(BasicParserSettings.FAIL_ON_UNKNOWN_LANGUAGES, true);
+ }
+
+ @Test
+ @Override
+ @Ignore("TODO: Determine why this test is breaking")
+ public void testIllegalPrefix()
+ throws RDFHandlerException, RDFParseException, IOException
+ {
+ }
+
+ @Test
+ public void testRoundTripNamespaces()
+ throws Exception
+ {
+ String exNs = "http://example.org/";
+ IRI uri1 = vf.createIRI(exNs, "uri1");
+ IRI uri2 = vf.createIRI(exNs, "uri2");
+ Literal plainLit = vf.createLiteral("plain", XMLSchema.STRING);
+
+ Statement st1 = vf.createStatement(uri1, uri2, plainLit);
+
+ ByteArrayOutputStream out = new ByteArrayOutputStream();
+ RDFWriter rdfWriter = rdfWriterFactory.getWriter(out);
+ rdfWriter.getWriterConfig().set(JSONLDSettings.JSONLD_MODE, JSONLDMode.COMPACT);
+ rdfWriter.handleNamespace("ex", exNs);
+ rdfWriter.startRDF();
+ rdfWriter.handleStatement(st1);
+ rdfWriter.endRDF();
+
+ ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
+ RDFParser rdfParser = rdfParserFactory.getParser();
+ ParserConfig config = new ParserConfig();
+ config.set(BasicParserSettings.FAIL_ON_UNKNOWN_DATATYPES, true);
+ config.set(BasicParserSettings.FAIL_ON_UNKNOWN_LANGUAGES, true);
+ rdfParser.setParserConfig(config);
+ rdfParser.setValueFactory(vf);
+ Model model = new LinkedHashModel();
+ rdfParser.setRDFHandler(new StatementCollector(model));
+
+ rdfParser.parse(in, "foo:bar");
+
+ assertEquals("Unexpected number of statements, found " + model.size(), 1, model.size());
+
+ assertTrue("missing namespaced statement", model.contains(st1));
+
+ if (rdfParser.getRDFFormat().supportsNamespaces()) {
+ assertTrue("Expected at least one namespace, found " + model.getNamespaces().size(),
+ model.getNamespaces().size() >= 1);
+ assertEquals(exNs, model.getNamespace("ex").get().getName());
+ }
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/n3/N3ParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/n3/N3ParserTest.java
new file mode 100644
index 00000000000..dd06ef277bb
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/n3/N3ParserTest.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.n3;
+
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.n3.N3ParserTestCase;
+import org.eclipse.rdf4j.rio.turtle.TurtleParser;
+import org.junit.Ignore;
+
+import junit.framework.Test;
+
+/**
+ * JUnit test for the N3 parser that uses the tests that are available online.
+ */
+@Ignore("FIXME: This test is badly broken")
+public class N3ParserTest extends N3ParserTestCase {
+
+ public static Test suite()
+ throws Exception
+ {
+ return new N3ParserTest().createTestSuite();
+ }
+
+ @Override
+ protected RDFParser createRDFParser() {
+ return new TurtleParser();
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsEarlReport.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsEarlReport.java
new file mode 100644
index 00000000000..bc5c3bc382f
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsEarlReport.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.nquads;
+
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.rio.EarlReport;
+
+/**
+ * Class for generating EARL reports for N-Quads parser.
+ *
+ * @author Peter Ansell
+ */
+public class NQuadsEarlReport {
+
+ public static void main(String[] args)
+ throws Exception
+ {
+ new EarlReport().generateReport(new NQuadsParserTest().createTestSuite(), EarlReport.ANSELL,
+ SimpleValueFactory.getInstance().createIRI("http://www.w3.org/TR/n-quads/"));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsHandlingTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsHandlingTest.java
new file mode 100644
index 00000000000..02a3f1c5ea2
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsHandlingTest.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.nquads;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.rio.AbstractParserHandlingTest;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.nquads.NQuadsParser;
+import org.eclipse.rdf4j.rio.nquads.NQuadsWriter;
+
+/**
+ * Test for error handling by N-Quads Parser.
+ *
+ * @author Peter Ansell
+ */
+public class NQuadsHandlingTest extends AbstractParserHandlingTest {
+
+ @Override
+ protected InputStream getUnknownDatatypeStream(Model unknownDatatypeStatements)
+ throws Exception
+ {
+ return writeNQuads(unknownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getKnownDatatypeStream(Model knownDatatypeStatements)
+ throws Exception
+ {
+ return writeNQuads(knownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getUnknownLanguageStream(Model unknownLanguageStatements)
+ throws Exception
+ {
+ return writeNQuads(unknownLanguageStatements);
+ }
+
+ @Override
+ protected InputStream getKnownLanguageStream(Model knownLanguageStatements)
+ throws Exception
+ {
+ return writeNQuads(knownLanguageStatements);
+ }
+
+ @Override
+ protected RDFParser getParser() {
+ return new NQuadsParser();
+ }
+
+ /**
+ * Helper method to write the given model to N-Triples and return an
+ * InputStream containing the results.
+ *
+ * @param statements
+ * @return An {@link InputStream} containing the results.
+ * @throws RDFHandlerException
+ */
+ private InputStream writeNQuads(Model statements)
+ throws RDFHandlerException
+ {
+ StringWriter writer = new StringWriter();
+
+ RDFWriter nQuadsWriter = new NQuadsWriter(writer);
+ nQuadsWriter.startRDF();
+ for (Statement nextStatement : statements) {
+ nQuadsWriter.handleStatement(nextStatement);
+ }
+ nQuadsWriter.endRDF();
+
+ return new ByteArrayInputStream(writer.toString().getBytes(Charset.forName("UTF-8")));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserTest.java
new file mode 100644
index 00000000000..9bed6413cbb
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserTest.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.nquads;
+
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.nquads.AbstractNQuadsParserTest;
+import org.eclipse.rdf4j.rio.nquads.NQuadsParser;
+
+import junit.framework.Test;
+
+/**
+ * JUnit test for the N-Quads parser.
+ *
+ * @author Arjohn Kampman
+ */
+public class NQuadsParserTest extends AbstractNQuadsParserTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return new NQuadsParserTest().createTestSuite();
+ }
+
+ @Override
+ protected RDFParser createRDFParser() {
+ return new NQuadsParser();
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserUnitTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserUnitTest.java
new file mode 100644
index 00000000000..4a7752fd0d9
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsParserUnitTest.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.nquads;
+
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.nquads.AbstractNQuadsParserUnitTest;
+import org.eclipse.rdf4j.rio.nquads.NQuadsParser;
+
+/**
+ * JUnit test for the N-Quads parser.
+ *
+ * @author Peter Ansell
+ */
+public class NQuadsParserUnitTest extends AbstractNQuadsParserUnitTest {
+
+ @Override
+ protected RDFParser createRDFParser() {
+ return new NQuadsParser();
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsWriterTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsWriterTest.java
new file mode 100644
index 00000000000..1fa4e97f1b6
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/nquads/NQuadsWriterTest.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.nquads;
+
+import org.eclipse.rdf4j.rio.nquads.AbstractNQuadsWriterTest;
+import org.eclipse.rdf4j.rio.nquads.NQuadsParserFactory;
+import org.eclipse.rdf4j.rio.nquads.NQuadsWriterFactory;
+
+public class NQuadsWriterTest extends AbstractNQuadsWriterTest {
+
+ public NQuadsWriterTest() {
+ super(new NQuadsWriterFactory(), new NQuadsParserFactory());
+ }
+
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesEarlReport.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesEarlReport.java
new file mode 100644
index 00000000000..b100a007c0e
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesEarlReport.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.ntriples;
+
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.rio.EarlReport;
+
+/**
+ * Class for generating EARL reports for N-Quads parser.
+ *
+ * @author Peter Ansell
+ */
+public class NTriplesEarlReport {
+
+ public static void main(String[] args)
+ throws Exception
+ {
+ new EarlReport().generateReport(new NTriplesParserTest().createTestSuite(), EarlReport.ANSELL,
+ SimpleValueFactory.getInstance().createIRI("http://www.w3.org/TR/n-triples/"));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesHandlingTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesHandlingTest.java
new file mode 100644
index 00000000000..63d50e7f1be
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesHandlingTest.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.ntriples;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.rio.AbstractParserHandlingTest;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.ntriples.NTriplesParser;
+import org.eclipse.rdf4j.rio.ntriples.NTriplesWriter;
+
+/**
+ * Test for error handling by N-Triples Parser.
+ *
+ * @author Peter Ansell
+ */
+public class NTriplesHandlingTest extends AbstractParserHandlingTest {
+
+ @Override
+ protected InputStream getUnknownDatatypeStream(Model unknownDatatypeStatements)
+ throws Exception
+ {
+ return writeNTriples(unknownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getKnownDatatypeStream(Model knownDatatypeStatements)
+ throws Exception
+ {
+ return writeNTriples(knownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getUnknownLanguageStream(Model unknownLanguageStatements)
+ throws Exception
+ {
+ return writeNTriples(unknownLanguageStatements);
+ }
+
+ @Override
+ protected InputStream getKnownLanguageStream(Model knownLanguageStatements)
+ throws Exception
+ {
+ return writeNTriples(knownLanguageStatements);
+ }
+
+ @Override
+ protected RDFParser getParser() {
+ return new NTriplesParser();
+ }
+
+ /**
+ * Helper method to write the given model to N-Triples and return an
+ * InputStream containing the results.
+ *
+ * @param statements
+ * @return An {@link InputStream} containing the results.
+ * @throws RDFHandlerException
+ */
+ private InputStream writeNTriples(Model statements)
+ throws RDFHandlerException
+ {
+ StringWriter writer = new StringWriter();
+
+ RDFWriter nTriplesWriter = new NTriplesWriter(writer);
+ nTriplesWriter.startRDF();
+ for (Statement nextStatement : statements) {
+ nTriplesWriter.handleStatement(nextStatement);
+ }
+ nTriplesWriter.endRDF();
+
+ return new ByteArrayInputStream(writer.toString().getBytes(Charset.forName("UTF-8")));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserTest.java
new file mode 100644
index 00000000000..8c19786488b
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserTest.java
@@ -0,0 +1,33 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.ntriples;
+
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.ntriples.AbstractNTriplesParserTest;
+import org.eclipse.rdf4j.rio.ntriples.NTriplesParser;
+
+import junit.framework.Test;
+
+/**
+ * JUnit test for the N-Triples parser.
+ *
+ * @author Arjohn Kampman
+ */
+public class NTriplesParserTest extends AbstractNTriplesParserTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return new NTriplesParserTest().createTestSuite();
+ }
+
+ @Override
+ protected RDFParser createRDFParser() {
+ return new NTriplesParser();
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserUnitTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserUnitTest.java
new file mode 100644
index 00000000000..8b37c4addf6
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesParserUnitTest.java
@@ -0,0 +1,25 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.ntriples;
+
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.ntriples.AbstractNTriplesParserUnitTest;
+import org.eclipse.rdf4j.rio.ntriples.NTriplesParser;
+
+/**
+ * JUnit test for the N-Triples parser.
+ *
+ * @author Arjohn Kampman
+ */
+public class NTriplesParserUnitTest extends AbstractNTriplesParserUnitTest {
+
+ @Override
+ protected RDFParser createRDFParser() {
+ return new NTriplesParser();
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesWriterTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesWriterTest.java
new file mode 100644
index 00000000000..3d1cb488963
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/ntriples/NTriplesWriterTest.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.ntriples;
+
+import org.eclipse.rdf4j.rio.RDFWriterTest;
+import org.eclipse.rdf4j.rio.ntriples.NTriplesParserFactory;
+import org.eclipse.rdf4j.rio.ntriples.NTriplesWriterFactory;
+
+/**
+ * JUnit test for the RDF/JSON parser.
+ * @author Peter Ansell
+ */
+public class NTriplesWriterTest extends RDFWriterTest {
+
+ public NTriplesWriterTest() {
+ super(new NTriplesWriterFactory(), new NTriplesParserFactory());
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONHandlingTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONHandlingTest.java
new file mode 100644
index 00000000000..8d73230b031
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONHandlingTest.java
@@ -0,0 +1,88 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfjson;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.rio.AbstractParserHandlingTest;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.rdfjson.RDFJSONParser;
+import org.eclipse.rdf4j.rio.rdfjson.RDFJSONWriter;
+
+/**
+ * Test for error handling by RDFJSON Parser.
+ *
+ * @author Peter Ansell
+ */
+public class RDFJSONHandlingTest extends AbstractParserHandlingTest {
+
+ @Override
+ protected InputStream getUnknownDatatypeStream(Model unknownDatatypeStatements)
+ throws Exception
+ {
+ return writeRDFJSON(unknownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getKnownDatatypeStream(Model knownDatatypeStatements)
+ throws Exception
+ {
+ return writeRDFJSON(knownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getUnknownLanguageStream(Model unknownLanguageStatements)
+ throws Exception
+ {
+ return writeRDFJSON(unknownLanguageStatements);
+ }
+
+ @Override
+ protected InputStream getKnownLanguageStream(Model knownLanguageStatements)
+ throws Exception
+ {
+ return writeRDFJSON(knownLanguageStatements);
+ }
+
+ @Override
+ protected RDFParser getParser() {
+ return new RDFJSONParser();
+ }
+
+ /**
+ * Helper method to write the given model to RDFJSON and return an
+ * InputStream containing the results.
+ *
+ * @param statements
+ * @return An {@link InputStream} containing the results.
+ * @throws RDFHandlerException
+ */
+ private InputStream writeRDFJSON(Model statements)
+ throws RDFHandlerException
+ {
+ StringWriter writer = new StringWriter();
+
+ RDFWriter rdfjsonWriter = new RDFJSONWriter(writer, RDFFormat.RDFJSON);
+ rdfjsonWriter.startRDF();
+ for (Statement nextStatement : statements) {
+ rdfjsonWriter.handleStatement(nextStatement);
+ }
+ rdfjsonWriter.endRDF();
+
+ return new ByteArrayInputStream(writer.toString().getBytes(Charset.forName("UTF-8")));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONMimeTypeTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONMimeTypeTest.java
new file mode 100644
index 00000000000..935a28110a7
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONMimeTypeTest.java
@@ -0,0 +1,37 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfjson;
+
+import static org.junit.Assert.*;
+
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.Rio;
+import org.junit.Test;
+
+/**
+ * @author Peter Ansell
+ */
+public class RDFJSONMimeTypeTest {
+
+ @Test
+ public void testApplicationRDFJSON() {
+ assertEquals(
+ RDFFormat.RDFJSON,
+ Rio.getParserFormatForMIMEType("application/rdf+json").orElseThrow(
+ Rio.unsupportedFormat(RDFFormat.RDFJSON)));
+ }
+
+ @Test
+ public void testApplicationRDFJSONUtf8() {
+ assertEquals(
+ RDFFormat.RDFJSON,
+ Rio.getParserFormatForMIMEType("application/rdf+json;charset=UTF-8").orElseThrow(
+ Rio.unsupportedFormat(RDFFormat.RDFJSON)));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserCustomTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserCustomTest.java
new file mode 100644
index 00000000000..7fd5f96a07c
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserCustomTest.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfjson;
+
+import static org.junit.Assert.*;
+
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.Rio;
+import org.junit.Test;
+
+/**
+ * Custom (non-manifest) tests for RDF/JSON parser.
+ *
+ * @author Peter Ansell
+ */
+public class RDFJSONParserCustomTest {
+
+ @Test
+ public void testSupportedSettings()
+ throws Exception
+ {
+ assertEquals(17, Rio.createParser(RDFFormat.RDFJSON).getSupportedSettings().size());
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserTest.java
new file mode 100644
index 00000000000..85742efea9e
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONParserTest.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfjson;
+
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.rdfjson.RDFJSONParser;
+import org.eclipse.rdf4j.rio.rdfjson.RDFJSONParserTestCase;
+
+/**
+ * JUnit test for the RDF/JSON parser.
+ *
+ * @author Peter Ansell
+ */
+public class RDFJSONParserTest extends RDFJSONParserTestCase {
+
+ public static junit.framework.Test suite()
+ throws Exception
+ {
+ return new RDFJSONParserTest().createTestSuite();
+ }
+
+ @Override
+ protected RDFParser createRDFParser() {
+ return new RDFJSONParser();
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONWriterTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONWriterTest.java
new file mode 100644
index 00000000000..f9c033aa2f7
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfjson/RDFJSONWriterTest.java
@@ -0,0 +1,23 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfjson;
+
+import org.eclipse.rdf4j.rio.RDFWriterTest;
+import org.eclipse.rdf4j.rio.rdfjson.RDFJSONParserFactory;
+import org.eclipse.rdf4j.rio.rdfjson.RDFJSONWriterFactory;
+
+/**
+ * JUnit test for the RDF/JSON parser.
+ * @author Peter Ansell
+ */
+public class RDFJSONWriterTest extends RDFWriterTest {
+
+ public RDFJSONWriterTest() {
+ super(new RDFJSONWriterFactory(), new RDFJSONParserFactory());
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLHandlingTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLHandlingTest.java
new file mode 100644
index 00000000000..f20f7227f7f
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLHandlingTest.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfxml;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.rio.AbstractParserHandlingTest;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.rdfxml.RDFXMLParser;
+import org.eclipse.rdf4j.rio.rdfxml.RDFXMLWriter;
+
+/**
+ * Test for error handling by RDFXML Parser.
+ *
+ * @author Peter Ansell
+ */
+public class RDFXMLHandlingTest extends AbstractParserHandlingTest {
+
+ @Override
+ protected InputStream getUnknownDatatypeStream(Model unknownDatatypeStatements)
+ throws Exception
+ {
+ return writeRDFXML(unknownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getKnownDatatypeStream(Model knownDatatypeStatements)
+ throws Exception
+ {
+ return writeRDFXML(knownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getUnknownLanguageStream(Model unknownLanguageStatements)
+ throws Exception
+ {
+ return writeRDFXML(unknownLanguageStatements);
+ }
+
+ @Override
+ protected InputStream getKnownLanguageStream(Model knownLanguageStatements)
+ throws Exception
+ {
+ return writeRDFXML(knownLanguageStatements);
+ }
+
+ @Override
+ protected RDFParser getParser() {
+ return new RDFXMLParser();
+ }
+
+ /**
+ * Helper method to write the given model to RDFXML and return an InputStream
+ * containing the results.
+ *
+ * @param statements
+ * @return An {@link InputStream} containing the results.
+ * @throws RDFHandlerException
+ */
+ private InputStream writeRDFXML(Model statements)
+ throws RDFHandlerException
+ {
+ StringWriter writer = new StringWriter();
+
+ RDFWriter rdfxmlWriter = new RDFXMLWriter(writer);
+ rdfxmlWriter.startRDF();
+ for (Statement nextStatement : statements) {
+ rdfxmlWriter.handleStatement(nextStatement);
+ }
+ rdfxmlWriter.endRDF();
+
+ return new ByteArrayInputStream(writer.toString().getBytes(Charset.forName("UTF-8")));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLParserCustomTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLParserCustomTest.java
new file mode 100644
index 00000000000..09955b9c6ae
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLParserCustomTest.java
@@ -0,0 +1,217 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfxml;
+
+import static org.junit.Assert.*;
+
+import java.io.StringReader;
+
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.impl.LinkedHashModel;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.rio.ParserConfig;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFParseException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.Rio;
+import org.eclipse.rdf4j.rio.RDFParser.DatatypeHandling;
+import org.eclipse.rdf4j.rio.helpers.StatementCollector;
+import org.eclipse.rdf4j.rio.helpers.XMLParserSettings;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * Custom tests for RDFXML Parser.
+ *
+ * @author Michael Grove
+ */
+public class RDFXMLParserCustomTest {
+
+ /**
+ * Test with the default ParserConfig settings. Ie, setParserConfig is not
+ * called.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testEntityExpansionDefaultSettings()
+ throws Exception
+ {
+ final Model aGraph = new LinkedHashModel();
+ RDFParser aParser = Rio.createParser(RDFFormat.RDFXML);
+ aParser.setRDFHandler(new StatementCollector(aGraph));
+
+ try {
+ // this should trigger a SAX parse exception that will blow up at the
+ // 64k
+ // entity limit rather than OOMing
+ aParser.parse(
+ this.getClass().getResourceAsStream("/testcases/rdfxml/openrdf/bad-entity-expansion-limit.rdf"),
+ "http://example.org");
+ fail("Parser did not throw an exception");
+ }
+ catch (RDFParseException e) {
+ // assertTrue(e.getMessage().contains(
+ // "The parser has encountered more than \"64,000\" entity expansions in this document; this is the limit imposed by the "));
+ }
+ }
+
+ /**
+ * Test with unrelated ParserConfig settings
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testEntityExpansionUnrelatedSettings()
+ throws Exception
+ {
+ final Model aGraph = new LinkedHashModel();
+ RDFParser aParser = Rio.createParser(RDFFormat.RDFXML);
+ aParser.setRDFHandler(new StatementCollector(aGraph));
+
+ ParserConfig config = new ParserConfig();
+ aParser.setParserConfig(config);
+
+ try {
+ // this should trigger a SAX parse exception that will blow up at the
+ // 64k entity limit rather than OOMing
+ aParser.parse(
+ this.getClass().getResourceAsStream("/testcases/rdfxml/openrdf/bad-entity-expansion-limit.rdf"),
+ "http://example.org");
+ fail("Parser did not throw an exception");
+ }
+ catch (RDFParseException e) {
+ // assertTrue(e.getMessage().contains(
+ // "The parser has encountered more than \"64,000\" entity expansions in this document; this is the limit imposed by the "));
+ }
+ }
+
+ /**
+ * Test with Secure processing setting on.
+ *
+ * @throws Exception
+ */
+ @Test
+ public void testEntityExpansionSecureProcessing()
+ throws Exception
+ {
+ final Model aGraph = new LinkedHashModel();
+ RDFParser aParser = Rio.createParser(RDFFormat.RDFXML);
+ aParser.setRDFHandler(new StatementCollector(aGraph));
+
+ ParserConfig config = new ParserConfig();
+ config.set(XMLParserSettings.SECURE_PROCESSING, true);
+ aParser.setParserConfig(config);
+
+ try {
+ // this should trigger a SAX parse exception that will blow up at the
+ // 64k entity limit rather than OOMing
+ aParser.parse(
+ this.getClass().getResourceAsStream("/testcases/rdfxml/openrdf/bad-entity-expansion-limit.rdf"),
+ "http://example.org");
+ fail("Parser did not throw an exception");
+ }
+ catch (RDFParseException e) {
+ // assertTrue(e.getMessage().contains(
+ // "The parser has encountered more than \"64,000\" entity expansions in this document; this is the limit imposed by the "));
+ }
+ }
+
+ /**
+ * Test with Secure processing setting off.
+ *
+ * IMPORTANT: Only turn this on to verify it is still working, as there is no
+ * way to safely perform this test.
+ *
+ * WARNING: This test will cause an OutOfMemoryException when it eventually
+ * fails, as it will eventually fail.
+ *
+ * @throws Exception
+ */
+ @Ignore
+ @Test(timeout = 10000)
+ public void testEntityExpansionNoSecureProcessing()
+ throws Exception
+ {
+ final Model aGraph = new LinkedHashModel();
+ RDFParser aParser = Rio.createParser(RDFFormat.RDFXML);
+ aParser.setRDFHandler(new StatementCollector(aGraph));
+
+ ParserConfig config = new ParserConfig();
+ config.set(XMLParserSettings.SECURE_PROCESSING, false);
+ aParser.setParserConfig(config);
+
+ try {
+ // IMPORTANT: This will not use the entity limit
+ aParser.parse(
+ this.getClass().getResourceAsStream("/testcases/rdfxml/openrdf/bad-entity-expansion-limit.rdf"),
+ "http://example.org");
+ fail("Parser did not throw an exception");
+ }
+ catch (RDFParseException e) {
+ // assertTrue(e.getMessage().contains(
+ // "The parser has encountered more than \"64,000\" entity expansions in this document; this is the limit imposed by the"));
+ }
+ }
+
+ @Test
+ public void testParseCollection()
+ throws Exception
+ {
+ // Example from:
+ // http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-parsetype-Collection
+ StringBuilder string = new StringBuilder();
+ string.append("\n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append("");
+
+ Model parse = Rio.parse(new StringReader(string.toString()), "", RDFFormat.RDFXML);
+ Rio.write(parse, System.out, RDFFormat.NTRIPLES);
+ assertEquals(7, parse.size());
+ assertEquals(3, parse.filter(null, RDF.FIRST, null).size());
+ assertEquals(3, parse.filter(null, RDF.REST, null).size());
+ assertEquals(1, parse.filter(null, null, RDF.NIL).size());
+ }
+
+ @Test
+ public void testParseCommentAtStart()
+ throws Exception
+ {
+ // Example from:
+ // http://www.w3.org/TR/rdf-syntax-grammar/#section-Syntax-parsetype-Collection
+ StringBuilder string = new StringBuilder();
+ string.append("\n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append(" Mango\n");
+ string.append(" \n");
+ string.append(" \n");
+ string.append("");
+
+ Model parse = Rio.parse(new StringReader(string.toString()), "", RDFFormat.RDFXML);
+ Rio.write(parse, System.out, RDFFormat.NTRIPLES);
+ assertEquals(1, parse.size());
+ }
+
+ @Test
+ public void testSupportedSettings()
+ throws Exception
+ {
+ assertEquals(21, Rio.createParser(RDFFormat.RDFXML).getSupportedSettings().size());
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLParserTest.java
new file mode 100644
index 00000000000..3038311d11a
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLParserTest.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfxml;
+
+import org.eclipse.rdf4j.rio.rdfxml.RDFXMLParser;
+import org.eclipse.rdf4j.rio.rdfxml.RDFXMLParserTest;
+import org.eclipse.rdf4j.rio.rdfxml.RDFXMLParserTestCase;
+
+import junit.framework.Test;
+
+/**
+ * JUnit test for the RDF/XML parser that uses the test manifest that is
+ * available online.
+ */
+public class RDFXMLParserTest extends RDFXMLParserTestCase {
+
+ public static Test suite()
+ throws Exception
+ {
+ return new RDFXMLParserTest().createTestSuite();
+ }
+
+ @Override
+ protected RDFXMLParser createRDFParser() {
+ RDFXMLParser rdfxmlParser = new RDFXMLParser();
+ rdfxmlParser.setParseStandAloneDocuments(true);
+ return rdfxmlParser;
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLPrettyWriterTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLPrettyWriterTest.java
new file mode 100644
index 00000000000..8d687a56852
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/rdfxml/RDFXMLPrettyWriterTest.java
@@ -0,0 +1,135 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.rdfxml;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.regex.Pattern;
+
+import org.apache.commons.io.IOUtils;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.rdfxml.RDFXMLParserFactory;
+import org.eclipse.rdf4j.rio.rdfxml.RDFXMLWriterTestCase;
+import org.eclipse.rdf4j.rio.rdfxml.util.RDFXMLPrettyWriterFactory;
+import org.junit.Test;
+
+public class RDFXMLPrettyWriterTest extends RDFXMLWriterTestCase {
+
+ private static ValueFactory vf = SimpleValueFactory.getInstance();
+
+ public RDFXMLPrettyWriterTest() {
+ super(new RDFXMLPrettyWriterFactory(), new RDFXMLParserFactory());
+ }
+
+ /**
+ * Extract lines that start an rdf element so basic assertions can be made.
+ */
+ private static List rdfOpenTags(String s)
+ throws IOException
+ {
+ String withoutSpaces = Pattern.compile("^\\s+", Pattern.MULTILINE).matcher(s).replaceAll("");
+
+ List rdfLines = new ArrayList();
+
+ for (String l : IOUtils.readLines(new StringReader(withoutSpaces))) {
+ if (l.startsWith(" rdfLines = rdfOpenTags(writer.toString());
+
+ assertEquals(Arrays.asList(" rdfLines = rdfOpenTags(writer.toString());
+
+ assertEquals(Arrays.asList(" rdfLines = rdfOpenTags(writer.toString());
+
+ assertEquals(Arrays.asList(" { [] \"Foo\" }"), "",
+ RDFFormat.TRIG);
+ }
+
+ @Test
+ public void testTrailingSemicolon()
+ throws Exception
+ {
+ Rio.parse(new StringReader("{ ;}"), "",
+ RDFFormat.TRIG);
+ }
+
+ @Test
+ public void testAnonymousGraph1()
+ throws Exception
+ {
+ Rio.parse(new StringReader("PREFIX : \n GRAPH [] { :s :p :o }"), "", RDFFormat.TRIG);
+ }
+
+ @Test
+ public void testAnonymousGraph2()
+ throws Exception
+ {
+ Rio.parse(new StringReader("PREFIX : \n [] { :s :p :o }"), "", RDFFormat.TRIG);
+ }
+
+ @Test
+ public void testTurtle()
+ throws Exception
+ {
+ Rio.parse(new StringReader(" "), "", RDFFormat.TRIG);
+ }
+
+ @Test
+ public void testMinimalWhitespace()
+ throws Exception
+ {
+ Rio.parse(
+ this.getClass().getResourceAsStream("/testcases/trig/trig-syntax-minimal-whitespace-01.trig"),
+ "", RDFFormat.TRIG);
+ }
+
+ @Test
+ public void testMinimalWhitespaceLine12()
+ throws Exception
+ {
+ Rio.parse(new StringReader("@prefix : . {_:s:p :o ._:s:p\"Alice\". _:s:p _:o .}"),
+ "", RDFFormat.TRIG);
+ }
+
+ @Test
+ public void testBadPname02()
+ throws Exception
+ {
+ try {
+ Rio.parse(new StringReader("@prefix : . {:a%2 :p :o .}"), "", RDFFormat.TRIG);
+ fail("Did not receive expected exception");
+ }
+ catch (RDFParseException e) {
+
+ }
+ }
+
+ @Test
+ public void testSupportedSettings()
+ throws Exception
+ {
+ assertEquals(12, Rio.createParser(RDFFormat.TRIG).getSupportedSettings().size());
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/trig/TriGParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/trig/TriGParserTest.java
new file mode 100644
index 00000000000..6caebde2f21
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/trig/TriGParserTest.java
@@ -0,0 +1,35 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.trig;
+
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.nquads.NQuadsParser;
+import org.eclipse.rdf4j.rio.trig.TriGParser;
+import org.eclipse.rdf4j.rio.trig.TriGParserTestCase;
+
+/**
+ * JUnit test for the TriG parser.
+ */
+public class TriGParserTest extends TriGParserTestCase {
+
+ public static junit.framework.Test suite()
+ throws Exception
+ {
+ return new TriGParserTest().createTestSuite();
+ }
+
+ @Override
+ protected RDFParser createTriGParser() {
+ return new TriGParser();
+ }
+
+ @Override
+ protected RDFParser createNQuadsParser() {
+ return new NQuadsParser();
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/trig/TriGWriterTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/trig/TriGWriterTest.java
new file mode 100644
index 00000000000..633fdefbd56
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/trig/TriGWriterTest.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.trig;
+
+import org.eclipse.rdf4j.rio.RDFWriterTest;
+import org.eclipse.rdf4j.rio.trig.TriGParserFactory;
+import org.eclipse.rdf4j.rio.trig.TriGWriterFactory;
+
+/**
+ * @author Arjohn Kampman
+ */
+public class TriGWriterTest extends RDFWriterTest {
+
+ public TriGWriterTest() {
+ super(new TriGWriterFactory(), new TriGParserFactory());
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/CustomTurtleParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/CustomTurtleParserTest.java
new file mode 100644
index 00000000000..6c7e0e67cc4
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/CustomTurtleParserTest.java
@@ -0,0 +1,494 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.turtle;
+
+import static org.junit.Assert.*;
+
+import java.io.StringReader;
+import java.io.StringWriter;
+import java.util.Collections;
+
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Namespace;
+import org.eclipse.rdf4j.model.URI;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.LinkedHashModel;
+import org.eclipse.rdf4j.model.impl.NamespaceImpl;
+import org.eclipse.rdf4j.model.impl.ValueFactoryImpl;
+import org.eclipse.rdf4j.model.util.Models;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.SKOS;
+import org.eclipse.rdf4j.rio.ParserConfig;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFParseException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.Rio;
+import org.eclipse.rdf4j.rio.helpers.BasicParserSettings;
+import org.eclipse.rdf4j.rio.helpers.ParseErrorCollector;
+import org.eclipse.rdf4j.rio.helpers.ParseErrorLogger;
+import org.eclipse.rdf4j.rio.helpers.StatementCollector;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.Timeout;
+
+/**
+ * Custom tests for Turtle Parser
+ *
+ * @author Peter Ansell
+ */
+public class CustomTurtleParserTest {
+
+ @Rule
+ public Timeout timeout = new Timeout(1000000);
+
+ private ValueFactory vf;
+
+ private ParserConfig settingsNoVerifyLangTag;
+
+ private ParseErrorCollector errors;
+
+ private RDFParser parser;
+
+ private StatementCollector statementCollector;
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp()
+ throws Exception
+ {
+ vf = ValueFactoryImpl.getInstance();
+ settingsNoVerifyLangTag = new ParserConfig();
+ settingsNoVerifyLangTag.set(BasicParserSettings.VERIFY_LANGUAGE_TAGS, false);
+ errors = new ParseErrorCollector();
+ parser = Rio.createParser(RDFFormat.TURTLE);
+ statementCollector = new StatementCollector(new LinkedHashModel());
+ parser.setRDFHandler(statementCollector);
+ }
+
+ @Test
+ public void testSES1887NoLangTagFailure()
+ throws Exception
+ {
+ try {
+ Rio.parse(new StringReader(" \"Foo\"@."), "", RDFFormat.TURTLE);
+ fail("Did not receive an exception");
+ }
+ catch (RDFParseException e) {
+ assertTrue(e.getMessage().contains("Expected a letter, found '.'"));
+ }
+ }
+
+ @Test
+ public void testSES1887NoLangTagFailure2()
+ throws Exception
+ {
+ try {
+ // NOTE: Bad things may happen when VERIFY_LANGUAGE_TAGS is turned off
+ // on a file of this structure
+ Rio.parse(new StringReader(" \"Foo\"@."), "", RDFFormat.TURTLE,
+ settingsNoVerifyLangTag, vf, errors);
+ fail("Did not receive an exception");
+ }
+ catch (RDFParseException e) {
+ assertTrue(e.getMessage().contains("Unexpected end of file"));
+ }
+ }
+
+ @Test
+ public void testSES1887Whitespace()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" \"Foo\"@fr-FR ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(null, null, vf.createLiteral("Foo", "fr-FR")));
+ }
+
+ @Test
+ public void testSES1887Period()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" \"Foo\"@fr-FR."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(null, null, vf.createLiteral("Foo", "fr-FR")));
+ }
+
+ @Test
+ public void testSES1887Semicolon()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(
+ " \"Foo\"@fr-FR;\"Blah\"@en-AU."),
+ "", RDFFormat.TURTLE);
+
+ assertEquals(2, model.size());
+ assertTrue(model.contains(null, null, vf.createLiteral("Foo", "fr-FR")));
+ assertTrue(model.contains(null, null, vf.createLiteral("Blah", "en-AU")));
+ }
+
+ @Test
+ public void testSES1887Comma()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(
+ " \"Foo\"@fr-FR,\"Blah\"@en-AU."), "", RDFFormat.TURTLE);
+
+ assertEquals(2, model.size());
+ assertTrue(model.contains(null, null, vf.createLiteral("Foo", "fr-FR")));
+ assertTrue(model.contains(null, null, vf.createLiteral("Blah", "en-AU")));
+ }
+
+ @Test
+ public void testSES1887CloseParentheses()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" (\"Foo\"@fr-FR)."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(3, model.size());
+ assertTrue(model.contains(null, null, vf.createLiteral("Foo", "fr-FR")));
+ }
+
+ @Test
+ public void testSES1887CloseSquareBracket()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader("[ \"Foo\"@fr-FR]."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(null, null, vf.createLiteral("Foo", "fr-FR")));
+ }
+
+ @Test
+ public void testLiteralWithNewlines()
+ throws Exception
+ {
+ String namespace = "http://www.foo.com/bar#";
+ String okLiteralString = "Literal \n without \n new line at the beginning. \n ";
+ String errLiteralString = "\n Literal \n with \n new line at the beginning. \n ";
+
+ URI mySubject = vf.createURI(namespace, "Subject");
+ URI myPredicate = vf.createURI(namespace, "Predicate");
+ Literal myOkObject = vf.createLiteral(okLiteralString);
+ Literal myErrObject = vf.createLiteral(errLiteralString);
+
+ StringWriter out = new StringWriter();
+ Model model = new LinkedHashModel();
+ model.add(mySubject, myPredicate, myOkObject);
+ model.add(mySubject, myPredicate, myErrObject);
+ Rio.write(model, out, RDFFormat.TURTLE);
+
+ String str = out.toString();
+
+ System.err.println(str);
+
+ assertTrue("okLiteralString not found", str.contains(okLiteralString));
+ assertTrue("errLiteralString not found", str.contains(errLiteralString));
+ }
+
+ @Test
+ public void testSupportedSettings()
+ throws Exception
+ {
+ assertEquals(12, parser.getSupportedSettings().size());
+ }
+
+ @Test
+ public void testSES1988BlankNodePeriodEOF()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" _:blank."), "", RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ }
+
+ @Test
+ public void testSES1988BlankNodePeriodSpace()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" _:blank. "), "", RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ }
+
+ @Test
+ public void testSES1988BlankNodePeriodTab()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" _:blank.\t"), "", RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ }
+
+ @Test
+ public void testSES1988BlankNodePeriodNewLine()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" _:blank.\n"), "", RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ }
+
+ @Test
+ public void testSES1988BlankNodePeriodCarriageReturn()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" _:blank.\r"), "", RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ }
+
+ @Test
+ public void testSES1988BlankNodePeriodURI()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" _:blank. ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(2, model.size());
+ }
+
+ @Test
+ public void testSES1988BlankNodePeriodBNode()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" _:blank._:blank ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(2, model.size());
+ }
+
+ @Test
+ public void testSES2013BlankNodeSemiColonBNodeSpaceA()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" a _:c2; a ."), "", RDFFormat.TURTLE);
+
+ assertEquals(2, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), RDF.TYPE, vf.createURI("urn:b")));
+ }
+
+ @Test
+ public void testSES2013BlankNodeSemiColonBNodeA()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" a _:c2;a ."), "", RDFFormat.TURTLE);
+
+ assertEquals(2, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), RDF.TYPE, vf.createURI("urn:b")));
+ }
+
+ @Test
+ public void testSES2013BlankNodeSemiColonBNodeSpaceURI()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" a _:c2; ."), "", RDFFormat.TURTLE);
+
+ assertEquals(2, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), vf.createURI("urn:b"), vf.createURI("urn:c")));
+ }
+
+ @Test
+ public void testSES2013BlankNodeSemiColonBNodeURI()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" a _:c2; ."), "", RDFFormat.TURTLE);
+
+ assertEquals(2, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), vf.createURI("urn:b"), vf.createURI("urn:c")));
+ }
+
+ @Test
+ public void testSES2019ParseLongLiterals()
+ throws Exception
+ {
+ parser.parse(this.getClass().getResourceAsStream("/testcases/turtle/turtle-long-literals-test.ttl"), "");
+
+ assertTrue(errors.getWarnings().isEmpty());
+ assertTrue(errors.getErrors().isEmpty());
+ assertTrue(errors.getFatalErrors().isEmpty());
+
+ assertFalse(statementCollector.getStatements().isEmpty());
+ assertEquals(5, statementCollector.getStatements().size());
+
+ Models.isomorphic(statementCollector.getStatements(), Rio.parse(
+ this.getClass().getResourceAsStream("/testcases/turtle/turtle-long-literals-test.nt"), "",
+ RDFFormat.NTRIPLES));
+ }
+
+ @Test
+ public void testSES2086PeriodEndingLocalNamesFailure1()
+ throws Exception
+ {
+ try {
+ Rio.parse(new StringReader(
+ "@prefix : .\n :test. ."), "",
+ RDFFormat.TURTLE);
+ fail("Did not receive an exception");
+ }
+ catch (RDFParseException e) {
+ System.out.println(e.getMessage());
+ assertTrue(e.getMessage().contains("Object for statement missing"));
+ }
+ }
+
+ @Test
+ public void testSES2086PeriodEndingLocalNamesFailure2()
+ throws Exception
+ {
+ try {
+ Rio.parse(
+ new StringReader(
+ "@prefix ns: . ns:uriWithDot. a ns:Product ; ns:title \"An example subject ending with a dot.\" . "),
+ "", RDFFormat.TURTLE);
+ fail("Did not receive an exception");
+ }
+ catch (RDFParseException e) {
+ System.out.println(e.getMessage());
+ assertTrue(e.getMessage().contains(
+ "Illegal predicate value: \"\"^^"));
+ }
+ }
+
+ @Test
+ public void testSES2086PeriodEndingLocalNamesFailure3()
+ throws Exception
+ {
+ try {
+ Rio.parse(
+ new StringReader(
+ "@prefix ns: . ns:1 a ns:Product ; ns:affects ns:4 , ns:16 , ns:uriWithDot. ; ns:title \"An example entity with uriWithDot as an object\" . "),
+ "", RDFFormat.TURTLE);
+ fail("Did not receive an exception");
+ }
+ catch (RDFParseException e) {
+ System.out.println(e.getMessage());
+ assertTrue(e.getMessage().contains("Expected an RDF value here, found ';'"));
+ }
+ }
+
+ @Test
+ public void testSES2086PeriodEndingLocalNamesFailure4()
+ throws Exception
+ {
+ try {
+ Rio.parse(
+ new StringReader(
+ "@prefix ns: . ns:1 a ns:uriWithDot. ; ns:title \"An example entity with uriWithDot as an object\" . "),
+ "", RDFFormat.TURTLE);
+ fail("Did not receive an exception");
+ }
+ catch (RDFParseException e) {
+ System.out.println(e.getMessage());
+ assertTrue(e.getMessage().contains("Expected an RDF value here, found ';'"));
+ }
+ }
+
+ @Test
+ public void testSES2165LiteralSpaceDatatypeNewline()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" \"testliteral\"^^\n ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), vf.createURI("urn:b"),
+ vf.createLiteral("testliteral", vf.createURI("urn:datatype"))));
+ }
+
+ @Test
+ public void testSES2165LiteralSpaceDatatypeTab()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" \"testliteral\"^^\t ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), vf.createURI("urn:b"),
+ vf.createLiteral("testliteral", vf.createURI("urn:datatype"))));
+ }
+
+ @Test
+ public void testSES2165LiteralSpaceDatatypeCarriageReturn()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" \"testliteral\"^^\r ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), vf.createURI("urn:b"),
+ vf.createLiteral("testliteral", vf.createURI("urn:datatype"))));
+ }
+
+ @Test
+ public void testSES2165LiteralSpaceDatatypeSpace()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" \"testliteral\"^^ ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), vf.createURI("urn:b"),
+ vf.createLiteral("testliteral", vf.createURI("urn:datatype"))));
+ }
+
+ @Test
+ public void testSES2165LiteralSpaceDatatypeComment()
+ throws Exception
+ {
+ Model model = Rio.parse(new StringReader(" \"testliteral\"^^#comment\n ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), vf.createURI("urn:b"),
+ vf.createLiteral("testliteral", vf.createURI("urn:datatype"))));
+ }
+
+ @Test
+ public void testParsingDefaultNamespaces() throws Exception {
+ Model model = Rio.parse(new StringReader(" skos:broader ."), "",
+ RDFFormat.TURTLE);
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), SKOS.BROADER, vf.createURI("urn:b")));
+ }
+
+ @Test
+ public void testParsingNamespacesWithOption() throws Exception {
+ ParserConfig aConfig = new ParserConfig();
+
+ aConfig.set(BasicParserSettings.NAMESPACES, Collections.singleton(new NamespaceImpl("foo", SKOS.NAMESPACE)));
+
+ Model model = Rio.parse(new StringReader(" foo:broader ."), "", RDFFormat.TURTLE, aConfig, vf, new ParseErrorLogger());
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), SKOS.BROADER, vf.createURI("urn:b")));
+ }
+
+ @Test
+ public void testParsingNamespacesWithOverride() throws Exception {
+ ParserConfig aConfig = new ParserConfig();
+
+ aConfig.set(BasicParserSettings.NAMESPACES, Collections.singleton(new NamespaceImpl("foo", SKOS.NAMESPACE)));
+
+ Model model = Rio.parse(new StringReader("@prefix skos : ." +
+ " skos:broader ."), "",
+ RDFFormat.TURTLE, aConfig, vf, new ParseErrorLogger());
+
+ assertEquals(1, model.size());
+ assertTrue(model.contains(vf.createURI("urn:a"), vf.createURI("urn:not_skos:broader"), vf.createURI("urn:b")));
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleEarlReport.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleEarlReport.java
new file mode 100644
index 00000000000..e42c8edbd35
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleEarlReport.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.turtle;
+
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.rio.EarlReport;
+
+/**
+ * Class for generating EARL reports for Turtle parser.
+ *
+ * @author Peter Ansell
+ */
+public class TurtleEarlReport {
+
+ public static void main(String[] args)
+ throws Exception
+ {
+ new EarlReport().generateReport(new TurtleParserTest().createTestSuite(), EarlReport.ANSELL,
+ SimpleValueFactory.getInstance().createIRI("http://www.w3.org/TR/turtle/"));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleHandlingTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleHandlingTest.java
new file mode 100644
index 00000000000..658fdf8a62e
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleHandlingTest.java
@@ -0,0 +1,87 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.turtle;
+
+import java.io.ByteArrayInputStream;
+import java.io.InputStream;
+import java.io.StringWriter;
+import java.nio.charset.Charset;
+
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.rio.AbstractParserHandlingTest;
+import org.eclipse.rdf4j.rio.RDFHandlerException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.RDFWriter;
+import org.eclipse.rdf4j.rio.turtle.TurtleParser;
+import org.eclipse.rdf4j.rio.turtle.TurtleWriter;
+
+/**
+ * Test for error handling by Turtle Parser.
+ *
+ * @author Peter Ansell
+ */
+public class TurtleHandlingTest extends AbstractParserHandlingTest {
+
+ @Override
+ protected InputStream getUnknownDatatypeStream(Model unknownDatatypeStatements)
+ throws Exception
+ {
+ return writeTurtle(unknownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getKnownDatatypeStream(Model knownDatatypeStatements)
+ throws Exception
+ {
+ return writeTurtle(knownDatatypeStatements);
+ }
+
+ @Override
+ protected InputStream getUnknownLanguageStream(Model unknownLanguageStatements)
+ throws Exception
+ {
+ return writeTurtle(unknownLanguageStatements);
+ }
+
+ @Override
+ protected InputStream getKnownLanguageStream(Model knownLanguageStatements)
+ throws Exception
+ {
+ return writeTurtle(knownLanguageStatements);
+ }
+
+ @Override
+ protected RDFParser getParser() {
+ return new TurtleParser();
+ }
+
+ /**
+ * Helper method to write the given model to Turtle and return an InputStream
+ * containing the results.
+ *
+ * @param statements
+ * @return An {@link InputStream} containing the results.
+ * @throws RDFHandlerException
+ */
+ private InputStream writeTurtle(Model statements)
+ throws RDFHandlerException
+ {
+ StringWriter writer = new StringWriter();
+
+ RDFWriter turtleWriter = new TurtleWriter(writer);
+ turtleWriter.startRDF();
+ for (Statement nextStatement : statements) {
+ turtleWriter.handleStatement(nextStatement);
+ }
+ turtleWriter.endRDF();
+
+ return new ByteArrayInputStream(writer.toString().getBytes(Charset.forName("UTF-8")));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleMimeTypeTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleMimeTypeTest.java
new file mode 100644
index 00000000000..6ab78b0d9e0
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleMimeTypeTest.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.turtle;
+
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.Rio;
+
+import junit.framework.TestCase;
+
+/**
+ * @author James Leigh
+ */
+public class TurtleMimeTypeTest extends TestCase {
+
+ public void testTextTurtle() {
+ assertEquals(
+ RDFFormat.TURTLE,
+ Rio.getParserFormatForMIMEType("text/turtle").orElseThrow(Rio.unsupportedFormat(RDFFormat.TURTLE)));
+ }
+
+ public void testTextTurtleUtf8() {
+ assertEquals(
+ RDFFormat.TURTLE,
+ Rio.getParserFormatForMIMEType("text/turtle;charset=UTF-8").orElseThrow(
+ Rio.unsupportedFormat(RDFFormat.TURTLE)));
+ }
+
+ public void testApplicationXTurtle() {
+ assertEquals(
+ RDFFormat.TURTLE,
+ Rio.getParserFormatForMIMEType("application/x-turtle").orElseThrow(
+ Rio.unsupportedFormat(RDFFormat.TURTLE)));
+ }
+
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleParserTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleParserTest.java
new file mode 100644
index 00000000000..2772287154e
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleParserTest.java
@@ -0,0 +1,40 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.turtle;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.helpers.TurtleParserSettings;
+import org.eclipse.rdf4j.rio.ntriples.NTriplesParser;
+import org.eclipse.rdf4j.rio.turtle.TurtleParser;
+import org.eclipse.rdf4j.rio.turtle.TurtleParserTestCase;
+
+/**
+ * JUnit test for the Turtle parser that uses the tests that are available online.
+ */
+public class TurtleParserTest extends TurtleParserTestCase {
+
+ public static Test suite()
+ throws Exception
+ {
+ return new TurtleParserTest().createTestSuite();
+ }
+
+ @Override
+ protected RDFParser createTurtleParser() {
+ RDFParser result = new TurtleParser();
+ return result;
+ }
+
+ @Override
+ protected RDFParser createNTriplesParser() {
+ return new NTriplesParser();
+ }
+}
diff --git a/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleWriterTest.java b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleWriterTest.java
new file mode 100644
index 00000000000..c74036cf892
--- /dev/null
+++ b/compliance/rio/src/test/java/org/eclipse/rdf4j/rio/turtle/TurtleWriterTest.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.rio.turtle;
+
+import org.eclipse.rdf4j.rio.RDFWriterTest;
+import org.eclipse.rdf4j.rio.turtle.TurtleParserFactory;
+import org.eclipse.rdf4j.rio.turtle.TurtleWriterFactory;
+
+/**
+ * @author Arjohn Kampman
+ */
+public class TurtleWriterTest extends RDFWriterTest {
+
+ public TurtleWriterTest() {
+ super(new TurtleWriterFactory(), new TurtleParserFactory());
+ }
+}
diff --git a/compliance/rio/src/test/resources/logback-test.xml b/compliance/rio/src/test/resources/logback-test.xml
new file mode 100644
index 00000000000..ab29c59504b
--- /dev/null
+++ b/compliance/rio/src/test/resources/logback-test.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %msg%n
+
+
+
+
+
+
+
+
+
diff --git a/compliance/serql/pom.xml b/compliance/serql/pom.xml
new file mode 100644
index 00000000000..678463eddfa
--- /dev/null
+++ b/compliance/serql/pom.xml
@@ -0,0 +1,103 @@
+
+
+ 4.0.0
+
+
+ org.eclipse.rdf4j
+ rdf4j-compliance
+ 4.1.0-SNAPSHOT
+
+
+ rdf4j-serql-compliance
+
+ RDF4J SeRQL query parser compliance tests
+ Tests for the SeRQL query language implementation
+
+
+
+ ${project.groupId}
+ rdf4j-runtime
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-serql-testsuite
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-queryparser-serql
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-sail
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sail-memory
+ ${project.version}
+
+
+
+ ch.qos.logback
+ logback-classic
+ test
+
+
+
+ junit
+ junit
+ compile
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+ 1
+ false
+ -Xmx512M -XX:MaxPermSize=256M
+
+ **/*Test.java
+
+
+ **/TestServer.java
+
+
+
+
+ integration-tests
+ integration-test
+
+ integration-test
+
+
+
+ verify
+ verify
+
+ verify
+
+
+
+
+
+
+
+
diff --git a/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/SeRQLParserTest.java b/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/SeRQLParserTest.java
new file mode 100644
index 00000000000..e56bea38b64
--- /dev/null
+++ b/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/SeRQLParserTest.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.serql;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.query.parser.QueryParser;
+import org.eclipse.rdf4j.query.parser.serql.SeRQLParser;
+import org.eclipse.rdf4j.query.parser.serql.SeRQLParserTestCase;
+
+public class SeRQLParserTest extends SeRQLParserTestCase {
+ public static Test suite() throws Exception {
+ return SeRQLParserTestCase.suite(new Factory() {
+ public Test createTest(String name, String queryFile, Value result) {
+ return new SeRQLParserTest(name, queryFile, result);
+ }
+ });
+ }
+
+ public SeRQLParserTest(String name, String queryFile, Value result) {
+ super(name, queryFile, result);
+ }
+
+ @Override
+ protected QueryParser createParser() {
+ return new SeRQLParser();
+ }
+}
diff --git a/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/SeRQLQueryTest.java b/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/SeRQLQueryTest.java
new file mode 100644
index 00000000000..aeff0871078
--- /dev/null
+++ b/compliance/serql/src/test/java/org/eclipse/rdf4j/query/parser/serql/SeRQLQueryTest.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.serql;
+
+import java.util.List;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.parser.serql.SeRQLQueryTestCase;
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class SeRQLQueryTest extends SeRQLQueryTestCase {
+
+ public static Test suite() throws Exception {
+ return SeRQLQueryTestCase.suite(new Factory() {
+ public Test createTest(String name, String dataFile,
+ List graphNames, String queryFile,
+ String resultFile, String entailment) {
+ return new SeRQLQueryTest(name, dataFile, graphNames,
+ queryFile, resultFile, entailment);
+ }
+ });
+ }
+
+ public SeRQLQueryTest(String name, String dataFile,
+ List graphNames, String queryFile, String resultFile,
+ String entailment) {
+ super(name, dataFile, graphNames, queryFile, resultFile, entailment);
+ }
+
+ @Override
+ protected QueryLanguage getQueryLanguage() {
+ return QueryLanguage.SERQL;
+ }
+
+ @Override
+ protected NotifyingSail newSail() {
+ return new MemoryStore();
+ }
+}
diff --git a/compliance/serql/src/test/resources/logback-test.xml b/compliance/serql/src/test/resources/logback-test.xml
new file mode 100644
index 00000000000..4a6f17fbfa4
--- /dev/null
+++ b/compliance/serql/src/test/resources/logback-test.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %msg%n
+
+
+
+
+
+
+
+
+
diff --git a/compliance/sparql/pom.xml b/compliance/sparql/pom.xml
new file mode 100644
index 00000000000..91b299dbe92
--- /dev/null
+++ b/compliance/sparql/pom.xml
@@ -0,0 +1,245 @@
+
+
+ 4.0.0
+
+
+ org.eclipse.rdf4j
+ rdf4j-compliance
+ 4.1.0-SNAPSHOT
+
+
+ rdf4j-sparql-compliance
+ war
+
+ RDF4J SPARQL query parser compliance tests
+ Tests for the SPARQL query language implementation
+
+
+
+ ${project.groupId}
+ rdf4j-model
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sparql-testsuite
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-api
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-rio-turtle
+ ${project.version}
+ runtime
+
+
+
+ ${project.groupId}
+ rdf4j-rio-rdfxml
+ ${project.version}
+ runtime
+
+
+
+ ${project.groupId}
+ rdf4j-query
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-queryresultio-api
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-queryresultio-sparqlxml
+ ${project.version}
+ runtime
+
+
+
+ ${project.groupId}
+ rdf4j-queryparser-api
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-queryparser-sparql
+ ${project.version}
+ runtime
+
+
+
+ ${project.groupId}
+ rdf4j-repository-api
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-dataset
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-contextaware
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-sail
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sail-api
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-http-server
+ ${project.version}
+ war
+
+
+
+ ${project.groupId}
+ rdf4j-sail-memory
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-util
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sail-federation
+ ${project.version}
+
+
+
+ org.slf4j
+ slf4j-api
+
+
+
+ ch.qos.logback
+ logback-classic
+ test
+
+
+
+ junit
+ junit
+ compile
+
+
+
+ ${project.groupId}
+ rdf4j-http-protocol
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-manager
+ ${project.version}
+
+
+
+
+ org.eclipse.jetty
+ jetty-server
+ 7.0.2.v20100331
+
+
+
+ org.eclipse.jetty
+ jetty-webapp
+ 7.0.2.v20100331
+
+
+
+ org.mortbay.jetty
+ jetty-jsp-2.1
+ 7.0.2.v20100331
+ runtime
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+ test
+
+
+ org.slf4j
+ log4j-over-slf4j
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ ${project.build.directory}/openrdf-sesame
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+ 1
+ false
+ -Xmx512M -XX:MaxPermSize=256M
+
+ **/*Test.java
+
+
+
+
+ integration-tests
+ integration-test
+
+ integration-test
+
+
+
+ verify
+ verify
+
+ verify
+
+
+
+
+
+
+
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/ArbitraryLengthPathTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/ArbitraryLengthPathTest.java
new file mode 100644
index 00000000000..a30ccfe1751
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/ArbitraryLengthPathTest.java
@@ -0,0 +1,106 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql;
+
+import junit.framework.TestCase;
+
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.RepositoryException;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * @author james
+ */
+public class ArbitraryLengthPathTest extends TestCase {
+
+ private Repository repo;
+
+ private RepositoryConnection con;
+
+ @Before
+ public void setUp()
+ throws Exception
+ {
+ repo = new SailRepository(new MemoryStore());
+ repo.initialize();
+ con = repo.getConnection();
+ }
+
+ @After
+ public void tearDown()
+ throws Exception
+ {
+ con.close();
+ repo.shutDown();
+ }
+
+ @Test
+ public void test10()
+ throws Exception
+ {
+ populate(10);
+ String sparql = "ASK { * }";
+ assertTrue(con.prepareBooleanQuery(QueryLanguage.SPARQL, sparql).evaluate());
+ }
+
+ @Test
+ public void test100()
+ throws Exception
+ {
+ populate(100);
+ String sparql = "ASK { * }";
+ assertTrue(con.prepareBooleanQuery(QueryLanguage.SPARQL, sparql).evaluate());
+ }
+
+ @Test
+ public void test1000()
+ throws Exception
+ {
+ populate(1000);
+ String sparql = "ASK { * }";
+ assertTrue(con.prepareBooleanQuery(QueryLanguage.SPARQL, sparql).evaluate());
+ }
+
+ @Test
+ public void test10000()
+ throws Exception
+ {
+ populate(10000);
+ String sparql = "ASK { * }";
+ assertTrue(con.prepareBooleanQuery(QueryLanguage.SPARQL, sparql).evaluate());
+ }
+
+ @Test
+ public void test100000()
+ throws Exception
+ {
+ populate(100000);
+ String sparql = "ASK { * }";
+ assertTrue(con.prepareBooleanQuery(QueryLanguage.SPARQL, sparql).evaluate());
+ }
+
+ private void populate(int n)
+ throws RepositoryException
+ {
+ ValueFactory vf = con.getValueFactory();
+ for (int i = 0; i < n; i++) {
+ con.add(vf.createIRI("urn:test:root"), vf.createIRI("urn:test:hasChild"),
+ vf.createIRI("urn:test:node" + i));
+ }
+ con.add(vf.createIRI("urn:test:root"), vf.createIRI("urn:test:hasChild"),
+ vf.createIRI("urn:test:node-end"));
+ }
+
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/MemoryComplexSPARQLQueryTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/MemoryComplexSPARQLQueryTest.java
new file mode 100644
index 00000000000..1c08edf4528
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/MemoryComplexSPARQLQueryTest.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql;
+
+import org.eclipse.rdf4j.query.parser.sparql.ComplexSPARQLQueryTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+/**
+ * @author jeen
+ */
+public class MemoryComplexSPARQLQueryTest extends ComplexSPARQLQueryTest {
+
+ @Override
+ protected Repository newRepository()
+ throws Exception
+ {
+ return new SailRepository(new MemoryStore());
+ }
+
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/MemorySPARQLUpdateTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/MemorySPARQLUpdateTest.java
new file mode 100644
index 00000000000..8a05a5e4e7c
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/MemorySPARQLUpdateTest.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql;
+
+import org.eclipse.rdf4j.query.parser.sparql.SPARQLUpdateTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+
+/**
+ * Test SPARQL 1.1 Update functionality on an in-memory store.
+ *
+ * @author Jeen Broekstra
+ */
+public class MemorySPARQLUpdateTest extends SPARQLUpdateTest {
+
+ @Override
+ protected Repository newRepository()
+ throws Exception
+ {
+ return new SailRepository(new MemoryStore());
+ }
+
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLEmbeddedServer.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLEmbeddedServer.java
new file mode 100644
index 00000000000..35fd60fd84e
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLEmbeddedServer.java
@@ -0,0 +1,129 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql;
+
+import java.io.File;
+import java.util.List;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.nio.BlockingChannelConnector;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.rdf4j.http.protocol.Protocol;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.RepositoryException;
+import org.eclipse.rdf4j.repository.config.RepositoryConfig;
+import org.eclipse.rdf4j.repository.config.RepositoryConfigException;
+import org.eclipse.rdf4j.repository.config.RepositoryConfigUtil;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.eclipse.rdf4j.repository.manager.SystemRepository;
+import org.eclipse.rdf4j.repository.sail.config.SailRepositoryConfig;
+import org.eclipse.rdf4j.sail.memory.config.MemoryStoreConfig;
+
+/**
+ * An embedded http server for SPARQL query testing. Initializes a memory store
+ * repository for each specified reposiotoryId.
+ *
+ * @author Andreas Schwarte
+ */
+public class SPARQLEmbeddedServer {
+
+ private static final String HOST = "localhost";
+
+ private static final int PORT = 18080;
+
+ private static final String OPENRDF_CONTEXT = "/openrdf";
+
+ private final List repositoryIds;
+
+ private final Server jetty;
+
+ /**
+ * @param repositoryIds
+ */
+ public SPARQLEmbeddedServer(List repositoryIds) {
+ this.repositoryIds = repositoryIds;
+ System.clearProperty("DEBUG");
+
+ jetty = new Server();
+
+ Connector conn = new BlockingChannelConnector();
+ conn.setHost(HOST);
+ conn.setPort(PORT);
+ jetty.addConnector(conn);
+
+ WebAppContext webapp = new WebAppContext();
+ webapp.setContextPath(OPENRDF_CONTEXT);
+ // warPath configured in pom.xml maven-war-plugin configuration
+ webapp.setWar("./target/openrdf-sesame");
+ jetty.setHandler(webapp);
+ }
+
+ /**
+ * @return the url to the repository with given id
+ */
+ public String getRepositoryUrl(String repoId) {
+ return Protocol.getRepositoryLocation(getServerUrl(), repoId);
+ }
+
+ /**
+ * @return the server url
+ */
+ public String getServerUrl() {
+ return "http://" + HOST + ":" + PORT + OPENRDF_CONTEXT;
+ }
+
+ public void start()
+ throws Exception
+ {
+ File dataDir = new File(System.getProperty("user.dir") + "/target/datadir");
+ dataDir.mkdirs();
+ System.setProperty("info.aduna.platform.appdata.basedir", dataDir.getAbsolutePath());
+
+ jetty.start();
+
+ createTestRepositories();
+ }
+
+ public void stop()
+ throws Exception
+ {
+ Repository systemRepo = new HTTPRepository(Protocol.getRepositoryLocation(getServerUrl(),
+ SystemRepository.ID));
+ RepositoryConnection con = systemRepo.getConnection();
+ try {
+ con.clear();
+ }
+ finally {
+ con.close();
+ systemRepo.shutDown();
+ }
+
+ jetty.stop();
+ System.clearProperty("org.mortbay.log.class");
+ }
+
+ private void createTestRepositories()
+ throws RepositoryException, RepositoryConfigException
+ {
+ Repository systemRep = new HTTPRepository(Protocol.getRepositoryLocation(getServerUrl(),
+ SystemRepository.ID));
+
+ // create a memory store for each provided repository id
+ for (String repId : repositoryIds) {
+ MemoryStoreConfig memStoreConfig = new MemoryStoreConfig();
+ memStoreConfig.setPersist(false);
+ SailRepositoryConfig sailRepConfig = new SailRepositoryConfig(memStoreConfig);
+ RepositoryConfig repConfig = new RepositoryConfig(repId, sailRepConfig);
+
+ RepositoryConfigUtil.updateRepositoryConfigs(systemRep, repConfig);
+ }
+
+ }
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLServiceEvaluationTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLServiceEvaluationTest.java
new file mode 100644
index 00000000000..aadb5301c13
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/SPARQLServiceEvaluationTest.java
@@ -0,0 +1,792 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.LinkedHashSet;
+import java.util.List;
+import java.util.Optional;
+import java.util.Set;
+
+import junit.framework.TestCase;
+
+import org.eclipse.rdf4j.common.io.IOUtil;
+import org.eclipse.rdf4j.common.iteration.Iterations;
+import org.eclipse.rdf4j.common.text.StringUtil;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.model.util.Models;
+import org.eclipse.rdf4j.model.vocabulary.FOAF;
+import org.eclipse.rdf4j.query.BindingSet;
+import org.eclipse.rdf4j.query.BooleanQuery;
+import org.eclipse.rdf4j.query.GraphQuery;
+import org.eclipse.rdf4j.query.GraphQueryResult;
+import org.eclipse.rdf4j.query.MalformedQueryException;
+import org.eclipse.rdf4j.query.Query;
+import org.eclipse.rdf4j.query.QueryEvaluationException;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.QueryResults;
+import org.eclipse.rdf4j.query.TupleQuery;
+import org.eclipse.rdf4j.query.TupleQueryResult;
+import org.eclipse.rdf4j.query.dawg.DAWGTestResultSetUtil;
+import org.eclipse.rdf4j.query.impl.MutableTupleQueryResult;
+import org.eclipse.rdf4j.query.impl.TupleQueryResultBuilder;
+import org.eclipse.rdf4j.query.resultio.QueryResultFormat;
+import org.eclipse.rdf4j.query.resultio.QueryResultIO;
+import org.eclipse.rdf4j.query.resultio.TupleQueryResultFormat;
+import org.eclipse.rdf4j.query.resultio.TupleQueryResultParser;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.RepositoryException;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFParseException;
+import org.eclipse.rdf4j.rio.RDFParser;
+import org.eclipse.rdf4j.rio.Rio;
+import org.eclipse.rdf4j.rio.RDFParser.DatatypeHandling;
+import org.eclipse.rdf4j.rio.helpers.StatementCollector;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Ignore;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test suite for evaluation of SPARQL queries involving SERVICE clauses. The
+ * test suite starts up an embedded Jetty server running Sesame, which functions
+ * as the SPARQL endpoint to test against. The test is configured to execute the
+ * W3C service tests located in
+ * sesame-sparql-testsuite/src/main/resources/testcases-service
+ *
+ * @author Jeen Broekstra
+ * @author Andreas Schwarte
+ */
+public class SPARQLServiceEvaluationTest extends TestCase {
+
+ static final Logger logger = LoggerFactory.getLogger(SPARQLServiceEvaluationTest.class);
+
+ /**
+ * The maximal number of endpoints occurring in a (single) test case
+ */
+ protected static final int MAX_ENDPOINTS = 3;
+
+ private SPARQLEmbeddedServer server;
+
+ private SailRepository localRepository;
+
+ private List remoteRepositories;
+
+ public SPARQLServiceEvaluationTest() {
+
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @Before
+ public void setUp()
+ throws Exception
+ {
+ // set up the server: the maximal number of endpoints must be known
+ List repositoryIds = new ArrayList(MAX_ENDPOINTS);
+ for (int i = 1; i <= MAX_ENDPOINTS; i++)
+ repositoryIds.add("endpoint" + i);
+ server = new SPARQLEmbeddedServer(repositoryIds);
+
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+
+ remoteRepositories = new ArrayList(MAX_ENDPOINTS);
+ for (int i = 1; i <= MAX_ENDPOINTS; i++) {
+ HTTPRepository r = new HTTPRepository(getRepositoryUrl(i));
+ r.initialize();
+ remoteRepositories.add(r);
+ }
+
+ localRepository = new SailRepository(new MemoryStore());
+ localRepository.initialize();
+ }
+
+ /**
+ * Get the repository url, initialized repositories are called endpoint1
+ * endpoint2 .. endpoint%MAX_ENDPOINTS%
+ *
+ * @param i
+ * the index of the repository, starting with 1
+ * @return
+ */
+ protected String getRepositoryUrl(int i) {
+ return server.getRepositoryUrl("endpoint" + i);
+ }
+
+ /**
+ * Get the repository, initialized repositories are called endpoint1
+ * endpoint2 .. endpoint%MAX_ENDPOINTS%
+ *
+ * @param i
+ * the index of the repository, starting with 1
+ * @return
+ */
+ public HTTPRepository getRepository(int i) {
+ return remoteRepositories.get(i - 1);
+ }
+
+ /**
+ * Prepare a particular test, and load the specified data. Note: the
+ * repositories are cleared before loading data
+ *
+ * @param localData
+ * a local data file that is added to local repository, use null if
+ * there is no local data
+ * @param endpointData
+ * a list of endpoint data files, dataFile at index is loaded to
+ * endpoint%i%, use empty list for no remote data
+ * @throws Exception
+ */
+ protected void prepareTest(String localData, List endpointData)
+ throws Exception
+ {
+
+ if (endpointData.size() > MAX_ENDPOINTS)
+ throw new RuntimeException("MAX_ENDPOINTs to low, " + endpointData.size()
+ + " repositories needed. Adjust configuration");
+
+ if (localData != null) {
+ loadDataSet(localRepository, localData);
+ }
+
+ int i = 1; // endpoint id, start with 1
+ for (String s : endpointData) {
+ loadDataSet(getRepository(i++), s);
+ }
+
+ }
+
+ /**
+ * Load a dataset. Note: the repositories are cleared before loading data
+ *
+ * @param rep
+ * @param datasetFile
+ * @throws RDFParseException
+ * @throws RepositoryException
+ * @throws IOException
+ */
+ protected void loadDataSet(Repository rep, String datasetFile)
+ throws RDFParseException, RepositoryException, IOException
+ {
+ logger.debug("loading dataset...");
+ InputStream dataset = SPARQLServiceEvaluationTest.class.getResourceAsStream(datasetFile);
+
+ if (dataset == null)
+ throw new IllegalArgumentException("Datasetfile " + datasetFile + " not found.");
+
+ RepositoryConnection con = rep.getConnection();
+ try {
+ con.clear();
+ con.add(dataset, "",
+ Rio.getParserFormatForFileName(datasetFile).orElseThrow(Rio.unsupportedFormat(datasetFile)));
+ }
+ finally {
+ dataset.close();
+ con.close();
+ }
+ logger.debug("dataset loaded.");
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ localRepository.shutDown();
+ }
+ finally {
+ server.stop();
+ }
+ }
+
+ @Test
+ public void testSimpleServiceQuery()
+ throws RepositoryException
+ {
+ // test setup
+ String EX_NS = "http://example.org/";
+ ValueFactory f = localRepository.getValueFactory();
+ IRI bob = f.createIRI(EX_NS, "bob");
+ IRI alice = f.createIRI(EX_NS, "alice");
+ IRI william = f.createIRI(EX_NS, "william");
+
+ // clears the repository and adds new data
+ try {
+ prepareTest("/testcases-service/simple-default-graph.ttl",
+ Arrays.asList("/testcases-service/simple.ttl"));
+ }
+ catch (Exception e1) {
+ fail(e1.getMessage());
+ }
+
+ StringBuilder qb = new StringBuilder();
+ qb.append(" SELECT * \n");
+ qb.append(" WHERE { \n");
+ qb.append(" SERVICE <" + getRepositoryUrl(1) + "> { \n");
+ qb.append(" ?X <" + FOAF.NAME + "> ?Y \n ");
+ qb.append(" } \n ");
+ qb.append(" ?X a <" + FOAF.PERSON + "> . \n");
+ qb.append(" } \n");
+
+ RepositoryConnection conn = localRepository.getConnection();
+ try {
+ TupleQuery tq = conn.prepareTupleQuery(QueryLanguage.SPARQL, qb.toString());
+
+ TupleQueryResult tqr = tq.evaluate();
+
+ assertNotNull(tqr);
+ assertTrue(tqr.hasNext());
+
+ int count = 0;
+ while (tqr.hasNext()) {
+ BindingSet bs = tqr.next();
+ count++;
+
+ Value x = bs.getValue("X");
+ Value y = bs.getValue("Y");
+
+ assertFalse(william.equals(x));
+
+ assertTrue(bob.equals(x) || alice.equals(x));
+ if (bob.equals(x)) {
+ f.createLiteral("Bob").equals(y);
+ }
+ else if (alice.equals(x)) {
+ f.createLiteral("Alice").equals(y);
+ }
+ }
+
+ assertEquals(2, count);
+
+ }
+ catch (MalformedQueryException e) {
+ fail(e.getMessage());
+ }
+ catch (QueryEvaluationException e) {
+ fail(e.getMessage());
+ }
+ finally {
+ conn.close();
+ }
+ }
+
+ @Test
+ public void test1()
+ throws Exception
+ {
+ prepareTest("/testcases-service/data01.ttl", Arrays.asList("/testcases-service/data01endpoint.ttl"));
+ execute("/testcases-service/service01.rq", "/testcases-service/service01.srx", false);
+ }
+
+ @Test
+ public void test2()
+ throws Exception
+ {
+ prepareTest(null,
+ Arrays.asList("/testcases-service/data02endpoint1.ttl", "/testcases-service/data02endpoint2.ttl"));
+ execute("/testcases-service/service02.rq", "/testcases-service/service02.srx", false);
+ }
+
+ @Test
+ public void test3()
+ throws Exception
+ {
+ prepareTest(null,
+ Arrays.asList("/testcases-service/data03endpoint1.ttl", "/testcases-service/data03endpoint2.ttl"));
+ execute("/testcases-service/service03.rq", "/testcases-service/service03.srx", false);
+ }
+
+ @Test
+ public void test4()
+ throws Exception
+ {
+ prepareTest("/testcases-service/data04.ttl", Arrays.asList("/testcases-service/data04endpoint.ttl"));
+ execute("/testcases-service/service04.rq", "/testcases-service/service04.srx", false);
+ }
+
+ @Test
+ public void test5()
+ throws Exception
+ {
+ prepareTest("/testcases-service/data05.ttl",
+ Arrays.asList("/testcases-service/data05endpoint1.ttl", "/testcases-service/data05endpoint2.ttl"));
+ execute("/testcases-service/service05.rq", "/testcases-service/service05.srx", false);
+ }
+
+ @Test
+ public void test6()
+ throws Exception
+ {
+ prepareTest(null, Arrays.asList("/testcases-service/data06endpoint1.ttl"));
+ execute("/testcases-service/service06.rq", "/testcases-service/service06.srx", false);
+ }
+
+ @Test
+ public void test7()
+ throws Exception
+ {
+ // clears the repository and adds new data + execute
+ prepareTest("/testcases-service/data07.ttl", Collections. emptyList());
+ execute("/testcases-service/service07.rq", "/testcases-service/service07.srx", false);
+ }
+
+ @Test
+ public void test8()
+ throws Exception
+ {
+ /* test where the SERVICE expression is to be evaluated as ASK request */
+ prepareTest("/testcases-service/data08.ttl", Arrays.asList("/testcases-service/data08endpoint.ttl"));
+ execute("/testcases-service/service08.rq", "/testcases-service/service08.srx", false);
+ }
+
+ @Test
+ public void test9()
+ throws Exception
+ {
+ /* test where the service endpoint is bound at runtime through BIND */
+ prepareTest(null, Arrays.asList("/testcases-service/data09endpoint.ttl"));
+ execute("/testcases-service/service09.rq", "/testcases-service/service09.srx", false);
+ }
+
+ @Test
+ public void test10()
+ throws Exception
+ {
+ /* test how we deal with blank node */
+ prepareTest("/testcases-service/data10.ttl", Arrays.asList("/testcases-service/data10endpoint.ttl"));
+ execute("/testcases-service/service10.rq", "/testcases-service/service10.srx", false);
+ }
+
+ @Test
+ public void test11()
+ throws Exception
+ {
+ /* test vectored join with more intermediate results */
+ // clears the repository and adds new data + execute
+ prepareTest("/testcases-service/data11.ttl", Arrays.asList("/testcases-service/data11endpoint.ttl"));
+ execute("/testcases-service/service11.rq", "/testcases-service/service11.srx", false);
+ }
+
+ // test on remote DBpedia endpoint disabled. Only enable for manual testing,
+ // should not be enabled for
+ // Surefire or Hudson.
+ // /**
+ // * This is a manual test to see the Fallback in action. Query asks
+ // * DBpedia, which does not support BINDINGS
+ // *
+ // * @throws Exception
+ // */
+ // public void testFallbackWithDBpedia() throws Exception {
+ // /* test vectored join with more intermediate results */
+ // // clears the repository and adds new data + execute
+ // prepareTest("/testcases-service/data12.ttl",
+ // Collections.emptyList());
+ // execute("/testcases-service/service12.rq",
+ // "/testcases-service/service12.srx", false);
+ // }
+
+ @Test
+ public void test13()
+ throws Exception
+ {
+ /* test for bug SES-899: cross product is required */
+ prepareTest(null, Arrays.asList("/testcases-service/data13.ttl"));
+ execute("/testcases-service/service13.rq", "/testcases-service/service13.srx", false);
+ }
+
+ @Test
+ public void testEmptyServiceBlock()
+ throws Exception
+ {
+ /* test for bug SES-900: nullpointer for empty service block */
+ prepareTest(null, Arrays.asList("/testcases-service/data13.ttl"));
+ execute("/testcases-service/service14.rq", "/testcases-service/service14.srx", false);
+ }
+
+ @Test
+ public void testNotProjectedCount()
+ throws Exception
+ {
+ /* test projection of subqueries - SES-1000 */
+ prepareTest(null, Arrays.asList("/testcases-service/data17endpoint1.ttl"));
+ execute("/testcases-service/service17.rq", "/testcases-service/service17.srx", false);
+ }
+
+ @Test
+ public void testNonAsciiCharHandling()
+ throws Exception
+ {
+ /* SES-1056 */
+ prepareTest(null, Arrays.asList("/testcases-service/data18endpoint1.rdf"));
+ execute("/testcases-service/service18.rq", "/testcases-service/service18.srx", false);
+ }
+
+ /**
+ * Execute a testcase, both queryFile and expectedResultFile must be files
+ * located on the class path.
+ *
+ * @param queryFile
+ * @param expectedResultFile
+ * @param checkOrder
+ * @throws Exception
+ */
+ private void execute(String queryFile, String expectedResultFile, boolean checkOrder)
+ throws Exception
+ {
+ RepositoryConnection conn = localRepository.getConnection();
+ String queryString = readQueryString(queryFile);
+
+ try {
+ Query query = conn.prepareQuery(QueryLanguage.SPARQL, queryString);
+
+ if (query instanceof TupleQuery) {
+ TupleQueryResult queryResult = ((TupleQuery)query).evaluate();
+
+ TupleQueryResult expectedResult = readExpectedTupleQueryResult(expectedResultFile);
+
+ compareTupleQueryResults(queryResult, expectedResult, checkOrder);
+
+ }
+ else if (query instanceof GraphQuery) {
+ GraphQueryResult gqr = ((GraphQuery)query).evaluate();
+ Set queryResult = Iterations.asSet(gqr);
+
+ Set expectedResult = readExpectedGraphQueryResult(expectedResultFile);
+
+ compareGraphs(queryResult, expectedResult);
+
+ }
+ else if (query instanceof BooleanQuery) {
+ // TODO implement if needed
+ throw new RuntimeException("Not yet supported " + query.getClass());
+ }
+ else {
+ throw new RuntimeException("Unexpected query type: " + query.getClass());
+ }
+ }
+ finally {
+ conn.close();
+ }
+ }
+
+ /**
+ * Read the query string from the specified resource
+ *
+ * @param queryResource
+ * @return
+ * @throws RepositoryException
+ * @throws IOException
+ */
+ private String readQueryString(String queryResource)
+ throws RepositoryException, IOException
+ {
+ InputStream stream = SPARQLServiceEvaluationTest.class.getResourceAsStream(queryResource);
+ try {
+ return IOUtil.readString(new InputStreamReader(stream, "UTF-8"));
+ }
+ finally {
+ stream.close();
+ }
+ }
+
+ /**
+ * Read the expected tuple query result from the specified resource
+ *
+ * @param queryResource
+ * @return
+ * @throws RepositoryException
+ * @throws IOException
+ */
+ private TupleQueryResult readExpectedTupleQueryResult(String resultFile)
+ throws Exception
+ {
+ Optional tqrFormat = QueryResultIO.getParserFormatForFileName(resultFile);
+
+ if (tqrFormat.isPresent()) {
+ InputStream in = SPARQLServiceEvaluationTest.class.getResourceAsStream(resultFile);
+ try {
+ TupleQueryResultParser parser = QueryResultIO.createTupleParser(tqrFormat.get());
+ parser.setValueFactory(SimpleValueFactory.getInstance());
+
+ TupleQueryResultBuilder qrBuilder = new TupleQueryResultBuilder();
+ parser.setQueryResultHandler(qrBuilder);
+
+ parser.parseQueryResult(in);
+ return qrBuilder.getQueryResult();
+ }
+ finally {
+ in.close();
+ }
+ }
+ else {
+ Set resultGraph = readExpectedGraphQueryResult(resultFile);
+ return DAWGTestResultSetUtil.toTupleQueryResult(resultGraph);
+ }
+ }
+
+ /**
+ * Read the expected graph query result from the specified resource
+ *
+ * @param resultFile
+ * @return
+ * @throws Exception
+ */
+ private Set readExpectedGraphQueryResult(String resultFile)
+ throws Exception
+ {
+ RDFFormat rdfFormat = Rio.getParserFormatForFileName(resultFile).orElseThrow(
+ Rio.unsupportedFormat(resultFile));
+
+ RDFParser parser = Rio.createParser(rdfFormat);
+ parser.setDatatypeHandling(DatatypeHandling.IGNORE);
+ parser.setPreserveBNodeIDs(true);
+ parser.setValueFactory(SimpleValueFactory.getInstance());
+
+ Set result = new LinkedHashSet();
+ parser.setRDFHandler(new StatementCollector(result));
+
+ InputStream in = SPARQLServiceEvaluationTest.class.getResourceAsStream(resultFile);
+ try {
+ parser.parse(in, null); // TODO check
+ }
+ finally {
+ in.close();
+ }
+
+ return result;
+ }
+
+ /**
+ * Compare two tuple query results
+ *
+ * @param queryResult
+ * @param expectedResult
+ * @param checkOrder
+ * @throws Exception
+ */
+ private void compareTupleQueryResults(TupleQueryResult queryResult, TupleQueryResult expectedResult,
+ boolean checkOrder)
+ throws Exception
+ {
+ // Create MutableTupleQueryResult to be able to re-iterate over the
+ // results
+ MutableTupleQueryResult queryResultTable = new MutableTupleQueryResult(queryResult);
+ MutableTupleQueryResult expectedResultTable = new MutableTupleQueryResult(expectedResult);
+
+ boolean resultsEqual;
+
+ resultsEqual = QueryResults.equals(queryResultTable, expectedResultTable);
+
+ if (checkOrder) {
+ // also check the order in which solutions occur.
+ queryResultTable.beforeFirst();
+ expectedResultTable.beforeFirst();
+
+ while (queryResultTable.hasNext()) {
+ BindingSet bs = queryResultTable.next();
+ BindingSet expectedBs = expectedResultTable.next();
+
+ if (!bs.equals(expectedBs)) {
+ resultsEqual = false;
+ break;
+ }
+ }
+ }
+
+ if (!resultsEqual) {
+ queryResultTable.beforeFirst();
+ expectedResultTable.beforeFirst();
+
+ /*
+ * StringBuilder message = new StringBuilder(128);
+ * message.append("\n============ "); message.append(getName());
+ * message.append(" =======================\n");
+ * message.append("Expected result: \n"); while
+ * (expectedResultTable.hasNext()) {
+ * message.append(expectedResultTable.next()); message.append("\n"); }
+ * message.append("============="); StringUtil.appendN('=',
+ * getName().length(), message);
+ * message.append("========================\n"); message.append("Query
+ * result: \n"); while (queryResultTable.hasNext()) {
+ * message.append(queryResultTable.next()); message.append("\n"); }
+ * message.append("============="); StringUtil.appendN('=',
+ * getName().length(), message);
+ * message.append("========================\n");
+ */
+
+ List queryBindings = Iterations.asList(queryResultTable);
+
+ List expectedBindings = Iterations.asList(expectedResultTable);
+
+ List missingBindings = new ArrayList(expectedBindings);
+ missingBindings.removeAll(queryBindings);
+
+ List unexpectedBindings = new ArrayList(queryBindings);
+ unexpectedBindings.removeAll(expectedBindings);
+
+ StringBuilder message = new StringBuilder(128);
+ message.append("\n============ ");
+ message.append(getName());
+ message.append(" =======================\n");
+
+ if (!missingBindings.isEmpty()) {
+
+ message.append("Missing bindings: \n");
+ for (BindingSet bs : missingBindings) {
+ message.append(bs);
+ message.append("\n");
+ }
+
+ message.append("=============");
+ StringUtil.appendN('=', getName().length(), message);
+ message.append("========================\n");
+ }
+
+ if (!unexpectedBindings.isEmpty()) {
+ message.append("Unexpected bindings: \n");
+ for (BindingSet bs : unexpectedBindings) {
+ message.append(bs);
+ message.append("\n");
+ }
+
+ message.append("=============");
+ StringUtil.appendN('=', getName().length(), message);
+ message.append("========================\n");
+ }
+
+ if (checkOrder && missingBindings.isEmpty() && unexpectedBindings.isEmpty()) {
+ message.append("Results are not in expected order.\n");
+ message.append(" =======================\n");
+ message.append("query result: \n");
+ for (BindingSet bs : queryBindings) {
+ message.append(bs);
+ message.append("\n");
+ }
+ message.append(" =======================\n");
+ message.append("expected result: \n");
+ for (BindingSet bs : expectedBindings) {
+ message.append(bs);
+ message.append("\n");
+ }
+ message.append(" =======================\n");
+
+ System.out.print(message.toString());
+ }
+
+ logger.error(message.toString());
+ fail(message.toString());
+ }
+ /* debugging only: print out result when test succeeds
+ else {
+ queryResultTable.beforeFirst();
+
+ List queryBindings = Iterations.asList(queryResultTable);
+ StringBuilder message = new StringBuilder(128);
+
+ message.append("\n============ ");
+ message.append(getName());
+ message.append(" =======================\n");
+
+ message.append(" =======================\n");
+ message.append("query result: \n");
+ for (BindingSet bs: queryBindings) {
+ message.append(bs);
+ message.append("\n");
+ }
+
+ System.out.print(message.toString());
+ }
+ */
+ }
+
+ /**
+ * Compare two graphs
+ *
+ * @param queryResult
+ * @param expectedResult
+ * @throws Exception
+ */
+ private void compareGraphs(Set queryResult, Set expectedResult)
+ throws Exception
+ {
+ if (!Models.isomorphic(expectedResult, queryResult)) {
+ // Don't use RepositoryUtil.difference, it reports incorrect diffs
+ /*
+ * Collection extends Statement> unexpectedStatements =
+ * RepositoryUtil.difference(queryResult, expectedResult); Collection
+ * extends Statement> missingStatements =
+ * RepositoryUtil.difference(expectedResult, queryResult);
+ * StringBuilder message = new StringBuilder(128);
+ * message.append("\n=======Diff: "); message.append(getName());
+ * message.append("========================\n"); if
+ * (!unexpectedStatements.isEmpty()) { message.append("Unexpected
+ * statements in result: \n"); for (Statement st :
+ * unexpectedStatements) { message.append(st.toString());
+ * message.append("\n"); } message.append("============="); for (int i =
+ * 0; i < getName().length(); i++) { message.append("="); }
+ * message.append("========================\n"); } if
+ * (!missingStatements.isEmpty()) { message.append("Statements missing
+ * in result: \n"); for (Statement st : missingStatements) {
+ * message.append(st.toString()); message.append("\n"); }
+ * message.append("============="); for (int i = 0; i <
+ * getName().length(); i++) { message.append("="); }
+ * message.append("========================\n"); }
+ */
+ StringBuilder message = new StringBuilder(128);
+ message.append("\n============ ");
+ message.append(getName());
+ message.append(" =======================\n");
+ message.append("Expected result: \n");
+ for (Statement st : expectedResult) {
+ message.append(st.toString());
+ message.append("\n");
+ }
+ message.append("=============");
+ StringUtil.appendN('=', getName().length(), message);
+ message.append("========================\n");
+
+ message.append("Query result: \n");
+ for (Statement st : queryResult) {
+ message.append(st.toString());
+ message.append("\n");
+ }
+ message.append("=============");
+ StringUtil.appendN('=', getName().length(), message);
+ message.append("========================\n");
+
+ logger.error(message.toString());
+ fail(message.toString());
+ }
+ }
+
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/CoreSPARQLSyntaxTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/CoreSPARQLSyntaxTest.java
new file mode 100644
index 00000000000..30a8c76a94a
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/CoreSPARQLSyntaxTest.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql.manifest;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.query.MalformedQueryException;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.parser.QueryParserUtil;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLSyntaxTest;
+
+public class CoreSPARQLSyntaxTest extends SPARQLSyntaxTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return SPARQLSyntaxTest.suite(new Factory() {
+
+ public SPARQLSyntaxTest createSPARQLSyntaxTest(String testURI, String testName, String testAction,
+ boolean positiveTest)
+ {
+ return new CoreSPARQLSyntaxTest(testURI, testName, testAction, positiveTest);
+ }
+ });
+ }
+
+ public CoreSPARQLSyntaxTest(String testURI, String name, String queryFileURL, boolean positiveTest) {
+ super(testURI, name, queryFileURL, positiveTest);
+ }
+
+ protected void parseQuery(String query, String queryFileURL)
+ throws MalformedQueryException
+ {
+ QueryParserUtil.parseQuery(QueryLanguage.SPARQL, query, queryFileURL);
+ }
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/EarlReport.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/EarlReport.java
new file mode 100644
index 00000000000..6802a6ea9db
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/EarlReport.java
@@ -0,0 +1,186 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql.manifest;
+
+import java.io.File;
+import java.io.FileOutputStream;
+import java.text.SimpleDateFormat;
+import java.util.Date;
+
+import junit.framework.AssertionFailedError;
+import junit.framework.Test;
+import junit.framework.TestListener;
+import junit.framework.TestResult;
+
+import org.eclipse.rdf4j.model.BNode;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.DC;
+import org.eclipse.rdf4j.model.vocabulary.DCTERMS;
+import org.eclipse.rdf4j.model.vocabulary.DOAP;
+import org.eclipse.rdf4j.model.vocabulary.EARL;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.model.vocabulary.XMLSchema;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11SyntaxTest;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLQueryTest;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLUpdateConformanceTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.RepositoryException;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFWriterFactory;
+import org.eclipse.rdf4j.rio.RDFWriterRegistry;
+import org.eclipse.rdf4j.rio.Rio;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author Arjohn Kampman
+ */
+public class EarlReport {
+
+ protected static Repository earlRepository;
+
+ protected static ValueFactory vf;
+
+ protected static RepositoryConnection con;
+
+ protected static Resource projectNode;
+
+ protected static Resource asserterNode;
+
+ private static Logger logger = LoggerFactory.getLogger(EarlReport.class);
+
+ public static void main(String[] args)
+ throws Exception
+ {
+ earlRepository = new SailRepository(new MemoryStore());
+ earlRepository.initialize();
+ vf = earlRepository.getValueFactory();
+ con = earlRepository.getConnection();
+ con.begin();
+
+ con.setNamespace("rdf", RDF.NAMESPACE);
+ con.setNamespace("xsd", XMLSchema.NAMESPACE);
+ con.setNamespace("doap", DOAP.NAMESPACE);
+ con.setNamespace("earl", EARL.NAMESPACE);
+ con.setNamespace("dcterms", DCTERMS.NAMESPACE);
+
+ projectNode = vf.createBNode();
+ BNode releaseNode = vf.createBNode();
+ con.add(projectNode, RDF.TYPE, DOAP.PROJECT);
+ con.add(projectNode, DOAP.NAME, vf.createLiteral("OpenRDF Sesame"));
+ con.add(projectNode, DOAP.RELEASE, releaseNode);
+ con.add(projectNode, DOAP.HOMEPAGE, vf.createIRI("http://www.openrdf.org/"));
+ con.add(releaseNode, RDF.TYPE, DOAP.VERSION);
+ con.add(releaseNode, DOAP.NAME, vf.createLiteral("Sesame 2.7.0"));
+ SimpleDateFormat xsdDataFormat = new SimpleDateFormat("yyyy-MM-dd");
+ String currentDate = xsdDataFormat.format(new Date());
+ con.add(releaseNode, DOAP.CREATED, vf.createLiteral(currentDate, XMLSchema.DATE));
+
+ asserterNode = vf.createBNode();
+ con.add(asserterNode, RDF.TYPE, EARL.SOFTWARE);
+ con.add(asserterNode, DC.TITLE, vf.createLiteral("OpenRDF SPARQL 1.1 compliance tests"));
+
+ TestResult testResult = new TestResult();
+ EarlTestListener listener = new EarlTestListener();
+ testResult.addListener(listener);
+
+ logger.info("running query evaluation tests..");
+ W3CApprovedSPARQL11QueryTest.suite().run(testResult);
+
+ logger.info("running syntax tests...");
+ W3CApprovedSPARQL11SyntaxTest.suite().run(testResult);
+
+ logger.info("running update tests...");
+ W3CApprovedSPARQL11UpdateTest.suite().run(testResult);
+ logger.info("tests complete, generating EARL report...");
+
+ con.commit();
+
+ RDFWriterFactory factory = RDFWriterRegistry.getInstance().get(RDFFormat.TURTLE).orElseThrow(
+ Rio.unsupportedFormat(RDFFormat.TURTLE));
+ File outFile = File.createTempFile("sesame-sparql-compliance",
+ "." + RDFFormat.TURTLE.getDefaultFileExtension());
+ FileOutputStream out = new FileOutputStream(outFile);
+ try {
+ con.export(factory.getWriter(out));
+ }
+ finally {
+ out.close();
+ }
+
+ con.close();
+ earlRepository.shutDown();
+
+ logger.info("EARL output written to " + outFile);
+ }
+
+ protected static class EarlTestListener implements TestListener {
+
+ private int errorCount;
+
+ private int failureCount;
+
+ public void startTest(Test test) {
+ errorCount = failureCount = 0;
+ }
+
+ public void endTest(Test test) {
+ String testURI = null;
+ ;
+ if (test instanceof SPARQLQueryTest) {
+ testURI = ((SPARQLQueryTest)test).testURI;
+ }
+ else if (test instanceof SPARQL11SyntaxTest) {
+ testURI = ((SPARQL11SyntaxTest)test).testURI;
+ }
+ else if (test instanceof SPARQLUpdateConformanceTest) {
+ testURI = ((SPARQLUpdateConformanceTest)test).testURI;
+ }
+ else {
+ throw new RuntimeException("Unexpected test type: " + test.getClass());
+ }
+
+ try {
+ BNode testNode = vf.createBNode();
+ BNode resultNode = vf.createBNode();
+ con.add(testNode, RDF.TYPE, EARL.ASSERTION);
+ con.add(testNode, EARL.ASSERTEDBY, asserterNode);
+ con.add(testNode, EARL.MODE, EARL.AUTOMATIC);
+ con.add(testNode, EARL.SUBJECT, projectNode);
+ con.add(testNode, EARL.TEST, vf.createIRI(testURI));
+ con.add(testNode, EARL.RESULT, resultNode);
+ con.add(resultNode, RDF.TYPE, EARL.TESTRESULT);
+
+ if (errorCount > 0) {
+ con.add(resultNode, EARL.OUTCOME, EARL.FAIL);
+ }
+ else if (failureCount > 0) {
+ con.add(resultNode, EARL.OUTCOME, EARL.FAIL);
+ }
+ else {
+ con.add(resultNode, EARL.OUTCOME, EARL.PASS);
+ }
+ }
+ catch (RepositoryException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ public void addError(Test test, Throwable t) {
+ errorCount++;
+ }
+
+ public void addFailure(Test test, AssertionFailedError error) {
+ failureCount++;
+ }
+ }
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/MemorySPARQLQueryTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/MemorySPARQLQueryTest.java
new file mode 100644
index 00000000000..0e4e29569e0
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/MemorySPARQLQueryTest.java
@@ -0,0 +1,58 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql.manifest;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.query.Dataset;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.ManifestTest;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLQueryTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemorySPARQLQueryTest extends SPARQLQueryTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return ManifestTest.suite(new Factory() {
+
+ public MemorySPARQLQueryTest createSPARQLQueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality)
+ {
+ return createSPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+ laxCardinality, false);
+ }
+
+ public MemorySPARQLQueryTest createSPARQLQueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+ {
+ return new MemorySPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+ laxCardinality, checkOrder);
+ }
+ });
+ }
+
+ protected MemorySPARQLQueryTest(String testURI, String name, String queryFileURL, String resultFileURL,
+ Dataset dataSet, boolean laxCardinality)
+ {
+ this(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, false);
+ }
+
+ protected MemorySPARQLQueryTest(String testURI, String name, String queryFileURL, String resultFileURL,
+ Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+ {
+ super(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, checkOrder);
+ }
+
+ protected Repository newRepository() {
+ return new DatasetRepository(new SailRepository(new MemoryStore()));
+ }
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11QueryTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11QueryTest.java
new file mode 100644
index 00000000000..0d35b23368c
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11QueryTest.java
@@ -0,0 +1,70 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql.manifest;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.query.Dataset;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11ManifestTest;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLQueryTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class W3CApprovedSPARQL11QueryTest extends SPARQLQueryTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return SPARQL11ManifestTest.suite(new Factory() {
+
+ public W3CApprovedSPARQL11QueryTest createSPARQLQueryTest(String testURI, String name,
+ String queryFileURL, String resultFileURL, Dataset dataSet, boolean laxCardinality)
+ {
+ return createSPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality,
+ false);
+ }
+
+ public W3CApprovedSPARQL11QueryTest createSPARQLQueryTest(String testURI, String name,
+ String queryFileURL, String resultFileURL, Dataset dataSet, boolean laxCardinality,
+ boolean checkOrder)
+ {
+ String[] ignoredTests = {
+ // test case incompatible with RDF 1.1 - see
+ // http://lists.w3.org/Archives/Public/public-sparql-dev/2013AprJun/0006.html
+ "STRDT TypeErrors",
+ // test case incompatible with RDF 1.1 - see
+ // http://lists.w3.org/Archives/Public/public-sparql-dev/2013AprJun/0006.html
+ "STRLANG TypeErrors",
+ // known issue: SES-937
+ "sq03 - Subquery within graph pattern, graph variable is not bound" };
+
+ return new W3CApprovedSPARQL11QueryTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+ laxCardinality, checkOrder, ignoredTests);
+ }
+ }, true, true, false, "service");
+ }
+
+ protected W3CApprovedSPARQL11QueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality, String... ignoredTests)
+ {
+ this(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, false, ignoredTests);
+ }
+
+ protected W3CApprovedSPARQL11QueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality, boolean checkOrder,
+ String... ignoredTests)
+ {
+ super(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, checkOrder, ignoredTests);
+ }
+
+ protected Repository newRepository() {
+ return new DatasetRepository(new SailRepository(new MemoryStore()));
+ }
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11SyntaxTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11SyntaxTest.java
new file mode 100644
index 00000000000..1620f923c72
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11SyntaxTest.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql.manifest;
+
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.query.MalformedQueryException;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.parser.ParsedOperation;
+import org.eclipse.rdf4j.query.parser.QueryParserUtil;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11SyntaxTest;
+
+public class W3CApprovedSPARQL11SyntaxTest extends SPARQL11SyntaxTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return SPARQL11SyntaxTest.suite(new Factory() {
+
+ public SPARQL11SyntaxTest createSPARQLSyntaxTest(String testURI, String testName, String testAction,
+ boolean positiveTest)
+ {
+ return new W3CApprovedSPARQL11SyntaxTest(testURI, testName, testAction, positiveTest);
+ }
+ }, false);
+ }
+
+ public W3CApprovedSPARQL11SyntaxTest(String testURI, String name, String queryFileURL, boolean positiveTest) {
+ super(testURI, name, queryFileURL, positiveTest);
+ }
+
+ protected ParsedOperation parseOperation(String operation, String fileURL)
+ throws MalformedQueryException
+ {
+ return QueryParserUtil.parseOperation(QueryLanguage.SPARQL, operation, fileURL);
+ }
+
+ @Override
+ protected void runTest()
+ throws Exception
+ {
+ if (this.getName().contains("syntax-update-54")) {
+ // we skip this negative syntax test because it is an unnecessarily restrictive test that is almost
+ // impossible to implement correctly, and which in practice Sesame handles correctly simply by
+ // assigning different blank node ids.
+ }
+ else {
+ super.runTest();
+ }
+ }
+}
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11UpdateTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11UpdateTest.java
new file mode 100644
index 00000000000..a3a8c5de9d5
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/query/parser/sparql/manifest/W3CApprovedSPARQL11UpdateTest.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.query.parser.sparql.manifest;
+
+import java.util.Map;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQL11ManifestTest;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLUpdateConformanceTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.contextaware.ContextAwareRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+
+/**
+ * @author Jeen Broekstra
+ */
+public class W3CApprovedSPARQL11UpdateTest extends SPARQLUpdateConformanceTest {
+
+ public W3CApprovedSPARQL11UpdateTest(String testURI, String name, String requestFile,
+ IRI defaultGraphURI, Map inputNamedGraphs, IRI resultDefaultGraphURI,
+ Map resultNamedGraphs)
+ {
+ super(testURI, name, requestFile, defaultGraphURI, inputNamedGraphs, resultDefaultGraphURI,
+ resultNamedGraphs);
+ }
+
+ public static Test suite()
+ throws Exception
+ {
+ return SPARQL11ManifestTest.suite(new Factory() {
+
+ public W3CApprovedSPARQL11UpdateTest createSPARQLUpdateConformanceTest(String testURI,
+ String name, String requestFile, IRI defaultGraphURI, Map inputNamedGraphs,
+ IRI resultDefaultGraphURI, Map resultNamedGraphs)
+ {
+ return new W3CApprovedSPARQL11UpdateTest(testURI, name, requestFile, defaultGraphURI,
+ inputNamedGraphs, resultDefaultGraphURI, resultNamedGraphs);
+ }
+
+ }, true, true, false);
+ }
+
+ @Override
+ protected ContextAwareRepository newRepository()
+ throws Exception
+ {
+ SailRepository repo = new SailRepository(new MemoryStore());
+
+ return new ContextAwareRepository(repo);
+ }
+
+}
+
diff --git a/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/federation/FederationSparqlTest.java b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/federation/FederationSparqlTest.java
new file mode 100644
index 00000000000..631103dab76
--- /dev/null
+++ b/compliance/sparql/src/test/java/org/eclipse/rdf4j/sail/federation/FederationSparqlTest.java
@@ -0,0 +1,64 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.federation;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.query.Dataset;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.ManifestTest;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLQueryTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.federation.Federation;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class FederationSparqlTest extends SPARQLQueryTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return ManifestTest.suite(new Factory() {
+
+ public SPARQLQueryTest createSPARQLQueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality)
+ {
+ return new FederationSparqlTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+ laxCardinality);
+ }
+
+ public SPARQLQueryTest createSPARQLQueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+ {
+ return new FederationSparqlTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+ laxCardinality, checkOrder);
+ }
+ });
+ }
+
+ public FederationSparqlTest(String testURI, String name, String queryFileURL, String resultFileURL,
+ Dataset dataSet, boolean laxCardinality)
+ {
+ super(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality);
+ }
+
+ public FederationSparqlTest(String testURI, String name, String queryFileURL, String resultFileURL,
+ Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+ {
+ super(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, checkOrder);
+ }
+
+ @Override
+ protected Repository newRepository() {
+ Federation sail = new Federation();
+ sail.addMember(new SailRepository(new MemoryStore()));
+ sail.addMember(new SailRepository(new MemoryStore()));
+ sail.addMember(new SailRepository(new MemoryStore()));
+ return new DatasetRepository(new SailRepository(sail));
+ }
+}
diff --git a/compliance/sparql/src/test/resources/logback-test.xml b/compliance/sparql/src/test/resources/logback-test.xml
new file mode 100644
index 00000000000..86b31ec4b71
--- /dev/null
+++ b/compliance/sparql/src/test/resources/logback-test.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %msg%n
+
+
+
+
+
+
+
+
+
diff --git a/compliance/store/pom.xml b/compliance/store/pom.xml
new file mode 100644
index 00000000000..1dfafb51770
--- /dev/null
+++ b/compliance/store/pom.xml
@@ -0,0 +1,200 @@
+
+
+ 4.0.0
+
+
+ org.eclipse.rdf4j
+ rdf4j-compliance
+ 4.1.0-SNAPSHOT
+
+
+ rdf4j-store-compliance
+ war
+
+ RDF4J SAIL and Repository compliance test
+ Tests for the core SAILs and Repositories
+
+
+
+ ${project.groupId}
+ rdf4j-store-testsuite
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-serql-testsuite
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sparql-testsuite
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-http
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-sail
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-sparql
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sail-memory
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sail-nativerdf
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-sail-federation
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-http-server
+ ${project.version}
+ war
+
+
+
+ junit
+ junit
+ compile
+
+
+
+ ch.qos.logback
+ logback-classic
+ test
+
+
+
+ postgresql
+ postgresql
+
+
+
+ mysql
+ mysql-connector-java
+
+
+
+ ${project.groupId}
+ rdf4j-http-protocol
+ ${project.version}
+
+
+
+ ${project.groupId}
+ rdf4j-repository-manager
+ ${project.version}
+
+
+
+
+
+ org.eclipse.jetty
+ jetty-server
+ 7.0.2.v20100331
+
+
+
+ org.eclipse.jetty
+ jetty-webapp
+ 7.0.2.v20100331
+
+
+
+ org.mortbay.jetty
+ jetty-jsp-2.1
+ 7.0.2.v20100331
+ runtime
+
+
+
+ org.slf4j
+ jcl-over-slf4j
+ test
+
+
+ org.slf4j
+ log4j-over-slf4j
+ test
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-war-plugin
+
+ ${project.build.directory}/openrdf-sesame
+
+
+
+ org.apache.maven.plugins
+ maven-surefire-plugin
+
+ true
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+ 1
+ false
+ -Xmx1024M -XX:MaxPermSize=256M
+
+ **/*Test.java
+
+
+ **/DataStorePerfTest.java
+ **/TestServer.java
+
+
+
+
+ integration-tests
+ integration-test
+
+ integration-test
+
+
+
+ verify
+ verify
+
+ verify
+
+
+
+
+
+
+
+
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPMemServer.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPMemServer.java
new file mode 100644
index 00000000000..b736eaac609
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPMemServer.java
@@ -0,0 +1,123 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.http;
+
+import java.io.File;
+
+import org.eclipse.jetty.server.Connector;
+import org.eclipse.jetty.server.Server;
+import org.eclipse.jetty.server.nio.BlockingChannelConnector;
+import org.eclipse.jetty.webapp.WebAppContext;
+import org.eclipse.rdf4j.http.protocol.Protocol;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.RepositoryException;
+import org.eclipse.rdf4j.repository.config.RepositoryConfig;
+import org.eclipse.rdf4j.repository.config.RepositoryConfigException;
+import org.eclipse.rdf4j.repository.config.RepositoryConfigUtil;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.eclipse.rdf4j.repository.manager.SystemRepository;
+import org.eclipse.rdf4j.repository.sail.config.SailRepositoryConfig;
+import org.eclipse.rdf4j.sail.inferencer.fc.config.ForwardChainingRDFSInferencerConfig;
+import org.eclipse.rdf4j.sail.memory.config.MemoryStoreConfig;
+
+/**
+ * @author Herko ter Horst
+ */
+public class HTTPMemServer {
+
+ private static final String HOST = "localhost";
+
+ private static final int PORT = 18080;
+
+ private static final String TEST_REPO_ID = "Test";
+
+ private static final String TEST_INFERENCE_REPO_ID = "Test-RDFS";
+
+ private static final String OPENRDF_CONTEXT = "/openrdf";
+
+ private static final String SERVER_URL = "http://" + HOST + ":" + PORT + OPENRDF_CONTEXT;
+
+ public static final String REPOSITORY_URL = Protocol.getRepositoryLocation(SERVER_URL, TEST_REPO_ID);
+
+ public static String INFERENCE_REPOSITORY_URL = Protocol.getRepositoryLocation(SERVER_URL,
+ TEST_INFERENCE_REPO_ID);
+
+ private final Server jetty;
+
+ public HTTPMemServer() {
+ System.clearProperty("DEBUG");
+
+ jetty = new Server();
+
+ Connector conn = new BlockingChannelConnector();
+ conn.setHost(HOST);
+ conn.setPort(PORT);
+ jetty.addConnector(conn);
+
+ WebAppContext webapp = new WebAppContext();
+ // TODO temporarily disabled so the integration test server shows server-side logging.
+// webapp.addSystemClass("org.slf4j.");
+// webapp.addSystemClass("ch.qos.logback.");
+ webapp.setContextPath(OPENRDF_CONTEXT);
+ // warPath configured in pom.xml maven-war-plugin configuration
+ webapp.setWar("./target/openrdf-sesame");
+ jetty.setHandler(webapp);
+ }
+
+ public void start()
+ throws Exception
+ {
+ File dataDir = new File(System.getProperty("user.dir") + "/target/datadir");
+ dataDir.mkdirs();
+ System.setProperty("info.aduna.platform.appdata.basedir", dataDir.getAbsolutePath());
+
+ jetty.start();
+
+ createTestRepositories();
+ }
+
+ public void stop()
+ throws Exception
+ {
+ Repository systemRepo = new HTTPRepository(Protocol.getRepositoryLocation(SERVER_URL,
+ SystemRepository.ID));
+ RepositoryConnection con = systemRepo.getConnection();
+ try {
+ con.clear();
+ }
+ finally {
+ con.close();
+ }
+
+ jetty.stop();
+ System.clearProperty("org.mortbay.log.class");
+ }
+
+ private void createTestRepositories()
+ throws RepositoryException, RepositoryConfigException
+ {
+ Repository systemRep = new HTTPRepository(Protocol.getRepositoryLocation(SERVER_URL,
+ SystemRepository.ID));
+
+ // create a (non-inferencing) memory store
+ MemoryStoreConfig memStoreConfig = new MemoryStoreConfig();
+ SailRepositoryConfig sailRepConfig = new SailRepositoryConfig(memStoreConfig);
+ RepositoryConfig repConfig = new RepositoryConfig(TEST_REPO_ID, sailRepConfig);
+
+ RepositoryConfigUtil.updateRepositoryConfigs(systemRep, repConfig);
+
+ // create an inferencing memory store
+ ForwardChainingRDFSInferencerConfig inferMemStoreConfig = new ForwardChainingRDFSInferencerConfig(
+ new MemoryStoreConfig());
+ sailRepConfig = new SailRepositoryConfig(inferMemStoreConfig);
+ repConfig = new RepositoryConfig(TEST_INFERENCE_REPO_ID, sailRepConfig);
+
+ RepositoryConfigUtil.updateRepositoryConfigs(systemRep, repConfig);
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPRepositoryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPRepositoryTest.java
new file mode 100644
index 00000000000..8c3928d9cd2
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPRepositoryTest.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.http;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryTest;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class HTTPRepositoryTest extends RepositoryTest {
+
+ private static HTTPMemServer server;
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ }
+
+ @Override
+ protected Repository createRepository() {
+ return new HTTPRepository(HTTPMemServer.REPOSITORY_URL);
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlDatasetTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlDatasetTest.java
new file mode 100644
index 00000000000..67de32929e6
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlDatasetTest.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.http;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlDatasetTest;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class HTTPSparqlDatasetTest extends SparqlDatasetTest {
+
+ private static HTTPMemServer server;
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ }
+
+ protected Repository newRepository() {
+ return new HTTPRepository(HTTPMemServer.REPOSITORY_URL);
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlSetBindingTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlSetBindingTest.java
new file mode 100644
index 00000000000..6567464a556
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlSetBindingTest.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.http;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlSetBindingTest;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class HTTPSparqlSetBindingTest extends SparqlSetBindingTest {
+
+ private static HTTPMemServer server;
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ }
+
+ protected Repository newRepository() {
+ return new HTTPRepository(HTTPMemServer.REPOSITORY_URL);
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlUpdateTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlUpdateTest.java
new file mode 100644
index 00000000000..9d6d40ee0b9
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPSparqlUpdateTest.java
@@ -0,0 +1,112 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.http;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import org.eclipse.rdf4j.model.vocabulary.FOAF;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.Update;
+import org.eclipse.rdf4j.query.parser.sparql.SPARQLUpdateTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * @author jeen
+ */
+public class HTTPSparqlUpdateTest extends SPARQLUpdateTest {
+
+ private static HTTPMemServer server;
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ }
+
+ @Override
+ protected Repository newRepository()
+ throws Exception
+ {
+ return new HTTPRepository(HTTPMemServer.REPOSITORY_URL);
+ }
+
+ @Ignore
+ @Test
+ @Override
+ public void testAutoCommitHandling() {
+ // transaction isolation is not supported for HTTP connections. disabling
+ // test.
+ System.err.println("temporarily disabled testAutoCommitHandling() for HTTPRepository. See SES-1652");
+ }
+
+ @Test
+ public void testBindingsInUpdateTransaction()
+ throws Exception
+ {
+ // See issue SES-1889
+ logger.debug("executing test testBindingsInUpdateTransaction");
+
+ StringBuilder update1 = new StringBuilder();
+ update1.append(getNamespaceDeclarations());
+ update1.append("DELETE { ?x foaf:name ?y } WHERE {?x foaf:name ?y }");
+
+ try {
+ assertTrue(con.hasStatement(bob, FOAF.NAME, f.createLiteral("Bob"), true));
+ assertTrue(con.hasStatement(alice, FOAF.NAME, f.createLiteral("Alice"), true));
+
+ con.begin();
+ Update operation = con.prepareUpdate(QueryLanguage.SPARQL, update1.toString());
+ operation.setBinding("x", bob);
+
+
+ operation.execute();
+
+ con.commit();
+
+ // only bob's name should have been deleted (due to the binding)
+ assertFalse(con.hasStatement(bob, FOAF.NAME, f.createLiteral("Bob"), true));
+ assertTrue(con.hasStatement(alice, FOAF.NAME, f.createLiteral("Alice"), true));
+
+ }
+ catch (Exception e) {
+ if(con.isActive()) {
+ con.rollback();
+ }
+ }
+ }
+
+ @Ignore
+ @Test
+ @Override
+ public void testConsecutiveUpdatesInSameTransaction() {
+ // transaction isolation is not supported for HTTP connections. disabling
+ // test.
+ System.err.println("temporarily disabled testConsecutiveUpdatesInSameTransaction() for HTTPRepository. See SES-1652");
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPStoreConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPStoreConnectionTest.java
new file mode 100644
index 00000000000..42d66df4b15
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/HTTPStoreConnectionTest.java
@@ -0,0 +1,120 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.http;
+
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.OpenRDFException;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.Update;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class HTTPStoreConnectionTest extends RepositoryConnectionTest {
+
+ private static HTTPMemServer server;
+
+ public HTTPStoreConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ }
+
+ @Override
+ protected Repository createRepository() {
+ return new HTTPRepository(HTTPMemServer.REPOSITORY_URL);
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testOrderByQueriesAreInterruptable() {
+ System.err.println("temporarily disabled testOrderByQueriesAreInterruptable() for HTTPRepository");
+ }
+
+ @Test
+ public void testUpdateExecution()
+ throws Exception
+ {
+
+ IRI foobar = vf.createIRI("foo:bar");
+
+ String sparql = "INSERT DATA { . } ";
+
+ Update update = testCon.prepareUpdate(QueryLanguage.SPARQL, sparql);
+
+ update.execute();
+
+ assertTrue(testCon.hasStatement(foobar, foobar, foobar, true));
+
+ testCon.clear();
+
+ assertFalse(testCon.hasStatement(foobar, foobar, foobar, true));
+
+ testCon.begin();
+ update.execute();
+ testCon.commit();
+
+ assertTrue(testCon.hasStatement(foobar, foobar, foobar, true));
+
+ }
+
+ @Test
+ @Override
+ public void testAddMalformedLiteralsDefaultConfig()
+ throws Exception
+ {
+ try {
+ testCon.add(
+ RepositoryConnectionTest.class.getResourceAsStream(TEST_DIR_PREFIX + "malformed-literals.ttl"),
+ "", RDFFormat.TURTLE);
+ }
+ catch (OpenRDFException e) {
+ fail("upload of malformed literals should not fail with error in default configuration for HTTPRepository");
+ }
+ }
+
+ @Test
+ @Override
+ @Ignore("See SES-1833")
+ public void testAddMalformedLiteralsStrictConfig()
+ throws Exception
+ {
+ System.err.println("SES-1833: temporarily disabled testAddMalformedLiteralsStrictConfig() for HTTPRepository");
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/RDFSchemaHTTPRepositoryConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/RDFSchemaHTTPRepositoryConnectionTest.java
new file mode 100644
index 00000000000..d18c28af3c1
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/http/RDFSchemaHTTPRepositoryConnectionTest.java
@@ -0,0 +1,197 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.http;
+
+import static org.junit.Assert.fail;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.OpenRDFException;
+import org.eclipse.rdf4j.repository.RDFSchemaRepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class RDFSchemaHTTPRepositoryConnectionTest extends RDFSchemaRepositoryConnectionTest {
+
+ private static HTTPMemServer server;
+
+ public RDFSchemaHTTPRepositoryConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ }
+
+ @Override
+ protected Repository createRepository() {
+ return new HTTPRepository(HTTPMemServer.INFERENCE_REPOSITORY_URL);
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testTransactionIsolationForRead()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testTransactionIsolationForRead() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testTransactionIsolationForReadWithDeleteOperation()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testTransactionIsolationForReadWithDeleteOperation() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testTransactionIsolation()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testTransactionIsolation() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testAutoCommit()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testAutoCommit() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testRollback()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testRollback() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testEmptyCommit()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testEmptyCommit() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testEmptyRollback()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testEmptyRollback() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testSizeCommit()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testSizeCommit() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testSizeRollback()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testSizeRollback() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testGetContextIDs()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testGetContextIDs() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testInferencerQueryDuringTransaction()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testInferencerDuringTransaction() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testInferencerTransactionIsolation()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testInferencerTransactionIsolation() for HTTPRepository");
+ }
+
+ @Ignore("temporarily disabled for HTTPRepository")
+ @Test
+ @Override
+ public void testOrderByQueriesAreInterruptable() {
+ System.err.println("temporarily disabled testOrderByQueriesAreInterruptable() for HTTPRepository");
+ }
+
+ @Test
+ @Override
+ public void testAddMalformedLiteralsDefaultConfig()
+ throws Exception
+ {
+ try {
+ testCon.add(
+ RepositoryConnectionTest.class.getResourceAsStream(TEST_DIR_PREFIX + "malformed-literals.ttl"),
+ "", RDFFormat.TURTLE);
+ }
+ catch (OpenRDFException e) {
+ fail("upload of malformed literals should not fail with error in default configuration for HTTPRepository");
+ }
+ }
+
+ @Test
+ @Override
+ @Ignore("See SES-1833")
+ public void testAddMalformedLiteralsStrictConfig()
+ throws Exception
+ {
+ System.err.println("SES-1833: temporarily disabled testAddMalformedLiteralsStrictConfig() for HTTPRepository");
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/CustomGraphQueryInferencerMemoryRepositoryConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/CustomGraphQueryInferencerMemoryRepositoryConnectionTest.java
new file mode 100644
index 00000000000..a887ca90629
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/CustomGraphQueryInferencerMemoryRepositoryConnectionTest.java
@@ -0,0 +1,39 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.common.io.ResourceUtil;
+import org.eclipse.rdf4j.query.MalformedQueryException;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.UnsupportedQueryLanguageException;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.inferencer.fc.CustomGraphQueryInferencer;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class CustomGraphQueryInferencerMemoryRepositoryConnectionTest extends RepositoryConnectionTest {
+
+ public CustomGraphQueryInferencerMemoryRepositoryConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @Override
+ protected Repository createRepository()
+ throws MalformedQueryException, UnsupportedQueryLanguageException, SailException, IOException
+ {
+ return new SailRepository(new CustomGraphQueryInferencer(new MemoryStore(),
+ QueryLanguage.SPARQL,
+ ResourceUtil.getString("/testcases/custom-query-inferencing/predicate/rule.rq"),
+ ResourceUtil.getString("/testcases/custom-query-inferencing/predicate/match.rq")));
+ }
+}
\ No newline at end of file
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryCascadeValueExceptionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryCascadeValueExceptionTest.java
new file mode 100644
index 00000000000..53125fdb7af
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryCascadeValueExceptionTest.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.CascadeValueExceptionTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemoryCascadeValueExceptionTest extends CascadeValueExceptionTest {
+
+ protected Repository newRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryGraphQueryResultTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryGraphQueryResultTest.java
new file mode 100644
index 00000000000..631a38ef558
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryGraphQueryResultTest.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.GraphQueryResultTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemoryGraphQueryResultTest extends GraphQueryResultTest {
+
+ protected Repository newRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryOptimisticIsolationTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryOptimisticIsolationTest.java
new file mode 100644
index 00000000000..25d0627e900
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryOptimisticIsolationTest.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.OptimisticIsolationTest;
+import org.eclipse.rdf4j.sail.memory.config.MemoryStoreFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class MemoryOptimisticIsolationTest extends OptimisticIsolationTest {
+
+ @BeforeClass
+ public static void setUpClass()
+ throws Exception
+ {
+ setSailFactory(new MemoryStoreFactory());
+ }
+
+ @AfterClass
+ public static void tearDown()
+ throws Exception
+ {
+ setSailFactory(null);
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySPARQLQueryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySPARQLQueryTest.java
new file mode 100644
index 00000000000..023ef380c4e
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySPARQLQueryTest.java
@@ -0,0 +1,51 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.query.Dataset;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.ManifestTest;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLQueryTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemorySPARQLQueryTest extends SPARQLQueryTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return ManifestTest.suite(new Factory() {
+
+ public MemorySPARQLQueryTest createSPARQLQueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality)
+ {
+ return createSPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, false);
+ }
+
+ public MemorySPARQLQueryTest createSPARQLQueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+ {
+ return new MemorySPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+ laxCardinality, checkOrder);
+ }
+ });
+ }
+
+ protected MemorySPARQLQueryTest(String testURI, String name, String queryFileURL, String resultFileURL,
+ Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+ {
+ super(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, checkOrder);
+ }
+
+ protected Repository newRepository() {
+ return new DatasetRepository(new SailRepository(new MemoryStore()));
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySeRQLQueryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySeRQLQueryTest.java
new file mode 100644
index 00000000000..bdfb7952fb2
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySeRQLQueryTest.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import java.util.List;
+
+import junit.framework.Test;
+
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.parser.serql.SeRQLQueryTestCase;
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemorySeRQLQueryTest extends SeRQLQueryTestCase {
+
+ public static Test suite() throws Exception {
+ return SeRQLQueryTestCase.suite(new Factory() {
+ public Test createTest(String name, String dataFile,
+ List graphNames, String queryFile,
+ String resultFile, String entailment) {
+ return new MemorySeRQLQueryTest(name, dataFile, graphNames,
+ queryFile, resultFile, entailment);
+ }
+ });
+ }
+
+ public MemorySeRQLQueryTest(String name, String dataFile,
+ List graphNames, String queryFile, String resultFile,
+ String entailment) {
+ super(name, dataFile, graphNames, queryFile, resultFile, entailment);
+ }
+
+ @Override
+ protected QueryLanguage getQueryLanguage() {
+ return QueryLanguage.SERQL;
+ }
+
+ @Override
+ protected NotifyingSail newSail() {
+ return new MemoryStore();
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlAggregatesTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlAggregatesTest.java
new file mode 100644
index 00000000000..221076e041d
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlAggregatesTest.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlAggregatesTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemorySparqlAggregatesTest extends SparqlAggregatesTest {
+
+ protected Repository newRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlDatasetTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlDatasetTest.java
new file mode 100644
index 00000000000..7a1ff4c2852
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlDatasetTest.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlDatasetTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemorySparqlDatasetTest extends SparqlDatasetTest {
+
+ protected Repository newRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlOrderByTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlOrderByTest.java
new file mode 100644
index 00000000000..250c8bfa3a7
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlOrderByTest.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlOrderByTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemorySparqlOrderByTest extends SparqlOrderByTest {
+
+ protected Repository newRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlRegexTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlRegexTest.java
new file mode 100644
index 00000000000..3e86f8444c4
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlRegexTest.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlRegexTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemorySparqlRegexTest extends SparqlRegexTest {
+
+ protected Repository newRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlSetBindingTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlSetBindingTest.java
new file mode 100644
index 00000000000..bdcfe95ba93
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemorySparqlSetBindingTest.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlRegexTest;
+import org.eclipse.rdf4j.repository.SparqlSetBindingTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemorySparqlSetBindingTest extends SparqlSetBindingTest {
+
+ protected Repository newRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryStoreConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryStoreConnectionTest.java
new file mode 100644
index 00000000000..a686df0fbf2
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryStoreConnectionTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemoryStoreConnectionTest extends RepositoryConnectionTest {
+
+ public MemoryStoreConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @Override
+ protected Repository createRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryStoreRepositoryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryStoreRepositoryTest.java
new file mode 100644
index 00000000000..4e4eb30b525
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryStoreRepositoryTest.java
@@ -0,0 +1,21 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemoryStoreRepositoryTest extends RepositoryTest {
+
+ @Override
+ protected Repository createRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryTupleQueryResultTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryTupleQueryResultTest.java
new file mode 100644
index 00000000000..ac8804e6ec4
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/MemoryTupleQueryResultTest.java
@@ -0,0 +1,20 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.TupleQueryResultTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemoryTupleQueryResultTest extends TupleQueryResultTest {
+
+ protected Repository newRepository() {
+ return new SailRepository(new MemoryStore());
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/RDFSchemaMemoryRepositoryConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/RDFSchemaMemoryRepositoryConnectionTest.java
new file mode 100644
index 00000000000..d8ff0313ddc
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/memory/RDFSchemaMemoryRepositoryConnectionTest.java
@@ -0,0 +1,27 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.memory;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.repository.RDFSchemaRepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.inferencer.fc.ForwardChainingRDFSInferencer;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class RDFSchemaMemoryRepositoryConnectionTest extends RDFSchemaRepositoryConnectionTest {
+
+ public RDFSchemaMemoryRepositoryConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @Override
+ protected Repository createRepository() {
+ return new SailRepository(new ForwardChainingRDFSInferencer(new MemoryStore()));
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/CustomGraphQueryInferencerNativeRepositoryConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/CustomGraphQueryInferencerNativeRepositoryConnectionTest.java
new file mode 100644
index 00000000000..2d4dc1f9d64
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/CustomGraphQueryInferencerNativeRepositoryConnectionTest.java
@@ -0,0 +1,56 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.common.io.ResourceUtil;
+import org.eclipse.rdf4j.query.MalformedQueryException;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.UnsupportedQueryLanguageException;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.inferencer.fc.CustomGraphQueryInferencer;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+public class CustomGraphQueryInferencerNativeRepositoryConnectionTest extends RepositoryConnectionTest {
+
+ private File dataDir;
+
+ public CustomGraphQueryInferencerNativeRepositoryConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @Override
+ protected Repository createRepository()
+ throws IOException, MalformedQueryException, UnsupportedQueryLanguageException, SailException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new CustomGraphQueryInferencer(new NativeStore(dataDir, "spoc"),
+ QueryLanguage.SPARQL,
+ ResourceUtil.getString("/testcases/custom-query-inferencing/predicate/rule.rq"),
+ ResourceUtil.getString("/testcases/custom-query-inferencing/predicate/match.rq")));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/LimitedSizeNativeStoreConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/LimitedSizeNativeStoreConnectionTest.java
new file mode 100644
index 00000000000..44257a03de9
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/LimitedSizeNativeStoreConnectionTest.java
@@ -0,0 +1,159 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.common.iteration.Iterations;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.query.QueryEvaluationException;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.TupleQuery;
+import org.eclipse.rdf4j.query.TupleQueryResult;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepositoryConnection;
+import org.eclipse.rdf4j.sail.nativerdf.LimitedSizeNativeStore;
+import org.eclipse.rdf4j.sail.nativerdf.LimitedSizeNativeStoreConnection;
+import org.junit.Test;
+
+public class LimitedSizeNativeStoreConnectionTest extends RepositoryConnectionTest {
+
+ private File dataDir;
+
+ public LimitedSizeNativeStoreConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @Override
+ protected Repository createRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new LimitedSizeNativeStore(dataDir, "spoc"));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+
+ @Test
+ public void testSES715()
+ throws Exception
+ {
+ // load 1000 triples in two different contexts
+ testCon.begin();
+ ValueFactory vf = testCon.getValueFactory();
+ IRI context1 = vf.createIRI("http://my.context.1");
+ IRI context2 = vf.createIRI("http://my.context.2");
+ IRI predicate = vf.createIRI("http://my.predicate");
+ IRI object = vf.createIRI("http://my.object");
+
+ for (int j = 0; j < 1000; j++) {
+ testCon.add(vf.createIRI("http://my.subject" + j), predicate, object, context1);
+ testCon.add(vf.createIRI("http://my.subject" + j), predicate, object, context2);
+ }
+ assertEquals(1000, Iterations.asList(testCon.getStatements(null, null, null, false, context1)).size());
+ assertEquals(1000, Iterations.asList(testCon.getStatements(null, null, null, false, context2)).size());
+
+ // remove all triples from context 1
+ testCon.clear(context1);
+ assertEquals(0, Iterations.asList(testCon.getStatements(null, null, null, false, context1)).size());
+ assertEquals(1000, Iterations.asList(testCon.getStatements(null, null, null, false, context2)).size());
+ testCon.commit();
+
+ // check context content using fresh connection
+ assertEquals(0, Iterations.asList(testCon2.getStatements(null, null, null, false, context1)).size());
+ assertEquals(1000, Iterations.asList(testCon2.getStatements(null, null, null, false, context2)).size());
+
+ testCon2.close();
+ }
+
+ @Test
+ public void testLimit()
+ throws Exception
+ {
+ ((LimitedSizeNativeStoreConnection)((SailRepositoryConnection)testCon).getSailConnection()).setMaxCollectionsSize(2);
+ testCon.begin();
+ ValueFactory vf = testCon.getValueFactory();
+ IRI context1 = vf.createIRI("http://my.context.1");
+ IRI predicate = vf.createIRI("http://my.predicate");
+ IRI object = vf.createIRI("http://my.object");
+
+ for (int j = 0; j < 100; j++) {
+ testCon.add(vf.createIRI("http://my.subject" + j), predicate, object, context1);
+ }
+ testCon.commit();
+ String queryString = "SELECT DISTINCT ?s WHERE {?s ?p ?o}";
+ TupleQuery q = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ QueryEvaluationException shouldThrow = runQuery(q);
+ assertNotNull(shouldThrow);
+
+ // There is just one object therefore we should not throw a new exception
+ queryString = "SELECT DISTINCT ?o WHERE {?s ?p ?o}";
+ q = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ shouldThrow = runQuery(q);
+ assertNull(shouldThrow);
+ }
+
+ @Test
+ public void testOrderAndLimit()
+ throws Exception
+ {
+ ((LimitedSizeNativeStoreConnection)((SailRepositoryConnection)testCon).getSailConnection()).setMaxCollectionsSize(2);
+ testCon.begin();
+ ValueFactory vf = testCon.getValueFactory();
+ IRI context1 = vf.createIRI("http://my.context.1");
+ IRI predicate = vf.createIRI("http://my.predicate");
+ IRI object = vf.createIRI("http://my.object");
+
+ for (int j = 0; j < 100; j++) {
+ testCon.add(vf.createIRI("http://my.subject" + j), predicate, object, context1);
+ }
+ testCon.commit();
+ String queryString = "SELECT DISTINCT ?s WHERE {?s ?p ?o} ORDER BY ?s";
+ TupleQuery q = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ QueryEvaluationException shouldThrow = runQuery(q);
+ assertNotNull(shouldThrow);
+
+ queryString = "SELECT DISTINCT ?s WHERE {?s ?p ?o} ORDER BY ?s LIMIT 2";
+ q = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryString);
+ shouldThrow = runQuery(q);
+ assertNull(shouldThrow);
+ }
+
+ protected QueryEvaluationException runQuery(TupleQuery q) {
+ QueryEvaluationException shouldThrow = null;
+ try {
+ TupleQueryResult r = q.evaluate();
+ assertTrue(r.hasNext());
+ while (r.hasNext()) {
+ assertNotNull(r.next());
+ }
+ }
+ catch (QueryEvaluationException e) {
+ shouldThrow = e;
+ }
+ return shouldThrow;
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeCascadeValueExceptionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeCascadeValueExceptionTest.java
new file mode 100644
index 00000000000..071fb2d0b5f
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeCascadeValueExceptionTest.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.repository.CascadeValueExceptionTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+public class NativeCascadeValueExceptionTest extends CascadeValueExceptionTest {
+
+ private File dataDir;
+
+ @Override
+ protected Repository newRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeComplexSPARQLQueryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeComplexSPARQLQueryTest.java
new file mode 100644
index 00000000000..00a197f4c71
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeComplexSPARQLQueryTest.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.query.parser.sparql.ComplexSPARQLQueryTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+/**
+ * @author jeen
+ */
+public class NativeComplexSPARQLQueryTest extends ComplexSPARQLQueryTest {
+
+ File dataDir = null;
+
+ @Override
+ protected Repository newRepository()
+ throws Exception
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeGraphQueryResultTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeGraphQueryResultTest.java
new file mode 100644
index 00000000000..532eaefcdd1
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeGraphQueryResultTest.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.repository.GraphQueryResultTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+public class NativeGraphQueryResultTest extends GraphQueryResultTest {
+
+ private File dataDir;
+
+ @Override
+ protected Repository newRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeOptimisticIsolationTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeOptimisticIsolationTest.java
new file mode 100644
index 00000000000..0c81ce7c4f7
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeOptimisticIsolationTest.java
@@ -0,0 +1,30 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import org.eclipse.rdf4j.repository.OptimisticIsolationTest;
+import org.eclipse.rdf4j.sail.nativerdf.config.NativeStoreFactory;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+public class NativeOptimisticIsolationTest extends OptimisticIsolationTest {
+
+ @BeforeClass
+ public static void setUpClass()
+ throws Exception
+ {
+ setSailFactory(new NativeStoreFactory());
+ }
+
+ @AfterClass
+ public static void tearDown()
+ throws Exception
+ {
+ setSailFactory(null);
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSPARQLQueryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSPARQLQueryTest.java
new file mode 100644
index 00000000000..44896f6a097
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSPARQLQueryTest.java
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.query.Dataset;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.ManifestTest;
+import org.eclipse.rdf4j.query.parser.sparql.manifest.SPARQLQueryTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+import junit.framework.Test;
+
+public class NativeSPARQLQueryTest extends SPARQLQueryTest {
+
+ public static Test suite()
+ throws Exception
+ {
+ return ManifestTest.suite(new Factory() {
+
+ public NativeSPARQLQueryTest createSPARQLQueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality)
+ {
+ return createSPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+ laxCardinality, false);
+ }
+
+ public NativeSPARQLQueryTest createSPARQLQueryTest(String testURI, String name, String queryFileURL,
+ String resultFileURL, Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+ {
+ return new NativeSPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+ laxCardinality, checkOrder);
+ }
+ });
+ }
+
+ private File dataDir;
+
+ protected NativeSPARQLQueryTest(String testURI, String name, String queryFileURL, String resultFileURL,
+ Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+ {
+ super(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, checkOrder);
+ }
+
+ @Override
+ protected Repository newRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new DatasetRepository(new SailRepository(new NativeStore(dataDir, "spoc")));
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSeRQLQueryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSeRQLQueryTest.java
new file mode 100644
index 00000000000..340ac6cea64
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSeRQLQueryTest.java
@@ -0,0 +1,57 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.parser.serql.SeRQLQueryTestCase;
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+import junit.framework.Test;
+
+public class NativeSeRQLQueryTest extends SeRQLQueryTestCase {
+
+ public static Test suite()
+ throws Exception
+ {
+ return SeRQLQueryTestCase.suite(new Factory() {
+
+ public Test createTest(String name, String dataFile, List graphNames, String queryFile,
+ String resultFile, String entailment)
+ {
+ return new NativeSeRQLQueryTest(name, dataFile, graphNames, queryFile, resultFile, entailment);
+ }
+ });
+ }
+
+ private File dataDir;
+
+ public NativeSeRQLQueryTest(String name, String dataFile, List graphNames, String queryFile,
+ String resultFile, String entailment)
+ {
+ super(name, dataFile, graphNames, queryFile, resultFile, entailment);
+ }
+
+ @Override
+ protected QueryLanguage getQueryLanguage() {
+ return QueryLanguage.SERQL;
+ }
+
+ @Override
+ protected NotifyingSail newSail()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new NativeStore(dataDir, "spoc");
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSparqlOrderByTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSparqlOrderByTest.java
new file mode 100644
index 00000000000..6d0cc365e29
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSparqlOrderByTest.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlOrderByTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+public class NativeSparqlOrderByTest extends SparqlOrderByTest {
+
+ private File dataDir;
+
+ @Override
+ protected Repository newRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSparqlRegexTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSparqlRegexTest.java
new file mode 100644
index 00000000000..7b8d5b3f633
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeSparqlRegexTest.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.SparqlRegexTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+public class NativeSparqlRegexTest extends SparqlRegexTest {
+
+ private File dataDir;
+
+ @Override
+ protected Repository newRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeStoreConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeStoreConnectionTest.java
new file mode 100644
index 00000000000..7c525ac3f47
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeStoreConnectionTest.java
@@ -0,0 +1,85 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import static org.junit.Assert.*;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.common.iteration.Iterations;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Test;
+
+public class NativeStoreConnectionTest extends RepositoryConnectionTest {
+
+ private File dataDir;
+
+ public NativeStoreConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @Override
+ protected Repository createRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+
+ @Test
+ public void testSES715()
+ throws Exception
+ {
+ // load 1000 triples in two different contexts
+ testCon.begin();
+ ValueFactory vf = testCon.getValueFactory();
+ IRI context1 = vf.createIRI("http://my.context.1");
+ IRI context2 = vf.createIRI("http://my.context.2");
+ IRI predicate = vf.createIRI("http://my.predicate");
+ IRI object = vf.createIRI("http://my.object");
+
+ for (int j = 0; j < 1000; j++) {
+ testCon.add(vf.createIRI("http://my.subject" + j), predicate, object, context1);
+ testCon.add(vf.createIRI("http://my.subject" + j), predicate, object, context2);
+ }
+ assertEquals(1000, Iterations.asList(testCon.getStatements(null, null, null, false, context1)).size());
+ assertEquals(1000, Iterations.asList(testCon.getStatements(null, null, null, false, context2)).size());
+
+ // remove all triples from context 1
+ testCon.clear(context1);
+ assertEquals(0, Iterations.asList(testCon.getStatements(null, null, null, false, context1)).size());
+ assertEquals(1000, Iterations.asList(testCon.getStatements(null, null, null, false, context2)).size());
+ testCon.commit();
+
+ // check context content using fresh connection
+ assertEquals(0, Iterations.asList(testCon2.getStatements(null, null, null, false, context1)).size());
+ assertEquals(1000, Iterations.asList(testCon2.getStatements(null, null, null, false, context2)).size());
+
+ testCon2.close();
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeStoreRepositoryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeStoreRepositoryTest.java
new file mode 100644
index 00000000000..cf33ceda2de
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeStoreRepositoryTest.java
@@ -0,0 +1,43 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+public class NativeStoreRepositoryTest extends RepositoryTest {
+
+ private File dataDir;
+
+ @Override
+ protected Repository createRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeTupleQueryResultTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeTupleQueryResultTest.java
new file mode 100644
index 00000000000..a04c618410a
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/NativeTupleQueryResultTest.java
@@ -0,0 +1,42 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.TupleQueryResultTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+public class NativeTupleQueryResultTest extends TupleQueryResultTest {
+
+ private File dataDir;
+
+ @Override
+ protected Repository newRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/RDFSchemaNativeRepositoryConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/RDFSchemaNativeRepositoryConnectionTest.java
new file mode 100644
index 00000000000..108b30b22a9
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/RDFSchemaNativeRepositoryConnectionTest.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.repository.RDFSchemaRepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.inferencer.fc.ForwardChainingRDFSInferencer;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+
+public class RDFSchemaNativeRepositoryConnectionTest extends RDFSchemaRepositoryConnectionTest {
+
+ private File dataDir;
+
+ public RDFSchemaNativeRepositoryConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @Override
+ protected Repository createRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new ForwardChainingRDFSInferencer(new NativeStore(dataDir, "spoc")));
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/TestNativeStoreMemoryOverflow.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/TestNativeStoreMemoryOverflow.java
new file mode 100644
index 00000000000..64ac7d2b0bb
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/nativerdf/TestNativeStoreMemoryOverflow.java
@@ -0,0 +1,163 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sail.nativerdf;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.IsolationLevels;
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.common.iteration.Iteration;
+import org.eclipse.rdf4j.common.iteration.Iterations;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.URI;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+/**
+ *
+ * @author James Leigh
+ */
+@RunWith(Parameterized.class)
+public class TestNativeStoreMemoryOverflow {
+
+ @Parameters(name="{0}")
+ public static final IsolationLevel[] parameters() {
+ return IsolationLevels.values();
+ }
+
+ private File dataDir;
+
+ private Repository testRepository;
+
+ private RepositoryConnection testCon;
+
+ private RepositoryConnection testCon2;
+
+ private IsolationLevel level;
+
+ public TestNativeStoreMemoryOverflow(IsolationLevel level) {
+ this.level = level;
+ }
+
+ @Before
+ public void setUp()
+ throws Exception
+ {
+ testRepository = createRepository();
+ testRepository.initialize();
+
+ testCon = testRepository.getConnection();
+ testCon.setIsolationLevel(level);
+ testCon.clear();
+ testCon.clearNamespaces();
+
+ testCon2 = testRepository.getConnection();
+ testCon2.setIsolationLevel(level);
+ }
+
+ private Repository createRepository()
+ throws IOException
+ {
+ dataDir = FileUtil.createTempDir("nativestore");
+ return new SailRepository(new NativeStore(dataDir, "spoc"));
+ }
+
+ @After
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ testCon2.close();
+ testCon.close();
+ testRepository.shutDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+
+ @Test
+ public void test()
+ throws Exception
+ {
+ int size = 10000; // this should really be bigger
+ // load a lot of triples in two different contexts
+ testCon.begin();
+ final ValueFactory vf = testCon.getValueFactory();
+ URI context1 = vf.createURI("http://my.context.1");
+ URI context2 = vf.createURI("http://my.context.2");
+ final URI predicate = vf.createURI("http://my.predicate");
+ final URI object = vf.createURI("http://my.object");
+
+ testCon.add(new DynamicIteration(size, predicate, object, vf), context1);
+ testCon.add(new DynamicIteration(size, predicate, object, vf), context2);
+
+ assertEquals(size, Iterations.asList(testCon.getStatements(null, null, null, false, context1)).size());
+ assertEquals(size, Iterations.asList(testCon.getStatements(null, null, null, false, context2)).size());
+ testCon.commit();
+
+ assertEquals(size, Iterations.asList(testCon.getStatements(null, null, null, false, context1)).size());
+ assertEquals(size, Iterations.asList(testCon.getStatements(null, null, null, false, context2)).size());
+
+ testCon.close();
+ }
+
+ private static final class DynamicIteration implements Iteration {
+
+ private final int size;
+
+ private final URI predicate;
+
+ private final URI object;
+
+ private final ValueFactory vf;
+
+ private int i;
+
+ private DynamicIteration(int size, URI predicate, URI object, ValueFactory vf) {
+ this.size = size;
+ this.predicate = predicate;
+ this.object = object;
+ this.vf = vf;
+ }
+
+ @Override
+ public boolean hasNext()
+ throws RuntimeException
+ {
+ return i < size;
+ }
+
+ @Override
+ public Statement next()
+ throws RuntimeException
+ {
+ return vf.createStatement(vf.createURI("http://my.subject" + i++), predicate, object);
+ }
+
+ @Override
+ public void remove()
+ throws RuntimeException
+ {
+ throw new UnsupportedOperationException();
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/MySqlSPARQL11QueryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/MySqlSPARQL11QueryTest.java
new file mode 100644
index 00000000000..c3260b0f27c
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/MySqlSPARQL11QueryTest.java
@@ -0,0 +1,62 @@
+package org.eclipse.rdf4j.repository.sail.rdbms;
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+// SES-1071 disabling rdbms-based tests
+//package org.eclipse.rdf4j.repository.sail.rdbms;
+//
+//import junit.framework.Test;
+//
+//import org.eclipse.rdf4j.query.Dataset;
+//import org.eclipse.rdf4j.query.parser.sparql.SPARQL11ManifestTest;
+//import org.eclipse.rdf4j.query.parser.sparql.SPARQLQueryTest;
+//import org.eclipse.rdf4j.repository.Repository;
+//import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+//import org.eclipse.rdf4j.repository.sail.SailRepository;
+//import org.eclipse.rdf4j.sail.rdbms.mysql.MySqlStore;
+//
+//public class MySqlSPARQL11QueryTest extends SPARQLQueryTest {
+//
+// public static Test suite()
+// throws Exception
+// {
+// return SPARQL11ManifestTest.suite(new Factory() {
+//
+// public MySqlSPARQL11QueryTest createSPARQLQueryTest(String testURI, String name,
+// String queryFileURL, String resultFileURL, Dataset dataSet, boolean laxCardinality)
+// {
+// return createSPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, false);
+// }
+//
+// public MySqlSPARQL11QueryTest createSPARQLQueryTest(String testURI, String name,
+// String queryFileURL, String resultFileURL, Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+// {
+// return new MySqlSPARQL11QueryTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+// laxCardinality, checkOrder);
+// }
+// });
+// }
+//
+// protected MySqlSPARQL11QueryTest(String testURI, String name, String queryFileURL, String resultFileURL,
+// Dataset dataSet, boolean laxCardinality)
+// {
+// this(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, false);
+// }
+//
+// protected MySqlSPARQL11QueryTest(String testURI, String name, String queryFileURL, String resultFileURL,
+// Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+// {
+// super(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, checkOrder);
+// }
+//
+// protected Repository newRepository() {
+// MySqlStore sail = new MySqlStore("sesame_test");
+// sail.setUser("sesame");
+// sail.setPassword("opensesame");
+// return new DatasetRepository(new SailRepository(sail));
+// }
+//}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/MySqlStoreConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/MySqlStoreConnectionTest.java
new file mode 100644
index 00000000000..ea25221e2f9
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/MySqlStoreConnectionTest.java
@@ -0,0 +1,39 @@
+package org.eclipse.rdf4j.repository.sail.rdbms;
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+// SES-1071 disabling rdbms-based tests
+//package org.eclipse.rdf4j.repository.sail.rdbms;
+//
+//import java.io.IOException;
+//
+//import org.eclipse.rdf4j.repository.Repository;
+//import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+//import org.eclipse.rdf4j.repository.sail.SailRepository;
+//import org.eclipse.rdf4j.sail.rdbms.mysql.MySqlStore;
+//
+//public class MySqlStoreConnectionTest extends RepositoryConnectionTest {
+//
+// public MySqlStoreConnectionTest(String name) {
+// super(name);
+// }
+//
+// @Override
+// protected Repository createRepository()
+// throws IOException
+// {
+// MySqlStore sail = new MySqlStore("sesame_test");
+// sail.setUser("sesame");
+// sail.setPassword("opensesame");
+// return new SailRepository(sail);
+// }
+//
+// @Override
+// public void testOrderByQueriesAreInterruptable() {
+// System.err.println("temporarily disabled testOrderByQueriesAreInterruptable() for RDBMS store");
+// }
+//}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/PgSqlSPARQL11QueryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/PgSqlSPARQL11QueryTest.java
new file mode 100644
index 00000000000..e284d3822f6
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/PgSqlSPARQL11QueryTest.java
@@ -0,0 +1,63 @@
+package org.eclipse.rdf4j.repository.sail.rdbms;
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+// SES-1071 disabling rdbms-based tests
+//package org.eclipse.rdf4j.repository.sail.rdbms;
+//
+//import junit.framework.Test;
+//
+//import org.eclipse.rdf4j.query.Dataset;
+//import org.eclipse.rdf4j.query.parser.sparql.SPARQL11ManifestTest;
+//import org.eclipse.rdf4j.query.parser.sparql.SPARQLQueryTest;
+//import org.eclipse.rdf4j.repository.Repository;
+//import org.eclipse.rdf4j.repository.dataset.DatasetRepository;
+//import org.eclipse.rdf4j.repository.sail.SailRepository;
+//import org.eclipse.rdf4j.sail.memory.MemoryStore;
+//import org.eclipse.rdf4j.sail.rdbms.postgresql.PgSqlStore;
+//
+//public class PgSqlSPARQL11QueryTest extends SPARQLQueryTest {
+//
+// public static Test suite()
+// throws Exception
+// {
+// return SPARQL11ManifestTest.suite(new Factory() {
+//
+// public PgSqlSPARQL11QueryTest createSPARQLQueryTest(String testURI, String name,
+// String queryFileURL, String resultFileURL, Dataset dataSet, boolean laxCardinality)
+// {
+// return createSPARQLQueryTest(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, false);
+// }
+//
+// public PgSqlSPARQL11QueryTest createSPARQLQueryTest(String testURI, String name,
+// String queryFileURL, String resultFileURL, Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+// {
+// return new PgSqlSPARQL11QueryTest(testURI, name, queryFileURL, resultFileURL, dataSet,
+// laxCardinality, checkOrder);
+// }
+// });
+// }
+//
+// protected PgSqlSPARQL11QueryTest(String testURI, String name, String queryFileURL, String resultFileURL,
+// Dataset dataSet, boolean laxCardinality)
+// {
+// this(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, false);
+// }
+//
+// protected PgSqlSPARQL11QueryTest(String testURI, String name, String queryFileURL, String resultFileURL,
+// Dataset dataSet, boolean laxCardinality, boolean checkOrder)
+// {
+// super(testURI, name, queryFileURL, resultFileURL, dataSet, laxCardinality, checkOrder);
+// }
+//
+// protected Repository newRepository() {
+// PgSqlStore sail = new PgSqlStore("sesame_test");
+// sail.setUser("sesame");
+// sail.setPassword("opensesame");
+// return new DatasetRepository(new SailRepository(sail));
+// }
+//}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/PgSqlStoreConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/PgSqlStoreConnectionTest.java
new file mode 100644
index 00000000000..f4f95a74e37
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sail/rdbms/PgSqlStoreConnectionTest.java
@@ -0,0 +1,39 @@
+package org.eclipse.rdf4j.repository.sail.rdbms;
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+// SES-1071 disabling rdbms-based tests
+//package org.eclipse.rdf4j.repository.sail.rdbms;
+//
+//import java.io.IOException;
+//
+//import org.eclipse.rdf4j.repository.Repository;
+//import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+//import org.eclipse.rdf4j.repository.sail.SailRepository;
+//import org.eclipse.rdf4j.sail.rdbms.postgresql.PgSqlStore;
+//
+//public class PgSqlStoreConnectionTest extends RepositoryConnectionTest {
+//
+// public PgSqlStoreConnectionTest(String name) {
+// super(name);
+// }
+//
+// @Override
+// protected Repository createRepository()
+// throws IOException
+// {
+// PgSqlStore sail = new PgSqlStore("sesame_test");
+// sail.setUser("sesame");
+// sail.setPassword("opensesame");
+// return new SailRepository(sail);
+// }
+//
+// @Override
+// public void testOrderByQueriesAreInterruptable() {
+// System.err.println("temporarily disabled testOrderByQueriesAreInterruptable() for RDBMS store");
+// }
+//}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLGraphQueryResultTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLGraphQueryResultTest.java
new file mode 100644
index 00000000000..1c295d70dfe
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLGraphQueryResultTest.java
@@ -0,0 +1,59 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sparql;
+
+import org.eclipse.rdf4j.http.protocol.Protocol;
+import org.eclipse.rdf4j.repository.GraphQueryResultTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.http.HTTPMemServer;
+import org.eclipse.rdf4j.repository.sparql.SPARQLRepository;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+
+
+/**
+ *
+ * @author Jeen Broekstra
+ */
+public class SPARQLGraphQueryResultTest extends GraphQueryResultTest {
+
+
+ private static HTTPMemServer server;
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ server = null;
+ }
+
+ @Override
+ protected Repository newRepository()
+ throws Exception
+ {
+ return new SPARQLRepository(HTTPMemServer.REPOSITORY_URL,
+ Protocol.getStatementsLocation(HTTPMemServer.REPOSITORY_URL));
+
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLRepositorySparqlUpdateTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLRepositorySparqlUpdateTest.java
new file mode 100644
index 00000000000..5d8f10c9b19
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLRepositorySparqlUpdateTest.java
@@ -0,0 +1,62 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sparql;
+
+import org.eclipse.rdf4j.query.parser.sparql.SPARQLUpdateTest;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.http.HTTPMemServer;
+import org.junit.Ignore;
+import org.junit.Test;
+
+/**
+ * @author Jeen Broekstra
+ */
+//public class SPARQLRepositorySparqlUpdateTest extends SPARQLUpdateTest {
+//
+// private HTTPMemServer server;
+//
+// @Override
+// public void setUp()
+// throws Exception
+// {
+// server = new HTTPMemServer();
+//
+// try {
+// server.start();
+// super.setUp();
+// }
+// catch (Exception e) {
+// server.stop();
+// throw e;
+// }
+// }
+//
+// @Override
+// public void tearDown()
+// throws Exception
+// {
+// super.tearDown();
+// server.stop();
+// }
+//
+// @Override
+// protected Repository newRepository()
+// throws Exception
+// {
+// return new SPARQLRepository(HTTPMemServer.REPOSITORY_URL, HTTPMemServer.REPOSITORY_URL + "/statements");
+// }
+//
+// @Ignore
+// @Test
+// @Override
+// public void testAutoCommitHandling()
+// {
+// // transaction isolation is not supported for HTTP connections. disabling test.
+// System.err.println("temporarily disabled testAutoCommitHandling() for HTTPRepository");
+// }
+//}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLRepositoryTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLRepositoryTest.java
new file mode 100644
index 00000000000..7b4862d5f3a
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLRepositoryTest.java
@@ -0,0 +1,72 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sparql;
+
+import org.eclipse.rdf4j.http.protocol.Protocol;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryTest;
+import org.eclipse.rdf4j.repository.http.HTTPMemServer;
+import org.eclipse.rdf4j.repository.sparql.SPARQLRepository;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+
+/**
+ * @author Jeen Broekstra
+ */
+public class SPARQLRepositoryTest extends RepositoryTest {
+
+ private static HTTPMemServer server;
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+
+ }
+
+ @Before
+ @Override
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+ // overwrite bnode test values as SPARQL endpoints do not generally work
+ // well with bnodes
+ bob = testRepository.getValueFactory().createIRI("urn:x-local:bob");
+ alice = testRepository.getValueFactory().createIRI("urn:x-local:alice");
+ alexander = testRepository.getValueFactory().createIRI("urn:x-local:alexander");
+
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ server = null;
+ }
+
+ @Override
+ protected Repository createRepository()
+ throws Exception
+ {
+ return new SPARQLRepository(HTTPMemServer.REPOSITORY_URL,
+ Protocol.getStatementsLocation(HTTPMemServer.REPOSITORY_URL));
+
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLServiceEvaluationTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLServiceEvaluationTest.java
new file mode 100644
index 00000000000..674473db267
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLServiceEvaluationTest.java
@@ -0,0 +1,203 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sparql;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+import java.io.InputStream;
+
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.FOAF;
+import org.eclipse.rdf4j.query.BindingSet;
+import org.eclipse.rdf4j.query.MalformedQueryException;
+import org.eclipse.rdf4j.query.QueryEvaluationException;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.TupleQuery;
+import org.eclipse.rdf4j.query.TupleQueryResult;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.RepositoryException;
+import org.eclipse.rdf4j.repository.http.HTTPMemServer;
+import org.eclipse.rdf4j.repository.http.HTTPRepository;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.rio.RDFParseException;
+import org.eclipse.rdf4j.rio.Rio;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+import org.junit.After;
+import org.junit.AfterClass;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * Test suite for evaluation of SPARQL queries involving SERVICE clauses. The
+ * test suite starts up an embedded Jetty server running Sesame, which functions
+ * as the SPARQL endpoint to test against.
+ *
+ * @author Jeen Broekstra
+ */
+public class SPARQLServiceEvaluationTest {
+
+ static final Logger logger = LoggerFactory.getLogger(SPARQLServiceEvaluationTest.class);
+
+ private static HTTPMemServer server;
+
+ private HTTPRepository remoteRepository;
+
+ private SailRepository localRepository;
+
+ private ValueFactory f;
+
+ private IRI bob;
+
+ private IRI alice;
+
+ private IRI william;
+
+ protected static final String EX_NS = "http://example.org/";
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ throw e;
+ }
+ }
+
+ @Before
+ public void setUp()
+ throws Exception
+ {
+ remoteRepository = new HTTPRepository(HTTPMemServer.REPOSITORY_URL);
+ remoteRepository.initialize();
+ loadDataSet(remoteRepository, "/testdata-query/graph1.ttl");
+ loadDataSet(remoteRepository, "/testdata-query/graph2.ttl");
+
+ localRepository = new SailRepository(new MemoryStore());
+ localRepository.initialize();
+
+ loadDataSet(localRepository, "/testdata-query/defaultgraph.ttl");
+
+ f = localRepository.getValueFactory();
+
+ bob = f.createIRI(EX_NS, "bob");
+ alice = f.createIRI(EX_NS, "alice");
+ william = f.createIRI(EX_NS, "william");
+ }
+
+ protected void loadDataSet(Repository rep, String datasetFile)
+ throws RDFParseException, RepositoryException, IOException
+ {
+ logger.debug("loading dataset...");
+ InputStream dataset = SPARQLServiceEvaluationTest.class.getResourceAsStream(datasetFile);
+
+ RepositoryConnection con = rep.getConnection();
+ try {
+ con.add(dataset, "",
+ Rio.getParserFormatForFileName(datasetFile).orElseThrow(Rio.unsupportedFormat(datasetFile)));
+ }
+ finally {
+ dataset.close();
+ con.close();
+ }
+ logger.debug("dataset loaded.");
+ }
+
+ /**
+ * @throws java.lang.Exception
+ */
+ @After
+ public void tearDown()
+ throws Exception
+ {
+ localRepository.shutDown();
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ server = null;
+ }
+
+ @Test
+ public void testSimpleServiceQuery()
+ throws RepositoryException
+ {
+ StringBuilder qb = new StringBuilder();
+ qb.append(" SELECT * \n");
+ qb.append(" WHERE { \n");
+ qb.append(" SERVICE <" + HTTPMemServer.REPOSITORY_URL + "> { \n");
+ qb.append(" ?X <" + FOAF.NAME + "> ?Y \n ");
+ qb.append(" } \n ");
+ qb.append(" ?X a <" + FOAF.PERSON + "> . \n");
+ qb.append(" } \n");
+
+ RepositoryConnection conn = localRepository.getConnection();
+ try {
+ TupleQuery tq = conn.prepareTupleQuery(QueryLanguage.SPARQL, qb.toString());
+
+ TupleQueryResult tqr = tq.evaluate();
+
+ assertNotNull(tqr);
+ assertTrue(tqr.hasNext());
+
+ int count = 0;
+ while (tqr.hasNext()) {
+ BindingSet bs = tqr.next();
+ count++;
+
+ Value x = bs.getValue("X");
+ Value y = bs.getValue("Y");
+
+ assertFalse(william.equals(x));
+
+ assertTrue(bob.equals(x) || alice.equals(x));
+ if (bob.equals(x)) {
+ f.createLiteral("Bob").equals(y);
+ }
+ else if (alice.equals(x)) {
+ f.createLiteral("Alice").equals(y);
+ }
+ }
+
+ assertEquals(2, count);
+
+ }
+ catch (MalformedQueryException e) {
+ fail(e.getMessage());
+ }
+ catch (QueryEvaluationException e) {
+ fail(e.getMessage());
+ }
+ finally {
+ conn.close();
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLStoreConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLStoreConnectionTest.java
new file mode 100644
index 00000000000..3b59209917d
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/repository/sparql/SPARQLStoreConnectionTest.java
@@ -0,0 +1,644 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.repository.sparql;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertTrue;
+
+import java.lang.reflect.Field;
+import java.lang.reflect.Modifier;
+import java.util.List;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.OpenRDFException;
+import org.eclipse.rdf4j.common.iteration.Iterations;
+import org.eclipse.rdf4j.http.protocol.Protocol;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.query.BindingSet;
+import org.eclipse.rdf4j.query.GraphQuery;
+import org.eclipse.rdf4j.query.GraphQueryResult;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.TupleQuery;
+import org.eclipse.rdf4j.query.TupleQueryResult;
+import org.eclipse.rdf4j.query.Update;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.http.HTTPMemServer;
+import org.eclipse.rdf4j.repository.sparql.SPARQLConnection;
+import org.eclipse.rdf4j.repository.sparql.SPARQLRepository;
+import org.junit.AfterClass;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Ignore;
+import org.junit.Test;
+
+public class SPARQLStoreConnectionTest extends RepositoryConnectionTest {
+
+ private static HTTPMemServer server;
+
+ public SPARQLStoreConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @BeforeClass
+ public static void startServer()
+ throws Exception
+ {
+ server = new HTTPMemServer();
+ try {
+ server.start();
+ }
+ catch (Exception e) {
+ server.stop();
+ server = null;
+ throw e;
+ }
+
+ }
+
+ @AfterClass
+ public static void stopServer()
+ throws Exception
+ {
+ server.stop();
+ server = null;
+ }
+
+ @Before
+ @Override
+ public void setUp()
+ throws Exception
+ {
+ super.setUp();
+ // overwrite bnode test values as SPARQL endpoints do not generally work
+ // well with bnodes
+ bob = testRepository.getValueFactory().createIRI("urn:x-local:bob");
+ alice = testRepository.getValueFactory().createIRI("urn:x-local:alice");
+ alexander = testRepository.getValueFactory().createIRI("urn:x-local:alexander");
+ }
+
+ @Override
+ protected Repository createRepository() {
+ return new SPARQLRepository(HTTPMemServer.REPOSITORY_URL,
+ Protocol.getStatementsLocation(HTTPMemServer.REPOSITORY_URL));
+ }
+
+ @Override
+ @Ignore
+ public void testDuplicateFilter() throws Exception {
+ System.err.println("temporarily disabled testDuplicateFilter() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testAddDelete()
+ throws OpenRDFException
+ {
+ System.err.println("temporarily disabled testAddDelete() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testAddRemoveInsert()
+ throws OpenRDFException
+ {
+ System.err.println("temporarily disabled testAddRemoveInsert() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testSizeRollback()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testSizeRollback() for SPARQLRepository");
+ }
+
+ @Test
+ @Ignore
+ @Override
+ public void testURISerialization()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testURISerialization() for SPARQLRepository");
+ }
+
+ @Test
+ @Ignore
+ @Override
+ public void testStatementSerialization()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testStatementSerialization() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testAutoCommit()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testAutoCommit() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testRollback()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testRollback() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testEmptyRollback()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testEmptyRollback() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testEmptyCommit()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testEmptyCommit() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testPrepareSeRQLQuery()
+ throws Exception
+ {
+ System.err.println("disabled testPrepareSeRQLQuery() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testLiteralSerialization()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testLiteralSerialization() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testSizeCommit()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testSizeCommit() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testGetStatementsInMultipleContexts()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testGetStatementsInMultipleContexts() for SPARQLRepository: implementation of statement context using SPARQL not yet complete");
+ // TODO see SES-1776
+ }
+
+ @Test
+ public void testGetStatementsContextHandling()
+ throws Exception
+ {
+ // enable quad mode
+ enableQuadModeOnConnection((SPARQLConnection)testCon);
+
+ testCon.clear();
+
+ testCon.begin();
+ testCon.add(alice, name, nameAlice, context1);
+ testCon.add(bob, name, nameBob);
+ testCon.commit();
+
+ List res;
+
+ // test 1: alice statement should have context 1
+ res = Iterations.asList(testCon.getStatements(alice, null, null, false));
+ Assert.assertEquals(1, res.size());
+ Assert.assertEquals(context1, res.iterator().next().getContext());
+
+ // test 2: bob statement should have default named graph
+ res = Iterations.asList(testCon.getStatements(bob, null, null, false));
+ Assert.assertEquals(1, res.size());
+ Assert.assertEquals(null, res.iterator().next().getContext());
+
+ // test 3: bound statement should fetch context
+ res = Iterations.asList(testCon.getStatements(alice, name, nameAlice, false));
+ Assert.assertEquals(1, res.size());
+ Assert.assertEquals(context1, res.iterator().next().getContext());
+
+ }
+
+ /**
+ * Enable the quadMode on the given connection. This is done
+ * via reflection here as the test setup already creates the
+ * repository and connection and we do not have a chance to
+ * set the mode easily inside the test (as quadMode is an
+ * immutable field of the connection).
+ *
+ * Note: this is only done such that we can reuse the test
+ * infrastructure of the base class.
+ */
+ private void enableQuadModeOnConnection(SPARQLConnection con)
+ throws Exception
+ {
+ Field quadModeField = SPARQLConnection.class.getDeclaredField("quadMode");
+ quadModeField.setAccessible(true);
+
+ // remove final modifier from field
+ Field modifiersField = Field.class.getDeclaredField("modifiers");
+ modifiersField.setAccessible(true);
+ modifiersField.setInt(quadModeField, quadModeField.getModifiers() & ~Modifier.FINAL);
+
+ quadModeField.set(con, true);
+ }
+
+ @Override
+ @Ignore
+ public void testGetStatementsInSingleContext()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testGetStatementsInSingleContext() for SPARQLRepository: implementation of statement context using SPARQL not yet complete");
+ // TODO see SES-1776
+ }
+
+ @Ignore
+ @Override
+ public void testOrderByQueriesAreInterruptable()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testOrderByQueriesAreInterruptable() for SPARQLRepository");
+ }
+
+ @Test
+ @Override
+ @Ignore("can not execute test because required data add results in illegal SPARQL syntax")
+ public void testGetStatementsMalformedLanguageLiteral()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testGetStatementsMalformedLanguageLiteral() for SPARQLRepository");
+ }
+
+ @Override
+ public void testPreparedTupleQuery()
+ throws Exception
+ {
+ testCon.add(alice, name, nameAlice, context2);
+ testCon.add(alice, mbox, mboxAlice, context2);
+ testCon.add(context2, publisher, nameAlice);
+
+ testCon.add(bob, name, nameBob, context1);
+ testCon.add(bob, mbox, mboxBob, context1);
+ testCon.add(context1, publisher, nameBob);
+
+ StringBuilder queryBuilder = new StringBuilder();
+ queryBuilder.append(" PREFIX foaf: <" + FOAF_NS + "> ");
+ queryBuilder.append(" SELECT ?name ?mbox");
+ queryBuilder.append(" WHERE { [] foaf:name ?name;");
+ queryBuilder.append(" foaf:mbox ?mbox. }");
+
+ TupleQuery query = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryBuilder.toString());
+ query.setBinding("name", nameBob);
+
+ TupleQueryResult result = query.evaluate();
+
+ try {
+ assertTrue(result != null);
+ assertTrue(result.hasNext());
+
+ while (result.hasNext()) {
+ BindingSet solution = result.next();
+ assertTrue(solution.hasBinding("name"));
+ assertTrue(solution.hasBinding("mbox"));
+
+ Value nameResult = solution.getValue("name");
+ Value mboxResult = solution.getValue("mbox");
+
+ assertEquals("unexpected value for name: " + nameResult, nameBob, nameResult);
+ assertEquals("unexpected value for mbox: " + mboxResult, mboxBob, mboxResult);
+ }
+ }
+ finally {
+ result.close();
+ }
+ }
+
+ @Override
+ @Ignore
+ public void testGetNamespaces()
+ throws Exception
+ {
+ System.err.println("disabled testGetNamespaces() as namespace retrieval is not supported by SPARQL");
+ }
+
+ @Override
+ @Ignore
+ public void testGetNamespace()
+ throws Exception
+ {
+ System.err.println("disabled testGetNamespace() as namespace retrieval is not supported by SPARQL");
+ }
+
+ @Ignore("temporarily disabled for SPARQLRepository")
+ @Test
+ @Override
+ public void testTransactionIsolationForRead()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testTransactionIsolationForRead() for SPARQLRepository");
+ }
+
+ @Ignore("temporarily disabled for SPARQLRepository")
+ @Test
+ @Override
+ public void testTransactionIsolationForReadWithDeleteOperation()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testTransactionIsolationForReadWithDeleteOperation() for SPARQLRepository");
+ }
+
+ @Override
+ @Ignore
+ public void testTransactionIsolation()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testTransactionIsolation() for SPARQLRepository");
+ }
+
+ @Override
+ public void testPreparedTupleQuery2()
+ throws Exception
+ {
+ testCon.add(alice, name, nameAlice, context2);
+ testCon.add(alice, mbox, mboxAlice, context2);
+ testCon.add(context2, publisher, nameAlice);
+
+ testCon.add(bob, name, nameBob, context1);
+ testCon.add(bob, mbox, mboxBob, context1);
+ testCon.add(context1, publisher, nameBob);
+
+ StringBuilder queryBuilder = new StringBuilder();
+ queryBuilder.append(" PREFIX foaf: <" + FOAF_NS + ">");
+ queryBuilder.append(" SELECT ?name ?mbox");
+ queryBuilder.append(" WHERE {?p foaf:name ?name ;");
+ queryBuilder.append(" foaf:mbox ?mbox .");
+ queryBuilder.append(" FILTER (?p = ?VAR) } ");
+
+ TupleQuery query = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryBuilder.toString());
+ query.setBinding("VAR", bob);
+
+ TupleQueryResult result = query.evaluate();
+
+ try {
+ assertTrue(result != null);
+ assertTrue(result.hasNext());
+
+ while (result.hasNext()) {
+ BindingSet solution = result.next();
+ assertTrue(solution.hasBinding("name"));
+ assertTrue(solution.hasBinding("mbox"));
+
+ Value nameResult = solution.getValue("name");
+ Value mboxResult = solution.getValue("mbox");
+
+ assertEquals("unexpected value for name: " + nameResult, nameBob, nameResult);
+ assertEquals("unexpected value for mbox: " + mboxResult, mboxBob, mboxResult);
+ }
+ }
+ finally {
+ result.close();
+ }
+ }
+
+ @Override
+ public void testPreparedTupleQueryUnicode()
+ throws Exception
+ {
+ testCon.add(alexander, name, Александър);
+
+ StringBuilder queryBuilder = new StringBuilder();
+ queryBuilder.append(" PREFIX foaf: <" + FOAF_NS + "> ");
+ queryBuilder.append(" SELECT ?person");
+ queryBuilder.append(" WHERE {?person foaf:name ?name . }");
+
+ TupleQuery query = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryBuilder.toString());
+ query.setBinding("name", Александър);
+
+ TupleQueryResult result = query.evaluate();
+
+ try {
+ assertNotNull(result);
+ assertTrue(result.hasNext());
+
+ while (result.hasNext()) {
+ BindingSet solution = result.next();
+ assertTrue(solution.hasBinding("person"));
+ assertEquals(alexander, solution.getValue("person"));
+ }
+ }
+ finally {
+ result.close();
+ }
+ }
+
+ @Override
+ public void testSimpleGraphQuery()
+ throws Exception
+ {
+ testCon.add(alice, name, nameAlice, context2);
+ testCon.add(alice, mbox, mboxAlice, context2);
+ testCon.add(context2, publisher, nameAlice);
+
+ testCon.add(bob, name, nameBob, context1);
+ testCon.add(bob, mbox, mboxBob, context1);
+ testCon.add(context1, publisher, nameBob);
+
+ StringBuilder queryBuilder = new StringBuilder();
+ queryBuilder.append(" PREFIX foaf: <" + FOAF_NS + ">");
+ queryBuilder.append(" CONSTRUCT ");
+ queryBuilder.append(" WHERE { [] foaf:name ?name; ");
+ queryBuilder.append(" foaf:mbox ?mbox. }");
+
+ GraphQueryResult result = testCon.prepareGraphQuery(QueryLanguage.SPARQL, queryBuilder.toString()).evaluate();
+
+ try {
+ assertTrue(result != null);
+ assertTrue(result.hasNext());
+
+ while (result.hasNext()) {
+ Statement st = result.next();
+ if (name.equals(st.getPredicate())) {
+ assertTrue(nameAlice.equals(st.getObject()) || nameBob.equals(st.getObject()));
+ }
+ else {
+ assertTrue(mbox.equals(st.getPredicate()));
+ assertTrue(mboxAlice.equals(st.getObject()) || mboxBob.equals(st.getObject()));
+ }
+ }
+ }
+ finally {
+ result.close();
+ }
+ }
+
+ @Override
+ public void testPreparedGraphQuery()
+ throws Exception
+ {
+ testCon.add(alice, name, nameAlice, context2);
+ testCon.add(alice, mbox, mboxAlice, context2);
+ testCon.add(context2, publisher, nameAlice);
+
+ testCon.add(bob, name, nameBob, context1);
+ testCon.add(bob, mbox, mboxBob, context1);
+ testCon.add(context1, publisher, nameBob);
+
+ StringBuilder queryBuilder = new StringBuilder();
+ queryBuilder.append(" PREFIX foaf: <" + FOAF_NS + "> ");
+ queryBuilder.append(" CONSTRUCT ");
+ queryBuilder.append(" WHERE { [] foaf:name ?name ;");
+ queryBuilder.append(" foaf:mbox ?mbox . ");
+ queryBuilder.append(" } ");
+
+ GraphQuery query = testCon.prepareGraphQuery(QueryLanguage.SPARQL, queryBuilder.toString());
+ query.setBinding("name", nameBob);
+
+ GraphQueryResult result = query.evaluate();
+
+ try {
+ assertTrue(result != null);
+ assertTrue(result.hasNext());
+
+ while (result.hasNext()) {
+ Statement st = result.next();
+ assertTrue(name.equals(st.getPredicate()) || mbox.equals(st.getPredicate()));
+ if (name.equals(st.getPredicate())) {
+ assertTrue("unexpected value for name: " + st.getObject(), nameBob.equals(st.getObject()));
+ }
+ else {
+ assertTrue(mbox.equals(st.getPredicate()));
+ assertTrue("unexpected value for mbox: " + st.getObject(), mboxBob.equals(st.getObject()));
+ }
+
+ }
+ }
+ finally {
+ result.close();
+ }
+ }
+
+ @Override
+ public void testSimpleTupleQuery()
+ throws Exception
+ {
+ testCon.add(alice, name, nameAlice, context2);
+ testCon.add(alice, mbox, mboxAlice, context2);
+ testCon.add(context2, publisher, nameAlice);
+
+ testCon.add(bob, name, nameBob, context1);
+ testCon.add(bob, mbox, mboxBob, context1);
+ testCon.add(context1, publisher, nameBob);
+
+ StringBuilder queryBuilder = new StringBuilder();
+ queryBuilder.append(" PREFIX foaf: <" + FOAF_NS + "> ");
+ queryBuilder.append(" SELECT ?name ?mbox");
+ queryBuilder.append(" WHERE { [] foaf:name ?name ;");
+ queryBuilder.append(" foaf:mbox ?mbox . ");
+ queryBuilder.append(" } ");
+ TupleQueryResult result = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryBuilder.toString()).evaluate();
+
+ try {
+ assertTrue(result != null);
+ assertTrue(result.hasNext());
+
+ while (result.hasNext()) {
+ BindingSet solution = result.next();
+ assertTrue(solution.hasBinding("name"));
+ assertTrue(solution.hasBinding("mbox"));
+
+ Value nameResult = solution.getValue("name");
+ Value mboxResult = solution.getValue("mbox");
+
+ assertTrue((nameAlice.equals(nameResult) || nameBob.equals(nameResult)));
+ assertTrue((mboxAlice.equals(mboxResult) || mboxBob.equals(mboxResult)));
+ }
+ }
+ finally {
+ result.close();
+ }
+ }
+
+ @Override
+ public void testSimpleTupleQueryUnicode()
+ throws Exception
+ {
+ testCon.add(alexander, name, Александър);
+
+ StringBuilder queryBuilder = new StringBuilder();
+ queryBuilder.append(" PREFIX foaf: <" + FOAF_NS + ">");
+ queryBuilder.append(" SELECT ?person");
+ queryBuilder.append(" WHERE { ?person foaf:name \"").append(Александър.getLabel()).append("\" . } ");
+
+ TupleQueryResult result = testCon.prepareTupleQuery(QueryLanguage.SPARQL, queryBuilder.toString()).evaluate();
+
+ try {
+ assertNotNull(result);
+ assertTrue(result.hasNext());
+
+ while (result.hasNext()) {
+ BindingSet solution = result.next();
+ assertTrue(solution.hasBinding("person"));
+ assertEquals(alexander, solution.getValue("person"));
+ }
+ }
+ finally {
+ result.close();
+ }
+ }
+
+ @Override
+ @Ignore
+ public void testBNodeSerialization()
+ throws Exception
+ {
+ System.err.println("temporarily disabled testBNodeSerialization() for SPARQLRepository");
+ }
+
+ @Test
+ public void testUpdateExecution()
+ throws Exception
+ {
+
+ IRI foobar = vf.createIRI("foo:bar");
+
+ String sparql = "INSERT DATA { . } ";
+
+ Update update = testCon.prepareUpdate(QueryLanguage.SPARQL, sparql);
+
+ update.execute();
+
+ assertTrue(testCon.hasStatement(foobar, foobar, foobar, true));
+
+ testCon.clear();
+
+ assertFalse(testCon.hasStatement(foobar, foobar, foobar, true));
+
+ testCon.begin();
+ update.execute();
+ testCon.commit();
+
+ assertTrue(testCon.hasStatement(foobar, foobar, foobar, true));
+
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/federation/FederationConnectionTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/federation/FederationConnectionTest.java
new file mode 100644
index 00000000000..a7ddd3cafd5
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/federation/FederationConnectionTest.java
@@ -0,0 +1,46 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.federation;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.IsolationLevel;
+import org.eclipse.rdf4j.IsolationLevels;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnectionTest;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.federation.Federation;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class FederationConnectionTest extends RepositoryConnectionTest {
+
+ @Parameters(name="{0}")
+ public static final IsolationLevel[] parametersNONE() {
+ // isolation is not supported
+ return new IsolationLevel[] { IsolationLevels.NONE };
+ }
+
+ public FederationConnectionTest(IsolationLevel level) {
+ super(level);
+ }
+
+ @Override
+ protected Repository createRepository()
+ throws IOException
+ {
+ Federation sail = new Federation();
+ sail.addMember(new SailRepository(new MemoryStore()));
+ sail.addMember(new SailRepository(new MemoryStore()));
+ sail.addMember(new SailRepository(new MemoryStore()));
+ return new SailRepository(sail);
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/federation/FederationTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/federation/FederationTest.java
new file mode 100644
index 00000000000..09fdbbc2fdf
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/federation/FederationTest.java
@@ -0,0 +1,44 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.federation;
+
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.sail.RDFStoreTest;
+import org.eclipse.rdf4j.sail.Sail;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.federation.Federation;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+/**
+ * An extension of RDFStoreTest for testing the class {@link MulgaraStore}.
+ */
+public class FederationTest extends RDFStoreTest {
+
+ /*--------------*
+ * Constructors *
+ *--------------*/
+ public FederationTest() {
+ super();
+ }
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected Sail createSail()
+ throws SailException
+ {
+ Federation sail = new Federation();
+ sail.addMember(new SailRepository(new MemoryStore()));
+ sail.addMember(new SailRepository(new MemoryStore()));
+ sail.addMember(new SailRepository(new MemoryStore()));
+ sail.initialize();
+ return sail;
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/helpers/NotifyingSailConnectionWrapperTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/helpers/NotifyingSailConnectionWrapperTest.java
new file mode 100644
index 00000000000..0dbfdb5677f
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/helpers/NotifyingSailConnectionWrapperTest.java
@@ -0,0 +1,114 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.helpers;
+
+import static org.hamcrest.core.Is.is;
+import static org.hamcrest.core.IsEqual.equalTo;
+import static org.junit.Assert.assertThat;
+
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.sail.SailConnectionListener;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.helpers.NotifyingSailConnectionWrapper;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+/**
+ * Some general tests for {@link NogifyingSailConnectionWrapper} expected
+ * behaviour.
+ *
+ * @author Dale Visser
+ */
+public class NotifyingSailConnectionWrapperTest {
+
+ /**
+ * @author Dale Visser
+ */
+ private final class TestListener implements SailConnectionListener {
+
+ int testCounter = 0;
+
+ @Override
+ public void statementAdded(Statement st) {
+ testCounter++;
+ }
+
+ @Override
+ public void statementRemoved(Statement st) {
+ testCounter--;
+ }
+
+ public int getCount() {
+ return testCounter;
+ }
+ }
+
+ NotifyingSailConnectionWrapper wrapper;
+
+ ValueFactory factory;
+
+ TestListener listener = new TestListener();
+
+ MemoryStore memoryStore = new MemoryStore();
+
+ @Before
+ public void before()
+ throws SailException
+ {
+ memoryStore.initialize();
+ wrapper = new NotifyingSailConnectionWrapper(memoryStore.getConnection());
+ factory = memoryStore.getValueFactory();
+ }
+
+ @After
+ public void after()
+ throws SailException
+ {
+ wrapper.close();
+ memoryStore.shutDown();
+ }
+
+ /**
+ * Regression test for SES-1934.
+ *
+ * @throws SailException
+ */
+ @Test
+ public void testAddThenRemoveListener()
+ throws SailException
+ {
+ wrapper.addConnectionListener(listener);
+ addStatement("a");
+ assertThat(listener.getCount(), is(equalTo(1)));
+ removeStatement("a");
+ assertThat(listener.getCount(), is(equalTo(0)));
+ wrapper.removeConnectionListener(listener);
+ addStatement("b");
+ assertThat(listener.getCount(), is(equalTo(0)));
+ }
+
+ private void removeStatement(String objectValue)
+ throws SailException
+ {
+ wrapper.begin();
+ wrapper.removeStatements(null, factory.createIRI("urn:pred"), factory.createLiteral(objectValue));
+ wrapper.commit();
+ }
+
+ private void addStatement(String objectValue)
+ throws SailException
+ {
+ wrapper.begin();
+ wrapper.addStatement(factory.createBNode(), factory.createIRI("urn:pred"),
+ factory.createLiteral(objectValue));
+ wrapper.commit();
+ }
+}
\ No newline at end of file
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemCustomInferencingTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemCustomInferencingTest.java
new file mode 100644
index 00000000000..583e11afc3c
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemCustomInferencingTest.java
@@ -0,0 +1,26 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.memory;
+
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.sail.CustomGraphQueryInferencerTest;
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemCustomInferencingTest extends CustomGraphQueryInferencerTest {
+
+ public MemCustomInferencingTest(String resourceFolder, Expectation testData, QueryLanguage language) {
+ super(resourceFolder, testData, language);
+ }
+
+ @Override
+ protected NotifyingSail newSail() {
+ NotifyingSail store = new MemoryStore();
+ return store;
+ }
+}
\ No newline at end of file
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemInferencingTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemInferencingTest.java
new file mode 100644
index 00000000000..c18daba3823
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemInferencingTest.java
@@ -0,0 +1,22 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.memory;
+
+import org.eclipse.rdf4j.sail.InferencingTest;
+import org.eclipse.rdf4j.sail.Sail;
+import org.eclipse.rdf4j.sail.inferencer.fc.ForwardChainingRDFSInferencer;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+public class MemInferencingTest extends InferencingTest {
+
+ @Override
+ protected Sail createSail() {
+ Sail sailStack = new ForwardChainingRDFSInferencer(new MemoryStore());
+ return sailStack;
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreConcurrencyTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreConcurrencyTest.java
new file mode 100644
index 00000000000..3f332e94b02
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreConcurrencyTest.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.memory;
+
+import org.eclipse.rdf4j.sail.Sail;
+import org.eclipse.rdf4j.sail.SailConcurrencyTest;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+/**
+ * An extension of {@link SailConcurrencyTest} for testing the class
+ * {@link MemoryStore}.
+ */
+public class MemoryStoreConcurrencyTest extends SailConcurrencyTest {
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected Sail createSail()
+ throws SailException
+ {
+ return new MemoryStore();
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreIsolationLevelTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreIsolationLevelTest.java
new file mode 100644
index 00000000000..d9cd8c9a15d
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreIsolationLevelTest.java
@@ -0,0 +1,31 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.memory;
+
+import org.eclipse.rdf4j.sail.Sail;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.SailIsolationLevelTest;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+/**
+ * An extension of {@link SailIsolationLevelTest} for testing the class
+ * {@link MemoryStore}.
+ */
+public class MemoryStoreIsolationLevelTest extends SailIsolationLevelTest {
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected Sail createSail()
+ throws SailException
+ {
+ return new MemoryStore();
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreTest.java
new file mode 100644
index 00000000000..e55350d9214
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/MemoryStoreTest.java
@@ -0,0 +1,34 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.memory;
+
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.RDFNotifyingStoreTest;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+
+/**
+ * An extension of RDFStoreTest for testing the class
+ * org.eclipse.rdf4j.sesame.sail.memory.MemoryStore.
+ */
+public class MemoryStoreTest extends RDFNotifyingStoreTest {
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected NotifyingSail createSail()
+ throws SailException
+ {
+ NotifyingSail sail = new MemoryStore();
+ sail.initialize();
+ return sail;
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/PersistentMemoryStoreTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/PersistentMemoryStoreTest.java
new file mode 100644
index 00000000000..f99fcbca48e
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/PersistentMemoryStoreTest.java
@@ -0,0 +1,54 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+
+package org.eclipse.rdf4j.sail.memory;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.RDFNotifyingStoreTest;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+/**
+ * An extension of RDFStoreTest for testing the class
+ * org.eclipse.rdf4j.sesame.sail.memory.MemoryStore.
+ */
+public class PersistentMemoryStoreTest extends RDFNotifyingStoreTest {
+
+ private volatile File dataDir;
+
+ @Override
+ protected NotifyingSail createSail()
+ throws SailException
+ {
+ try {
+ dataDir = FileUtil.createTempDir(PersistentMemoryStoreTest.class.getSimpleName());
+ NotifyingSail sail = new MemoryStore(dataDir);
+ sail.initialize();
+ return sail;
+ }
+ catch (IOException e) {
+ throw new SailException(e);
+ }
+ }
+
+ @Override
+ public void tearDown()
+ throws Exception
+ {
+ try {
+ super.tearDown();
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/StoreSerializationTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/StoreSerializationTest.java
new file mode 100644
index 00000000000..e63c10af784
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/memory/StoreSerializationTest.java
@@ -0,0 +1,195 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.memory;
+
+import java.io.File;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.common.iteration.CloseableIteration;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Literal;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.query.BindingSet;
+import org.eclipse.rdf4j.query.QueryEvaluationException;
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.query.algebra.TupleExpr;
+import org.eclipse.rdf4j.query.impl.EmptyBindingSet;
+import org.eclipse.rdf4j.query.parser.ParsedTupleQuery;
+import org.eclipse.rdf4j.query.parser.QueryParserUtil;
+import org.eclipse.rdf4j.sail.SailConnection;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.memory.MemoryStore;
+
+import junit.framework.TestCase;
+
+public class StoreSerializationTest extends TestCase {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ private File dataDir;
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected void setUp()
+ throws Exception
+ {
+ super.setUp();
+ dataDir = FileUtil.createTempDir("memorystore");
+ }
+
+ @Override
+ protected void tearDown()
+ throws Exception
+ {
+ super.tearDown();
+ FileUtil.deleteDir(dataDir);
+ }
+
+ public void testShortLiterals()
+ throws Exception
+ {
+ MemoryStore store = new MemoryStore(dataDir);
+ store.initialize();
+
+ ValueFactory factory = store.getValueFactory();
+ IRI foo = factory.createIRI("http://www.foo.example/foo");
+
+ StringBuilder sb = new StringBuilder(4);
+ for (int i = 0; i < 4; i++) {
+ sb.append('a');
+ }
+
+ Literal longLiteral = factory.createLiteral(sb.toString());
+
+ SailConnection con = store.getConnection();
+ con.begin();
+ con.addStatement(foo, RDF.VALUE, longLiteral);
+ con.commit();
+
+ con.close();
+ store.shutDown();
+
+ store = new MemoryStore(dataDir);
+ store.initialize();
+
+ con = store.getConnection();
+
+ CloseableIteration extends Statement, SailException> iter = con.getStatements(foo, RDF.VALUE, null,
+ false);
+ assertTrue(iter.hasNext());
+ iter.next();
+ iter.close();
+
+ con.close();
+ store.shutDown();
+ }
+
+ public void testSerialization()
+ throws Exception
+ {
+ MemoryStore store = new MemoryStore(dataDir);
+ store.initialize();
+
+ ValueFactory factory = store.getValueFactory();
+ IRI foo = factory.createIRI("http://www.foo.example/foo");
+ IRI bar = factory.createIRI("http://www.foo.example/bar");
+
+ SailConnection con = store.getConnection();
+ con.begin();
+ con.addStatement(foo, RDF.TYPE, bar);
+ con.commit();
+
+ ParsedTupleQuery query = QueryParserUtil.parseTupleQuery(QueryLanguage.SERQL,
+ "SELECT X, P, Y FROM {X} P {Y}", null);
+ TupleExpr tupleExpr = query.getTupleExpr();
+
+ CloseableIteration extends BindingSet, QueryEvaluationException> iter = con.evaluate(tupleExpr, null,
+ EmptyBindingSet.getInstance(), false);
+
+ BindingSet bindingSet = iter.next();
+
+ assertEquals(bindingSet.getValue("X"), foo);
+ assertEquals(bindingSet.getValue("P"), RDF.TYPE);
+ assertEquals(bindingSet.getValue("Y"), bar);
+ iter.close();
+ con.close();
+
+ store.shutDown();
+
+ store = new MemoryStore(dataDir);
+ store.initialize();
+
+ factory = store.getValueFactory();
+ foo = factory.createIRI("http://www.foo.example/foo");
+ bar = factory.createIRI("http://www.foo.example/bar");
+
+ con = store.getConnection();
+
+ iter = con.evaluate(tupleExpr, null, EmptyBindingSet.getInstance(), false);
+
+ bindingSet = iter.next();
+
+ assertEquals(bindingSet.getValue("X"), foo);
+ assertEquals(bindingSet.getValue("P"), RDF.TYPE);
+ assertEquals(bindingSet.getValue("Y"), bar);
+
+ iter.close();
+ con.begin();
+ con.addStatement(bar, RDF.TYPE, foo);
+ con.commit();
+ con.close();
+
+ store.shutDown();
+ }
+
+ public void testLongLiterals()
+ throws Exception
+ {
+ MemoryStore store = new MemoryStore(dataDir);
+ store.initialize();
+
+ ValueFactory factory = store.getValueFactory();
+ IRI foo = factory.createIRI("http://www.foo.example/foo");
+
+ StringBuilder sb = new StringBuilder(66000);
+ for (int i = 0; i < 66000; i++) {
+ sb.append('a');
+ }
+
+ Literal longLiteral = factory.createLiteral(sb.toString());
+
+ SailConnection con = store.getConnection();
+ con.begin();
+ con.addStatement(foo, RDF.VALUE, longLiteral);
+ con.commit();
+
+ con.close();
+ store.shutDown();
+
+ store = new MemoryStore(dataDir);
+ store.initialize();
+
+ con = store.getConnection();
+
+ CloseableIteration extends Statement, SailException> iter = con.getStatements(foo, RDF.VALUE, null,
+ false);
+ assertTrue(iter.hasNext());
+ iter.next();
+ iter.close();
+
+ con.close();
+ store.shutDown();
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreConcurrencyTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreConcurrencyTest.java
new file mode 100644
index 00000000000..b6db4449936
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreConcurrencyTest.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.SailConcurrencyTest;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * An extension of {@link SailConcurrencyTest} for testing the class
+ * {@link NativeStore}.
+ */
+public class NativeStoreConcurrencyTest extends SailConcurrencyTest {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected NotifyingSail createSail()
+ throws SailException
+ {
+ try {
+ return new NativeStore(tempDir.newFolder("nativestore"), "spoc,posc");
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreConsistencyTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreConsistencyTest.java
new file mode 100644
index 00000000000..1f043fe6e35
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreConsistencyTest.java
@@ -0,0 +1,138 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+
+import org.eclipse.rdf4j.common.iteration.Iterations;
+import org.eclipse.rdf4j.model.IRI;
+import org.eclipse.rdf4j.model.Model;
+import org.eclipse.rdf4j.model.Resource;
+import org.eclipse.rdf4j.model.Statement;
+import org.eclipse.rdf4j.model.Value;
+import org.eclipse.rdf4j.model.ValueFactory;
+import org.eclipse.rdf4j.model.impl.LinkedHashModel;
+import org.eclipse.rdf4j.model.impl.SimpleValueFactory;
+import org.eclipse.rdf4j.repository.Repository;
+import org.eclipse.rdf4j.repository.RepositoryConnection;
+import org.eclipse.rdf4j.repository.sail.SailRepository;
+import org.eclipse.rdf4j.repository.util.RepositoryUtil;
+import org.eclipse.rdf4j.rio.RDFFormat;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * Integration tests for checking Native Store index consistency.
+ *
+ * @author Jeen Broekstra
+ */
+public class NativeStoreConsistencyTest {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Test
+ public void testSES1867IndexCorruption() throws Exception {
+ ValueFactory vf = SimpleValueFactory.getInstance();
+ IRI oldContext = vf.createIRI("http://example.org/oldContext");
+ IRI newContext = vf.createIRI("http://example.org/newContext");
+
+ File dataDir = tempDir.newFolder("nativestore-consistency");
+
+ Repository repo = new SailRepository(new NativeStore(dataDir, "spoc,psoc"));
+ repo.initialize();
+
+ RepositoryConnection conn = repo.getConnection();
+
+ // Step1: setup the initial database state
+ System.out.println("Preserving initial state ...");
+ conn.add(getClass().getResourceAsStream("/nativestore-testdata/SES-1867/initialState.nq"), "",
+ RDFFormat.NQUADS);
+ System.out.println("Number of statements: " + conn.size());
+
+ // Step 2: in a single transaction remove "oldContext", then add
+ // statements to "newContext"
+ conn.begin();
+
+ System.out.println("Removing old context");
+ conn.remove((Resource)null, (IRI)null, (Value)null, oldContext);
+
+ System.out.println("Adding updated context");
+ conn.add(getClass().getResourceAsStream("/nativestore-testdata/SES-1867/newTriples.nt"), "",
+ RDFFormat.NTRIPLES, newContext);
+ conn.commit();
+
+ // Step 3: check whether oldContext is actually empty
+ List stmts = Iterations.asList(conn.getStatements(null, null, null, false, oldContext));
+ System.out.println("Not deleted statements: " + stmts.size());
+
+ conn.close();
+ repo.shutDown();
+
+ // Step 4: check the repository size with SPOC only
+ new File(dataDir, "triples.prop").delete(); // delete triples.prop to
+ // update index usage
+ repo = new SailRepository(new NativeStore(dataDir, "spoc"));
+ repo.initialize();
+ conn = repo.getConnection();
+ System.out.println("Repository size with SPOC index only: " + conn.size());
+ Model spocStatements = Iterations.addAll(conn.getStatements(null, null, null, false),
+ new LinkedHashModel());
+ conn.close();
+ repo.shutDown();
+
+ // Step 5: check the repository size with PSOC only
+ new File(dataDir, "triples.prop").delete(); // delete triples.prop to
+ // update index usage
+ repo = new SailRepository(new NativeStore(dataDir, "psoc"));
+ repo.initialize();
+ conn = repo.getConnection();
+ System.out.println("Repository size with PSOC index only: " + conn.size());
+ Model psocStatements = Iterations.addAll(conn.getStatements(null, null, null, false),
+ new LinkedHashModel());
+ conn.close();
+ repo.shutDown();
+
+ // Step 6: computing the differences of the contents of the indices
+ System.out.println("Computing differences of sets...");
+
+ Collection extends Statement> differenceA = RepositoryUtil.difference(spocStatements, psocStatements);
+ Collection extends Statement> differenceB = RepositoryUtil.difference(psocStatements, spocStatements);
+
+ System.out.println("Difference SPOC MINUS PSOC: " + differenceA.size());
+ System.out.println("Difference PSOC MINUS SPOC: " + differenceB.size());
+
+ System.out.println("Different statements in SPOC MINUS PSOC (Mind the contexts):");
+ for (Statement st : differenceA) {
+ System.out.println(" * " + st);
+ }
+
+ System.out.println("Different statements in PSOC MINUS SPOC (Mind the contexts):");
+ for (Statement st : differenceB) {
+ System.out.println(" * " + st);
+ }
+
+ assertEquals(0, differenceA.size());
+ assertEquals(0, differenceB.size());
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreContextTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreContextTest.java
new file mode 100644
index 00000000000..8fe84d8ed7e
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreContextTest.java
@@ -0,0 +1,48 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.RDFNotifyingStoreTest;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * An extension of RDFStoreTest for testing the class {@link NativeStore}.
+ */
+public class NativeStoreContextTest extends RDFNotifyingStoreTest {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected NotifyingSail createSail()
+ throws SailException
+ {
+ try {
+ NotifyingSail sail = new NativeStore(tempDir.newFolder("nativestore"), "spoc,posc");
+ sail.initialize();
+ return sail;
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreCustomInferencingTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreCustomInferencingTest.java
new file mode 100644
index 00000000000..92ffec07534
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreCustomInferencingTest.java
@@ -0,0 +1,41 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import static org.junit.Assert.fail;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.query.QueryLanguage;
+import org.eclipse.rdf4j.sail.CustomGraphQueryInferencerTest;
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+public class NativeStoreCustomInferencingTest extends CustomGraphQueryInferencerTest {
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ public NativeStoreCustomInferencingTest(String resourceFolder, Expectation testData, QueryLanguage language)
+ {
+ super(resourceFolder, testData, language);
+ }
+
+ @Override
+ protected NotifyingSail newSail() {
+ try {
+ return new NativeStore(tempDir.newFolder("nativestore"), "spoc,posc");
+ }
+ catch (IOException e) {
+ fail(e.getMessage());
+ throw new AssertionError(e);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreDirLockTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreDirLockTest.java
new file mode 100644
index 00000000000..c216ebb27eb
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreDirLockTest.java
@@ -0,0 +1,53 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+
+import org.eclipse.rdf4j.sail.SailLockedException;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+public class NativeStoreDirLockTest {
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ @Test
+ public void testLocking()
+ throws Exception
+ {
+ File dataDir = tempDir.newFolder("nativestore");
+ NativeStore sail = new NativeStore(dataDir, "spoc,posc");
+ sail.initialize();
+
+ try {
+ NativeStore sail2 = new NativeStore(dataDir, "spoc,posc");
+ sail2.initialize();
+ try {
+ fail("initialized a second native store with same dataDir");
+ }
+ finally {
+ sail2.shutDown();
+ }
+ }
+ catch (SailLockedException e) {
+ // Expected: should not be able to open two native stores with the
+ // same dataDir
+ assertNotNull(e);
+ }
+ finally {
+ sail.shutDown();
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreInferencingTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreInferencingTest.java
new file mode 100644
index 00000000000..2b107fc471a
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreInferencingTest.java
@@ -0,0 +1,36 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.sail.InferencingTest;
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.Sail;
+import org.eclipse.rdf4j.sail.inferencer.fc.ForwardChainingRDFSInferencer;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+public class NativeStoreInferencingTest extends InferencingTest {
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ @Override
+ protected Sail createSail() {
+ try {
+ NotifyingSail sailStack = new NativeStore(tempDir.newFolder("nativestore"), "spoc,posc");
+ sailStack = new ForwardChainingRDFSInferencer(sailStack);
+ return sailStack;
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreInterruptTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreInterruptTest.java
new file mode 100644
index 00000000000..380ed1e66e2
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreInterruptTest.java
@@ -0,0 +1,49 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.SailConcurrencyTest;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.SailInterruptTest;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * An extension of {@link SailConcurrencyTest} for testing the class
+ * {@link NativeStore}.
+ */
+public class NativeStoreInterruptTest extends SailInterruptTest {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected NotifyingSail createSail()
+ throws SailException
+ {
+ try {
+ return new NativeStore(tempDir.newFolder("nativestore"), "spoc,posc");
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreIsolationLevelTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreIsolationLevelTest.java
new file mode 100644
index 00000000000..2bdebe3c939
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreIsolationLevelTest.java
@@ -0,0 +1,47 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.SailIsolationLevelTest;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * An extension of {@link SailIsolationLevelTest} for testing the class
+ * {@link NativeStore}.
+ */
+public class NativeStoreIsolationLevelTest extends SailIsolationLevelTest {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected NotifyingSail createSail()
+ throws SailException
+ {
+ try {
+ return new NativeStore(tempDir.newFolder("nativestore"), "spoc,posc");
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreTest.java
new file mode 100644
index 00000000000..380f9842f64
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/NativeStoreTest.java
@@ -0,0 +1,71 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf;
+
+import static org.junit.Assert.assertEquals;
+
+import java.io.IOException;
+
+import org.eclipse.rdf4j.model.vocabulary.RDF;
+import org.eclipse.rdf4j.sail.NotifyingSail;
+import org.eclipse.rdf4j.sail.RDFNotifyingStoreTest;
+import org.eclipse.rdf4j.sail.SailException;
+import org.eclipse.rdf4j.sail.nativerdf.NativeStore;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.TemporaryFolder;
+
+/**
+ * An extension of RDFStoreTest for testing the class {@link NativeStore}.
+ */
+public class NativeStoreTest extends RDFNotifyingStoreTest {
+
+ /*-----------*
+ * Variables *
+ *-----------*/
+
+ @Rule
+ public TemporaryFolder tempDir = new TemporaryFolder();
+
+ /*---------*
+ * Methods *
+ *---------*/
+
+ @Override
+ protected NotifyingSail createSail()
+ throws SailException
+ {
+ try {
+ NotifyingSail sail = new NativeStore(tempDir.newFolder("nativestore"), "spoc,posc");
+ sail.initialize();
+ return sail;
+ }
+ catch (IOException e) {
+ throw new AssertionError(e);
+ }
+ }
+
+ // Test for SES-542
+ @Test()
+ public void testGetNamespacePersistence()
+ throws Exception
+ {
+ con.begin();
+ con.setNamespace("rdf", RDF.NAMESPACE);
+ con.commit();
+ assertEquals(RDF.NAMESPACE, con.getNamespace("rdf"));
+
+ con.close();
+ sail.shutDown();
+ sail.initialize();
+ con = sail.getConnection();
+
+ assertEquals(RDF.NAMESPACE, con.getNamespace("rdf"));
+ }
+
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/datastore/DataStorePerfTest.java b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/datastore/DataStorePerfTest.java
new file mode 100644
index 00000000000..a69a68ef2e9
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/datastore/DataStorePerfTest.java
@@ -0,0 +1,118 @@
+/*******************************************************************************
+ * 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.
+ *******************************************************************************/
+package org.eclipse.rdf4j.sail.nativerdf.datastore;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+import org.eclipse.rdf4j.common.io.FileUtil;
+import org.eclipse.rdf4j.sail.nativerdf.datastore.DataStore;
+
+/**
+ *
+ */
+public class DataStorePerfTest {
+
+ public static void main(String[] args)
+ throws Exception
+ {
+ System.out.println("DataStore performance test");
+ System.out.println("==========================");
+
+ System.out.println("Warming up...");
+ for (int i = 0; i < 3; i++) {
+ runPerformanceTest(10000);
+ System.gc();
+ Thread.sleep(2000);
+ }
+
+ System.out.println("Starting test...");
+
+ List timeDataList = new ArrayList();
+
+ for (int stringCount = 1000000; stringCount <= 3000000; stringCount += 1000000) {
+ timeDataList.add( runPerformanceTest(stringCount));
+ System.gc();
+ Thread.sleep(1000);
+ }
+
+ System.out.println("Performance test results, average times in micro seconds");
+ System.out.println("#str\tstore\tgetID\tgetData");
+ for (long[] timeData : timeDataList) {
+ System.out.printf("%d\t%d\t%d\t%d",
+ timeData[0], timeData[1]/1000, timeData[2]/1000, timeData[3]/1000);
+ System.out.println();
+ }
+ }
+
+ private static long[] runPerformanceTest(int stringCount)
+ throws Exception
+ {
+ System.out.println("Running performance test with " + stringCount + " strings...");
+
+ long[] timeData = new long[4];
+ timeData[0] = stringCount;
+
+ File dataDir = FileUtil.createTempDir("datastoretest");
+
+ try {
+ System.out.println("Initializing data store in directory " + dataDir);
+ DataStore dataStore = new DataStore(dataDir, "strings");
+
+ System.out.println("Storing strings...");
+ long startTime = System.nanoTime();
+
+ for (int i = 1; i <= stringCount; i++) {
+ dataStore.storeData(String.valueOf(i).getBytes());
+ }
+
+ dataStore.sync();
+ long endTime = System.nanoTime();
+ timeData[1] = (endTime - startTime) / stringCount;
+ System.out.println("Strings stored in " + (endTime-startTime)/1E6 + " ms");
+
+ System.out.println("Fetching IDs for all strings...");
+ startTime = System.nanoTime();
+
+ for (int i = 1; i <= stringCount; i++) {
+ int sID = dataStore.getID(String.valueOf(i).getBytes());
+ if (sID == -1) {
+ throw new RuntimeException("Failed to get ID for string \"" + i + "\"");
+ }
+ }
+
+ endTime = System.nanoTime();
+ timeData[2] = (endTime - startTime) / stringCount;
+ System.out.println("All IDs fetched in " + (endTime-startTime)/1E6 + " ms");
+
+ System.out.println("Fetching data for all IDs...");
+ startTime = System.nanoTime();
+
+ for (int id = 1; id <= stringCount; id++) {
+ String s = new String(dataStore.getData(id));
+ if (s == null) {
+ throw new RuntimeException("Failed to get data for ID " + id);
+ }
+ }
+
+ endTime = System.nanoTime();
+ timeData[3] = (endTime - startTime) / stringCount;
+ System.out.println("All data fetched in " + (endTime-startTime)/1E6 + " ms");
+
+ System.out.println("Closing DataStore...");
+ dataStore.close();
+ System.out.println("Done.");
+
+ return timeData;
+ }
+ finally {
+ FileUtil.deleteDir(dataDir);
+ }
+ }
+}
diff --git a/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/datastore/measurements.txt b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/datastore/measurements.txt
new file mode 100644
index 00000000000..05fa38e7253
--- /dev/null
+++ b/compliance/store/src/test/java/org/eclipse/rdf4j/sail/nativerdf/datastore/measurements.txt
@@ -0,0 +1,26 @@
+Performance test results of DataStorePerfTest. Average times in micro seconds.
+Results gathered on Dell Latitude D610 w/ 1.73GHz Pentium M, 1 GB mem @800MHz,
+Toshiba MK6026GAX 60GB hard drive @5400rpm.
+
+===Baseline times===
+#str store getID getData
+1000000 93 17 14
+2000000 268 17 14
+
+===2005-12-21: hash file stores IDs instead of offsets; removed ID from data file===
+#str store getID getData
+1000000 87 21 13
+2000000 136 21 13
+3000000 166 21 14
+
+===2005-12-22: replaced hash file with btree w/ 2048 byte nodes===
+#str store getID getData
+1000000 91 31 14
+2000000 116 36 14
+3000000 247 43 14
+
+===2006-01-05: hash file, bug fixed IDIterator loops===
+#str store getID getData
+1000000 85 21 14
+2000000 106 21 14
+3000000 250 22 14
\ No newline at end of file
diff --git a/compliance/store/src/test/resources/log4j.properties b/compliance/store/src/test/resources/log4j.properties
new file mode 100644
index 00000000000..885932a0ea6
--- /dev/null
+++ b/compliance/store/src/test/resources/log4j.properties
@@ -0,0 +1,18 @@
+# root logger
+log4j.rootLogger=WARN, MainLog
+
+# MainLog configuration
+log4j.appender.MainLog=org.apache.log4j.DailyRollingFileAppender
+log4j.appender.MainLog.DatePattern='.'yyyy-MM-dd
+# Real filename is set in AppConfiguration, relative to dataDir
+log4j.appender.MainLog.File=target/combined-client-server.log
+
+# MainLog uses a custom PatternLayout that also outputs stack traces
+log4j.appender.MainLog.layout=info.aduna.logging.file.log4j.StackTracePatternLayout
+
+# OpenRDF logging
+log4j.logger.org.openrdf=DEBUG
+
+# Aduna logging
+log4j.logger.info.aduna.iteration=DEBUG
+log4j.logger.info.aduna.collections=DEBUG
diff --git a/compliance/store/src/test/resources/logback-test.xml b/compliance/store/src/test/resources/logback-test.xml
new file mode 100644
index 00000000000..4a6f17fbfa4
--- /dev/null
+++ b/compliance/store/src/test/resources/logback-test.xml
@@ -0,0 +1,15 @@
+
+
+
+
+
+ %d{HH:mm:ss.SSS} [%thread] %-5level %msg%n
+
+
+
+
+
+
+
+
+
diff --git a/compliance/store/src/test/resources/nativestore-testdata/SES-1867/initialState.nq b/compliance/store/src/test/resources/nativestore-testdata/SES-1867/initialState.nq
new file mode 100755
index 00000000000..57b7facb872
--- /dev/null
+++ b/compliance/store/src/test/resources/nativestore-testdata/SES-1867/initialState.nq
@@ -0,0 +1,59991 @@
+ .
+ .
+ "1ac494e5da5f59dffa0bc7b9c26331d2c9262baf4cbff0eb0d95bada13befcbf" .
+ .
+ "90631bc85d77d4e499ccefaef93719cafe3b6e05fe4c783c474ff64b4b2361a4" .
+ "5233559d21a86abffab5a50811a3fef635c6665b47c6bf175e670a09178597ca" .
+ "a354c85c6b65d514f428592b698c80df5443465c496979be99ad771361a36ab1" .
+ .
+ .
+ "364075b6fa26518d49f5ac8f4b4cf066f69b26ebb70f31b7106b1adc3ca1c599" .
+ "64af40e9a0ad777cc50e88f5c83e004697378bed0bad1348f00132ce4545d08e" .
+ "cc661425d96fb8569a2fa170dbf799e20374ba12e6406fd2428585c2d65b2bec" .
+ "74297d1544703954e5241af3b2bc73cca998294fc52eb1dbd7ca9a249f24a74b" .
+ "090f8c082d07ee72264f9dbdd057638b5678e7bcd2912fa8a9746e136825605d" .
+