http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/test/java/org/apache/atlas/query/QueryProcessorTest.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/query/QueryProcessorTest.java b/repository/src/test/java/org/apache/atlas/query/QueryProcessorTest.java deleted file mode 100644 index 57bc74f..0000000 --- a/repository/src/test/java/org/apache/atlas/query/QueryProcessorTest.java +++ /dev/null @@ -1,157 +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.atlas.query; - -import com.google.common.collect.ImmutableSet; -import org.apache.atlas.AtlasException; -import org.apache.atlas.typesystem.types.ClassType; -import org.apache.atlas.typesystem.types.DataTypes; -import org.apache.atlas.typesystem.types.DataTypes.TypeCategory; -import org.apache.atlas.typesystem.types.HierarchicalTypeDefinition; -import org.apache.atlas.typesystem.types.IDataType; -import org.apache.atlas.typesystem.types.TypeSystem; -import org.apache.atlas.typesystem.types.cache.DefaultTypeCache; -import org.testng.annotations.Test; -import scala.util.Either; -import scala.util.parsing.combinator.Parsers; - -import java.util.HashSet; -import java.util.Set; - -import static org.apache.atlas.typesystem.types.utils.TypesUtil.createClassTypeDef; -import static org.apache.atlas.typesystem.types.utils.TypesUtil.createRequiredAttrDef; -import static org.testng.Assert.assertFalse; -import static org.testng.Assert.assertTrue; - -/** - * Tests the logic for skipping type cache lookup for things that - * cannot be types. - * - */ -public class QueryProcessorTest { - - - @Test - public void testAliasesNotTreatedAsTypes() throws Exception { - - ValidatingTypeCache tc = findTypeLookupsDuringQueryParsing("hive_db as inst where inst.name=\"Reporting\" select inst as id, inst.name"); - assertTrue(tc.wasTypeRequested("hive_db")); - assertFalse(tc.wasTypeRequested("inst")); - assertFalse(tc.wasTypeRequested("name")); - - } - - - @Test - public void testFieldInComparisionNotTreatedAsType() throws Exception { - - //test when the IdExpression is on the left, on the right, and on both sides of the ComparsionExpression - ValidatingTypeCache tc = findTypeLookupsDuringQueryParsing("hive_db where name=\"Reporting\" or \"Reporting\" = name or name=name"); - assertTrue(tc.wasTypeRequested("hive_db")); - assertFalse(tc.wasTypeRequested("name")); - - } - - - @Test - public void testFieldInArithmeticExprNotTreatedAsType() throws Exception { - - //test when the IdExpression is on the left, on the right, and on both sides of the ArithmeticExpression - ValidatingTypeCache tc = findTypeLookupsDuringQueryParsing("hive_db where (tableCount + 3) > (tableCount + tableCount) select (3 + tableCount) as updatedCount"); - - assertTrue(tc.wasTypeRequested("hive_db")); - assertFalse(tc.wasTypeRequested("tableCount")); - assertFalse(tc.wasTypeRequested("updatedCount")); - - } - - @Test - public void testFieldInSelectListWithAlasNotTreatedAsType() throws Exception { - - ValidatingTypeCache tc = findTypeLookupsDuringQueryParsing("hive_db select name as theName"); - assertTrue(tc.wasTypeRequested("hive_db")); - assertFalse(tc.wasTypeRequested("theName")); - assertFalse(tc.wasTypeRequested("name")); - - } - - @Test - public void testFieldInSelectListNotTreatedAsType() throws Exception { - - - ValidatingTypeCache tc = findTypeLookupsDuringQueryParsing("hive_db select name"); - assertTrue(tc.wasTypeRequested("hive_db")); - assertFalse(tc.wasTypeRequested("name")); - - } - - private ValidatingTypeCache findTypeLookupsDuringQueryParsing(String query) throws AtlasException { - TypeSystem typeSystem = TypeSystem.getInstance(); - ValidatingTypeCache result = new ValidatingTypeCache(); - typeSystem.setTypeCache(result); - typeSystem.reset(); - HierarchicalTypeDefinition<ClassType> hiveTypeDef = createClassTypeDef("hive_db", "", ImmutableSet.<String>of(), - createRequiredAttrDef("name", DataTypes.STRING_TYPE), - createRequiredAttrDef("tableCount", DataTypes.INT_TYPE) - ); - typeSystem.defineClassType(hiveTypeDef); - - Either<Parsers.NoSuccess, Expressions.Expression> either = QueryParser.apply(query, null); - Expressions.Expression expression = either.right().get(); - - QueryProcessor.validate(expression); - - return result; - } - - private static class ValidatingTypeCache extends DefaultTypeCache { - - private Set<String> typesRequested = new HashSet<>(); - - @Override - public boolean has(String typeName) throws AtlasException { - typesRequested.add(typeName); - return super.has(typeName); - } - - @Override - public boolean has(TypeCategory typeCategory, String typeName) throws AtlasException { - typesRequested.add(typeName); - return super.has(typeCategory, typeName); - } - - @Override - public IDataType get(String typeName) throws AtlasException { - typesRequested.add(typeName); - return super.get(typeName); - } - - @Override - public IDataType get(TypeCategory typeCategory, String typeName) throws AtlasException { - typesRequested.add(typeName); - return super.get(typeCategory, typeName); - } - - public boolean wasTypeRequested(String name) { - return typesRequested.contains(name); - } - } - - - -}
http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/test/java/org/apache/atlas/repository/BaseTest.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/BaseTest.java b/repository/src/test/java/org/apache/atlas/repository/BaseTest.java deleted file mode 100755 index 7e1df67..0000000 --- a/repository/src/test/java/org/apache/atlas/repository/BaseTest.java +++ /dev/null @@ -1,30 +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.atlas.repository; - -import org.apache.atlas.typesystem.types.TypeSystem; -import org.testng.annotations.BeforeMethod; - -public abstract class BaseTest { - @BeforeMethod - public void setup() throws Exception { - TypeSystem ts = TypeSystem.getInstance(); - ts.reset(); - } -} http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java b/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java index 551e6ab..47fd9cf 100644 --- a/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java +++ b/repository/src/test/java/org/apache/atlas/repository/audit/AuditRepositoryTestBase.java @@ -19,8 +19,8 @@ package org.apache.atlas.repository.audit; import org.apache.atlas.EntityAuditEvent; -import org.apache.atlas.TestUtils; -import org.apache.atlas.typesystem.Referenceable; +import org.apache.atlas.TestUtilsV2; +import org.apache.atlas.v1.model.instance.Referenceable; import org.testng.annotations.BeforeTest; import org.testng.annotations.Test; @@ -34,7 +34,7 @@ public class AuditRepositoryTestBase { protected EntityAuditRepository eventRepository; private String rand() { - return TestUtils.randomString(10); + return TestUtilsV2.randomString(10); } @BeforeTest @@ -44,37 +44,34 @@ public class AuditRepositoryTestBase { @Test public void testAddEvents() throws Exception { - TestUtils.skipForGremlin3EnabledGraphDb(); EntityAuditEvent event = new EntityAuditEvent(rand(), System.currentTimeMillis(), "u1", EntityAuditEvent.EntityAuditAction.ENTITY_CREATE, "d1", new Referenceable(rand())); eventRepository.putEvents(event); - List<EntityAuditEvent> events = - eventRepository.listEvents(event.getEntityId(), null, (short) 10); + List<EntityAuditEvent> events = eventRepository.listEvents(event.getEntityId(), null, (short) 10); + assertEquals(events.size(), 1); assertEventEquals(events.get(0), event); } @Test public void testListPagination() throws Exception { - TestUtils.skipForGremlin3EnabledGraphDb(); - String id1 = "id1" + rand(); - String id2 = "id2" + rand(); - String id3 = "id3" + rand(); - long ts = System.currentTimeMillis(); - Referenceable entity = new Referenceable(rand()); + String id1 = "id1" + rand(); + String id2 = "id2" + rand(); + String id3 = "id3" + rand(); + long ts = System.currentTimeMillis(); + Referenceable entity = new Referenceable(rand()); List<EntityAuditEvent> expectedEvents = new ArrayList<>(3); + for (int i = 0; i < 3; i++) { //Add events for both ids - EntityAuditEvent event = new EntityAuditEvent(id2, ts - i, "user" + i, - EntityAuditEvent.EntityAuditAction.ENTITY_UPDATE, "details" + i, entity); + EntityAuditEvent event = new EntityAuditEvent(id2, ts - i, "user" + i, EntityAuditEvent.EntityAuditAction.ENTITY_UPDATE, "details" + i, entity); + eventRepository.putEvents(event); expectedEvents.add(event); - eventRepository.putEvents(new EntityAuditEvent(id1, ts - i, "user" + i, - EntityAuditEvent.EntityAuditAction.TAG_DELETE, "details" + i, entity)); - eventRepository.putEvents(new EntityAuditEvent(id3, ts - i, "user" + i, - EntityAuditEvent.EntityAuditAction.TAG_ADD, "details" + i, entity)); + eventRepository.putEvents(new EntityAuditEvent(id1, ts - i, "user" + i, EntityAuditEvent.EntityAuditAction.TAG_DELETE, "details" + i, entity)); + eventRepository.putEvents(new EntityAuditEvent(id3, ts - i, "user" + i, EntityAuditEvent.EntityAuditAction.TAG_ADD, "details" + i, entity)); } //Use ts for which there is no event - ts + 2 @@ -92,8 +89,8 @@ public class AuditRepositoryTestBase { @Test public void testInvalidEntityId() throws Exception { - TestUtils.skipForGremlin3EnabledGraphDb(); List<EntityAuditEvent> events = eventRepository.listEvents(rand(), null, (short) 3); + assertEquals(events.size(), 0); } http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryHATest.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryHATest.java b/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryHATest.java deleted file mode 100644 index f66ac74..0000000 --- a/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryHATest.java +++ /dev/null @@ -1,96 +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 - * <p/> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p/> - * 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.atlas.repository.audit; - -import org.apache.atlas.AtlasException; -import org.apache.atlas.ha.HAConfiguration; -import org.apache.commons.configuration.Configuration; -import org.apache.hadoop.hbase.TableName; -import org.apache.hadoop.hbase.client.Admin; -import org.apache.hadoop.hbase.client.Connection; -import org.mockito.Mock; -import org.mockito.MockitoAnnotations; -import org.testng.annotations.BeforeMethod; -import org.testng.annotations.Test; - -import java.io.IOException; - -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.verifyZeroInteractions; -import static org.mockito.Mockito.when; - -public class HBaseBasedAuditRepositoryHATest { - - @Mock - private Configuration configuration; - - @Mock - private org.apache.hadoop.conf.Configuration hbaseConf; - - @Mock - private Connection connection; - - @BeforeMethod - public void setup() { - MockitoAnnotations.initMocks(this); - } - - @Test - public void testTableShouldNotBeCreatedOnStartIfHAIsEnabled() throws IOException, AtlasException { - when(configuration.containsKey(HAConfiguration.ATLAS_SERVER_HA_ENABLED_KEY)).thenReturn(true); - when(configuration.getBoolean(HAConfiguration.ATLAS_SERVER_HA_ENABLED_KEY)).thenReturn(true); - when(configuration.getString(HBaseBasedAuditRepository.CONFIG_TABLE_NAME, - HBaseBasedAuditRepository.DEFAULT_TABLE_NAME)). - thenReturn(HBaseBasedAuditRepository.DEFAULT_TABLE_NAME); - HBaseBasedAuditRepository auditRepository = new HBaseBasedAuditRepository() { - @Override - protected Connection createConnection(org.apache.hadoop.conf.Configuration hbaseConf) { - return connection; - } - }; - auditRepository.startInternal(configuration, hbaseConf); - - verifyZeroInteractions(connection); - } - - @Test - public void testShouldCreateTableWhenReactingToActive() throws AtlasException, IOException { - when(configuration.containsKey(HAConfiguration.ATLAS_SERVER_HA_ENABLED_KEY)).thenReturn(true); - when(configuration.getBoolean(HAConfiguration.ATLAS_SERVER_HA_ENABLED_KEY)).thenReturn(true); - when(configuration.getString(HBaseBasedAuditRepository.CONFIG_TABLE_NAME, - HBaseBasedAuditRepository.DEFAULT_TABLE_NAME)). - thenReturn(HBaseBasedAuditRepository.DEFAULT_TABLE_NAME); - TableName tableName = TableName.valueOf(HBaseBasedAuditRepository.DEFAULT_TABLE_NAME); - Admin admin = mock(Admin.class); - when(connection.getAdmin()).thenReturn(admin); - when(admin.tableExists(tableName)).thenReturn(true); - HBaseBasedAuditRepository auditRepository = new HBaseBasedAuditRepository() { - @Override - protected Connection createConnection(org.apache.hadoop.conf.Configuration hbaseConf) { - return connection; - } - }; - auditRepository.startInternal(configuration, hbaseConf); - auditRepository.instanceIsActive(); - - verify(connection).getAdmin(); - verify(admin).tableExists(tableName); - } -} http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryTest.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryTest.java b/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryTest.java deleted file mode 100644 index a9dfee3..0000000 --- a/repository/src/test/java/org/apache/atlas/repository/audit/HBaseBasedAuditRepositoryTest.java +++ /dev/null @@ -1,72 +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 - * <p/> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p/> - * 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.atlas.repository.audit; - -import org.apache.atlas.ApplicationProperties; -import org.apache.atlas.EntityAuditEvent; -import org.apache.atlas.TestUtils; -import org.apache.commons.configuration.Configuration; -import org.apache.hadoop.hbase.TableName; -import org.apache.hadoop.hbase.client.Admin; -import org.apache.hadoop.hbase.client.Connection; -import org.testng.annotations.AfterClass; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import static org.testng.Assert.assertNull; -import static org.testng.Assert.assertTrue; - -public class HBaseBasedAuditRepositoryTest extends AuditRepositoryTestBase { - private TableName tableName; - - @BeforeClass - public void setup() throws Exception { - //ATLAS-1591 Currently, some tests are skipped for titan1 backened. As these tests are hard coded to use Gremlin2. See ATLAS-1591 once it is fixed, please remove it. - - TestUtils.skipForGremlin3EnabledGraphDb(); - eventRepository = new HBaseBasedAuditRepository(); - HBaseTestUtils.startCluster(); - ((HBaseBasedAuditRepository) eventRepository).start(); - - Configuration properties = ApplicationProperties.get(); - String tableNameStr = properties.getString(HBaseBasedAuditRepository.CONFIG_TABLE_NAME, - HBaseBasedAuditRepository.DEFAULT_TABLE_NAME); - tableName = TableName.valueOf(tableNameStr); - } - - @AfterClass - public void teardown() throws Exception { - ((HBaseBasedAuditRepository) eventRepository).stop(); - HBaseTestUtils.stopCluster(); - } - - @Test - public void testTableCreated() throws Exception { - TestUtils.skipForGremlin3EnabledGraphDb(); - Connection connection = HBaseTestUtils.getConnection(); - Admin admin = connection.getAdmin(); - assertTrue(admin.tableExists(tableName)); - } - - @Override - protected void assertEventEquals(EntityAuditEvent actual, EntityAuditEvent expected) { - super.assertEventEquals(actual, expected); - assertNull(actual.getEntityDefinition()); - } -} \ No newline at end of file http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/test/java/org/apache/atlas/repository/audit/HBaseTestUtils.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/audit/HBaseTestUtils.java b/repository/src/test/java/org/apache/atlas/repository/audit/HBaseTestUtils.java deleted file mode 100644 index 984acfe..0000000 --- a/repository/src/test/java/org/apache/atlas/repository/audit/HBaseTestUtils.java +++ /dev/null @@ -1,53 +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 - * <p/> - * http://www.apache.org/licenses/LICENSE-2.0 - * <p/> - * 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.atlas.repository.audit; - -import org.apache.atlas.ApplicationProperties; -import org.apache.hadoop.conf.Configuration; -import org.apache.hadoop.hbase.HBaseTestingUtility; -import org.apache.hadoop.hbase.LocalHBaseCluster; -import org.apache.hadoop.hbase.client.Connection; - -import java.io.IOException; - -public class HBaseTestUtils { - private static HBaseTestingUtility hbaseTestUtility; - private static LocalHBaseCluster hbaseCluster; - - public static void startCluster() throws Exception { - Configuration hbaseConf = - HBaseBasedAuditRepository.getHBaseConfiguration(ApplicationProperties.get()); - hbaseTestUtility = HBaseTestingUtility.createLocalHTU(hbaseConf); - int zkPort = hbaseConf.getInt("hbase.zookeeper.property.clientPort", 19026); - hbaseTestUtility.startMiniZKCluster(1, zkPort); - - hbaseCluster = new LocalHBaseCluster(hbaseTestUtility.getConfiguration()); - hbaseCluster.startup(); - } - - public static void stopCluster() throws Exception { - hbaseTestUtility.getConnection().close(); - hbaseCluster.shutdown(); - hbaseTestUtility.shutdownMiniZKCluster(); - } - - public static Connection getConnection() throws IOException { - return hbaseTestUtility.getConnection(); - } -} http://git-wip-us.apache.org/repos/asf/atlas/blob/435fe3fb/repository/src/test/java/org/apache/atlas/repository/graph/AbstractGremlinQueryOptimizerTest.java ---------------------------------------------------------------------- diff --git a/repository/src/test/java/org/apache/atlas/repository/graph/AbstractGremlinQueryOptimizerTest.java b/repository/src/test/java/org/apache/atlas/repository/graph/AbstractGremlinQueryOptimizerTest.java deleted file mode 100644 index 88de2c4..0000000 --- a/repository/src/test/java/org/apache/atlas/repository/graph/AbstractGremlinQueryOptimizerTest.java +++ /dev/null @@ -1,708 +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.atlas.repository.graph; - -import org.apache.atlas.AtlasException; -import org.apache.atlas.gremlin.GremlinExpressionFactory; -import org.apache.atlas.gremlin.optimizer.GremlinQueryOptimizer; -import org.apache.atlas.gremlin.optimizer.RangeFinder; -import org.apache.atlas.groovy.AbstractFunctionExpression; -import org.apache.atlas.groovy.FunctionCallExpression; -import org.apache.atlas.groovy.GroovyExpression; -import org.apache.atlas.groovy.IdentifierExpression; -import org.apache.atlas.groovy.LiteralExpression; -import org.apache.atlas.groovy.TraversalStepType; -import org.apache.atlas.query.GraphPersistenceStrategies; -import org.apache.atlas.query.TypeUtils.FieldInfo; -import org.apache.atlas.repository.Constants; -import org.apache.atlas.repository.MetadataRepository; -import org.apache.atlas.repository.RepositoryException; -import org.apache.atlas.repository.graphdb.AtlasEdgeDirection; -import org.apache.atlas.repository.graphdb.AtlasGraph; -import org.apache.atlas.repository.graphdb.GremlinVersion; -import org.apache.atlas.typesystem.types.AttributeDefinition; -import org.apache.atlas.typesystem.types.AttributeInfo; -import org.apache.atlas.typesystem.types.DataTypes; -import org.apache.atlas.typesystem.types.IDataType; -import org.apache.atlas.typesystem.types.Multiplicity; -import org.apache.atlas.typesystem.types.TypeSystem; -import org.testng.annotations.BeforeClass; -import org.testng.annotations.Test; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -import static org.mockito.Matchers.any; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.when; -import static org.testng.Assert.assertEquals; -import static org.testng.Assert.assertNotNull; - - -public abstract class AbstractGremlinQueryOptimizerTest implements IAtlasGraphProvider { - - protected abstract GremlinExpressionFactory getFactory(); - - private MetadataRepository repo; - private final GraphPersistenceStrategies STRATEGY = mock(GraphPersistenceStrategies.class); - - @BeforeClass - public void setUp() throws RepositoryException { - GremlinQueryOptimizer.reset(); - GremlinQueryOptimizer.setExpressionFactory(getFactory()); - when(STRATEGY.typeAttributeName()).thenReturn(Constants.ENTITY_TYPE_PROPERTY_KEY); - when(STRATEGY.superTypeAttributeName()).thenReturn(Constants.SUPER_TYPES_PROPERTY_KEY); - repo = new GraphBackedMetadataRepository(new HardDeleteHandler(TypeSystem.getInstance()), this.get()); - } - - private FieldInfo getTestFieldInfo() throws AtlasException { - AttributeDefinition def = new AttributeDefinition("foo", DataTypes.STRING_TYPE.getName(), Multiplicity.REQUIRED, false, null); - AttributeInfo attrInfo = new AttributeInfo(TypeSystem.getInstance(), def, null); - return new FieldInfo(DataTypes.STRING_TYPE, attrInfo, null, null); - } - - private GroovyExpression getVerticesExpression() { - IdentifierExpression g = new IdentifierExpression("g"); - return new FunctionCallExpression(TraversalStepType.START, g, "V"); - } - - - @Test - public void testPullHasExpressionsOutOfAnd() throws AtlasException { - - GroovyExpression expr1 = makeOutExpression(null, "out1"); - GroovyExpression expr2 = makeOutExpression(null, "out2"); - GroovyExpression expr3 = makeHasExpression("prop1","Fred"); - GroovyExpression expr4 = makeHasExpression("prop2","George"); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "and", Arrays.asList(expr1, expr2, expr3, expr4)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestPullHasExpressionsOutOfHas()); - } - - protected abstract String getExpectedGremlinForTestPullHasExpressionsOutOfHas(); - - - @Test - public void testOrGrouping() throws AtlasException { - GroovyExpression expr1 = makeOutExpression(null, "out1"); - GroovyExpression expr2 = makeOutExpression(null, "out2"); - GroovyExpression expr3 = makeHasExpression("prop1","Fred"); - GroovyExpression expr4 = makeHasExpression("prop2","George"); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(expr1, expr2, expr3, expr4)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestOrGrouping()); - } - - protected abstract String getExpectedGremlinForTestOrGrouping(); - - - @Test - public void testAndOfOrs() throws AtlasException { - - GroovyExpression or1Cond1 = makeHasExpression("p1","e1"); - GroovyExpression or1Cond2 = makeHasExpression("p2","e2"); - GroovyExpression or2Cond1 = makeHasExpression("p3","e3"); - GroovyExpression or2Cond2 = makeHasExpression("p4","e4"); - - GroovyExpression or1 = getFactory().generateLogicalExpression(null, "or", Arrays.asList(or1Cond1, or1Cond2)); - GroovyExpression or2 = getFactory().generateLogicalExpression(null, "or", Arrays.asList(or2Cond1, or2Cond2)); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "and", Arrays.asList(or1, or2)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAndOfOrs()); - - } - - protected abstract String getExpectedGremlinForTestAndOfOrs(); - - @Test - public void testAndWithMultiCallArguments() throws AtlasException { - - GroovyExpression cond1 = makeHasExpression("p1","e1"); - GroovyExpression cond2 = makeHasExpression(cond1, "p2","e2"); - GroovyExpression cond3 = makeHasExpression("p3","e3"); - GroovyExpression cond4 = makeHasExpression(cond3, "p4","e4"); - - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "and", Arrays.asList(cond2, cond4)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAndWithMultiCallArguments()); - } - - - protected abstract String getExpectedGremlinForTestAndWithMultiCallArguments(); - - @Test - public void testOrOfAnds() throws AtlasException { - - GroovyExpression or1Cond1 = makeHasExpression("p1","e1"); - GroovyExpression or1Cond2 = makeHasExpression("p2","e2"); - GroovyExpression or2Cond1 = makeHasExpression("p3","e3"); - GroovyExpression or2Cond2 = makeHasExpression("p4","e4"); - - GroovyExpression or1 = getFactory().generateLogicalExpression(null, "and", Arrays.asList(or1Cond1, or1Cond2)); - GroovyExpression or2 = getFactory().generateLogicalExpression(null, "and", Arrays.asList(or2Cond1, or2Cond2)); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(or1, or2)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestOrOfAnds()); - } - - protected abstract String getExpectedGremlinForTestOrOfAnds(); - - @Test - public void testHasNotMovedToResult() throws AtlasException { - GroovyExpression toOptimize = getVerticesExpression(); - GroovyExpression or1Cond1 = makeHasExpression("p1","e1"); - GroovyExpression or1Cond2 = makeHasExpression("p2","e2"); - - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(or1Cond1, or1Cond2)); - toOptimize = makeHasExpression(toOptimize, "p3","e3"); - toOptimize = getFactory().generateAliasExpression(toOptimize, "_src"); - toOptimize = getFactory().generateSelectExpression(toOptimize, Collections.singletonList(new LiteralExpression("src1")), Collections.<GroovyExpression>singletonList(new IdentifierExpression("it"))); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), - getExpectedGremlinForTestHasNotMovedToResult()); - } - - protected abstract String getExpectedGremlinForTestHasNotMovedToResult(); - - @Test - public void testOptimizeLoopExpression() throws AtlasException { - - - GroovyExpression input = getVerticesExpression(); - input = getFactory().generateTypeTestExpression(STRATEGY, input, "DataSet", TestIntSequence.INSTANCE).get(0); - input = makeHasExpression(input, "name","Fred"); - input = getFactory().generateAliasExpression(input, "label"); - - - GroovyExpression loopExpr = getFactory().getLoopExpressionParent(input); - loopExpr = getFactory().generateAdjacentVerticesExpression(loopExpr, AtlasEdgeDirection.IN, "inputTables"); - loopExpr = getFactory().generateAdjacentVerticesExpression(loopExpr, AtlasEdgeDirection.OUT, "outputTables"); - GroovyExpression result = getFactory().generateLoopExpression(input, STRATEGY, DataTypes.STRING_TYPE, loopExpr, "label", null); - result = getFactory().generateToListExpression(result); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(result); - - assertEquals(optimized.toString(), getExpectedGremlinForOptimizeLoopExpression()); - } - - protected abstract String getExpectedGremlinForOptimizeLoopExpression(); - - @Test - public void testLongStringEndingWithOr() throws AtlasException { - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = makeHasExpression(toOptimize, "name","Fred"); - toOptimize = makeHasExpression(toOptimize, "age","13"); - toOptimize = makeOutExpression(toOptimize, "livesIn"); - toOptimize = makeHasExpression(toOptimize, "state","Massachusetts"); - - GroovyExpression or1cond1 = makeHasExpression("p1", "e1"); - GroovyExpression or1cond2 = makeHasExpression("p2", "e2"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(or1cond1, or1cond2)); - - GroovyExpression or2cond1 = makeHasExpression("p3", "e3"); - GroovyExpression or2cond2 = makeHasExpression("p4", "e4"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(or2cond1, or2cond2)); - toOptimize = makeHasExpression(toOptimize, "p5","e5"); - toOptimize = makeHasExpression(toOptimize, "p6","e6"); - GroovyExpression or3cond1 = makeHasExpression("p7", "e7"); - GroovyExpression or3cond2 = makeHasExpression("p8", "e8"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(or3cond1, or3cond2)); - - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestLongStringEndingWithOr()); - } - - protected abstract String getExpectedGremlinForTestLongStringEndingWithOr(); - - @Test - public void testLongStringNotEndingWithOr() throws AtlasException { - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = makeHasExpression(toOptimize, "name","Fred"); - toOptimize = makeHasExpression(toOptimize, "age","13"); - toOptimize = makeOutExpression(toOptimize, "livesIn"); - toOptimize = makeHasExpression(toOptimize, "state","Massachusetts"); - - GroovyExpression or1cond1 = makeHasExpression("p1", "e1"); - GroovyExpression or1cond2 = makeHasExpression("p2", "e2"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(or1cond1, or1cond2)); - - GroovyExpression or2cond1 = makeHasExpression("p3", "e3"); - GroovyExpression or2cond2 = makeHasExpression("p4", "e4"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(or2cond1, or2cond2)); - toOptimize = makeHasExpression(toOptimize, "p5","e5"); - toOptimize = makeHasExpression(toOptimize, "p6","e6"); - GroovyExpression or3cond1 = makeHasExpression("p7", "e7"); - GroovyExpression or3cond2 = makeHasExpression("p8", "e8"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(or3cond1, or3cond2)); - toOptimize = makeHasExpression(toOptimize, "p9","e9"); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestLongStringNotEndingWithOr()); - } - - protected abstract String getExpectedGremlinForTestLongStringNotEndingWithOr(); - - @Test - public void testToListConversion() throws AtlasException { - - GroovyExpression expr1 = makeHasExpression("prop1","Fred"); - GroovyExpression expr2 = makeHasExpression("prop2","George"); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(expr1, expr2)); - toOptimize = new FunctionCallExpression(TraversalStepType.END, toOptimize,"toList"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestToListConversion()); - } - - protected abstract String getExpectedGremlinForTestToListConversion(); - - @Test - public void testToListWithExtraStuff() throws AtlasException { - - GroovyExpression expr1 = makeHasExpression("prop1","Fred"); - GroovyExpression expr2 = makeHasExpression("prop2","George"); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(expr1, expr2)); - toOptimize = new FunctionCallExpression(TraversalStepType.END, toOptimize,"toList"); - toOptimize = new FunctionCallExpression(toOptimize,"size"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestToListWithExtraStuff()); - - } - - protected abstract String getExpectedGremlinForTestToListWithExtraStuff(); - - public void testAddClosureWithExitExpressionDifferentFromExpr() throws AtlasException { - - GroovyExpression expr1 = makeHasExpression("prop1","Fred"); - GroovyExpression expr2 = makeHasExpression("prop2","George"); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(expr1, expr2)); - toOptimize = makeOutExpression(toOptimize, "knows"); - toOptimize = makeOutExpression(toOptimize, "livesIn"); - toOptimize = new FunctionCallExpression(TraversalStepType.END, toOptimize,"toList"); - toOptimize = new FunctionCallExpression(toOptimize,"size"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAddClosureWithExitExpressionDifferentFromExpr()); - - } - - protected abstract String getExpectedGremlinForTestAddClosureWithExitExpressionDifferentFromExpr(); - - @Test - public void testAddClosureNoExitExpression() throws AtlasException { - - GroovyExpression expr1 = makeHasExpression("prop1","Fred"); - GroovyExpression expr2 = makeHasExpression("prop2","George"); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(expr1, expr2)); - toOptimize = makeOutExpression(toOptimize, "knows"); - toOptimize = makeOutExpression(toOptimize, "livesIn"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAddClosureNoExitExpression()); - } - - protected abstract String getExpectedGremlinForTestAddClosureNoExitExpression(); - - - private GroovyExpression makeOutExpression(GroovyExpression parent, String label) { - return getFactory().generateAdjacentVerticesExpression(parent, AtlasEdgeDirection.OUT, label); - } - - @Test - public void testAddClosureWithExitExpressionEqualToExpr() throws AtlasException { - - GroovyExpression expr1 = makeHasExpression("prop1","Fred"); - GroovyExpression expr2 = makeHasExpression("prop2","George"); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(expr1, expr2)); - - toOptimize = makeOutExpression(toOptimize, "knows"); - toOptimize = makeOutExpression(toOptimize, "livesIn"); - toOptimize = new FunctionCallExpression(TraversalStepType.END, toOptimize,"toList"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAddClosureWithExitExpressionEqualToExpr()); - } - - protected abstract String getExpectedGremlinForTestAddClosureWithExitExpressionEqualToExpr(); - - - @Test - public void testClosureNotCreatedWhenNoOrs() throws AtlasException { - - GroovyExpression expr1 = makeHasExpression("prop1","Fred"); - GroovyExpression expr2 = makeHasExpression("prop2","George"); - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "and", Arrays.asList(expr1, expr2)); - toOptimize = makeOutExpression(toOptimize, "knows"); - toOptimize = makeOutExpression(toOptimize, "livesIn"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestClosureNotCreatedWhenNoOrs()); - } - - protected abstract String getExpectedGremlinForTestClosureNotCreatedWhenNoOrs(); - - - private GroovyExpression makeHasExpression(String name, String value) throws AtlasException { - return makeHasExpression(null, name, value); - } - private GroovyExpression makeHasExpression(GroovyExpression parent, String name, String value) throws AtlasException { - return getFactory().generateHasExpression(STRATEGY, parent, name, "=", new LiteralExpression(value), getTestFieldInfo()); - } - private GroovyExpression makeFieldExpression(GroovyExpression parent, String fieldName) throws AtlasException { - return getFactory().generateFieldExpression(parent, getTestFieldInfo(), fieldName, false); - } - - @Test - public void testOrFollowedByAnd() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression("name","George"); - GroovyExpression expr3 = makeHasExpression("age","13"); - GroovyExpression expr4 = makeHasExpression("age","14"); - - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(expr1,expr2)); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "and", Arrays.asList(expr3, expr4)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestOrFollowedByAnd()); - } - - protected abstract String getExpectedGremlinForTestOrFollowedByAnd(); - - @Test - public void testOrFollowedByOr() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression("name","George"); - GroovyExpression expr3 = makeHasExpression("age","13"); - GroovyExpression expr4 = makeHasExpression("age","14"); - - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "or", Arrays.asList(expr1,expr2)); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr3, expr4)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestOrFollowedByOr()); - } - - protected abstract String getExpectedGremlinForTestOrFollowedByOr(); - - @Test - public void testMassiveOrExpansion() throws AtlasException { - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = makeHasExpression(toOptimize, "h1","h2"); - toOptimize = makeHasExpression(toOptimize, "h3","h4"); - for(int i = 0; i < 5; i++) { - GroovyExpression expr1 = makeHasExpression("p1" + i,"e1" + i); - GroovyExpression expr2 = makeHasExpression("p2" + i,"e2" + i); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1,expr2)); - toOptimize = makeHasExpression(toOptimize, "ha" + i,"hb" + i); - toOptimize = makeHasExpression(toOptimize, "hc" + i,"hd" + i); - } - toOptimize = makeHasExpression(toOptimize, "h5","h6"); - toOptimize = makeHasExpression(toOptimize, "h7","h8"); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestMassiveOrExpansion()); - } - - protected abstract String getExpectedGremlinForTestMassiveOrExpansion(); - - @Test - public void testAndFollowedByAnd() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression("name","George"); - GroovyExpression expr3 = makeHasExpression("age","13"); - GroovyExpression expr4 = makeHasExpression("age","14"); - - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "and", Arrays.asList(expr1,expr2)); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "and", Arrays.asList(expr3, expr4)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAndFollowedByAnd()); - - - } - - protected abstract String getExpectedGremlinForTestAndFollowedByAnd(); - - @Test - public void testAndFollowedByOr() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression("name","George"); - GroovyExpression expr3 = makeHasExpression("age","13"); - GroovyExpression expr4 = makeHasExpression("age","14"); - - GroovyExpression toOptimize = getFactory().generateLogicalExpression(getVerticesExpression(), "and", Arrays.asList(expr1,expr2)); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr3, expr4)); - - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAndFollowedByOr()); - } - - protected abstract String getExpectedGremlinForTestAndFollowedByOr(); - - @Test - public void testInitialAlias() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression("name","George"); - - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateAliasExpression(toOptimize, "x"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1, expr2)); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestInitialAlias()); - } - - protected abstract String getExpectedGremlinForTestInitialAlias(); - - @Test - public void testFinalAlias() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression("name","George"); - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1, expr2)); - toOptimize = getFactory().generateAliasExpression(toOptimize, "x"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestFinalAlias()); - } - - protected abstract String getExpectedGremlinForTestFinalAlias(); - - @Test - public void testAliasInMiddle() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression("name","George"); - GroovyExpression expr3 = makeHasExpression("age","13"); - GroovyExpression expr4 = makeHasExpression("age","14"); - - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1, expr2)); - toOptimize = getFactory().generateAliasExpression(toOptimize, "x"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr3, expr4)); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAliasInMiddle()); - } - - protected abstract String getExpectedGremlinForTestAliasInMiddle(); - - @Test - public void testMultipleAliases() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression("name","George"); - GroovyExpression expr3 = makeHasExpression("age","13"); - GroovyExpression expr4 = makeHasExpression("age","14"); - - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1, expr2)); - toOptimize = getFactory().generateAliasExpression(toOptimize, "x"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr3, expr4)); - toOptimize = getFactory().generateAliasExpression(toOptimize, "y"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGreminForTestMultipleAliases()); - } - - protected abstract String getExpectedGreminForTestMultipleAliases(); - - @Test - public void testAliasInOrExpr() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = getFactory().generateAliasExpression(makeHasExpression("name","George"), "george"); - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1, expr2)); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestAliasInOrExpr()); - } - - protected abstract String getExpectedGremlinForTestAliasInOrExpr(); - - @Test - public void testAliasInAndExpr() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = getFactory().generateAliasExpression(makeHasExpression("name","George"), "george"); - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "and", Arrays.asList(expr1, expr2)); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - //expression with alias cannot currently be pulled out of the and - assertEquals(optimized.toString(), getExpectedGremlinForTestAliasInAndExpr()); - } - - - protected abstract String getExpectedGremlinForTestAliasInAndExpr(); - @Test - public void testFlatMapExprInAnd() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression(makeOutExpression(null,"knows"), "name","George"); - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "and", Arrays.asList(expr1, expr2)); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestFlatMapExprInAnd()); - } - - - protected abstract String getExpectedGremlinForTestFlatMapExprInAnd(); - @Test - public void testFlatMapExprInOr() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression(makeOutExpression(null,"knows"), "name","George"); - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1, expr2)); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestFlatMapExprInOr()); - } - - protected abstract String getExpectedGremlinForTestFlatMapExprInOr(); - - @Test - public void testFieldExpressionPushedToResultExpression() throws AtlasException { - GroovyExpression expr1 = makeHasExpression("name","Fred"); - GroovyExpression expr2 = makeHasExpression(makeOutExpression(null,"knows"), "name","George"); - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1, expr2)); - toOptimize = makeFieldExpression(toOptimize, "name"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestFieldExpressionPushedToResultExpression()); - } - - protected abstract String getExpectedGremlinForTestFieldExpressionPushedToResultExpression(); - - @Test - public void testOrWithNoChildren() throws AtlasException { - GroovyExpression toOptimize = getVerticesExpression(); - GroovyExpression expr1 = makeHasExpression(toOptimize, "name","Fred"); - - toOptimize = getFactory().generateLogicalExpression(expr1, "or", Collections.<GroovyExpression>emptyList()); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - //or with no children matches no vertices - assertEquals(optimized.toString(), getExpectedGremlinFortestOrWithNoChildren()); - } - - protected abstract String getExpectedGremlinFortestOrWithNoChildren(); - - @Test - public void testFinalAliasNeeded() throws AtlasException { - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = makeHasExpression(toOptimize, "name", "Fred"); - toOptimize = getFactory().generateAliasExpression(toOptimize, "person"); - toOptimize = makeOutExpression(toOptimize, "livesIn"); - GroovyExpression isChicago = makeHasExpression(null, "name", "Chicago"); - GroovyExpression isBoston = makeHasExpression(null, "name", "Boston"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(isChicago, isBoston)); - toOptimize = getFactory().generateAliasExpression(toOptimize, "city"); - toOptimize = makeOutExpression(toOptimize, "state"); - toOptimize = makeHasExpression(toOptimize, "name", "Massachusetts"); - toOptimize = getFactory().generatePathExpression(toOptimize); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestFinalAliasNeeded()); - } - - protected abstract String getExpectedGremlinForTestFinalAliasNeeded(); - - @Test - public void testSimpleRangeExpression() throws AtlasException { - GroovyExpression expr1 = makeHasExpression(null, "name","Fred"); - GroovyExpression expr2 = makeHasExpression(null, "name","George"); - GroovyExpression expr3 = makeHasExpression(null, "age","34"); - GroovyExpression expr4 = makeHasExpression(null, "size","small"); - - GroovyExpression toOptimize = getVerticesExpression(); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr1, expr2)); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "and", Collections.singletonList(expr3)); - toOptimize = getFactory().generateAdjacentVerticesExpression(toOptimize, AtlasEdgeDirection.OUT, "eats"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "and", Collections.singletonList(expr4)); - toOptimize = makeHasExpression(toOptimize, "color","blue"); - toOptimize = getFactory().generateRangeExpression(toOptimize, 0, 10); - toOptimize = new FunctionCallExpression(TraversalStepType.END, toOptimize, "toList"); - toOptimize = new FunctionCallExpression(toOptimize, "size"); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestSimpleRangeExpression()); - } - - protected abstract String getExpectedGremlinForTestSimpleRangeExpression(); - - - @Test - public void testRangeWithNonZeroOffset() throws Exception { - // g.V().or(has('__typeName','OMAS_OMRSAsset'),has('__superTypeNames','OMAS_OMRSAsset')).range(5,10).as('inst').select('inst') - GroovyExpression toOptimize = getVerticesExpression(); - - GroovyExpression expr0 = makeHasExpression("__typeName", "OMAS_OMRSAsset"); - GroovyExpression expr1 = makeHasExpression("__superTypeNames", "OMAS_OMRSAsset"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr0, expr1)); - toOptimize = getFactory().generateRangeExpression(toOptimize, 5, 10); - toOptimize = getFactory().generateAliasExpression(toOptimize, "inst"); - toOptimize = getFactory().generateSelectExpression(toOptimize, Collections.singletonList(new LiteralExpression("inst")), Collections.<GroovyExpression>emptyList()); - RangeFinder visitor = new RangeFinder(getFactory()); - GremlinQueryOptimizer.visitCallHierarchy(toOptimize, visitor); - List<AbstractFunctionExpression> rangeExpressions = visitor.getRangeExpressions(); - assertEquals(rangeExpressions.size(), 1); - int[] rangeParameters = getFactory().getRangeParameters(rangeExpressions.get(0)); - assertNotNull(rangeParameters); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - // The range optimization is not supported with a non-zero start index, so the optimizer should not add range expressions - // to the expanded or's. - assertEquals(optimized.toString(), getExpectedGremlinForTestRangeWithNonZeroOffset()); - } - - protected abstract String getExpectedGremlinForTestRangeWithNonZeroOffset(); - - @Test - public void testRangeWithOrderBy() throws Exception { - // The range optimization is not supported with order, so the optimizer should not add range expressions - // to the expanded or's. - GroovyExpression toOptimize = getVerticesExpression(); - - GroovyExpression expr0 = makeHasExpression("__typeName", "OMAS_OMRSAsset"); - GroovyExpression expr1 = makeHasExpression("__superTypeNames", "OMAS_OMRSAsset"); - toOptimize = getFactory().generateLogicalExpression(toOptimize, "or", Arrays.asList(expr0, expr1)); - toOptimize = getFactory().generateRangeExpression(toOptimize, 5, 10); - toOptimize = getFactory().generateAliasExpression(toOptimize, "inst"); - //toOptimize = getFactory().generateSelectExpression(toOptimize, Collections.singletonList(new LiteralExpression("inst")), Collections.<GroovyExpression>emptyList()); - GroovyExpression orderFielda = makeFieldExpression(getFactory().getCurrentTraverserObject(getFactory().getClosureArgumentValue()), "name"); - GroovyExpression orderFieldb = makeFieldExpression(getFactory().getCurrentTraverserObject(getFactory().getClosureArgumentValue()), "name"); - toOptimize = getFactory().generateOrderByExpression(toOptimize,Arrays.asList(orderFielda, orderFieldb), true); - RangeFinder visitor = new RangeFinder(getFactory()); - GremlinQueryOptimizer.visitCallHierarchy(toOptimize, visitor); - List<AbstractFunctionExpression> rangeExpressions = visitor.getRangeExpressions(); - assertEquals(rangeExpressions.size(), 1); - int[] rangeParameters = getFactory().getRangeParameters(rangeExpressions.get(0)); - assertNotNull(rangeParameters); - GroovyExpression optimized = GremlinQueryOptimizer.getInstance().optimize(toOptimize); - assertEquals(optimized.toString(), getExpectedGremlinForTestRangeWithOrderBy()); - } - - - - protected abstract String getExpectedGremlinForTestRangeWithOrderBy(); - - @Override - public AtlasGraph get() throws RepositoryException { - AtlasGraph graph = mock(AtlasGraph.class); - when(graph.getSupportedGremlinVersion()).thenReturn(GremlinVersion.THREE); - when(graph.isPropertyValueConversionNeeded(any(IDataType.class))).thenReturn(false); - return graph; - } -}