diff --git a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantTableOperationBaseIT.java b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantTableOperationBaseIT.java new file mode 100644 index 00000000000..5fe1a9ea5aa --- /dev/null +++ b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantTableOperationBaseIT.java @@ -0,0 +1,74 @@ +/* + * 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.phoenix.pherf.workload.mt.tenantoperation; + +import org.apache.phoenix.end2end.ParallelStatsDisabledIT; +import org.apache.phoenix.pherf.PherfConstants; +import org.apache.phoenix.pherf.XMLConfigParserTest; +import org.apache.phoenix.pherf.configuration.DataModel; +import org.apache.phoenix.pherf.configuration.XMLConfigParser; +import org.apache.phoenix.pherf.schema.SchemaReader; +import org.apache.phoenix.pherf.util.PhoenixUtil; +import org.junit.BeforeClass; + +import java.net.URL; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.ArrayList; +import java.util.List; +import java.util.Properties; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.assertTrue; + +public class MultiTenantTableOperationBaseIT extends ParallelStatsDisabledIT { + + protected static final String matcherScenario = ".*scenario/.*test_tbl_workload.*xml"; + protected static final String matcherSchema = ".*datamodel/.*test_schema_tbl*.*sql"; + + protected static PhoenixUtil util = PhoenixUtil.create(true); + protected static Properties properties; + protected static SchemaReader reader; + protected static XMLConfigParser parser; + protected static List resources; + + @BeforeClass public static synchronized void setUp() throws Exception { + PherfConstants constants = PherfConstants.create(); + properties = constants.getProperties(PherfConstants.PHERF_PROPERTIES, false); + + PhoenixUtil.setZookeeper("localhost"); + reader = new SchemaReader(util, matcherSchema); + parser = new XMLConfigParser(matcherScenario); + reader.applySchema(); + resources = new ArrayList<>(reader.getResourceList()); + + assertTrue("Could not pull list of schema files.", resources.size() > 0); + assertNotNull("Could not read schema file.", reader.resourceToString(resources.get(0))); + + } + + public DataModel readTestDataModel(String resourceName) throws Exception { + URL scenarioUrl = XMLConfigParserTest.class.getResource(resourceName); + assertNotNull(scenarioUrl); + Path p = Paths.get(scenarioUrl.toURI()); + return XMLConfigParser.readDataModel(p); + } + +} diff --git a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantTestUtils.java b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantTestUtils.java new file mode 100644 index 00000000000..873e0614295 --- /dev/null +++ b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantTestUtils.java @@ -0,0 +1,267 @@ +/* + * 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.phoenix.pherf.workload.mt.tenantoperation; + +import com.lmax.disruptor.LifecycleAware; +import com.lmax.disruptor.WorkHandler; +import org.apache.phoenix.pherf.configuration.DataModel; +import org.apache.phoenix.pherf.configuration.LoadProfile; +import org.apache.phoenix.pherf.configuration.Scenario; +import org.apache.phoenix.pherf.util.PhoenixUtil; +import org.apache.phoenix.pherf.workload.Workload; +import org.apache.phoenix.pherf.workload.mt.Operation; +import org.apache.phoenix.pherf.workload.mt.OperationStats; +import org.apache.phoenix.thirdparty.com.google.common.base.Function; +import org.apache.phoenix.thirdparty.com.google.common.base.Supplier; +import org.apache.phoenix.thirdparty.com.google.common.collect.Lists; +import org.apache.phoenix.thirdparty.com.google.common.collect.Maps; +import org.junit.Assert; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +import java.net.InetAddress; +import java.util.List; +import java.util.Map; +import java.util.Properties; +import java.util.concurrent.CountDownLatch; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; +import java.util.concurrent.TimeUnit; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +public class MultiTenantTestUtils { + private static final Logger LOGGER = LoggerFactory.getLogger(MultiTenantTestUtils.class); + enum TestOperationGroup { + upsertOp, queryOp1, queryOp2, idleOp, udfOp + } + + public void testWorkloadWithOneHandler(Properties properties, DataModel model, + String scenarioName, int expectedTenantGroups, int expectedOpGroups) throws Exception { + + int numHandlers = 1; + int totalOperations = 50; + int perHandlerCount = 50; + + ExecutorService executor = null; + try { + executor = Executors.newFixedThreadPool(numHandlers); + PhoenixUtil pUtil = PhoenixUtil.create(); + for (Scenario scenario : model.getScenarios()) { + if (scenarioName != null && !scenarioName.isEmpty() + && scenario.getName().compareTo(scenarioName) != 0) { + continue; + } + LOGGER.debug(String.format("Testing %s", scenario.getName())); + LoadProfile loadProfile = scenario.getLoadProfile(); + + // Set the total number of operations for this load profile + loadProfile.setNumOperations(totalOperations); + TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, + scenario); + assertEquals("tenant group size is not as expected: ", expectedTenantGroups, + loadProfile.getTenantDistribution().size()); + assertEquals("operation group size from the factory is not as expected: ", + expectedOpGroups, opFactory.getOperations().size()); + + // populate the handlers and countdown latches. + String handlerId = String + .format("%s.%d", InetAddress.getLocalHost().getHostName(), numHandlers); + List workers = Lists.newArrayList(); + Map latches = Maps.newConcurrentMap(); + workers.add(new EventCountingWorkHandler(opFactory, handlerId, latches)); + latches.put(handlerId, new CountDownLatch(perHandlerCount)); + // submit the workload + Workload workload = new TenantOperationWorkload(pUtil, model, scenario, workers, + properties); + Future status = executor.submit(workload.execute()); + // Just make sure there are no exceptions + status.get(); + + // Wait for the handlers to count down + for (Map.Entry latch : latches.entrySet()) { + assertTrue(latch.getValue().await(60, TimeUnit.SECONDS)); + } + } + } finally { + if (executor != null) { + executor.shutdown(); + } + } + } + + public void testWorkloadWithManyHandlers(Properties properties, DataModel model, + String scenarioName, int expectedTenantGroups, int expectedOpGroups) throws Exception { + + int numHandlers = 5; + int totalOperations = 500; + int perHandlerCount = 50; + + ExecutorService executor = Executors.newFixedThreadPool(numHandlers); + PhoenixUtil pUtil = PhoenixUtil.create(); + for (Scenario scenario : model.getScenarios()) { + if (scenarioName != null && !scenarioName.isEmpty() + && scenario.getName().compareTo(scenarioName) != 0) { + continue; + } + LOGGER.debug(String.format("Testing %s", scenario.getName())); + LoadProfile loadProfile = scenario.getLoadProfile(); + + // Set the total number of operations for this load profile + loadProfile.setNumOperations(totalOperations); + TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, scenario); + assertEquals("tenant group size is not as expected: ", expectedTenantGroups, + loadProfile.getTenantDistribution().size()); + + assertEquals("operation group size from the factory is not as expected: ", + expectedOpGroups, opFactory.getOperations().size()); + + // populate the handlers and countdown latches. + List workers = Lists.newArrayList(); + Map latches = Maps.newConcurrentMap(); + for (int i = 0; i < numHandlers; i++) { + String handlerId = String + .format("%s.%d", InetAddress.getLocalHost().getHostName(), i); + workers.add(new EventCountingWorkHandler(opFactory, handlerId, latches)); + latches.put(handlerId, new CountDownLatch(perHandlerCount)); + } + // submit the workload + Workload workload = new TenantOperationWorkload(pUtil, model, scenario, workers, + properties); + Future status = executor.submit(workload.execute()); + // Just make sure there are no exceptions + status.get(); + // Wait for the handlers to count down + for (Map.Entry latch : latches.entrySet()) { + assertTrue(latch.getValue().await(60, TimeUnit.SECONDS)); + } + } + executor.shutdown(); + } + + public void testVariousOperations(Properties properties, DataModel model, String scenarioName, + int expectedTenantGroups, int expectedOpGroups) throws Exception { + + int numRuns = 10; + int numOperations = 10; + + PhoenixUtil pUtil = PhoenixUtil.create(); + for (Scenario scenario : model.getScenarios()) { + if (scenarioName != null && !scenarioName.isEmpty() + && scenario.getName().compareTo(scenarioName) != 0) { + continue; + } + LOGGER.debug(String.format("Testing %s", scenario.getName())); + LoadProfile loadProfile = scenario.getLoadProfile(); + assertEquals("tenant group size is not as expected: ", expectedTenantGroups, + loadProfile.getTenantDistribution().size()); + assertEquals("operation group size is not as expected: ", expectedOpGroups, + loadProfile.getOpDistribution().size()); + + TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, scenario); + TenantOperationEventGenerator evtGen = new TenantOperationEventGenerator( + opFactory.getOperations(), model, scenario); + + assertEquals("operation group size from the factory is not as expected: ", + expectedOpGroups, opFactory.getOperations().size()); + + int numRowsInserted = 0; + for (int i = 0; i < numRuns; i++) { + int ops = numOperations; + loadProfile.setNumOperations(ops); + while (ops-- > 0) { + TenantOperationInfo info = evtGen.next(); + Supplier> opSupplier = opFactory + .getOperationSupplier(info); + OperationStats stats = opSupplier.get().apply(info); + LOGGER.info(PhoenixUtil.getGSON().toJson(stats)); + if (info.getOperation().getType() == Operation.OperationType.PRE_RUN) continue; + assertTrue(stats.getStatus() != -1); + switch (TestOperationGroup + .valueOf(info.getOperationGroupId())) { + case upsertOp: + assertTrue(opSupplier.getClass() + .isAssignableFrom(UpsertOperationSupplier.class)); + numRowsInserted += stats.getRowCount(); + break; + case queryOp1: + case queryOp2: + assertTrue(opFactory.getOperationSupplier(info).getClass() + .isAssignableFrom(QueryOperationSupplier.class)); + + // expected row count > 0 + // Since the same view/table is being used by many tests. + // Keeping query return values would require lot of housekeeping + assertTrue(stats.getRowCount() > 0); + break; + case idleOp: + assertTrue(opFactory.getOperationSupplier(info).getClass() + .isAssignableFrom(IdleTimeOperationSupplier.class)); + assertEquals(0, stats.getRowCount()); + // expected think time (no-op) to be ~50ms + assertTrue(40 < stats.getDurationInMs() && stats.getDurationInMs() < 60); + break; + case udfOp: + assertTrue(opFactory.getOperationSupplier(info).getClass() + .isAssignableFrom(UserDefinedOperationSupplier.class)); + assertEquals(0, stats.getRowCount()); + break; + default: + Assert.fail(); + } + } + } + } + } + + private static class EventCountingWorkHandler + implements WorkHandler, LifecycleAware { + private final String handlerId; + private final TenantOperationFactory tenantOperationFactory; + private final Map latches; + + public EventCountingWorkHandler(TenantOperationFactory tenantOperationFactory, + String handlerId, Map latches) { + this.handlerId = handlerId; + this.tenantOperationFactory = tenantOperationFactory; + this.latches = latches; + } + + @Override public void onStart() { + } + + @Override public void onShutdown() { + } + + @Override public void onEvent(TenantOperationWorkload.TenantOperationEvent event) + throws Exception { + TenantOperationInfo input = event.getTenantOperationInfo(); + Supplier> + opSupplier + = tenantOperationFactory.getOperationSupplier(input); + OperationStats stats = opSupplier.get().apply(input); + LOGGER.info(PhoenixUtil.getGSON().toJson(stats)); + assertEquals(0, stats.getStatus()); + latches.get(handlerId).countDown(); + } + } + +} diff --git a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantOperationBaseIT.java b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantViewOperationBaseIT.java similarity index 91% rename from phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantOperationBaseIT.java rename to phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantViewOperationBaseIT.java index f2003814aa9..ba719776e81 100644 --- a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantOperationBaseIT.java +++ b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/MultiTenantViewOperationBaseIT.java @@ -19,7 +19,6 @@ package org.apache.phoenix.pherf.workload.mt.tenantoperation; -import org.apache.hadoop.hbase.HConstants; import org.apache.phoenix.end2end.NeedsOwnMiniClusterTest; import org.apache.phoenix.end2end.ParallelStatsDisabledIT; import org.apache.phoenix.pherf.PherfConstants; @@ -28,7 +27,6 @@ import org.apache.phoenix.pherf.configuration.XMLConfigParser; import org.apache.phoenix.pherf.schema.SchemaReader; import org.apache.phoenix.pherf.util.PhoenixUtil; -import org.junit.After; import org.junit.AfterClass; import org.junit.BeforeClass; import org.junit.experimental.categories.Category; @@ -44,14 +42,7 @@ import static org.junit.Assert.assertTrue; @Category(NeedsOwnMiniClusterTest.class) -public class MultiTenantOperationBaseIT extends ParallelStatsDisabledIT { - enum TestOperationGroup { - upsertOp, queryOp1, queryOp2, idleOp, udfOp - } - - static enum TestTenantGroup { - tg1, tg2, tg3 - } +public class MultiTenantViewOperationBaseIT extends ParallelStatsDisabledIT { protected static final String matcherScenario = ".*scenario/.*test_mt_workload.*xml"; protected static final String matcherSchema = ".*datamodel/.*test_schema_mt*.*sql"; diff --git a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationIT.java b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationIT.java deleted file mode 100644 index 737080a9632..00000000000 --- a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationIT.java +++ /dev/null @@ -1,112 +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.phoenix.pherf.workload.mt.tenantoperation; - -import org.apache.phoenix.pherf.configuration.DataModel; -import org.apache.phoenix.pherf.configuration.LoadProfile; -import org.apache.phoenix.pherf.configuration.Scenario; -import org.apache.phoenix.pherf.util.PhoenixUtil; -import org.apache.phoenix.pherf.workload.mt.Operation; -import org.apache.phoenix.pherf.workload.mt.OperationStats; -import org.apache.phoenix.thirdparty.com.google.common.base.Function; -import org.apache.phoenix.thirdparty.com.google.common.base.Supplier; -import org.junit.Assert; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Tests focused on tenant operations and their validations - */ -public class TenantOperationIT extends MultiTenantOperationBaseIT { - private static final Logger LOGGER = LoggerFactory.getLogger(TenantOperationIT.class); - - @Test - public void testVariousOperations() throws Exception { - int numTenantGroups = 3; - int numOpGroups = 5; - int numRuns = 10; - int numOperations = 10; - - PhoenixUtil pUtil = PhoenixUtil.create(); - DataModel model = readTestDataModel("/scenario/test_mt_workload.xml"); - for (Scenario scenario : model.getScenarios()) { - LOGGER.debug(String.format("Testing %s", scenario.getName())); - LoadProfile loadProfile = scenario.getLoadProfile(); - assertEquals("tenant group size is not as expected: ", - numTenantGroups, loadProfile.getTenantDistribution().size()); - assertEquals("operation group size is not as expected: ", - numOpGroups, loadProfile.getOpDistribution().size()); - - TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, scenario); - TenantOperationEventGenerator evtGen = new TenantOperationEventGenerator( - opFactory.getOperations(), model, scenario); - - assertEquals("operation group size from the factory is not as expected: ", - numOpGroups, opFactory.getOperations().size()); - - int numRowsInserted = 0; - for (int i = 0; i < numRuns; i++) { - int ops = numOperations; - loadProfile.setNumOperations(ops); - while (ops-- > 0) { - TenantOperationInfo info = evtGen.next(); - Supplier> opSupplier = - opFactory.getOperationSupplier(info); - OperationStats stats = opSupplier.get().apply(info); - LOGGER.info(pUtil.getGSON().toJson(stats)); - if (info.getOperation().getType() == Operation.OperationType.PRE_RUN) continue; - switch (TestOperationGroup.valueOf(info.getOperationGroupId())) { - case upsertOp: - assertTrue(opSupplier.getClass() - .isAssignableFrom(UpsertOperationSupplier.class)); - numRowsInserted += stats.getRowCount(); - break; - case queryOp1: - case queryOp2: - assertTrue(opFactory.getOperationSupplier(info).getClass() - .isAssignableFrom(QueryOperationSupplier.class)); - - // expected row count == num rows inserted - assertEquals(numRowsInserted, stats.getRowCount()); - break; - case idleOp: - assertTrue(opFactory.getOperationSupplier(info).getClass() - .isAssignableFrom(IdleTimeOperationSupplier.class)); - assertEquals(0, stats.getRowCount()); - // expected think time (no-op) to be ~50ms - assertTrue(40 < stats.getDurationInMs() && stats.getDurationInMs() < 60); - break; - case udfOp: - assertTrue(opFactory.getOperationSupplier(info).getClass() - .isAssignableFrom(UserDefinedOperationSupplier.class)); - assertEquals(0, stats.getRowCount()); - break; - default: - Assert.fail(); - } - } - } - } - } -} diff --git a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationWorkloadIT.java b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationWorkloadIT.java deleted file mode 100644 index c6d4dfdf201..00000000000 --- a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationWorkloadIT.java +++ /dev/null @@ -1,166 +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.phoenix.pherf.workload.mt.tenantoperation; - -import com.clearspring.analytics.util.Lists; -import org.apache.phoenix.thirdparty.com.google.common.base.Function; -import org.apache.phoenix.thirdparty.com.google.common.base.Supplier; -import org.apache.phoenix.thirdparty.com.google.common.collect.Maps; -import com.lmax.disruptor.LifecycleAware; -import com.lmax.disruptor.WorkHandler; -import org.apache.phoenix.pherf.configuration.DataModel; -import org.apache.phoenix.pherf.configuration.Scenario; -import org.apache.phoenix.pherf.util.PhoenixUtil; -import org.apache.phoenix.pherf.workload.Workload; -import org.apache.phoenix.pherf.workload.mt.OperationStats; -import org.apache.phoenix.pherf.workload.mt.tenantoperation.TenantOperationWorkload.TenantOperationEvent; -import org.junit.Test; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; - -import java.net.InetAddress; -import java.util.List; -import java.util.Map; -import java.util.concurrent.CountDownLatch; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.Future; -import java.util.concurrent.TimeUnit; - -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; - -/** - * Tests focused on tenant operation workloads {@link TenantOperationWorkload} - * and workload handlers {@link WorkHandler} - */ -public class TenantOperationWorkloadIT extends MultiTenantOperationBaseIT { - - private static class EventCountingWorkHandler implements - WorkHandler, LifecycleAware { - private final String handlerId; - private final TenantOperationFactory tenantOperationFactory; - private static final Logger LOGGER = LoggerFactory.getLogger(EventCountingWorkHandler.class); - private final Map latches; - public EventCountingWorkHandler(TenantOperationFactory tenantOperationFactory, - String handlerId, Map latches) { - this.handlerId = handlerId; - this.tenantOperationFactory = tenantOperationFactory; - this.latches = latches; - } - - @Override public void onStart() {} - - @Override public void onShutdown() {} - - @Override public void onEvent(TenantOperationEvent event) - throws Exception { - TenantOperationInfo input = event.getTenantOperationInfo(); - Supplier> - opSupplier = tenantOperationFactory.getOperationSupplier(input); - OperationStats stats = opSupplier.get().apply(input); - LOGGER.info(tenantOperationFactory.getPhoenixUtil().getGSON().toJson(stats)); - assertEquals(0, stats.getStatus()); - latches.get(handlerId).countDown(); - } - } - - @Test - public void testWorkloadWithOneHandler() throws Exception { - int numOpGroups = 5; - int numHandlers = 1; - int totalOperations = 50; - int perHandlerCount = 50; - - ExecutorService executor = null; - try { - executor = Executors.newFixedThreadPool(numHandlers); - PhoenixUtil pUtil = PhoenixUtil.create(); - DataModel model = readTestDataModel("/scenario/test_mt_workload.xml"); - for (Scenario scenario : model.getScenarios()) { - // Set the total number of operations for this load profile - scenario.getLoadProfile().setNumOperations(totalOperations); - TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, scenario); - assertEquals("operation group size from the factory is not as expected: ", - numOpGroups, opFactory.getOperations().size()); - - // populate the handlers and countdown latches. - String handlerId = String.format("%s.%d", InetAddress.getLocalHost().getHostName(), numHandlers); - List workers = Lists.newArrayList(); - Map latches = Maps.newConcurrentMap(); - workers.add(new EventCountingWorkHandler(opFactory, handlerId, latches)); - latches.put(handlerId, new CountDownLatch(perHandlerCount)); - // submit the workload - Workload workload = new TenantOperationWorkload(pUtil, model, scenario, workers, properties); - Future status = executor.submit(workload.execute()); - // Just make sure there are no exceptions - status.get(); - - // Wait for the handlers to count down - for (Map.Entry latch : latches.entrySet()) { - assertTrue(latch.getValue().await(60, TimeUnit.SECONDS)); - } - } - } finally { - if (executor != null) { - executor.shutdown(); - } - } - } - - @Test - public void testWorkloadWithManyHandlers() throws Exception { - int numOpGroups = 5; - int numHandlers = 5; - int totalOperations = 500; - int perHandlerCount = 50; - - ExecutorService executor = Executors.newFixedThreadPool(numHandlers); - PhoenixUtil pUtil = PhoenixUtil.create(); - DataModel model = readTestDataModel("/scenario/test_mt_workload.xml"); - for (Scenario scenario : model.getScenarios()) { - // Set the total number of operations for this load profile - scenario.getLoadProfile().setNumOperations(totalOperations); - TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, scenario); - assertEquals("operation group size from the factory is not as expected: ", - numOpGroups, opFactory.getOperations().size()); - - // populate the handlers and countdown latches. - List workers = Lists.newArrayList(); - Map latches = Maps.newConcurrentMap(); - for (int i=0;i latch : latches.entrySet()) { - assertTrue(latch.getValue().await(60, TimeUnit.SECONDS)); - } - } - executor.shutdown(); - } - -} diff --git a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantTableOperationWorkloadIT.java b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantTableOperationWorkloadIT.java new file mode 100644 index 00000000000..dc988488814 --- /dev/null +++ b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantTableOperationWorkloadIT.java @@ -0,0 +1,72 @@ +/* + * 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.phoenix.pherf.workload.mt.tenantoperation; + +import com.lmax.disruptor.WorkHandler; +import org.apache.phoenix.pherf.configuration.DataModel; +import org.junit.Test; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +/** + * Tests focused on tenant tablee operations and their validations + * Tests focused on tenant operation workloads {@link TenantOperationWorkload} + * and workload handlers {@link WorkHandler} + */ +public class TenantTableOperationWorkloadIT extends MultiTenantTableOperationBaseIT { + private final MultiTenantTestUtils multiTenantTestUtils = new MultiTenantTestUtils(); + private final DataModel model; + + public TenantTableOperationWorkloadIT() throws Exception { + model = readTestDataModel("/scenario/test_tbl_workload.xml"); + } + + @Test public void testVariousOperations() throws Exception { + int expectedTenantGroups = 1; + int expectedWriteOpGroups = 1; + int expectedReadOpGroups = 2; + multiTenantTestUtils.testVariousOperations(properties, model, "TEST_TABLE_WRITE", + expectedTenantGroups, expectedWriteOpGroups); + multiTenantTestUtils.testVariousOperations(properties, model, "TEST_TABLE_READ", + expectedTenantGroups, expectedReadOpGroups); + } + + @Test public void testWorkloadWithOneHandler() throws Exception { + int expectedTenantGroups = 1; + int expectedWriteOpGroups = 1; + int expectedReadOpGroups = 2; + multiTenantTestUtils.testWorkloadWithOneHandler(properties, model, "TEST_TABLE_WRITE", + expectedTenantGroups, expectedWriteOpGroups); + multiTenantTestUtils.testWorkloadWithOneHandler(properties, model, "TEST_TABLE_READ", + expectedTenantGroups, expectedReadOpGroups); + } + + @Test public void testWorkloadWithManyHandlers() throws Exception { + int expectedTenantGroups = 1; + int expectedWriteOpGroups = 1; + int expectedReadOpGroups = 2; + multiTenantTestUtils.testWorkloadWithManyHandlers(properties, model, "TEST_TABLE_WRITE", + expectedTenantGroups, expectedWriteOpGroups); + multiTenantTestUtils.testWorkloadWithManyHandlers(properties, model, "TEST_TABLE_READ", + expectedTenantGroups, expectedReadOpGroups); + } + +} diff --git a/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantViewOperationWorkloadIT.java b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantViewOperationWorkloadIT.java new file mode 100644 index 00000000000..66bbe38d3d3 --- /dev/null +++ b/phoenix-pherf/src/it/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantViewOperationWorkloadIT.java @@ -0,0 +1,61 @@ +/* + * 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.phoenix.pherf.workload.mt.tenantoperation; + +import com.lmax.disruptor.WorkHandler; +import org.apache.phoenix.pherf.configuration.DataModel; +import org.junit.Test; + +/** + * Tests focused on tenant view operations and their validations + * Tests focused on tenant operation workloads {@link TenantOperationWorkload} + * and workload handlers {@link WorkHandler} + */ +public class TenantViewOperationWorkloadIT extends MultiTenantViewOperationBaseIT { + + private final MultiTenantTestUtils multiTenantTestUtils = new MultiTenantTestUtils(); + private final DataModel model; + + public TenantViewOperationWorkloadIT() throws Exception { + model = readTestDataModel("/scenario/test_mt_workload.xml"); + } + + @Test public void testVariousOperations() throws Exception { + int expectedTenantGroups = 3; + int expectedOpGroups = 5; + multiTenantTestUtils.testVariousOperations(properties, model, null, + expectedTenantGroups, expectedOpGroups); + } + + @Test public void testWorkloadWithOneHandler() throws Exception { + int expectedTenantGroups = 3; + int expectedOpGroups = 5; + multiTenantTestUtils.testWorkloadWithOneHandler(properties, model, null, + expectedTenantGroups, expectedOpGroups); + + } + + @Test public void testWorkloadWithManyHandlers() throws Exception { + int expectedTenantGroups = 3; + int expectedOpGroups = 5; + multiTenantTestUtils.testWorkloadWithManyHandlers(properties, model, null, + expectedTenantGroups, expectedOpGroups); + } +} diff --git a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Upsert.java b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Upsert.java index dfbe9e628a9..810a7422526 100644 --- a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Upsert.java +++ b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/configuration/Upsert.java @@ -19,8 +19,11 @@ package org.apache.phoenix.pherf.configuration; import org.apache.phoenix.pherf.rules.RulesApplier; +import org.apache.phoenix.thirdparty.com.google.common.collect.Lists; import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; import java.util.List; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -30,7 +33,7 @@ public class Upsert { private String id; private String upsertGroup; private String statement; - private List columns; + private List column; private boolean useGlobalConnection; private Pattern pattern; private long timeoutDuration = Long.MAX_VALUE; @@ -90,12 +93,13 @@ public void setId(String id) { this.id = id; } - public List getColumns() { - return columns; + public List getColumn() { + if (column == null) return Lists.newArrayList(); + return column; } - public void setColumns(List columns) { - this.columns = columns; + public void setColumn(List column) { + this.column = column; } @XmlAttribute @@ -124,12 +128,4 @@ public void setStatement(String statement) { // normalize statement - merge all consecutive spaces into one this.statement = statement.replaceAll("\\s+", " "); } - - public List getColumn() { - return columns; - } - - public void setColumn(List columns) { - this.columns = columns; - } } diff --git a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/QueryOperationSupplier.java b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/QueryOperationSupplier.java index 99188ce0203..e14966141a7 100644 --- a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/QueryOperationSupplier.java +++ b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/QueryOperationSupplier.java @@ -69,7 +69,7 @@ public OperationStats apply(final TenantOperationInfo input) { String opName = String.format("%s:%s:%s:%s:%s", scenarioName, tableName, opGroup, tenantGroup, input.getTenantId()); - LOGGER.info("\nExecuting query " + query.getStatement()); + LOGGER.debug("\nExecuting query " + query.getStatement()); long startTime = 0; int status = 0; diff --git a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationFactory.java b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationFactory.java index 6e86e1465b4..ee74fad655a 100644 --- a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationFactory.java +++ b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationFactory.java @@ -18,6 +18,7 @@ package org.apache.phoenix.pherf.workload.mt.tenantoperation; +import org.apache.phoenix.pherf.configuration.Column; import org.apache.phoenix.thirdparty.com.google.common.base.Charsets; import org.apache.phoenix.thirdparty.com.google.common.base.Function; import org.apache.phoenix.thirdparty.com.google.common.base.Supplier; @@ -49,6 +50,8 @@ import java.util.List; import java.util.Map; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * Factory class for operation suppliers. @@ -94,6 +97,7 @@ public String getViewName() { Maps.newEnumMap(Operation.OperationType.class); private final BloomFilter tenantsLoaded; + private ReadWriteLock rwLock = new ReentrantReadWriteLock(); public TenantOperationFactory(PhoenixUtil phoenixUtil, DataModel model, Scenario scenario) { this.phoenixUtil = phoenixUtil; @@ -269,48 +273,15 @@ public Supplier> getOperationSuppl // Check if pre run ddls are needed. if (!tenantsLoaded.mightContain(tenantView)) { - - Supplier> preRunOpSupplier = - operationSuppliers.get(Operation.OperationType.PRE_RUN); - // Check if the scenario has a PRE_RUN operation. - if (preRunOpSupplier != null) { - // Initialize the tenant using the pre scenario ddls. - final PreScenarioOperation - operation = new PreScenarioOperation() { - @Override public List getPreScenarioDdls() { - List ddls = scenario.getPreScenarioDdls(); - return ddls == null ? Lists.newArrayList() : ddls; - } - - @Override public String getId() { - return OperationType.PRE_RUN.name(); - } - - @Override public OperationType getType() { - return OperationType.PRE_RUN; - } - }; - // Initialize with the pre run operation. - TenantOperationInfo preRunSample = new TenantOperationInfo( - input.getModelName(), - input.getScenarioName(), - input.getTableName(), - input.getTenantGroupId(), - Operation.OperationType.PRE_RUN.name(), - input.getTenantId(), operation); - - try { - // Run the initialization operation. - OperationStats stats = preRunOpSupplier.get().apply(preRunSample); - LOGGER.info(phoenixUtil.getGSON().toJson(stats)); - } catch (Exception e) { - LOGGER.error(String.format("Failed to initialize tenant. [%s, %s] ", - tenantView.tenantId, - tenantView.viewName), e); + rwLock.writeLock().lock(); + try { + if (!tenantsLoaded.mightContain(tenantView)) { + executePreRunOpsForTenant(tenantView, input); + tenantsLoaded.put(tenantView); } + } finally { + rwLock.writeLock().unlock(); } - - tenantsLoaded.put(tenantView); } Supplier> opSupplier = @@ -321,4 +292,47 @@ public Supplier> getOperationSuppl return opSupplier; } + private void executePreRunOpsForTenant(TenantView tenantView, TenantOperationInfo input) { + + Supplier> preRunOpSupplier = + operationSuppliers.get(Operation.OperationType.PRE_RUN); + // Check if the scenario has a PRE_RUN operation. + if (preRunOpSupplier != null) { + // Initialize the tenant using the pre scenario ddls. + final PreScenarioOperation + operation = new PreScenarioOperation() { + @Override public List getPreScenarioDdls() { + List ddls = scenario.getPreScenarioDdls(); + return ddls == null ? Lists.newArrayList() : ddls; + } + + @Override public String getId() { + return OperationType.PRE_RUN.name(); + } + + @Override public OperationType getType() { + return OperationType.PRE_RUN; + } + }; + // Initialize with the pre run operation. + TenantOperationInfo preRunSample = new TenantOperationInfo( + input.getModelName(), + input.getScenarioName(), + input.getTableName(), + input.getTenantGroupId(), + Operation.OperationType.PRE_RUN.name(), + input.getTenantId(), operation); + + try { + // Run the initialization operation. + OperationStats stats = preRunOpSupplier.get().apply(preRunSample); + LOGGER.info(phoenixUtil.getGSON().toJson(stats)); + } catch (Exception e) { + LOGGER.error(String.format("Failed to initialize tenant. [%s, %s] ", + tenantView.tenantId, + tenantView.viewName), e); + } + } + } + } diff --git a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/UpsertOperationSupplier.java b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/UpsertOperationSupplier.java index 30f953b8735..f7ff24aa84e 100644 --- a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/UpsertOperationSupplier.java +++ b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/UpsertOperationSupplier.java @@ -37,17 +37,19 @@ import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.List; +import java.util.concurrent.locks.ReadWriteLock; +import java.util.concurrent.locks.ReentrantReadWriteLock; /** * A supplier of {@link Function} that takes {@link UpsertOperation} as an input */ class UpsertOperationSupplier extends BaseOperationSupplier { private static final Logger LOGGER = LoggerFactory.getLogger(UpsertOperationSupplier.class); + private ReadWriteLock rwLock = new ReentrantReadWriteLock(); public UpsertOperationSupplier(PhoenixUtil phoenixUtil, DataModel model, Scenario scenario) { super(phoenixUtil, model, scenario); } - @Override public Function get() { return new Function() { @@ -65,7 +67,7 @@ public OperationStats apply(final TenantOperationInfo input) { final String opGroup = input.getOperationGroupId(); final String tableName = input.getTableName(); final String scenarioName = input.getScenarioName(); - final List columns = upsert.getColumn(); + // TODO: // Ideally the fact that the op needs to executed using global connection // needs to be built into the framework and injected during event generation. @@ -73,23 +75,39 @@ public OperationStats apply(final TenantOperationInfo input) { final boolean isTenantGroupGlobal = (tenantGroup.compareTo(TenantGroup.DEFAULT_GLOBAL_ID) == 0); final String tenantId = isTenantGroupGlobal || upsert.isUseGlobalConnection() ? null : input.getTenantId(); - final String opName = String.format("%s:%s:%s:%s:%s", scenarioName, tableName, opGroup, tenantGroup, input.getTenantId()); - long rowsCreated = 0; long startTime = 0, duration, totalDuration; int status = 0; SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); + try (Connection connection = phoenixUtil.getConnection(tenantId)) { - String sql = phoenixUtil.buildSql(columns, tableName); + // If list of columns has not been not provided or lazy loaded + // then use the metadata call to get the column list. + if (upsert.getColumn().isEmpty()) { + rwLock.writeLock().lock(); + try { + if (upsert.getColumn().isEmpty()) { + LOGGER.info("Fetching columns metadata from db for operation : " + opName); + List allCols = phoenixUtil.getColumnsFromPhoenix(scenario.getSchemaName(), + scenario.getTableNameWithoutSchemaName(), + connection); + upsert.setColumn(allCols); + } + } finally { + rwLock.writeLock().unlock(); + } + } + + String sql = phoenixUtil.buildSql(upsert.getColumn(), tableName); + LOGGER.info("Operation " + opName + " executing " + sql); startTime = EnvironmentEdgeManager.currentTimeMillis(); PreparedStatement stmt = null; try { stmt = connection.prepareStatement(sql); for (long i = rowCount; i > 0; i--) { - LOGGER.debug("Operation " + opName + " executing "); - stmt = phoenixUtil.buildStatement(rulesApplier, scenario, columns, stmt, simpleDateFormat); + stmt = phoenixUtil.buildStatement(rulesApplier, scenario, upsert.getColumn(), stmt, simpleDateFormat); if (useBatchApi) { stmt.addBatch(); } else { diff --git a/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ResultBaseTest.java b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ResultBaseTest.java index 531af265d90..a4b7648cfad 100644 --- a/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ResultBaseTest.java +++ b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/ResultBaseTest.java @@ -18,15 +18,10 @@ package org.apache.phoenix.pherf; -import org.apache.commons.io.FileUtils; import org.apache.phoenix.pherf.result.ResultUtil; -import org.apache.phoenix.pherf.workload.mt.tenantoperation.TenantOperationIT; import org.junit.AfterClass; import org.junit.BeforeClass; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import java.io.File; import java.util.Properties; public class ResultBaseTest { diff --git a/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_table.sql b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_base_table.sql similarity index 94% rename from phoenix-pherf/src/test/resources/datamodel/test_schema_mt_table.sql rename to phoenix-pherf/src/test/resources/datamodel/test_schema_mt_base_table.sql index b6791bf134b..184180ae8c8 100644 --- a/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_table.sql +++ b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_base_table.sql @@ -15,7 +15,7 @@ -- See the License for the specific language governing permissions and -- limitations under the License. */ -CREATE TABLE IF NOT EXISTS PHERF.TEST_MULTI_TENANT_TABLE ( +CREATE TABLE IF NOT EXISTS PHERF.TEST_BASE_TABLE ( TENANT_ID CHAR(15) NOT NULL, IDENTIFIER CHAR(3) NOT NULL, ID CHAR(15) NOT NULL, diff --git a/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view.sql b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view1.sql similarity index 88% rename from phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view.sql rename to phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view1.sql index ad25e9b2fdc..51080ddba62 100644 --- a/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view.sql +++ b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view1.sql @@ -16,7 +16,7 @@ -- limitations under the License. */ -CREATE VIEW IF NOT EXISTS PHERF.TEST_GLOBAL_VIEW ( +CREATE VIEW IF NOT EXISTS PHERF.TEST_GLOBAL_VIEW1 ( GID CHAR(15) NOT NULL, FIELD1 VARCHAR, OTHER_INT INTEGER @@ -24,4 +24,4 @@ CREATE VIEW IF NOT EXISTS PHERF.TEST_GLOBAL_VIEW ( ( GID ) -) AS SELECT * FROM PHERF.TEST_MULTI_TENANT_TABLE WHERE IDENTIFIER = 'EV1' +) AS SELECT * FROM PHERF.TEST_BASE_TABLE WHERE IDENTIFIER = 'EV1' diff --git a/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view2.sql b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view2.sql new file mode 100644 index 00000000000..a435eb77d94 --- /dev/null +++ b/phoenix-pherf/src/test/resources/datamodel/test_schema_mt_view2.sql @@ -0,0 +1,27 @@ +/* + -- 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. +*/ + +CREATE VIEW IF NOT EXISTS PHERF.TEST_GLOBAL_VIEW2 ( + GID CHAR(15) NOT NULL, + FIELD1 VARCHAR, + OTHER_INT INTEGER + CONSTRAINT PK PRIMARY KEY + ( + GID + ) +) AS SELECT * FROM PHERF.TEST_BASE_TABLE WHERE IDENTIFIER = 'EV2' diff --git a/phoenix-pherf/src/test/resources/datamodel/test_schema_tbl_simple.sql b/phoenix-pherf/src/test/resources/datamodel/test_schema_tbl_simple.sql new file mode 100644 index 00000000000..8b76820f933 --- /dev/null +++ b/phoenix-pherf/src/test/resources/datamodel/test_schema_tbl_simple.sql @@ -0,0 +1,33 @@ +/* + -- 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. +*/ +CREATE TABLE IF NOT EXISTS PHERF.TEST_MULTI_TENANT_TABLE ( + HOST CHAR(2) NOT NULL, + DOMAIN VARCHAR NOT NULL, + FEATURE VARCHAR NOT NULL, + DATE DATE NOT NULL, + USAGE.CORE BIGINT, + USAGE.DB BIGINT, + STATS.ACTIVE_VISITOR INTEGER + CONSTRAINT PK PRIMARY KEY + ( + HOST, + DOMAIN, + FEATURE, + DATE + ) +) VERSIONS=1, MULTI_TENANT=true diff --git a/phoenix-pherf/src/test/resources/scenario/test_mt_workload.xml b/phoenix-pherf/src/test/resources/scenario/test_mt_workload.xml index d3b83a21550..00d613b8192 100644 --- a/phoenix-pherf/src/test/resources/scenario/test_mt_workload.xml +++ b/phoenix-pherf/src/test/resources/scenario/test_mt_workload.xml @@ -44,6 +44,26 @@ 0 GENERAL_INTEGER + + INTEGER + SEQUENTIAL + + + + 0 + INT_ID + + + DATE + + RANDOM + + + + 0 + true + GENERAL_DATE + CHAR 3 @@ -63,9 +83,14 @@ + + CHAR + 3 + IDENTIFIER + - + 1 10 @@ -80,7 +105,7 @@ - + @@ -131,5 +156,71 @@ + + + 1 + 10 + + + + + + + + + + + + + + + + + + CHAR + ID + + + INTEGER + SOME_INT + + + CHAR + GID + + + VARCHAR + FIELD1 + + + INTEGER + OTHER_INT + + + INTEGER + INT_ID + + + CHAR + TYPE + + + + + + + + + + + + + + org.apache.phoenix.pherf.ConfigurationParserTest.TestUDF + Hello + World + + + diff --git a/phoenix-pherf/src/test/resources/scenario/test_tbl_workload.xml b/phoenix-pherf/src/test/resources/scenario/test_tbl_workload.xml new file mode 100644 index 00000000000..286dcf8251d --- /dev/null +++ b/phoenix-pherf/src/test/resources/scenario/test_tbl_workload.xml @@ -0,0 +1,169 @@ + + + + + + + CHAR + 2 + true + SEQUENTIAL + HOST + + + + + NA + + + CS + + + EU + + + + + VARCHAR + true + SEQUENTIAL + DOMAIN + + + + + Salesforce.com + + + Apple.com + + + Google.com + + + Amazon.com + + + + + VARCHAR + true + SEQUENTIAL + FEATURE + + + + + Login + + + Report + + + Dashboard + + + Sales + + + UI + + + + + DATE + true + SEQUENTIAL + DATE + + + DATE + true + + RANDOM + + + + 0 + 2020 + 2025 + DATE_O + + + + BIGINT + RANDOM + 1 + 100 + + + + 0 + USAGE.CORE + + + BIGINT + RANDOM + 1 + 2000 + + + + 0 + USAGE.DB + + + INTEGER + RANDOM + 1 + 10000 + + + + 0 + STATS.ACTIVE_VISITOR + + + + + + 1 + + + + + + + + + + + 1 + + + + + + + + + + + +