PHOENIX-6431 Add support for auto assigning pmfs

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
index 5fe1a9e..89420ed 100644
--- 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
@@ -19,6 +19,7 @@
 
 package org.apache.phoenix.pherf.workload.mt.tenantoperation;
 
+import org.apache.phoenix.end2end.NeedsOwnMiniClusterTest;
 import org.apache.phoenix.end2end.ParallelStatsDisabledIT;
 import org.apache.phoenix.pherf.PherfConstants;
 import org.apache.phoenix.pherf.XMLConfigParserTest;
@@ -27,6 +28,7 @@
 import org.apache.phoenix.pherf.schema.SchemaReader;
 import org.apache.phoenix.pherf.util.PhoenixUtil;
 import org.junit.BeforeClass;
+import org.junit.experimental.categories.Category;
 
 import java.net.URL;
 import java.nio.file.Path;
@@ -38,6 +40,7 @@
 import static org.junit.Assert.assertNotNull;
 import static org.junit.Assert.assertTrue;
 
+@Category(NeedsOwnMiniClusterTest.class)
 public class MultiTenantTableOperationBaseIT extends ParallelStatsDisabledIT {
 
     protected static final String matcherScenario = ".*scenario/.*test_tbl_workload.*xml";
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
index 873e061..fe535eb 100644
--- 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
@@ -207,10 +207,10 @@
                         assertTrue(opFactory.getOperationSupplier(info).getClass()
                                 .isAssignableFrom(QueryOperationSupplier.class));
 
-                        // expected row count > 0
+                        // 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);
+                        assertTrue(stats.getRowCount() >= 0);
                         break;
                     case idleOp:
                         assertTrue(opFactory.getOperationSupplier(info).getClass()
diff --git a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationEventGenerator.java b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationEventGenerator.java
index de8f95a..942633a 100644
--- a/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationEventGenerator.java
+++ b/phoenix-pherf/src/main/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationEventGenerator.java
@@ -46,6 +46,7 @@
         implements EventGenerator<TenantOperationInfo> {
 
     private static class WeightedRandomSampler {
+        private static String AUTO_WEIGHTED_OPERATION_ID = "xxxxxx";
         private final Random RANDOM = new Random();
         private final LoadProfile loadProfile;
         private final String modelName;
@@ -55,7 +56,8 @@
 
         private final Map<String, TenantGroup> tenantGroupMap = Maps.newHashMap();
         private final Map<String, Operation> operationMap = Maps.newHashMap();
-        private final Map<String, OperationGroup> operationGroupMap = Maps.newHashMap();
+        private final List<String> autoWeightedOperations = Lists.newArrayList();
+        private final int numAutoWeightedOperations;
 
         public WeightedRandomSampler(List<Operation> operationList, DataModel model, Scenario scenario) {
             this.modelName = model.getName();
@@ -72,44 +74,17 @@
                     "Tenant group cannot be empty");
 
             for (Operation op : operationList) {
-                for (OperationGroup og : loadProfile.getOpDistribution()) {
-                    if (op.getId().compareTo(og.getId()) == 0) {
+                for (OperationGroup loadOp : loadProfile.getOpDistribution()) {
+                    if (op.getId().compareTo(loadOp.getId()) == 0) {
                         operationMap.put(op.getId(), op);
-                        operationGroupMap.put(op.getId(), og);
                     }
                 }
             }
             Preconditions.checkArgument(!operationMap.isEmpty(),
                     "Operation list and load profile operation do not match");
+            this.distribution = initProbabilityDistribution(scenario.getLoadProfile());
+            this.numAutoWeightedOperations = autoWeightedOperations.size();
 
-            double totalTenantGroupWeight = 0.0f;
-            double totalOperationGroupWeight = 0.0f;
-            // Sum the weights to find the total weight,
-            // so that the weights can be used in the total probability distribution.
-            for (TenantGroup tg : loadProfile.getTenantDistribution()) {
-                totalTenantGroupWeight += tg.getWeight();
-            }
-            for (OperationGroup og : loadProfile.getOpDistribution()) {
-                totalOperationGroupWeight += og.getWeight();
-            }
-
-            Preconditions.checkArgument(totalTenantGroupWeight != 0.0f,
-                    "Total tenant group weight cannot be zero");
-            Preconditions.checkArgument(totalOperationGroupWeight != 0.0f,
-                    "Total operation group weight cannot be zero");
-
-            // Initialize the sample probability distribution
-            List<Pair<String, Double>> pmf = Lists.newArrayList();
-            double totalWeight = totalTenantGroupWeight * totalOperationGroupWeight;
-            for (TenantGroup tg : loadProfile.getTenantDistribution()) {
-                for (String opId : operationMap.keySet()) {
-                    String sampleName = String.format("%s:%s", tg.getId(), opId);
-                    int opWeight = operationGroupMap.get(opId).getWeight();
-                    double probability = (tg.getWeight() * opWeight)/totalWeight;
-                    pmf.add(new Pair(sampleName, probability));
-                }
-            }
-            this.distribution = new EnumeratedDistribution(pmf);
         }
 
         public TenantOperationInfo nextSample() {
@@ -119,6 +94,10 @@
             String opId = parts[1];
 
             Operation op = operationMap.get(opId);
+            if (op == null && opId.compareTo(AUTO_WEIGHTED_OPERATION_ID) == 0) {
+                opId = autoWeightedOperations.get(RANDOM.nextInt(numAutoWeightedOperations));
+                op = operationMap.get(opId);
+            }
             int numTenants = tenantGroupMap.get(tenantGroupId).getNumTenants();
             String tenantIdPrefix = Strings.padStart(tenantGroupId, loadProfile.getGroupIdLength(), 'x');
             String formattedTenantId = String.format(loadProfile.getTenantIdFormat(),
@@ -130,6 +109,59 @@
                     tenantGroupId, opId, tenantId, op);
             return sample;
         }
+
+        private EnumeratedDistribution initProbabilityDistribution(LoadProfile loadProfile) {
+            double totalTenantGroupWeight = 0.0f;
+            double totalOperationWeight = 0.0f;
+            double remainingOperationWeight = 0.0f;
+
+            // Sum the weights to find the total weight,
+            // so that the weights can be used in the total probability distribution.
+            for (TenantGroup tg : loadProfile.getTenantDistribution()) {
+                Preconditions.checkArgument(tg.getWeight() > 0.0f,
+                        "Tenant group weight cannot be less than zero");
+                totalTenantGroupWeight += tg.getWeight();
+            }
+            for (OperationGroup op : loadProfile.getOpDistribution()) {
+                if (op.getWeight() > 0.0f) {
+                    totalOperationWeight += op.getWeight();
+                } else {
+                    autoWeightedOperations.add(op.getId());
+                }
+            }
+
+            if (!autoWeightedOperations.isEmpty()) {
+                remainingOperationWeight = 100.0f - totalOperationWeight;
+                totalOperationWeight = 100.0f;
+            }
+
+            Preconditions.checkArgument(totalTenantGroupWeight == 100.0f,
+                    "Total tenant group weight cannot be <> 100.0");
+            Preconditions.checkArgument(totalOperationWeight == 100.0f,
+                    "Total operation group weight cannot be <> 100.0");
+
+            // Initialize the sample probability distribution
+            List<Pair<String, Double>> pmf = Lists.newArrayList();
+            double totalWeight = totalTenantGroupWeight * totalOperationWeight;
+            for (TenantGroup tg : loadProfile.getTenantDistribution()) {
+                for (OperationGroup op : loadProfile.getOpDistribution()) {
+                    int opWeight = op.getWeight();
+                    if (opWeight > 0.0f) {
+                        String sampleName = String.format("%s:%s", tg.getId(), op.getId());
+                        double probability = (tg.getWeight() * opWeight)/totalWeight;
+                        pmf.add(new Pair(sampleName, probability));
+                    }
+                }
+
+                if (!autoWeightedOperations.isEmpty()) {
+                    String sampleName = String.format("%s:%s", tg.getId(), AUTO_WEIGHTED_OPERATION_ID);
+                    double probability = (tg.getWeight() * remainingOperationWeight)/totalWeight;
+                    pmf.add(new Pair(sampleName, probability));
+                }
+            }
+            EnumeratedDistribution distribution = new EnumeratedDistribution(pmf);
+            return distribution;
+        }
     }
 
     private final WeightedRandomSampler sampler;
@@ -150,4 +182,5 @@
     @Override public TenantOperationInfo next() {
         return this.sampler.nextSample();
     }
+
 }
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 ee74fad..818bc6b 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
@@ -45,6 +45,7 @@
 import org.apache.phoenix.pherf.workload.mt.Operation;
 import org.apache.phoenix.pherf.workload.mt.OperationStats;
 import org.apache.phoenix.pherf.workload.mt.PreScenarioOperation;
+import org.apache.phoenix.pherf.workload.mt.UpsertOperation;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -169,7 +170,7 @@
     private List<Operation> getUpsertOperationsForScenario(Scenario scenario) {
         List<Operation> opList = Lists.newArrayList();
         for (final Upsert upsert : scenario.getUpserts()) {
-            Operation upsertOp = new org.apache.phoenix.pherf.workload.mt.UpsertOperation() {
+            final Operation upsertOp = new UpsertOperation() {
                 @Override public Upsert getUpsert() {
                     return upsert;
                 }
diff --git a/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationEventGeneratorTest.java b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationEventGeneratorTest.java
index 46eaa80..9d48034 100644
--- a/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationEventGeneratorTest.java
+++ b/phoenix-pherf/src/test/java/org/apache/phoenix/pherf/workload/mt/tenantoperation/TenantOperationEventGeneratorTest.java
@@ -46,6 +46,10 @@
         upsertOp, queryOp1, queryOp2, idleOp, udfOp
     }
 
+    private enum TestOperationGroup2 {
+        upsertOp, queryOp1, queryOp2, queryOp3, queryOp4, queryOp5, queryOp6, queryOp7, queryOp8, idleOp, udfOp
+    }
+
     private enum TestTenantGroup {
         tg1, tg2, tg3
     }
@@ -58,19 +62,14 @@
     }
 
     /**
-     * Case 1 : where some operations have zero weight
-     * Case 2 : where some tenant groups have zero weight
-     * Case 3 : where no operations and tenant groups have zero weight
-     * Case 4 : where some combinations of operation and tenant groups have zero weight
-     *
-     * @throws Exception
+     * Case : where no operations and tenant groups have zero weight
+     * * @throws Exception
      */
     @Test
     public void testVariousEventGeneration() throws Exception {
         int numRuns = 10;
         int numOperations = 100000;
-        int allowedVariance = 1500;
-        int normalizedOperations = (numOperations * numRuns) / 10000;
+        double normalizedOperations = (double) (numOperations * numRuns) / 10000.0f;
         int numTenantGroups = 3;
         int numOpGroups = 5;
 
@@ -84,22 +83,23 @@
             assertEquals("operation group size is not as expected: ",
                     numOpGroups, loadProfile.getOpDistribution().size());
             // Calculate the expected distribution.
-            int[][] expectedDistribution = new int[numOpGroups][numTenantGroups];
+            double[][] expectedDistribution = new double[numOpGroups][numTenantGroups];
             for (int r = 0; r < numOpGroups; r++) {
                 for (int c = 0; c < numTenantGroups; c++) {
                     int tenantWeight = loadProfile.getTenantDistribution().get(c).getWeight();
                     int opWeight = loadProfile.getOpDistribution().get(r).getWeight();
                     expectedDistribution[r][c] = normalizedOperations * (tenantWeight * opWeight);
-                    LOGGER.debug(String.format("Expected [%d,%d] = %d", r, c, expectedDistribution[r][c]));
+                    LOGGER.debug(String.format("Expected [%d,%d] = %f", r, c, expectedDistribution[r][c]));
                 }
             }
-            TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, scenario);
 
             // Calculate the actual distribution.
-            int[][] distribution = new int[numOpGroups][numTenantGroups];
+            TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, scenario);
+
+            double[][] distribution = new double[numOpGroups][numTenantGroups];
             for (int i = 0; i < numRuns; i++) {
                 int ops = numOperations;
-                loadProfile.setNumOperations(ops);
+                scenario.getLoadProfile().setNumOperations(ops);
                 TenantOperationEventGenerator evtGen = new TenantOperationEventGenerator(
                         opFactory.getOperations(), model, scenario);
                 while (ops-- > 0) {
@@ -109,19 +109,102 @@
                     distribution[row][col]++;
                 }
             }
+            validateResults(numOpGroups, numTenantGroups, expectedDistribution, distribution);
+        }
+    }
 
-            // Validate that the expected and actual distribution
-            // is within the margin of allowed variance.
+    /**
+     * Case  : where some operations have zero weight
+     */
+    @Test
+    public void testAutoAssignedPMFs() throws Exception {
+        int numRuns = 10;
+        int numOperations = 100000;
+        double normalizedOperations = (double) (numOperations * numRuns) / 10000.0f;
+        int numTenantGroups = 3;
+        int numOpGroups = 11;
+
+        PhoenixUtil pUtil = PhoenixUtil.create();
+        DataModel model = readTestDataModel("/scenario/test_evt_gen2.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());
+
+            float totalOperationWeight = 0.0f;
+            float autoAssignedOperationWeight = 0.0f;
+            float remainingOperationWeight = 0.0f;
+            int numAutoWeightedOperations = 0;
+            for (int r = 0; r < numOpGroups; r++) {
+                int opWeight = loadProfile.getOpDistribution().get(r).getWeight();
+                if (opWeight > 0.0f) {
+                    totalOperationWeight += opWeight;
+                } else {
+                    numAutoWeightedOperations++;
+                }
+            }
+            remainingOperationWeight = 100.0f - totalOperationWeight;
+            if (numAutoWeightedOperations > 0) {
+                autoAssignedOperationWeight = remainingOperationWeight/((float) numAutoWeightedOperations);
+            }
+            LOGGER.debug(String.format("Auto [%d,%f] = %f", numAutoWeightedOperations,
+                    remainingOperationWeight, autoAssignedOperationWeight ));
+
+            // Calculate the expected distribution.
+            double[][] expectedDistribution = new double[numOpGroups][numTenantGroups];
             for (int r = 0; r < numOpGroups; r++) {
                 for (int c = 0; c < numTenantGroups; c++) {
-                    LOGGER.debug(String.format("Actual[%d,%d] = %d", r, c, distribution[r][c]));
-                    int diff = Math.abs(expectedDistribution[r][c] - distribution[r][c]);
-                    boolean isAllowed = diff < allowedVariance;
-                    assertTrue(String.format("Difference is outside the allowed variance "
-                            + "[expected = %d, actual = %d]", allowedVariance, diff), isAllowed);
-
+                    float tenantWeight = loadProfile.getTenantDistribution().get(c).getWeight();
+                    float opWeight = loadProfile.getOpDistribution().get(r).getWeight();
+                    if (opWeight <= 0.0f) {
+                        opWeight = autoAssignedOperationWeight;
+                    }
+                    expectedDistribution[r][c] = Math.round(normalizedOperations * (tenantWeight * opWeight));
+                    LOGGER.debug(String.format("Expected [%d,%d] = %f", r, c, expectedDistribution[r][c]));
                 }
             }
+
+            // Calculate the actual distribution.
+            TenantOperationFactory opFactory = new TenantOperationFactory(pUtil, model, scenario);
+
+            double[][] distribution = new double[numOpGroups][numTenantGroups];
+            for (int i = 0; i < numRuns; i++) {
+                int ops = numOperations;
+                scenario.getLoadProfile().setNumOperations(ops);
+                TenantOperationEventGenerator evtGen = new TenantOperationEventGenerator(
+                        opFactory.getOperations(), model, scenario);
+                while (ops-- > 0) {
+                    TenantOperationInfo info = evtGen.next();
+                    int row = TestOperationGroup2.valueOf(info.getOperationGroupId()).ordinal();
+                    int col = TestTenantGroup.valueOf(info.getTenantGroupId()).ordinal();
+                    distribution[row][col]++;
+                }
+            }
+            validateResults(numOpGroups, numTenantGroups, expectedDistribution, distribution);
+        }
+    }
+
+    private void validateResults(int numOpGroups, int numTenantGroups,
+            double[][] expectedDistribution,
+            double[][] actualDistribution) throws Exception {
+
+        double variancePercent = 0.05f; // 5 percent
+
+        // Validate that the expected and actual distribution
+        // is within the margin of allowed variance.
+        for (int r = 0; r < numOpGroups; r++) {
+            for (int c = 0; c < numTenantGroups; c++) {
+                double allowedVariance = expectedDistribution[r][c] * variancePercent;
+                double diff = Math.abs(expectedDistribution[r][c] - actualDistribution[r][c]);
+                boolean isAllowed = diff < allowedVariance;
+                LOGGER.debug(String.format("Actual[%d,%d] = %f, %f, %f",
+                        r, c, actualDistribution[r][c], diff, allowedVariance));
+                assertTrue(String.format("Difference is outside the allowed variance "
+                        + "[expected = %f, actual = %f]", allowedVariance, diff), isAllowed);
+            }
         }
     }
 }
diff --git a/phoenix-pherf/src/test/resources/scenario/test_evt_gen1.xml b/phoenix-pherf/src/test/resources/scenario/test_evt_gen1.xml
index c1c6f8e..c2aace6 100644
--- a/phoenix-pherf/src/test/resources/scenario/test_evt_gen1.xml
+++ b/phoenix-pherf/src/test/resources/scenario/test_evt_gen1.xml
@@ -36,11 +36,11 @@
                 <tenantDistribution id="tg1" weight="10" numTenants="10"></tenantDistribution>
                 <tenantDistribution id="tg2" weight="10" numTenants="10"></tenantDistribution>
                 <tenantDistribution id="tg3" weight="80" numTenants="10"></tenantDistribution>
-                <opDistribution id="upsertOp" weight="50"></opDistribution>
-                <opDistribution id="queryOp1" weight="0"></opDistribution>
-                <opDistribution id="queryOp2" weight="0"></opDistribution>
-                <opDistribution id="idleOp" weight="50"></opDistribution>
-                <opDistribution id="udfOp" weight="0"></opDistribution>
+                <opDistribution id="upsertOp" weight="40"></opDistribution>
+                <opDistribution id="queryOp1" weight="20"></opDistribution>
+                <opDistribution id="queryOp2" weight="20"></opDistribution>
+                <opDistribution id="idleOp" weight="10"></opDistribution>
+                <opDistribution id="udfOp" weight="10"></opDistribution>
             </loadProfile>
             <upserts>
                 <upsert id="upsertOp">
@@ -66,119 +66,5 @@
                 </udf>
             </udfs>
         </scenario>
-        <scenario tableName="PHERF.EVT_GEN2" name="EVT_GEN2">
-            <loadProfile>
-                <batchSize>1</batchSize>
-                <numOperations>1000</numOperations>
-                <!-- Case 3 : where some tenant groups have zero weight -->
-                <tenantDistribution id="tg1" weight="0" numTenants="10"></tenantDistribution>
-                <tenantDistribution id="tg2" weight="0" numTenants="10"></tenantDistribution>
-                <tenantDistribution id="tg3" weight="100" numTenants="10"></tenantDistribution>
-                <opDistribution id="upsertOp" weight="20"></opDistribution>
-                <opDistribution id="queryOp1" weight="20"></opDistribution>
-                <opDistribution id="queryOp2" weight="20"></opDistribution>
-                <opDistribution id="idleOp" weight="20"></opDistribution>
-                <opDistribution id="udfOp" weight="20"></opDistribution>
-            </loadProfile>
-            <upserts>
-                <upsert id="upsertOp">
-                    <column>
-                        <type>CHAR</type>
-                        <name>COLUMN1</name>
-                    </column>
-                </upsert>
-            </upserts>
-
-            <querySet>
-                <query id="queryOp1" statement="select count(*) from PHERF.Z12"/>
-                <query id="queryOp2" statement="select sum(SOME_INT) from PHERF.Z12"/>
-            </querySet>
-            <idleTimes>
-                <idleTime id="idleOp" idleTime="50"></idleTime>
-            </idleTimes>
-            <udfs>
-                <udf id="udfOp" >
-                    <clazzName>org.apache.phoenix.pherf.ConfigurationParserTest.TestUDF</clazzName>
-                    <args>Hello</args>
-                    <args>World</args>
-                </udf>
-            </udfs>
-        </scenario>
-        <scenario tableName="PHERF.EVT_GEN3" name="EVT_GEN3">
-            <loadProfile>
-                <batchSize>1</batchSize>
-                <numOperations>1000</numOperations>
-                <!-- Case 2 : where no operations and tenant groups have zero weight -->
-                <tenantDistribution id="tg1" weight="30" numTenants="10"></tenantDistribution>
-                <tenantDistribution id="tg2" weight="30" numTenants="10"></tenantDistribution>
-                <tenantDistribution id="tg3" weight="40" numTenants="10"></tenantDistribution>
-                <opDistribution id="upsertOp" weight="20"></opDistribution>
-                <opDistribution id="queryOp1" weight="20"></opDistribution>
-                <opDistribution id="queryOp2" weight="20"></opDistribution>
-                <opDistribution id="idleOp" weight="20"></opDistribution>
-                <opDistribution id="udfOp" weight="20"></opDistribution>
-            </loadProfile>
-            <upserts>
-                <upsert id="upsertOp">
-                    <column>
-                        <type>CHAR</type>
-                        <name>COLUMN1</name>
-                    </column>
-                </upsert>
-            </upserts>
-
-            <querySet>
-                <query id="queryOp1" statement="select count(*) from PHERF.Z13"/>
-                <query id="queryOp2" statement="select sum(SOME_INT) from PHERF.Z13"/>
-            </querySet>
-            <idleTimes>
-                <idleTime id="idleOp" idleTime="50"></idleTime>
-            </idleTimes>
-            <udfs>
-                <udf id="udfOp" >
-                    <clazzName>org.apache.phoenix.pherf.ConfigurationParserTest.TestUDF</clazzName>
-                    <args>Hello</args>
-                    <args>World</args>
-                </udf>
-            </udfs>
-        </scenario>
-        <scenario tableName="PHERF.EVT_GEN4" name="EVT_GEN4">
-            <loadProfile>
-                <batchSize>1</batchSize>
-                <numOperations>1000</numOperations>
-                <!-- Case 4 : where some combinations of operation and tenant groups have zero weight -->
-                <tenantDistribution id="tg1" weight="25" numTenants="10"></tenantDistribution>
-                <tenantDistribution id="tg2" weight="0" numTenants="10"></tenantDistribution>
-                <tenantDistribution id="tg3" weight="75" numTenants="10"></tenantDistribution>
-                <opDistribution id="upsertOp" weight="40"></opDistribution>
-                <opDistribution id="queryOp1" weight="0"></opDistribution>
-                <opDistribution id="queryOp2" weight="40"></opDistribution>
-                <opDistribution id="idleOp" weight="20"></opDistribution>
-                <opDistribution id="udfOp" weight="0"></opDistribution>
-            </loadProfile>
-            <upserts>
-                <upsert id="upsertOp">
-                    <column>
-                        <type>CHAR</type>
-                        <name>COLUMN1</name>
-                    </column>
-                </upsert>
-            </upserts>
-
-            <querySet>
-                <query id="queryOp1" statement="select count(*) from PHERF.Z14"/>
-                <query id="queryOp2" statement="select sum(SOME_INT) from PHERF.Z14"/>
-            </querySet>
-            <idleTimes>
-                <idleTime id="idleOp" idleTime="50"></idleTime>
-            </idleTimes>
-            <udfs>
-                <udf id="udfOp" >
-                    <clazzName>org.apache.phoenix.pherf.ConfigurationParserTest.TestUDF</clazzName>
-                    <args>Hello</args>
-                    <args>World</args>
-                </udf>
-            </udfs>
-        </scenario>
     </scenarios>
 </datamodel>
diff --git a/phoenix-pherf/src/test/resources/scenario/test_evt_gen2.xml b/phoenix-pherf/src/test/resources/scenario/test_evt_gen2.xml
new file mode 100644
index 0000000..b153bbd
--- /dev/null
+++ b/phoenix-pherf/src/test/resources/scenario/test_evt_gen2.xml
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<!--
+  ~ 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.
+  -->
+
+<datamodel name="model_1">
+    <datamapping>
+        <column>
+            <!-- This column type defines what will generally happen to VARCHAR fields unless they are explicitly defined or overridden elsewhere -->
+            <type>VARCHAR</type>
+            <dataSequence>RANDOM</dataSequence>
+            <length>15</length>
+            <name>GENERAL_VARCHAR</name>
+        </column>
+    </datamapping>
+    <scenarios>
+        <scenario tableName="PHERF.EVT_GEN2" name="EVT_GEN2">
+            <loadProfile>
+                <batchSize>1</batchSize>
+                <numOperations>1000</numOperations>
+                <!-- Case 1 : where some operations have zero weight -->
+                <tenantDistribution id="tg1" weight="10" numTenants="10"></tenantDistribution>
+                <tenantDistribution id="tg2" weight="10" numTenants="10"></tenantDistribution>
+                <tenantDistribution id="tg3" weight="80" numTenants="10"></tenantDistribution>
+                <opDistribution id="upsertOp" weight="40"></opDistribution>
+                <opDistribution id="queryOp1" weight="10"></opDistribution>
+                <opDistribution id="queryOp2" weight="10"></opDistribution>
+                <opDistribution id="queryOp3" weight="0"></opDistribution>
+                <opDistribution id="queryOp4" weight="0"></opDistribution>
+                <opDistribution id="queryOp5" weight="0"></opDistribution>
+                <opDistribution id="queryOp6" weight="0"></opDistribution>
+                <opDistribution id="queryOp7" weight="0"></opDistribution>
+                <opDistribution id="queryOp8" weight="0"></opDistribution>
+                <opDistribution id="idleOp" weight="10"></opDistribution>
+                <opDistribution id="udfOp" weight="10"></opDistribution>
+            </loadProfile>
+            <upserts>
+                <upsert id="upsertOp">
+                    <column>
+                        <type>CHAR</type>
+                        <name>COLUMN1</name>
+                    </column>
+                </upsert>
+            </upserts>
+
+            <querySet>
+                <query id="queryOp1" statement="select count(*) from PHERF.Z11"/>
+                <query id="queryOp2" statement="select sum(SOME_INT) from PHERF.Z11"/>
+                <query id="queryOp3" statement="select sum(SOME_INT) +3 from PHERF.Z11"/>
+                <query id="queryOp4" statement="select sum(SOME_INT) +4 from PHERF.Z11"/>
+                <query id="queryOp5" statement="select sum(SOME_INT) +5 from PHERF.Z11"/>
+                <query id="queryOp6" statement="select sum(SOME_INT) +6 from PHERF.Z11"/>
+                <query id="queryOp7" statement="select sum(SOME_INT) +7 from PHERF.Z11"/>
+                <query id="queryOp8" statement="select sum(SOME_INT) +8 from PHERF.Z11"/>
+            </querySet>
+            <idleTimes>
+                <idleTime id="idleOp" idleTime="50"></idleTime>
+            </idleTimes>
+            <udfs>
+                <udf id="udfOp" >
+                    <clazzName>org.apache.phoenix.pherf.ConfigurationParserTest.TestUDF</clazzName>
+                    <args>Hello</args>
+                    <args>World</args>
+                </udf>
+            </udfs>
+        </scenario>
+    </scenarios>
+</datamodel>
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 00d613b..af19eb0 100644
--- a/phoenix-pherf/src/test/resources/scenario/test_mt_workload.xml
+++ b/phoenix-pherf/src/test/resources/scenario/test_mt_workload.xml
@@ -93,11 +93,11 @@
         <scenario tableName="PHERF.EVT_1" name="EVT_11">
             <loadProfile>
                 <batchSize>1</batchSize>
-                <numOperations>10</numOperations>
+                <numOperations>100</numOperations>
                 <!-- Case 1 : Upsert Operation test -->
-                <tenantDistribution id="tg1" weight="100" numTenants="1"></tenantDistribution>
-                <tenantDistribution id="tg2" weight="0" numTenants="0"></tenantDistribution>
-                <tenantDistribution id="tg3" weight="0" numTenants="0"></tenantDistribution>
+                <tenantDistribution id="tg1" weight="50" numTenants="1"></tenantDistribution>
+                <tenantDistribution id="tg2" weight="40" numTenants="9"></tenantDistribution>
+                <tenantDistribution id="tg3" weight="10" numTenants="10"></tenantDistribution>
                 <opDistribution id="upsertOp" weight="20"></opDistribution>
                 <opDistribution id="queryOp1" weight="20"></opDistribution>
                 <opDistribution id="queryOp2" weight="20"></opDistribution>
@@ -159,11 +159,11 @@
         <scenario tableName="PHERF.EVT_2" name="EVT_21">
             <loadProfile>
                 <batchSize>1</batchSize>
-                <numOperations>10</numOperations>
+                <numOperations>100</numOperations>
                 <!-- Case 1 : Upsert Operation test -->
-                <tenantDistribution id="tg1" weight="100" numTenants="1"></tenantDistribution>
-                <tenantDistribution id="tg2" weight="0" numTenants="0"></tenantDistribution>
-                <tenantDistribution id="tg3" weight="0" numTenants="0"></tenantDistribution>
+                <tenantDistribution id="tg1" weight="50" numTenants="1"></tenantDistribution>
+                <tenantDistribution id="tg2" weight="40" numTenants="9"></tenantDistribution>
+                <tenantDistribution id="tg3" weight="10" numTenants="10"></tenantDistribution>
                 <opDistribution id="upsertOp" weight="20"></opDistribution>
                 <opDistribution id="queryOp1" weight="20"></opDistribution>
                 <opDistribution id="queryOp2" weight="20"></opDistribution>
diff --git a/phoenix-pherf/src/test/resources/scenario/test_tbl_workload.xml b/phoenix-pherf/src/test/resources/scenario/test_tbl_workload.xml
index 286dcf8..f266131 100644
--- a/phoenix-pherf/src/test/resources/scenario/test_tbl_workload.xml
+++ b/phoenix-pherf/src/test/resources/scenario/test_tbl_workload.xml
@@ -156,8 +156,8 @@
             <loadProfile>
                 <numOperations>1</numOperations>
                 <tenantDistribution useGlobalConnection="true"/>
-                <opDistribution id="queryOp1" weight="20"/>
-                <opDistribution id="queryOp2" weight="20"/>
+                <opDistribution id="queryOp1" weight="50"/>
+                <opDistribution id="queryOp2" weight="50"/>
             </loadProfile>
 
             <querySet>