http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/4576f556/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoDbSmartUriIT.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoDbSmartUriIT.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoDbSmartUriIT.java
index d5fe97c..6b73691 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoDbSmartUriIT.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoDbSmartUriIT.java
@@ -51,7 +51,7 @@ import 
org.apache.rya.indexing.entity.storage.mongo.ConvertingCursor;
 import org.apache.rya.indexing.mongodb.MongoDbSmartUri;
 import org.apache.rya.indexing.smarturi.SmartUriAdapter;
 import org.apache.rya.indexing.smarturi.SmartUriException;
-import org.apache.rya.mongodb.MongoTestBase;
+import org.apache.rya.mongodb.MongoITBase;
 import org.joda.time.DateTime;
 import org.junit.Before;
 import org.junit.Test;
@@ -77,7 +77,7 @@ import info.aduna.iteration.CloseableIteration;
 /**
  * Tests for MongoDB based Smart URI.
  */
-public class MongoDbSmartUriIT extends MongoTestBase {
+public class MongoDbSmartUriIT extends MongoITBase {
     private static final String NAMESPACE = RyaSchema.NAMESPACE;
     private static final ValueFactory VALUE_FACTORY = 
ValueFactoryImpl.getInstance();
 

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/4576f556/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndex2IT.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndex2IT.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndex2IT.java
new file mode 100644
index 0000000..ee3869f
--- /dev/null
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndex2IT.java
@@ -0,0 +1,248 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.mongo;
+
+import java.util.List;
+
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.indexing.entity.EntityIndexOptimizer;
+import org.apache.rya.indexing.entity.model.Entity;
+import org.apache.rya.indexing.entity.model.Property;
+import org.apache.rya.indexing.entity.model.Type;
+import org.apache.rya.indexing.entity.query.EntityQueryNode;
+import org.apache.rya.indexing.entity.storage.EntityStorage;
+import org.apache.rya.indexing.entity.storage.TypeStorage;
+import org.apache.rya.mongodb.MongoITBase;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.BeforeClass;
+import org.junit.Test;
+import org.openrdf.model.vocabulary.RDF;
+import org.openrdf.query.MalformedQueryException;
+import org.openrdf.query.algebra.QueryModelNode;
+import org.openrdf.query.algebra.StatementPattern;
+import org.openrdf.query.algebra.TupleExpr;
+import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
+import org.openrdf.query.algebra.helpers.StatementPatternCollector;
+import org.openrdf.query.parser.sparql.SPARQLParser;
+
+import com.google.common.collect.ImmutableSet;
+
+public class MongoEntityIndex2IT extends MongoITBase {
+    private static final Type PERSON_TYPE =
+            new Type(new RyaURI("urn:person"),
+                ImmutableSet.<RyaURI>builder()
+                    .add(new RyaURI("urn:name"))
+                    .add(new RyaURI("urn:age"))
+                    .add(new RyaURI("urn:eye"))
+                    .build());
+    private static final RyaURI RYA_PERSON_TYPE = new RyaURI("urn:person");
+
+    private EntityIndexOptimizer optimizer;
+    private EntityStorage entityStorage;
+
+    @Before
+    public void beforeClass() throws Exception {
+        optimizer = new EntityIndexOptimizer();
+        optimizer.setConf(conf);
+
+        final TypeStorage typeStorage = optimizer.getTypeStorage();
+        typeStorage.create(PERSON_TYPE);
+
+        final Entity entity = Entity.builder()
+                .setSubject(new RyaURI("urn:SSN:111-11-1111"))
+                .setExplicitType(RYA_PERSON_TYPE)
+                .setProperty(RYA_PERSON_TYPE, new Property(new 
RyaURI("urn:age"), new RyaType("25")))
+                .setProperty(RYA_PERSON_TYPE, new Property(new 
RyaURI("urn:eye"), new RyaType("blue")))
+                .setProperty(RYA_PERSON_TYPE, new Property(new 
RyaURI("urn:name"), new RyaType("bob")))
+                .build();
+        entityStorage = optimizer.getEntityStorage();
+        entityStorage.create(entity);
+    }
+
+    @Test()
+    public void queryIsFullEntity() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(query), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsPartEntity() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(query), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsPartEntityandExtra() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:222-22-2222> <urn:age> ?age . " +
+                "<urn:SSN:222-22-2222> <urn:eye> ?eye . " +
+                "<urn:SSN:222-22-2222> <urn:name> ?name . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsFullEntityWithExtra() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+                "<urn:SSN:222-22-2222> <urn:age> ?age . " +
+                "<urn:SSN:222-22-2222> <urn:eye> ?eye . " +
+                "<urn:SSN:222-22-2222> <urn:name> ?name . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsFullEntityWithOptional() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+                "  OPTIONAL{" +
+                "    <urn:SSN:222-22-2222> <urn:age> ?age . " +
+                "    <urn:SSN:222-22-2222> <urn:eye> ?eye . " +
+                "    <urn:SSN:222-22-2222> <urn:name> ?name . " +
+                " } . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryIsSplitEntityWithOptional() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "  OPTIONAL{" +
+                "    <urn:SSN:111-11-1111> <urn:name> ?name . " +
+                " } . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    @Test()
+    public void queryEntityInOptional() throws Exception {
+        // A pattern that has two different subjects.
+        final String query = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
+                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
+                "  OPTIONAL{" +
+                "    <urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "    <urn:SSN:111-11-1111> <urn:name> ?name . " +
+                " } . " +
+            "}";
+
+        final String expectedQuery = "SELECT * WHERE { " +
+                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
+                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
+            "}";
+
+        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
+        assertOptimizer(query, expected);
+    }
+
+    private static List<StatementPattern> getSPs(final String sparql) throws 
MalformedQueryException {
+        final StatementPatternCollector spCollector = new 
StatementPatternCollector();
+        new SPARQLParser().parseQuery(sparql, 
null).getTupleExpr().visit(spCollector);
+        return spCollector.getStatementPatterns();
+    }
+
+    private void assertOptimizer(final String query, final EntityQueryNode 
expected) throws Exception {
+        final SPARQLParser parser = new SPARQLParser();
+        final TupleExpr expr = parser.parseQuery(query, null).getTupleExpr();
+
+        optimizer.optimize(expr, null, null);
+        expr.visit(new EntityFetchingAsserterVisitor(expected));
+    }
+
+    private class EntityFetchingAsserterVisitor extends 
QueryModelVisitorBase<Exception> {
+        private final EntityQueryNode expected;
+        public EntityFetchingAsserterVisitor(final EntityQueryNode expected) {
+            this.expected = expected;
+        }
+        @Override
+        protected void meetNode(final QueryModelNode node) throws Exception {
+            if(node instanceof EntityQueryNode) {
+                Assert.assertEquals(expected, node);
+            } else {
+                super.meetNode(node);
+            }
+        }
+    }
+}
+

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/4576f556/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java
index e476874..463cabc 100644
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexIT.java
@@ -33,7 +33,7 @@ import org.apache.rya.indexing.entity.storage.EntityStorage;
 import org.apache.rya.indexing.entity.storage.TypeStorage;
 import org.apache.rya.indexing.entity.update.mongo.MongoEntityIndexer;
 import org.apache.rya.mongodb.MongoDBRdfConfiguration;
-import org.apache.rya.mongodb.MongoTestBase;
+import org.apache.rya.mongodb.MongoITBase;
 import org.apache.rya.sail.config.RyaSailFactory;
 import org.junit.Test;
 import org.openrdf.model.URI;
@@ -51,7 +51,7 @@ import org.openrdf.sail.Sail;
 
 import com.google.common.collect.ImmutableSet;
 
-public class MongoEntityIndexIT extends MongoTestBase {
+public class MongoEntityIndexIT extends MongoITBase {
     private static final ValueFactory VF = ValueFactoryImpl.getInstance();
 
     @Override

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/4576f556/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexTest.java
deleted file mode 100644
index 2fe0cb3..0000000
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoEntityIndexTest.java
+++ /dev/null
@@ -1,248 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.rya.indexing.mongo;
-
-import java.util.List;
-
-import org.apache.rya.api.domain.RyaType;
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.indexing.entity.EntityIndexOptimizer;
-import org.apache.rya.indexing.entity.model.Entity;
-import org.apache.rya.indexing.entity.model.Property;
-import org.apache.rya.indexing.entity.model.Type;
-import org.apache.rya.indexing.entity.query.EntityQueryNode;
-import org.apache.rya.indexing.entity.storage.EntityStorage;
-import org.apache.rya.indexing.entity.storage.TypeStorage;
-import org.apache.rya.mongodb.MongoTestBase;
-import org.junit.Assert;
-import org.junit.Before;
-import org.junit.BeforeClass;
-import org.junit.Test;
-import org.openrdf.model.vocabulary.RDF;
-import org.openrdf.query.MalformedQueryException;
-import org.openrdf.query.algebra.QueryModelNode;
-import org.openrdf.query.algebra.StatementPattern;
-import org.openrdf.query.algebra.TupleExpr;
-import org.openrdf.query.algebra.helpers.QueryModelVisitorBase;
-import org.openrdf.query.algebra.helpers.StatementPatternCollector;
-import org.openrdf.query.parser.sparql.SPARQLParser;
-
-import com.google.common.collect.ImmutableSet;
-
-public class MongoEntityIndexTest extends MongoTestBase {
-    private static final Type PERSON_TYPE =
-            new Type(new RyaURI("urn:person"),
-                ImmutableSet.<RyaURI>builder()
-                    .add(new RyaURI("urn:name"))
-                    .add(new RyaURI("urn:age"))
-                    .add(new RyaURI("urn:eye"))
-                    .build());
-    private static final RyaURI RYA_PERSON_TYPE = new RyaURI("urn:person");
-
-    private EntityIndexOptimizer optimizer;
-    private EntityStorage entityStorage;
-
-    @Before
-    public void beforeClass() throws Exception {
-        optimizer = new EntityIndexOptimizer();
-        optimizer.setConf(conf);
-
-        final TypeStorage typeStorage = optimizer.getTypeStorage();
-        typeStorage.create(PERSON_TYPE);
-
-        final Entity entity = Entity.builder()
-                .setSubject(new RyaURI("urn:SSN:111-11-1111"))
-                .setExplicitType(RYA_PERSON_TYPE)
-                .setProperty(RYA_PERSON_TYPE, new Property(new 
RyaURI("urn:age"), new RyaType("25")))
-                .setProperty(RYA_PERSON_TYPE, new Property(new 
RyaURI("urn:eye"), new RyaType("blue")))
-                .setProperty(RYA_PERSON_TYPE, new Property(new 
RyaURI("urn:name"), new RyaType("bob")))
-                .build();
-        entityStorage = optimizer.getEntityStorage();
-        entityStorage.create(entity);
-    }
-
-    @Test()
-    public void queryIsFullEntity() throws Exception {
-        // A pattern that has two different subjects.
-        final String query = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
-                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
-            "}";
-
-        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(query), entityStorage);
-        assertOptimizer(query, expected);
-    }
-
-    @Test()
-    public void queryIsPartEntity() throws Exception {
-        // A pattern that has two different subjects.
-        final String query = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-            "}";
-
-        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(query), entityStorage);
-        assertOptimizer(query, expected);
-    }
-
-    @Test()
-    public void queryIsPartEntityandExtra() throws Exception {
-        // A pattern that has two different subjects.
-        final String query = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:222-22-2222> <urn:age> ?age . " +
-                "<urn:SSN:222-22-2222> <urn:eye> ?eye . " +
-                "<urn:SSN:222-22-2222> <urn:name> ?name . " +
-            "}";
-
-        final String expectedQuery = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-            "}";
-
-        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
-        assertOptimizer(query, expected);
-    }
-
-    @Test()
-    public void queryIsFullEntityWithExtra() throws Exception {
-        // A pattern that has two different subjects.
-        final String query = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
-                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
-                "<urn:SSN:222-22-2222> <urn:age> ?age . " +
-                "<urn:SSN:222-22-2222> <urn:eye> ?eye . " +
-                "<urn:SSN:222-22-2222> <urn:name> ?name . " +
-            "}";
-
-        final String expectedQuery = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
-                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
-            "}";
-
-        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
-        assertOptimizer(query, expected);
-    }
-
-    @Test()
-    public void queryIsFullEntityWithOptional() throws Exception {
-        // A pattern that has two different subjects.
-        final String query = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
-                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
-                "  OPTIONAL{" +
-                "    <urn:SSN:222-22-2222> <urn:age> ?age . " +
-                "    <urn:SSN:222-22-2222> <urn:eye> ?eye . " +
-                "    <urn:SSN:222-22-2222> <urn:name> ?name . " +
-                " } . " +
-            "}";
-
-        final String expectedQuery = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
-                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
-            "}";
-
-        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
-        assertOptimizer(query, expected);
-    }
-
-    @Test()
-    public void queryIsSplitEntityWithOptional() throws Exception {
-        // A pattern that has two different subjects.
-        final String query = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
-                "  OPTIONAL{" +
-                "    <urn:SSN:111-11-1111> <urn:name> ?name . " +
-                " } . " +
-            "}";
-
-        final String expectedQuery = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
-            "}";
-
-        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
-        assertOptimizer(query, expected);
-    }
-
-    @Test()
-    public void queryEntityInOptional() throws Exception {
-        // A pattern that has two different subjects.
-        final String query = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <urn:age> ?age . " +
-                "<urn:SSN:111-11-1111> <urn:eye> ?eye . " +
-                "  OPTIONAL{" +
-                "    <urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "    <urn:SSN:111-11-1111> <urn:name> ?name . " +
-                " } . " +
-            "}";
-
-        final String expectedQuery = "SELECT * WHERE { " +
-                "<urn:SSN:111-11-1111> <" + RDF.TYPE + "> <urn:person> ."+
-                "<urn:SSN:111-11-1111> <urn:name> ?name . " +
-            "}";
-
-        final EntityQueryNode expected = new EntityQueryNode(PERSON_TYPE, 
getSPs(expectedQuery), entityStorage);
-        assertOptimizer(query, expected);
-    }
-
-    private static List<StatementPattern> getSPs(final String sparql) throws 
MalformedQueryException {
-        final StatementPatternCollector spCollector = new 
StatementPatternCollector();
-        new SPARQLParser().parseQuery(sparql, 
null).getTupleExpr().visit(spCollector);
-        return spCollector.getStatementPatterns();
-    }
-
-    private void assertOptimizer(final String query, final EntityQueryNode 
expected) throws Exception {
-        final SPARQLParser parser = new SPARQLParser();
-        final TupleExpr expr = parser.parseQuery(query, null).getTupleExpr();
-
-        optimizer.optimize(expr, null, null);
-        expr.visit(new EntityFetchingAsserterVisitor(expected));
-    }
-
-    private class EntityFetchingAsserterVisitor extends 
QueryModelVisitorBase<Exception> {
-        private final EntityQueryNode expected;
-        public EntityFetchingAsserterVisitor(final EntityQueryNode expected) {
-            this.expected = expected;
-        }
-        @Override
-        protected void meetNode(final QueryModelNode node) throws Exception {
-            if(node instanceof EntityQueryNode) {
-                Assert.assertEquals(expected, node);
-            } else {
-                super.meetNode(node);
-            }
-        }
-    }
-}
-

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/4576f556/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerIT.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerIT.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerIT.java
new file mode 100644
index 0000000..a8d496e
--- /dev/null
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerIT.java
@@ -0,0 +1,188 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.rya.indexing.mongo;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+import java.util.HashSet;
+import java.util.Set;
+
+import org.apache.rya.api.domain.RyaStatement;
+import org.apache.rya.api.domain.RyaType;
+import org.apache.rya.api.domain.RyaURI;
+import org.apache.rya.api.resolver.RdfToRyaConversions;
+import org.apache.rya.api.resolver.RyaToRdfConversions;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.mongodb.freetext.MongoFreeTextIndexer;
+import org.apache.rya.mongodb.MongoITBase;
+import org.junit.Test;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.Value;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.URIImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.model.vocabulary.RDFS;
+
+import com.google.common.collect.Sets;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * Integration tests the methods of {@link MongoFreeTextIndexer}.
+ */
+public class MongoFreeTextIndexerIT extends MongoITBase {
+    private static final StatementConstraints EMPTY_CONSTRAINTS = new 
StatementConstraints();
+
+    @Test
+    public void testSearch() throws Exception {
+        try (MongoFreeTextIndexer f = new MongoFreeTextIndexer()) {
+            f.setConf(conf);
+            f.init();
+
+            final ValueFactory vf = new ValueFactoryImpl();
+
+            final URI subject = new URIImpl("foo:subj");
+            final URI predicate = RDFS.LABEL;
+            final Value object = vf.createLiteral("this is a new hat");
+
+            final URI context = new URIImpl("foo:context");
+
+            final Statement statement = vf.createStatement(subject, predicate, 
object, context);
+            f.storeStatement(RdfToRyaConversions.convertStatement(statement));
+            f.flush();
+
+            assertEquals(Sets.newHashSet(), getSet(f.queryText("asdf", 
EMPTY_CONSTRAINTS)));
+
+            assertEquals(Sets.newHashSet(statement), getSet(f.queryText("new", 
EMPTY_CONSTRAINTS)));
+            assertEquals(Sets.newHashSet(statement), getSet(f.queryText("hat 
new", EMPTY_CONSTRAINTS)));
+        }
+    }
+
+    @Test
+    public void testDelete() throws Exception {
+        try (MongoFreeTextIndexer f = new MongoFreeTextIndexer()) {
+            f.setConf(conf);
+            f.init();
+
+            final ValueFactory vf = new ValueFactoryImpl();
+
+            final URI subject1 = new URIImpl("foo:subj");
+            final URI predicate1 = RDFS.LABEL;
+            final Value object1 = vf.createLiteral("this is a new hat");
+
+            final URI context1 = new URIImpl("foo:context");
+
+            final Statement statement1 = vf.createStatement(subject1, 
predicate1, object1, context1);
+            f.storeStatement(RdfToRyaConversions.convertStatement(statement1));
+
+            final URI subject2 = new URIImpl("foo:subject");
+            final URI predicate2 = RDFS.LABEL;
+            final Value object2 = vf.createLiteral("Do you like my new hat?");
+
+            final URI context2 = new URIImpl("foo:context");
+
+            final Statement statement2 = vf.createStatement(subject2, 
predicate2, object2, context2);
+            f.storeStatement(RdfToRyaConversions.convertStatement(statement2));
+
+            f.flush();
+
+
+            
f.deleteStatement(RdfToRyaConversions.convertStatement(statement1));
+            assertEquals(Sets.newHashSet(statement2), getSet(f.queryText("Do 
you like my new hat?", EMPTY_CONSTRAINTS)));
+
+            // Check that "new" didn't get deleted from the term table after 
"this is a new hat"
+            // was deleted since "new" is still in "Do you like my new hat?"
+            assertEquals(Sets.newHashSet(statement2), 
getSet(f.queryText("new", EMPTY_CONSTRAINTS)));
+
+            
f.deleteStatement(RdfToRyaConversions.convertStatement(statement2));
+            assertEquals(Sets.newHashSet(), getSet(f.queryText("this is a new 
hat", EMPTY_CONSTRAINTS)));
+            assertEquals(Sets.newHashSet(), getSet(f.queryText("Do you like my 
new hat?", EMPTY_CONSTRAINTS)));
+        }
+    }
+
+    @Test
+    public void testRestrictPredicatesSearch() throws Exception {
+        conf.setStrings(ConfigUtils.FREETEXT_PREDICATES_LIST, "pred:1,pred:2");
+
+        try (MongoFreeTextIndexer f = new MongoFreeTextIndexer()) {
+            f.setConf(conf);
+            f.init();
+
+            // These should not be stored because they are not in the 
predicate list
+            f.storeStatement(new RyaStatement(new RyaURI("foo:subj1"), new 
RyaURI(RDFS.LABEL.toString()), new RyaType("invalid")));
+            f.storeStatement(new RyaStatement(new RyaURI("foo:subj2"), new 
RyaURI(RDFS.COMMENT.toString()), new RyaType("invalid")));
+
+            final RyaURI pred1 = new RyaURI("pred:1");
+            final RyaURI pred2 = new RyaURI("pred:2");
+
+            // These should be stored because they are in the predicate list
+            final RyaStatement s3 = new RyaStatement(new RyaURI("foo:subj3"), 
pred1, new RyaType("valid"));
+            final RyaStatement s4 = new RyaStatement(new RyaURI("foo:subj4"), 
pred2, new RyaType("valid"));
+            f.storeStatement(s3);
+            f.storeStatement(s4);
+
+            // This should not be stored because the object is not a literal
+            f.storeStatement(new RyaStatement(new RyaURI("foo:subj5"), pred1, 
new RyaURI("in:validURI")));
+
+            f.flush();
+
+            assertEquals(Sets.newHashSet(), getSet(f.queryText("invalid", 
EMPTY_CONSTRAINTS)));
+            assertEquals(Sets.newHashSet(), getSet(f.queryText("in:validURI", 
EMPTY_CONSTRAINTS)));
+
+            final Set<Statement> actual = getSet(f.queryText("valid", 
EMPTY_CONSTRAINTS));
+            assertEquals(2, actual.size());
+            
assertTrue(actual.contains(RyaToRdfConversions.convertStatement(s3)));
+            
assertTrue(actual.contains(RyaToRdfConversions.convertStatement(s4)));
+        }
+    }
+
+    @Test
+    public void testContextSearch() throws Exception {
+        try (MongoFreeTextIndexer f = new MongoFreeTextIndexer()) {
+            f.setConf(conf);
+            f.init();
+
+            final ValueFactory vf = new ValueFactoryImpl();
+            final URI subject = new URIImpl("foo:subj");
+            final URI predicate = new URIImpl(RDFS.COMMENT.toString());
+            final Value object = vf.createLiteral("this is a new hat");
+            final URI context = new URIImpl("foo:context");
+
+            final Statement statement = vf.createStatement(subject, predicate, 
object, context);
+            f.storeStatement(RdfToRyaConversions.convertStatement(statement));
+            f.flush();
+
+            assertEquals(Sets.newHashSet(statement), getSet(f.queryText("hat", 
EMPTY_CONSTRAINTS)));
+            assertEquals(Sets.newHashSet(statement), getSet(f.queryText("hat", 
new StatementConstraints().setContext(context))));
+            assertEquals(Sets.newHashSet(),
+                    getSet(f.queryText("hat", new 
StatementConstraints().setContext(vf.createURI("foo:context2")))));
+        }
+    }
+
+    private static <X> Set<X> getSet(final CloseableIteration<X, ?> iter) 
throws Exception {
+        final Set<X> set = new HashSet<>();
+        while (iter.hasNext()) {
+            set.add(iter.next());
+        }
+        return set;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/4576f556/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
deleted file mode 100644
index 71840ea..0000000
--- 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoFreeTextIndexerTest.java
+++ /dev/null
@@ -1,188 +0,0 @@
-/**
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *   http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package org.apache.rya.indexing.mongo;
-
-import static org.junit.Assert.assertEquals;
-import static org.junit.Assert.assertTrue;
-
-import java.util.HashSet;
-import java.util.Set;
-
-import org.apache.rya.api.domain.RyaStatement;
-import org.apache.rya.api.domain.RyaType;
-import org.apache.rya.api.domain.RyaURI;
-import org.apache.rya.api.resolver.RdfToRyaConversions;
-import org.apache.rya.api.resolver.RyaToRdfConversions;
-import org.apache.rya.indexing.StatementConstraints;
-import org.apache.rya.indexing.accumulo.ConfigUtils;
-import org.apache.rya.indexing.mongodb.freetext.MongoFreeTextIndexer;
-import org.apache.rya.mongodb.MongoTestBase;
-import org.junit.Test;
-import org.openrdf.model.Statement;
-import org.openrdf.model.URI;
-import org.openrdf.model.Value;
-import org.openrdf.model.ValueFactory;
-import org.openrdf.model.impl.URIImpl;
-import org.openrdf.model.impl.ValueFactoryImpl;
-import org.openrdf.model.vocabulary.RDFS;
-
-import com.google.common.collect.Sets;
-
-import info.aduna.iteration.CloseableIteration;
-
-/**
- * Integration tests the methods of {@link MongoFreeTextIndexer}.
- */
-public class MongoFreeTextIndexerTest extends MongoTestBase {
-    private static final StatementConstraints EMPTY_CONSTRAINTS = new 
StatementConstraints();
-
-    @Test
-    public void testSearch() throws Exception {
-        try (MongoFreeTextIndexer f = new MongoFreeTextIndexer()) {
-            f.setConf(conf);
-            f.init();
-
-            final ValueFactory vf = new ValueFactoryImpl();
-
-            final URI subject = new URIImpl("foo:subj");
-            final URI predicate = RDFS.LABEL;
-            final Value object = vf.createLiteral("this is a new hat");
-
-            final URI context = new URIImpl("foo:context");
-
-            final Statement statement = vf.createStatement(subject, predicate, 
object, context);
-            f.storeStatement(RdfToRyaConversions.convertStatement(statement));
-            f.flush();
-
-            assertEquals(Sets.newHashSet(), getSet(f.queryText("asdf", 
EMPTY_CONSTRAINTS)));
-
-            assertEquals(Sets.newHashSet(statement), getSet(f.queryText("new", 
EMPTY_CONSTRAINTS)));
-            assertEquals(Sets.newHashSet(statement), getSet(f.queryText("hat 
new", EMPTY_CONSTRAINTS)));
-        }
-    }
-
-    @Test
-    public void testDelete() throws Exception {
-        try (MongoFreeTextIndexer f = new MongoFreeTextIndexer()) {
-            f.setConf(conf);
-            f.init();
-
-            final ValueFactory vf = new ValueFactoryImpl();
-
-            final URI subject1 = new URIImpl("foo:subj");
-            final URI predicate1 = RDFS.LABEL;
-            final Value object1 = vf.createLiteral("this is a new hat");
-
-            final URI context1 = new URIImpl("foo:context");
-
-            final Statement statement1 = vf.createStatement(subject1, 
predicate1, object1, context1);
-            f.storeStatement(RdfToRyaConversions.convertStatement(statement1));
-
-            final URI subject2 = new URIImpl("foo:subject");
-            final URI predicate2 = RDFS.LABEL;
-            final Value object2 = vf.createLiteral("Do you like my new hat?");
-
-            final URI context2 = new URIImpl("foo:context");
-
-            final Statement statement2 = vf.createStatement(subject2, 
predicate2, object2, context2);
-            f.storeStatement(RdfToRyaConversions.convertStatement(statement2));
-
-            f.flush();
-
-
-            
f.deleteStatement(RdfToRyaConversions.convertStatement(statement1));
-            assertEquals(Sets.newHashSet(statement2), getSet(f.queryText("Do 
you like my new hat?", EMPTY_CONSTRAINTS)));
-
-            // Check that "new" didn't get deleted from the term table after 
"this is a new hat"
-            // was deleted since "new" is still in "Do you like my new hat?"
-            assertEquals(Sets.newHashSet(statement2), 
getSet(f.queryText("new", EMPTY_CONSTRAINTS)));
-
-            
f.deleteStatement(RdfToRyaConversions.convertStatement(statement2));
-            assertEquals(Sets.newHashSet(), getSet(f.queryText("this is a new 
hat", EMPTY_CONSTRAINTS)));
-            assertEquals(Sets.newHashSet(), getSet(f.queryText("Do you like my 
new hat?", EMPTY_CONSTRAINTS)));
-        }
-    }
-
-    @Test
-    public void testRestrictPredicatesSearch() throws Exception {
-        conf.setStrings(ConfigUtils.FREETEXT_PREDICATES_LIST, "pred:1,pred:2");
-
-        try (MongoFreeTextIndexer f = new MongoFreeTextIndexer()) {
-            f.setConf(conf);
-            f.init();
-
-            // These should not be stored because they are not in the 
predicate list
-            f.storeStatement(new RyaStatement(new RyaURI("foo:subj1"), new 
RyaURI(RDFS.LABEL.toString()), new RyaType("invalid")));
-            f.storeStatement(new RyaStatement(new RyaURI("foo:subj2"), new 
RyaURI(RDFS.COMMENT.toString()), new RyaType("invalid")));
-
-            final RyaURI pred1 = new RyaURI("pred:1");
-            final RyaURI pred2 = new RyaURI("pred:2");
-
-            // These should be stored because they are in the predicate list
-            final RyaStatement s3 = new RyaStatement(new RyaURI("foo:subj3"), 
pred1, new RyaType("valid"));
-            final RyaStatement s4 = new RyaStatement(new RyaURI("foo:subj4"), 
pred2, new RyaType("valid"));
-            f.storeStatement(s3);
-            f.storeStatement(s4);
-
-            // This should not be stored because the object is not a literal
-            f.storeStatement(new RyaStatement(new RyaURI("foo:subj5"), pred1, 
new RyaURI("in:validURI")));
-
-            f.flush();
-
-            assertEquals(Sets.newHashSet(), getSet(f.queryText("invalid", 
EMPTY_CONSTRAINTS)));
-            assertEquals(Sets.newHashSet(), getSet(f.queryText("in:validURI", 
EMPTY_CONSTRAINTS)));
-
-            final Set<Statement> actual = getSet(f.queryText("valid", 
EMPTY_CONSTRAINTS));
-            assertEquals(2, actual.size());
-            
assertTrue(actual.contains(RyaToRdfConversions.convertStatement(s3)));
-            
assertTrue(actual.contains(RyaToRdfConversions.convertStatement(s4)));
-        }
-    }
-
-    @Test
-    public void testContextSearch() throws Exception {
-        try (MongoFreeTextIndexer f = new MongoFreeTextIndexer()) {
-            f.setConf(conf);
-            f.init();
-
-            final ValueFactory vf = new ValueFactoryImpl();
-            final URI subject = new URIImpl("foo:subj");
-            final URI predicate = new URIImpl(RDFS.COMMENT.toString());
-            final Value object = vf.createLiteral("this is a new hat");
-            final URI context = new URIImpl("foo:context");
-
-            final Statement statement = vf.createStatement(subject, predicate, 
object, context);
-            f.storeStatement(RdfToRyaConversions.convertStatement(statement));
-            f.flush();
-
-            assertEquals(Sets.newHashSet(statement), getSet(f.queryText("hat", 
EMPTY_CONSTRAINTS)));
-            assertEquals(Sets.newHashSet(statement), getSet(f.queryText("hat", 
new StatementConstraints().setContext(context))));
-            assertEquals(Sets.newHashSet(),
-                    getSet(f.queryText("hat", new 
StatementConstraints().setContext(vf.createURI("foo:context2")))));
-        }
-    }
-
-    private static <X> Set<X> getSet(final CloseableIteration<X, ?> iter) 
throws Exception {
-        final Set<X> set = new HashSet<>();
-        while (iter.hasNext()) {
-            set.add(iter.next());
-        }
-        return set;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/incubator-rya/blob/4576f556/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoTemporalIndexerIT.java
----------------------------------------------------------------------
diff --git 
a/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoTemporalIndexerIT.java
 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoTemporalIndexerIT.java
new file mode 100644
index 0000000..e92bcbb
--- /dev/null
+++ 
b/extras/indexing/src/test/java/org/apache/rya/indexing/mongo/MongoTemporalIndexerIT.java
@@ -0,0 +1,722 @@
+package org.apache.rya.indexing.mongo;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+
+import static org.apache.rya.api.resolver.RdfToRyaConversions.convertStatement;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.security.NoSuchAlgorithmException;
+import java.util.Arrays;
+import java.util.HashSet;
+
+import org.apache.accumulo.core.client.TableExistsException;
+import org.apache.accumulo.core.client.TableNotFoundException;
+import org.apache.rya.indexing.StatementConstraints;
+import org.apache.rya.indexing.TemporalInstant;
+import org.apache.rya.indexing.TemporalInstantRfc3339;
+import org.apache.rya.indexing.TemporalInterval;
+import org.apache.rya.indexing.accumulo.ConfigUtils;
+import org.apache.rya.indexing.mongodb.temporal.MongoTemporalIndexer;
+import org.apache.rya.mongodb.MongoDBRdfConfiguration;
+import org.apache.rya.mongodb.MongoITBase;
+import org.junit.Test;
+import org.openrdf.model.Statement;
+import org.openrdf.model.URI;
+import org.openrdf.model.ValueFactory;
+import org.openrdf.model.impl.StatementImpl;
+import org.openrdf.model.impl.ValueFactoryImpl;
+import org.openrdf.model.vocabulary.RDFS;
+import org.openrdf.query.QueryEvaluationException;
+
+import com.mongodb.DB;
+import com.mongodb.DBCollection;
+import com.mongodb.DBCursor;
+import com.mongodb.DBObject;
+import com.mongodb.MongoException;
+import com.mongodb.MongoSecurityException;
+
+import info.aduna.iteration.CloseableIteration;
+
+/**
+ * JUnit tests for TemporalIndexer and it's implementation MongoTemporalIndexer
+ *
+ * If you enjoy this test, please read RyaTemporalIndexerTest and YagoKBTest, 
which contain
+ * many example SPARQL queries and updates and attempts to test independently 
of Mongo:
+ *
+ *     
extras/indexingSail/src/test/java/org.apache/rya/indexing/Mongo/RyaTemporalIndexerTest.java
+ *     {@link org.apache.rya.indexing.Mongo.RyaTemporalIndexerTest}
+ *     {@link org.apache.rya.indexing.Mongo.YagoKBTest.java}
+ *
+ * Remember, this class in instantiated fresh for each @test method.
+ * so fields are reset, unless they are static.
+ *
+ * These are covered:
+ *   Instance {before, equals, after} given Instance
+ *   Instance {before, after, inside} given Interval
+ *   Instance {hasBeginning, hasEnd} given Interval
+ * And a few more.
+ *
+ */
+public final class MongoTemporalIndexerIT extends MongoITBase {
+
+    private static final String URI_PROPERTY_EVENT_TIME = 
"Property:event:time";
+    private static final String URI_PROPERTY_CIRCA = "Property:circa";
+    private static final String URI_PROPERTY_AT_TIME = "Property:atTime";
+    private static final StatementConstraints EMPTY_CONSTRAINTS = new 
StatementConstraints();
+
+    // Assign this in setUpBeforeClass, store them in each test.
+    // setup() deletes table before each test.
+    static final Statement spo_B00_E01;
+    static final Statement spo_B03_E20;
+    static final Statement spo_B02_E29;
+    static final Statement spo_B02_E30;
+    static final Statement spo_B02_E40;
+    static final Statement spo_B02_E31;
+    static final Statement spo_B29_E30;
+    static final Statement spo_B30_E32;
+
+    // Instants:
+    static final Statement spo_B02;
+    static final int SERIES_OF_SECONDS = 41;
+    static final Statement seriesSpo[] = new Statement[SERIES_OF_SECONDS];
+
+    // These are shared for several tests. Only the seconds are different.
+    // tvB03_E20 read as: interval Begins 3 seconds, ends at 20 seconds
+    static final TemporalInterval tvB00_E01 = new 
TemporalInterval(makeInstant(00), makeInstant(01));
+    static final TemporalInterval tvB29_E30= new 
TemporalInterval(makeInstant(29), makeInstant(30));
+    static final TemporalInterval tvB30_E32= new 
TemporalInterval(makeInstant(30), makeInstant(32));
+    static final TemporalInterval tvB03_E20 = new 
TemporalInterval(makeInstant(03), makeInstant(20));
+    // 30 seconds, Begins earlier, ends later
+    static final TemporalInterval tvB02_E30= new 
TemporalInterval(makeInstant(02), makeInstant(30));
+    // use for interval after
+    static final TemporalInterval tvB02_E29= new 
TemporalInterval(makeInstant(02), makeInstant(29));
+    // same as above, but ends in the middle
+    static final TemporalInterval tvB02_E31 = new 
TemporalInterval(makeInstant(02), makeInstant(31));
+    // same as above, but ends even later
+    static final TemporalInterval tvB02_E40 = new 
TemporalInterval(makeInstant(02), makeInstant(40));
+    // instant, match beginnings of several above, before tiB03_E20
+    static final TemporalInstant tsB02 = makeInstant(02);
+    // instant, after all above
+    static final TemporalInstant tsB04 = makeInstant(04);
+
+    // Create a series of instants about times 0 - 40 seconds
+    static final TemporalInstant seriesTs[];
+    static {
+        seriesTs = new TemporalInstant[SERIES_OF_SECONDS];
+        for (int i = 0; i <= 40; i++) {
+            seriesTs[i] = makeInstant(i);
+        }
+    };
+
+    /**
+     * Make an uniform instant with given seconds.
+     */
+    static TemporalInstant makeInstant(final int secondsMakeMeUnique) {
+        return new TemporalInstantRfc3339(2015, 12, 30, 12, 00, 
secondsMakeMeUnique);
+    }
+
+    static {
+        // Setup the statements only once. Each test will store some of these 
in there own index table.
+        final ValueFactory vf = new ValueFactoryImpl();
+        final URI pred1_atTime = vf.createURI(URI_PROPERTY_AT_TIME);
+        // tiB03_E20 read as: time interval that Begins 3 seconds, ends at 20 
seconds,
+        // Each time element the same, except seconds. year, month, .... 
minute are the same for each statement below.
+        spo_B00_E01 = new StatementImpl(vf.createURI("foo:event0"), 
pred1_atTime, vf.createLiteral(tvB00_E01.toString()));
+        spo_B02_E29 = new StatementImpl(vf.createURI("foo:event2"), 
pred1_atTime, vf.createLiteral(tvB02_E29.toString()));
+        spo_B02_E30 = new StatementImpl(vf.createURI("foo:event2"), 
pred1_atTime, vf.createLiteral(tvB02_E30.toString()));
+        spo_B02_E31 = new StatementImpl(vf.createURI("foo:event3"), 
pred1_atTime, vf.createLiteral(tvB02_E31.toString()));
+        spo_B02_E40 = new StatementImpl(vf.createURI("foo:event4"), 
pred1_atTime, vf.createLiteral(tvB02_E40.toString()));
+        spo_B03_E20 = new StatementImpl(vf.createURI("foo:event5"), 
pred1_atTime, vf.createLiteral(tvB03_E20.toString()));
+        spo_B29_E30 = new StatementImpl(vf.createURI("foo:event1"), 
pred1_atTime, vf.createLiteral(tvB29_E30.toString()));
+        spo_B30_E32 = new StatementImpl(vf.createURI("foo:event1"), 
pred1_atTime, vf.createLiteral(tvB30_E32.toString()));
+        spo_B02 = new StatementImpl(vf.createURI("foo:event6"), pred1_atTime, 
vf.createLiteral(tsB02.getAsReadable()));
+
+        // Create statements about time instants 0 - 40 seconds
+        for (int i = 0; i < seriesTs.length; i++) {
+            seriesSpo[i] = new StatementImpl(vf.createURI("foo:event0" + i), 
pred1_atTime, vf.createLiteral(seriesTs[i].getAsReadable()));
+        }
+    }
+
+    @Override
+    protected void updateConfiguration(final MongoDBRdfConfiguration conf) {
+        // This is from http://linkedevents.org/ontology
+        // and http://motools.sourceforge.net/event/event.html
+        conf.setStrings(ConfigUtils.TEMPORAL_PREDICATES_LIST, ""
+                + URI_PROPERTY_AT_TIME + ","
+                + URI_PROPERTY_CIRCA + ","
+                + URI_PROPERTY_EVENT_TIME);
+    }
+
+    /**
+     * Test method for {@link 
MongoTemporalIndexer#storeStatement(convertStatement(org.openrdf.model.Statement)}
+     */
+    @Test
+    public void testStoreStatement() throws IOException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            final ValueFactory vf = new ValueFactoryImpl();
+
+            final URI pred1_atTime = vf.createURI(URI_PROPERTY_AT_TIME);
+            final URI pred2_circa = vf.createURI(URI_PROPERTY_CIRCA);
+
+            // Should not be stored because they are not in the predicate list
+            final String validDateStringWithThirteens = "1313-12-13T13:13:13Z";
+            tIndexer.storeStatement(convertStatement(new 
StatementImpl(vf.createURI("foo:subj1"), RDFS.LABEL, 
vf.createLiteral(validDateStringWithThirteens))));
+
+            final String invalidDateString = "ThisIsAnInvalidDate";
+            tIndexer.storeStatement(convertStatement(new 
StatementImpl(vf.createURI("foo:subj2"), pred1_atTime, 
vf.createLiteral(invalidDateString))));
+
+            // These are different datetimes instant but from different time 
zones.
+            // This is an arbitrary zone, BRST=Brazil, better if not local.
+            // same as "2015-01-01T01:59:59Z"
+            final String testDate2014InBRST = "2014-12-31T23:59:59-02:00";
+            // next year, same as "2017-01-01T01:59:59Z"
+            final String testDate2016InET = "2016-12-31T20:59:59-05:00";
+
+            // These should be stored because they are in the predicate list.
+            // BUT they will get converted to the same exact datetime in UTC.
+            final Statement s3 = new StatementImpl(vf.createURI("foo:subj3"), 
pred1_atTime, vf.createLiteral(testDate2014InBRST));
+            final Statement s4 = new StatementImpl(vf.createURI("foo:subj4"), 
pred2_circa, vf.createLiteral(testDate2016InET));
+            tIndexer.storeStatement(convertStatement(s3));
+            tIndexer.storeStatement(convertStatement(s4));
+
+            // This should not be stored because the object is not a literal
+            tIndexer.storeStatement(convertStatement(new 
StatementImpl(vf.createURI("foo:subj5"), pred1_atTime, 
vf.createURI("in:valid"))));
+
+            printTables(tIndexer, "junit testing: Temporal entities stored in 
testStoreStatement");
+            assertEquals(2, tIndexer.getCollection().find().count());
+        }
+    }
+
+    @Test
+    public void testDelete() throws IOException, MongoException, 
TableNotFoundException, TableExistsException, NoSuchAlgorithmException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            final ValueFactory vf = new ValueFactoryImpl();
+
+            final URI pred1_atTime = vf.createURI(URI_PROPERTY_AT_TIME);
+            final URI pred2_circa = vf.createURI(URI_PROPERTY_CIRCA);
+
+            final String testDate2014InBRST = "2014-12-31T23:59:59-02:00";
+            final String testDate2016InET = "2016-12-31T20:59:59-05:00";
+
+            // These should be stored because they are in the predicate list.
+            // BUT they will get converted to the same exact datetime in UTC.
+            final Statement s1 = new StatementImpl(vf.createURI("foo:subj3"), 
pred1_atTime, vf.createLiteral(testDate2014InBRST));
+            final Statement s2 = new StatementImpl(vf.createURI("foo:subj4"), 
pred2_circa, vf.createLiteral(testDate2016InET));
+            tIndexer.storeStatement(convertStatement(s1));
+            tIndexer.storeStatement(convertStatement(s2));
+
+            final String dbName = conf.getMongoDBName();
+            final DB db = super.getMongoClient().getDB(dbName);
+            DBCollection collection = 
db.getCollection(conf.get(MongoDBRdfConfiguration.MONGO_COLLECTION_PREFIX, 
"rya") + tIndexer.getCollectionName());
+
+            printTables(tIndexer, "junit testing: Temporal entities stored in 
testDelete before delete");
+            assertEquals("Number of rows stored.", 2, collection.count()); // 
4 index entries per statement
+
+            tIndexer.deleteStatement(convertStatement(s1));
+            tIndexer.deleteStatement(convertStatement(s2));
+
+            printTables(tIndexer, "junit testing: Temporal entities stored in 
testDelete after delete");
+            assertEquals("Number of rows stored after delete.", 0, 
collection.count());
+        }
+    }
+
+    /**
+     * Test instant after a given instant.
+     * From the series: instant {equal, before, after} instant
+     * @throws MongoSecurityException
+     * @throws MongoException
+     * @throws TableNotFoundException
+     */
+    @Test
+    public void testQueryInstantAfterInstant() throws IOException, 
QueryEvaluationException, TableNotFoundException, MongoException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            // these should not match as they are not instances.
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+
+            // seriesSpo[s] and seriesTs[s] are statements and instant for s 
seconds after the uniform time.
+            final int searchForSeconds = 4;
+            final int expectedResultCount = 9;
+            for (int s = 0; s <= searchForSeconds + expectedResultCount; s++) 
{ // <== logic here
+                tIndexer.storeStatement(convertStatement(seriesSpo[s]));
+            }
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = 
tIndexer.queryInstantAfterInstant(seriesTs[searchForSeconds], 
EMPTY_CONSTRAINTS);
+            int count = 0;
+            while (iter.hasNext()) {
+                final Statement s = iter.next();
+                final Statement nextExpectedStatement = 
seriesSpo[searchForSeconds + count + 1]; // <== logic here
+                assertTrue("Should match: " + nextExpectedStatement + " == " + 
s, nextExpectedStatement.equals(s));
+                count++;
+            }
+            assertEquals("Should find count of rows.", expectedResultCount, 
count);
+        }
+    }
+    /**
+     * Test instant before a given instant.
+     * From the series: instant {equal, before, after} instant
+     */
+    @Test
+    public void testQueryInstantBeforeInstant() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            // these should not match as they are not instances.
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+
+            // seriesSpo[s] and seriesTs[s] are statements and instant for s 
seconds after the uniform time.
+            final int searchForSeconds = 4;
+            final int expectedResultCount = 4;
+            for (int s = 0; s <= searchForSeconds + 15; s++) { // <== logic 
here
+                tIndexer.storeStatement(convertStatement(seriesSpo[s]));
+            }
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+
+            iter = 
tIndexer.queryInstantBeforeInstant(seriesTs[searchForSeconds], 
EMPTY_CONSTRAINTS);
+            int count = 0;
+            while (iter.hasNext()) {
+                final Statement s = iter.next();
+                final Statement nextExpectedStatement = seriesSpo[count]; // 
<== logic here
+                assertTrue("Should match: " + nextExpectedStatement + " == " + 
s, nextExpectedStatement.equals(s));
+                count++;
+            }
+            assertEquals("Should find count of rows.", expectedResultCount, 
count);
+        }
+    }
+
+    /**
+     * Test instant before given interval.
+     * From the series:  Instance {before, after, inside} given Interval
+     */
+    @Test
+    public void testQueryInstantBeforeInterval() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            // these should not match as they are not instances.
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+
+            // seriesSpo[s] and seriesTs[s] are statements and instants for s 
seconds after the uniform time.
+            final TemporalInterval searchForSeconds = tvB02_E31;
+            final int expectedResultCount = 2; // 00 and 01 seconds.
+            for (int s = 0; s <= 40; s++) { // <== logic here
+                tIndexer.storeStatement(convertStatement(seriesSpo[s]));
+            }
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = tIndexer.queryInstantBeforeInterval(searchForSeconds, 
EMPTY_CONSTRAINTS);
+            int count = 0;
+            while (iter.hasNext()) {
+                final Statement s = iter.next();
+                final Statement nextExpectedStatement = seriesSpo[count]; // 
<== logic here
+                assertTrue("Should match: " + nextExpectedStatement + " == " + 
s, nextExpectedStatement.equals(s));
+                count++;
+            }
+            assertEquals("Should find count of rows.", expectedResultCount, 
count);
+        }
+    }
+
+    /**
+     * Test instant after given interval.
+     * Instance {before, after, inside} given Interval
+     */
+    @Test
+    public void testQueryInstantAfterInterval() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            // these should not match as they are not instances.
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+
+            // seriesSpo[s] and seriesTs[s] are statements and instants for s 
seconds after the uniform time.
+            final TemporalInterval searchAfterInterval = tvB02_E31; // from 2 
to 31 seconds
+            final int endingSeconds = 31;
+            final int expectedResultCount = 9; // 32,33,...,40 seconds.
+            for (int s = 0; s <= endingSeconds + expectedResultCount; s++) { 
// <== logic here
+                tIndexer.storeStatement(convertStatement(seriesSpo[s]));
+            }
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = tIndexer.queryInstantAfterInterval(searchAfterInterval, 
EMPTY_CONSTRAINTS);
+            int count = 0;
+            while (iter.hasNext()) {
+                final Statement s = iter.next();
+                final Statement nextExpectedStatement = seriesSpo[count + 
endingSeconds + 1]; // <== logic here
+                assertTrue("Should match: " + nextExpectedStatement + " == " + 
s, nextExpectedStatement.equals(s));
+                count++;
+            }
+            assertEquals("Should find count of rows.", expectedResultCount, 
count);
+        }
+    }
+
+    /**
+     * Test instant inside given interval.
+     * Instance {before, after, inside} given Interval
+     */
+    @Test
+    public void testQueryInstantInsideInterval() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            // these should not match as they are not instances.
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+
+            // seriesSpo[s] and seriesTs[s] are statements and instants for s 
seconds after the uniform time.
+            final TemporalInterval searchInsideInterval = tvB02_E31; // from 2 
to 31 seconds
+            final int beginningSeconds = 2; // <== logic here, and next few 
lines.
+            final int endingSeconds = 31;
+            final int expectedResultCount = endingSeconds - beginningSeconds - 
1; // 3,4,...,30 seconds.
+            for (int s = 0; s <= 40; s++) {
+                tIndexer.storeStatement(convertStatement(seriesSpo[s]));
+            }
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = tIndexer.queryInstantInsideInterval(searchInsideInterval, 
EMPTY_CONSTRAINTS);
+            int count = 0;
+            while (iter.hasNext()) {
+                final Statement s = iter.next();
+                final Statement nextExpectedStatement = seriesSpo[count + 
beginningSeconds + 1]; // <== logic here
+                assertTrue("Should match: " + nextExpectedStatement + " == " + 
s, nextExpectedStatement.equals(s));
+                count++;
+            }
+            assertEquals("Should find count of rows.", expectedResultCount, 
count);
+        }
+    }
+
+    /**
+     * Test instant is the Beginning of the given interval.
+     * from the series: Instance {hasBeginning, hasEnd} Interval
+     */
+    @Test
+    public void testQueryInstantHasBeginningInterval() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            // these should not match as they are not instances.
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+
+            // seriesSpo[s] and seriesTs[s] are statements and instants for s 
seconds after the uniform time.
+            final TemporalInterval searchInsideInterval = tvB02_E31; // from 2 
to 31 seconds
+            final int searchSeconds = 2; // <== logic here, and next few lines.
+            final int expectedResultCount = 1; // 2 seconds.
+            for (int s = 0; s <= 10; s++) {
+                tIndexer.storeStatement(convertStatement(seriesSpo[s]));
+            }
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = 
tIndexer.queryInstantHasBeginningInterval(searchInsideInterval, 
EMPTY_CONSTRAINTS);
+            int count = 0;
+            while (iter.hasNext()) {
+                final Statement s = iter.next();
+                final Statement nextExpectedStatement = 
seriesSpo[searchSeconds]; // <== logic here
+                assertTrue("Should match: " + nextExpectedStatement + " == " + 
s, nextExpectedStatement.equals(s));
+                count++;
+            }
+            assertEquals("Should find count of rows.", expectedResultCount, 
count);
+        }
+    }
+
+    /**
+     * Test instant is the end of the given interval.
+     * from the series: Instance {hasBeginning, hasEnd} Interval
+     */
+    @Test
+    public void testQueryInstantHasEndInterval()  throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            // these should not match as they are not instances.
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+
+            // seriesSpo[s] and seriesTs[s] are statements and instants for s 
seconds after the uniform time.
+            final TemporalInterval searchInsideInterval = tvB02_E31; // from 2 
to 31 seconds
+            final int searchSeconds = 31; // <== logic here, and next few 
lines.
+            final int expectedResultCount = 1; // 31 seconds.
+            for (int s = 0; s <= 40; s++) {
+                tIndexer.storeStatement(convertStatement(seriesSpo[s]));
+            }
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = tIndexer.queryInstantHasEndInterval(searchInsideInterval, 
EMPTY_CONSTRAINTS);
+            int count = 0;
+            while (iter.hasNext()) {
+                final Statement s = iter.next();
+                final Statement nextExpectedStatement = 
seriesSpo[searchSeconds]; // <== logic here
+                assertTrue("Should match: " + nextExpectedStatement + " == " + 
s, nextExpectedStatement.equals(s));
+                count++;
+            }
+            assertEquals("Should find count of rows.", expectedResultCount, 
count);
+        }
+    }
+
+    /**
+     * Test method for
+     * {@link 
org.apache.rya.indexing.Mongo.temporal.MongoTemporalIndexer#queryIntervalEquals(TemporalInterval,
 StatementConstraints)}
+     * .
+     * @throws IOException
+     * @throws QueryEvaluationException
+     *
+     */
+    @Test
+    public void testQueryIntervalEquals() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+            tIndexer.storeStatement(convertStatement(seriesSpo[4])); // 
instance at 4 seconds
+
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = tIndexer.queryIntervalEquals(tvB02_E40, EMPTY_CONSTRAINTS);
+            // Should be found twice:
+            assertTrue("queryIntervalEquals: spo_B02_E40 should be found, but 
actually returned empty results. spo_B02_E40=" + spo_B02_E40, iter.hasNext());
+            assertTrue("queryIntervalEquals: spo_B02_E40 should be found, but 
does not match.", spo_B02_E40.equals(iter.next()));
+            assertFalse("queryIntervalEquals: Find no more than one, but 
actually has more.", iter.hasNext());
+        }
+    }
+
+    /**
+     * Test interval before a given interval, for method:
+     * {@link MongoTemporalIndexer#queryIntervalBefore(TemporalInterval, 
StatementConstraints)}.
+     *
+     * @throws IOException
+     * @throws QueryEvaluationException
+     */
+    @Test
+    public void testQueryIntervalBefore() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            tIndexer.storeStatement(convertStatement(spo_B00_E01));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            // instants should be ignored.
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+            tIndexer.storeStatement(convertStatement(seriesSpo[1])); // 
instance at 1 seconds
+            tIndexer.storeStatement(convertStatement(seriesSpo[2]));
+            tIndexer.storeStatement(convertStatement(seriesSpo[31]));
+
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = tIndexer.queryIntervalBefore(tvB02_E31, EMPTY_CONSTRAINTS);
+            // Should be found twice:
+            assertTrue("spo_B00_E01 should be found, but actually returned 
empty results. spo_B00_E01=" + spo_B00_E01, iter.hasNext());
+            assertTrue("spo_B00_E01 should be found, but found another.", 
spo_B00_E01.equals(iter.next()));
+            assertFalse("Find no more than one, but actually has more.", 
iter.hasNext());
+        }
+    }
+
+    /**
+     * interval is after the given interval.  Find interval beginnings after 
the endings of the given interval.
+     * {@link MongoTemporalIndexer#queryIntervalAfter(TemporalInterval, 
StatementContraints).
+     *
+     * @throws IOException
+     * @throws QueryEvaluationException
+     */
+    @Test
+    public void testQueryIntervalAfter() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            tIndexer.storeStatement(convertStatement(spo_B00_E01));
+            tIndexer.storeStatement(convertStatement(spo_B02_E29)); //<- after 
this one.
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B29_E30));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+            // instants should be ignored.
+            tIndexer.storeStatement(convertStatement(spo_B02));
+            tIndexer.storeStatement(convertStatement(seriesSpo[1])); // 
instance at 1 seconds
+            tIndexer.storeStatement(convertStatement(seriesSpo[2]));
+            tIndexer.storeStatement(convertStatement(seriesSpo[31]));
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            iter = tIndexer.queryIntervalAfter(tvB02_E29, EMPTY_CONSTRAINTS);
+            // Should be found twice:
+            assertTrue("spo_B30_E32 should be found, but actually returned 
empty results. spo_B30_E32=" + spo_B30_E32, iter.hasNext());
+            final Statement s = iter.next();
+            assertTrue("spo_B30_E32 should be found, but found another. 
spo_B30_E32="+spo_B30_E32+", but found="+s, spo_B30_E32.equals(s));
+            assertFalse("Find no more than one, but actually has more.", 
iter.hasNext());
+        }
+    }
+
+    /**
+     * Test instant after a given instant WITH two different predicates as 
constraints.
+     */
+    @Test
+    public void testQueryWithMultiplePredicates() throws IOException, 
QueryEvaluationException {
+        try(MongoTemporalIndexer tIndexer = new MongoTemporalIndexer()) {
+            tIndexer.setConf(conf);
+            tIndexer.init();
+
+            // tiB02_E30 read as: Begins 2 seconds, ends at 30 seconds
+            // these should not match as they are not instances.
+            tIndexer.storeStatement(convertStatement(spo_B03_E20));
+            tIndexer.storeStatement(convertStatement(spo_B02_E30));
+            tIndexer.storeStatement(convertStatement(spo_B02_E40));
+            tIndexer.storeStatement(convertStatement(spo_B02_E31));
+            tIndexer.storeStatement(convertStatement(spo_B30_E32));
+
+            // seriesSpo[s] and seriesTs[s] are statements and instant for s 
seconds after the uniform time.
+            final int searchForSeconds = 4;
+            final int expectedResultCount = 9;
+            for (int s = 0; s <= searchForSeconds + expectedResultCount; s++) 
{ // <== logic here
+                tIndexer.storeStatement(convertStatement(seriesSpo[s]));
+            }
+            final ValueFactory vf = new ValueFactoryImpl();
+            final URI pred3_CIRCA_ = vf.createURI(URI_PROPERTY_CIRCA);  // 
this one to ignore.
+            final URI pred2_eventTime = vf.createURI(URI_PROPERTY_EVENT_TIME);
+            final URI pred1_atTime = vf.createURI(URI_PROPERTY_AT_TIME);
+
+            // add the predicate = EventTime ; Store in an array for 
verification.
+            final Statement[] SeriesTs_EventTime = new 
Statement[expectedResultCount+1];
+            for (int s = 0; s <= searchForSeconds + expectedResultCount; s++) 
{ // <== logic here
+                final Statement statement = new 
StatementImpl(vf.createURI("foo:EventTimeSubj0" + s), pred2_eventTime, 
vf.createLiteral(seriesTs[s].getAsReadable()));
+                tIndexer.storeStatement(convertStatement(statement));
+                if (s>searchForSeconds) {
+                    SeriesTs_EventTime[s - searchForSeconds -1 ] = statement;
+                }
+            }
+            // add the predicate = CIRCA ; to be ignored because it is not in 
the constraints.
+            for (int s = 0; s <= searchForSeconds + expectedResultCount; s++) 
{ // <== logic here
+                final Statement statement = new 
StatementImpl(vf.createURI("foo:CircaEventSubj0" + s), pred3_CIRCA_, 
vf.createLiteral(seriesTs[s].getAsReadable()));
+                tIndexer.storeStatement(convertStatement(statement));
+            }
+
+            CloseableIteration<Statement, QueryEvaluationException> iter;
+            final StatementConstraints constraints = new 
StatementConstraints();
+            constraints.setPredicates(new HashSet<>(Arrays.asList( 
pred2_eventTime,  pred1_atTime )));
+
+            iter = 
tIndexer.queryInstantAfterInstant(seriesTs[searchForSeconds], constraints); // 
EMPTY_CONSTRAINTS);//
+            int count_AtTime = 0;
+            int count_EventTime = 0;
+            while (iter.hasNext()) {
+                final Statement s = iter.next();
+                final Statement nextExpectedStatement = 
seriesSpo[searchForSeconds + count_AtTime + 1]; // <== logic here
+                if (s.getPredicate().equals(pred1_atTime)) {
+                    assertTrue("Should match atTime: " + nextExpectedStatement 
+ " == " + s, nextExpectedStatement.equals(s));
+                    count_AtTime++;
+                }
+                else if (s.getPredicate().equals(pred2_eventTime)) {
+                    assertTrue("Should match eventTime: " + 
SeriesTs_EventTime[count_EventTime] + " == " + s, 
SeriesTs_EventTime[count_EventTime].equals(s));
+                    count_EventTime++;
+                } else {
+                    assertTrue("This predicate should not be returned: "+s, 
false);
+                }
+
+            }
+
+            assertEquals("Should find count of atTime    rows.", 
expectedResultCount, count_AtTime);
+            assertEquals("Should find count of eventTime rows.", 
expectedResultCount, count_EventTime);
+        }
+    }
+
+    /**
+     * Print and gather statistics on the entire index table.
+     *
+     * @param description
+     *            Printed to the console to find the test case.
+     * @param out
+     *            null or System.out or other output to send a listing.
+     * @param statistics
+     *            Hashes, sums, and counts for assertions.
+     * @return Count of entries in the index table.
+     * @throws IOException
+     */
+    public void printTables(MongoTemporalIndexer tIndexer, final String 
description) throws IOException {
+        System.out.println("-- start printTables() -- " + description);
+        System.out.println("Reading : " + 
tIndexer.getCollection().getFullName());
+        final DBCursor cursor = tIndexer.getCollection().find();
+        while(cursor.hasNext()) {
+            final DBObject dbo = cursor.next();
+            System.out.println(dbo.toString());
+        }
+        System.out.println();
+    }
+}

Reply via email to