| /* |
| * 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.mongodb.aggregation; |
| |
| import java.util.Arrays; |
| import java.util.LinkedList; |
| import java.util.List; |
| |
| import org.bson.Document; |
| import org.junit.Assert; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.mockito.Mockito; |
| import org.openrdf.model.URI; |
| import org.openrdf.model.ValueFactory; |
| import org.openrdf.model.impl.ValueFactoryImpl; |
| import org.openrdf.model.vocabulary.RDF; |
| import org.openrdf.query.algebra.Compare; |
| import org.openrdf.query.algebra.ExtensionElem; |
| import org.openrdf.query.algebra.IsLiteral; |
| import org.openrdf.query.algebra.Not; |
| import org.openrdf.query.algebra.ProjectionElem; |
| import org.openrdf.query.algebra.ProjectionElemList; |
| import org.openrdf.query.algebra.StatementPattern; |
| import org.openrdf.query.algebra.ValueConstant; |
| import org.openrdf.query.algebra.Var; |
| |
| import com.google.common.collect.HashBiMap; |
| import com.google.common.collect.Sets; |
| import com.mongodb.MongoNamespace; |
| import com.mongodb.client.MongoCollection; |
| |
| public class AggregationPipelineQueryNodeTest { |
| private static final ValueFactory VF = ValueFactoryImpl.getInstance(); |
| |
| private static final String LUBM = "urn:lubm"; |
| private static final URI UNDERGRAD = VF.createURI(LUBM, "UndergraduateStudent"); |
| private static final URI TAKES = VF.createURI(LUBM, "takesCourse"); |
| |
| private static Var constant(URI value) { |
| return new Var(value.stringValue(), value); |
| } |
| |
| private MongoCollection<Document> collection; |
| |
| @Before |
| @SuppressWarnings("unchecked") |
| public void setUp() { |
| collection = Mockito.mock(MongoCollection.class); |
| Mockito.when(collection.getNamespace()).thenReturn(new MongoNamespace("db", "collection")); |
| } |
| |
| @Test |
| public void testEquals() { |
| final AggregationPipelineQueryNode node1 = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| final AggregationPipelineQueryNode node2 = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| Assert.assertEquals(node1, node2); |
| Assert.assertEquals(node1.hashCode(), node2.hashCode()); |
| final AggregationPipelineQueryNode diff1 = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y"), |
| HashBiMap.create()); |
| final AggregationPipelineQueryNode diff2 = new AggregationPipelineQueryNode( |
| collection, |
| Arrays.asList(new Document()), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| HashBiMap<String, String> varMapping = HashBiMap.create(); |
| varMapping.put("field-x", "x"); |
| final AggregationPipelineQueryNode diff3 = new AggregationPipelineQueryNode( |
| collection, |
| Arrays.asList(new Document()), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| varMapping); |
| Assert.assertNotEquals(diff1, node1); |
| Assert.assertNotEquals(diff2, node1); |
| Assert.assertNotEquals(diff3, node1); |
| node1.joinWith(new StatementPattern(new Var("x"), constant(TAKES), new Var("c"))); |
| node2.joinWith(new StatementPattern(new Var("x"), constant(TAKES), new Var("c"))); |
| Assert.assertEquals(node1, node2); |
| node2.joinWith(new StatementPattern(new Var("x"), constant(TAKES), new Var("c"))); |
| Assert.assertNotEquals(node1, node2); |
| } |
| |
| @Test |
| public void testClone() { |
| final AggregationPipelineQueryNode base = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| final AggregationPipelineQueryNode copy = base.clone(); |
| Assert.assertEquals(base, copy); |
| copy.getPipeline().add(new Document("$project", new Document())); |
| Assert.assertNotEquals(base, copy); |
| base.getPipeline().add(new Document("$project", new Document())); |
| Assert.assertEquals(base, copy); |
| } |
| |
| @Test |
| public void testStatementPattern() throws Exception { |
| // All variables |
| StatementPattern sp = new StatementPattern(new Var("s"), new Var("p"), new Var("o")); |
| AggregationPipelineQueryNode node = new AggregationPipelineQueryNode(collection, sp); |
| Assert.assertEquals(Sets.newHashSet("s", "p", "o"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("s", "p", "o"), node.getAssuredBindingNames()); |
| Assert.assertEquals(2, node.getPipeline().size()); |
| // All constants |
| sp = new StatementPattern(constant(VF.createURI("urn:Alice")), constant(RDF.TYPE), constant(UNDERGRAD)); |
| node = new AggregationPipelineQueryNode(collection, sp); |
| Assert.assertEquals(Sets.newHashSet(), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet(), node.getAssuredBindingNames()); |
| Assert.assertEquals(2, node.getPipeline().size()); |
| // Mixture |
| sp = new StatementPattern(new Var("student"), constant(RDF.TYPE), constant(UNDERGRAD)); |
| node = new AggregationPipelineQueryNode(collection, sp); |
| Assert.assertEquals(Sets.newHashSet("student"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("student"), node.getAssuredBindingNames()); |
| Assert.assertEquals(2, node.getPipeline().size()); |
| } |
| |
| @Test |
| public void testJoin() throws Exception { |
| final AggregationPipelineQueryNode base = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| // Join on one shared variable |
| AggregationPipelineQueryNode node = base.clone(); |
| boolean success = node.joinWith(new StatementPattern(new Var("x"), constant(TAKES), new Var("c"))); |
| Assert.assertTrue(success); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "c", "opt"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "c"), node.getAssuredBindingNames()); |
| Assert.assertEquals(4, node.getPipeline().size()); |
| // Join on multiple shared variables |
| node = base.clone(); |
| success = node.joinWith(new StatementPattern(new Var("x"), constant(TAKES), new Var("y"))); |
| Assert.assertTrue(success); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "opt"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y"), node.getAssuredBindingNames()); |
| Assert.assertEquals(5, node.getPipeline().size()); |
| } |
| |
| @Test |
| public void testProject() { |
| final AggregationPipelineQueryNode base = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| // Add a single projection |
| ProjectionElemList singleProjection = new ProjectionElemList(); |
| singleProjection.addElement(new ProjectionElem("x", "z")); |
| singleProjection.addElement(new ProjectionElem("y", "y")); |
| List<ProjectionElemList> projections = Arrays.asList(singleProjection); |
| AggregationPipelineQueryNode node = base.clone(); |
| boolean success = node.project(projections); |
| Assert.assertTrue(success); |
| Assert.assertEquals(1, node.getPipeline().size()); |
| Assert.assertEquals(Sets.newHashSet("z", "y"), |
| node.getAssuredBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("z", "y"), |
| node.getBindingNames()); |
| // Add a multi-projection |
| ProjectionElemList p1 = new ProjectionElemList(); |
| p1.addElement(new ProjectionElem("x", "solution")); |
| ProjectionElemList p2 = new ProjectionElemList(); |
| p2.addElement(new ProjectionElem("y", "solution")); |
| ProjectionElemList p3 = new ProjectionElemList(); |
| p3.addElement(new ProjectionElem("x", "x")); |
| p3.addElement(new ProjectionElem("x", "solution")); |
| p3.addElement(new ProjectionElem("y", "y")); |
| projections = Arrays.asList(p1, p2, p3); |
| node = base.clone(); |
| success = node.project(projections); |
| Assert.assertTrue(success); |
| Assert.assertEquals(3, node.getPipeline().size()); |
| Assert.assertEquals(Sets.newHashSet("solution"), |
| node.getAssuredBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "solution"), |
| node.getBindingNames()); |
| // Add no projections |
| node = base.clone(); |
| success = node.project(Arrays.asList()); |
| Assert.assertFalse(success); |
| Assert.assertEquals(base, node); |
| } |
| |
| @Test |
| public void testExtend() { |
| final AggregationPipelineQueryNode base = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| // Extend with a mix of variables and constants |
| List<ExtensionElem> extensionElements = Arrays.asList( |
| new ExtensionElem(new Var("x"), "subject"), |
| new ExtensionElem(new ValueConstant(RDF.TYPE), "predicate"), |
| new ExtensionElem(new Var("y"), "object")); |
| AggregationPipelineQueryNode node = base.clone(); |
| boolean success = node.extend(extensionElements); |
| Assert.assertTrue(success); |
| Assert.assertEquals(1, node.getPipeline().size()); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "subject", "predicate", "object"), |
| node.getAssuredBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "subject", "predicate", "object", "opt"), |
| node.getBindingNames()); |
| // Attempt to extend with an unsupported expression |
| extensionElements = Arrays.asList( |
| new ExtensionElem(new Var("x"), "subject"), |
| new ExtensionElem(new Not(new ValueConstant(VF.createLiteral(true))), "notTrue")); |
| node = base.clone(); |
| success = node.extend(extensionElements); |
| Assert.assertFalse(success); |
| Assert.assertEquals(base, node); |
| } |
| |
| @Test |
| public void testDistinct() { |
| final AggregationPipelineQueryNode base = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| AggregationPipelineQueryNode node = base.clone(); |
| boolean success = node.distinct(); |
| Assert.assertTrue(success); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "opt"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y"), node.getAssuredBindingNames()); |
| Assert.assertEquals(1, node.getPipeline().size()); |
| } |
| |
| @Test |
| public void testFilter() { |
| final AggregationPipelineQueryNode base = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| // Extend with a supported filter |
| AggregationPipelineQueryNode node = base.clone(); |
| boolean success = node.filter(new Compare(new Var("x"), new Var("y"), Compare.CompareOp.EQ)); |
| Assert.assertTrue(success); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "opt"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y"), node.getAssuredBindingNames()); |
| Assert.assertEquals(3, node.getPipeline().size()); |
| // Extend with an unsupported filter |
| node = base.clone(); |
| success = node.filter(new IsLiteral(new Var("opt"))); |
| Assert.assertFalse(success); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "opt"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y"), node.getAssuredBindingNames()); |
| Assert.assertEquals(0, node.getPipeline().size()); |
| } |
| |
| @Test |
| public void testRequireSourceDerivationLevel() throws Exception { |
| final AggregationPipelineQueryNode base = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| // Extend with a level greater than zero |
| AggregationPipelineQueryNode node = base.clone(); |
| node.requireSourceDerivationDepth(3); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "opt"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y"), node.getAssuredBindingNames()); |
| Assert.assertEquals(1, node.getPipeline().size()); |
| // Extend with a level of zero (no effect) |
| node = base.clone(); |
| node.requireSourceDerivationDepth(0); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "opt"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y"), node.getAssuredBindingNames()); |
| Assert.assertEquals(0, node.getPipeline().size()); |
| } |
| |
| @Test |
| public void testRequireSourceTimestamp() { |
| final AggregationPipelineQueryNode base = new AggregationPipelineQueryNode( |
| collection, |
| new LinkedList<>(), |
| Sets.newHashSet("x", "y"), |
| Sets.newHashSet("x", "y", "opt"), |
| HashBiMap.create()); |
| // Extend with a level greater than zero |
| AggregationPipelineQueryNode node = base.clone(); |
| node.requireSourceTimestamp(System.currentTimeMillis()); |
| Assert.assertEquals(Sets.newHashSet("x", "y", "opt"), node.getBindingNames()); |
| Assert.assertEquals(Sets.newHashSet("x", "y"), node.getAssuredBindingNames()); |
| Assert.assertEquals(1, node.getPipeline().size()); |
| } |
| } |