Author: aadamchik Date: Fri Jun 16 06:42:51 2006 New Revision: 414825 URL: http://svn.apache.org/viewvc?rev=414825&view=rev Log: adding a profiling case that randomly inserts/deletes/updates/slects objects, maintaining an almost constant number of objects in the table. Useful for load testing.
Added: incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/java/org/apache/cayenne/profile/cases/RandomOperationCase.java incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/jmeter/load-test.jmx Added: incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/java/org/apache/cayenne/profile/cases/RandomOperationCase.java URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/java/org/apache/cayenne/profile/cases/RandomOperationCase.java?rev=414825&view=auto ============================================================================== --- incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/java/org/apache/cayenne/profile/cases/RandomOperationCase.java (added) +++ incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/java/org/apache/cayenne/profile/cases/RandomOperationCase.java Fri Jun 16 06:42:51 2006 @@ -0,0 +1,137 @@ +/* + * Copyright 2006 The Apache Software Foundation + * + * Licensed 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.cayenne.profile.cases; + +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; + +import org.apache.cayenne.profile.AbstractCase; +import org.apache.cayenne.profile.entity.Entity1; +import org.objectstyle.cayenne.CayenneRuntimeException; +import org.objectstyle.cayenne.access.DataContext; +import org.objectstyle.cayenne.query.SQLTemplate; +import org.objectstyle.cayenne.query.SelectQuery; + +/** + * Does a random insert/delete/update based on the current object count. + * + * @author Andrus Adamchik + */ +public class RandomOperationCase extends AbstractCase { + + static final int MEDIAN_COUNT = 500; + static final int RANGE = 50; + + protected Random r = new Random(System.currentTimeMillis()); + protected int minObjects = MEDIAN_COUNT - (RANGE / 2); + protected int maxObjects = MEDIAN_COUNT + (RANGE / 2); + + protected void doRequest( + DataContext context, + HttpServletRequest request, + HttpServletResponse response) { + + if (r.nextBoolean()) { + doSelect(context); + return; + } + + // do update... + String table = context + .getEntityResolver() + .lookupDbEntity(Entity1.class) + .getName(); + SQLTemplate count = new SQLTemplate( + Entity1.class, + "SELECT #result('count(*)' 'int' 'C') FROM " + table); + count.setFetchingDataRows(true); + Map row = (Map) context.performQuery(count).get(0); + int c = ((Number) row.get("C")).intValue(); + + if (c < minObjects) { + doInsert(context); + } + else if (c > maxObjects) { + doDelete(context); + } + else { + switch (r.nextInt(3)) { + case 0: + doInsert(context); + break; + case 1: + doUpdate(context); + break; + case 2: + doDelete(context); + break; + } + } + + context.commitChanges(); + } + + protected void doInsert(DataContext context) { + Entity1 e = (Entity1) context.newObject(Entity1.class); + e.setName("X" + System.currentTimeMillis()); + } + + protected void doUpdate(DataContext context) { + Entity1 e = getRandomObject(context); + if (e != null) { + e.setName("Y" + System.currentTimeMillis()); + } + } + + protected void doDelete(DataContext context) { + Entity1 e = getRandomObject(context); + if (e != null) { + context.deleteObject(e); + } + } + + protected void doSelect(DataContext context) { + SelectQuery q = new SelectQuery(Entity1.class); + q.setFetchLimit(300); + context.performQuery(q); + } + + protected Entity1 getRandomObject(DataContext context) { + SelectQuery q = new SelectQuery(Entity1.class); + q.setPageSize(3); + + for (int i = 0; i < 20; i++) { + List allObjects = context.performQuery(q); + if (allObjects.size() > 0) { + int x = r.nextInt(allObjects.size()); + + try { + return (Entity1) allObjects.get(x); + } + catch (CayenneRuntimeException e) { + // this can happen due to concurrency isses - other threads may have + // deleted this page + } + } + } + + return null; + } +} Added: incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/jmeter/load-test.jmx URL: http://svn.apache.org/viewvc/incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/jmeter/load-test.jmx?rev=414825&view=auto ============================================================================== --- incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/jmeter/load-test.jmx (added) +++ incubator/cayenne/main/trunk/cayenne-regression-profiler/src/main/jmeter/load-test.jmx Fri Jun 16 06:42:51 2006 @@ -0,0 +1,312 @@ +<jmeterTestPlan version="1.1" properties="1.7"> + <hashTree> + <TestPlan> + <elementProp name="TestPlan.user_defined_variables" elementType="org.apache.jmeter.config.Arguments"> + <stringProp name="TestElement.gui_class">org.apache.jmeter.config.gui.ArgumentsPanel</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.config.Arguments</stringProp> + <collectionProp name="Arguments.arguments"/> + <stringProp name="TestElement.name">User Defined Variables</stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + </elementProp> + <stringProp name="TestElement.gui_class">org.apache.jmeter.control.gui.TestPlanGui</stringProp> + <stringProp name="TestPlan.user_define_classpath"></stringProp> + <boolProp name="TestPlan.serialize_threadgroups">true</boolProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.testelement.TestPlan</stringProp> + <stringProp name="TestElement.name">CayenneProfile</stringProp> + <boolProp name="TestPlan.functional_mode">false</boolProp> + <boolProp name="TestElement.enabled">true</boolProp> + <stringProp name="TestPlan.comments">Profiling cayenne performance under light load +</stringProp> + </TestPlan> + <hashTree> + <ConfigTestElement> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.config.gui.HttpDefaultsGui</stringProp> + <stringProp name="HTTPSampler.path"></stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.config.ConfigTestElement</stringProp> + <stringProp name="TestElement.name">HTTP Request Defaults</stringProp> + <stringProp name="HTTPSampler.domain">localhost</stringProp> + <stringProp name="HTTPSampler.protocol"></stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <elementProp name="HTTPsampler.Arguments" elementType="org.apache.jmeter.config.Arguments"> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.config.Arguments</stringProp> + <collectionProp name="Arguments.arguments"/> + <stringProp name="TestElement.name">User Defined Variables</stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + </elementProp> + <stringProp name="HTTPSampler.port">8080</stringProp> + </ConfigTestElement> + <hashTree/> + <CookieManager> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.CookiePanel</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.protocol.http.control.CookieManager</stringProp> + <stringProp name="TestElement.name">HTTP Cookie Manager</stringProp> + <boolProp name="CookieManager.clearEachIteration">false</boolProp> + <boolProp name="TestElement.enabled">true</boolProp> + <collectionProp name="CookieManager.cookies"/> + </CookieManager> + <hashTree/> + <ThreadGroup> + <longProp name="ThreadGroup.start_time">1148151181000</longProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.threads.ThreadGroup</stringProp> + <stringProp name="ThreadGroup.delay"></stringProp> + <stringProp name="ThreadGroup.duration"></stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <stringProp name="ThreadGroup.num_threads">1</stringProp> + <boolProp name="ThreadGroup.scheduler">false</boolProp> + <stringProp name="TestElement.gui_class">org.apache.jmeter.threads.gui.ThreadGroupGui</stringProp> + <elementProp name="ThreadGroup.main_controller" elementType="org.apache.jmeter.control.LoopController"> + <stringProp name="TestElement.gui_class">org.apache.jmeter.control.gui.LoopControlPanel</stringProp> + <stringProp name="LoopController.loops">1</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.control.LoopController</stringProp> + <stringProp name="TestElement.name">Loop Controller</stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <boolProp name="LoopController.continue_forever">false</boolProp> + </elementProp> + <stringProp name="TestElement.name">Setup</stringProp> + <longProp name="ThreadGroup.end_time">1148151181000</longProp> + <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> + <stringProp name="ThreadGroup.ramp_time">1</stringProp> + </ThreadGroup> + <hashTree> + <HTTPSampler> + <stringProp name="HTTPSampler.path">/cayenne-regression-profiler/profile/session/SetupCase</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</stringProp> + <stringProp name="HTTPSampler.method">GET</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <stringProp name="HTTPSampler.protocol"></stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.port"></stringProp> + <elementProp name="HTTPsampler.Arguments" elementType="org.apache.jmeter.config.Arguments"> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.config.Arguments</stringProp> + <collectionProp name="Arguments.arguments"/> + <stringProp name="TestElement.name">User Defined Variables</stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + </elementProp> + <stringProp name="HTTPSampler.mimetype"></stringProp> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</stringProp> + <stringProp name="HTTPSampler.FILE_FIELD"></stringProp> + <stringProp name="TestElement.name">SetupRequest</stringProp> + <stringProp name="HTTPSampler.monitor">false</stringProp> + <stringProp name="HTTPSampler.domain"></stringProp> + <stringProp name="HTTPSampler.FILE_NAME"></stringProp> + <boolProp name="HTTPSampler.auto_redirects">true</boolProp> + </HTTPSampler> + <hashTree/> + </hashTree> + <ThreadGroup> + <longProp name="ThreadGroup.start_time">1148151181000</longProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.threads.ThreadGroup</stringProp> + <stringProp name="ThreadGroup.delay"></stringProp> + <stringProp name="ThreadGroup.duration"></stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <stringProp name="ThreadGroup.num_threads">1</stringProp> + <boolProp name="ThreadGroup.scheduler">false</boolProp> + <stringProp name="TestElement.gui_class">org.apache.jmeter.threads.gui.ThreadGroupGui</stringProp> + <elementProp name="ThreadGroup.main_controller" elementType="org.apache.jmeter.control.LoopController"> + <stringProp name="TestElement.gui_class">org.apache.jmeter.control.gui.LoopControlPanel</stringProp> + <stringProp name="LoopController.loops">1</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.control.LoopController</stringProp> + <stringProp name="TestElement.name">Loop Controller</stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <boolProp name="LoopController.continue_forever">false</boolProp> + </elementProp> + <stringProp name="TestElement.name">Insert</stringProp> + <longProp name="ThreadGroup.end_time">1148151181000</longProp> + <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> + <stringProp name="ThreadGroup.ramp_time">1</stringProp> + </ThreadGroup> + <hashTree> + <HTTPSampler> + <stringProp name="HTTPSampler.path">/cayenne-regression-profiler/profile/session/InsertCase</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</stringProp> + <stringProp name="HTTPSampler.method">GET</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <stringProp name="HTTPSampler.protocol"></stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.port"></stringProp> + <elementProp name="HTTPsampler.Arguments" elementType="org.apache.jmeter.config.Arguments"> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.config.Arguments</stringProp> + <collectionProp name="Arguments.arguments"/> + <stringProp name="TestElement.name">User Defined Variables</stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + </elementProp> + <stringProp name="HTTPSampler.mimetype"></stringProp> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</stringProp> + <stringProp name="HTTPSampler.FILE_FIELD"></stringProp> + <stringProp name="TestElement.name">InsertRequest</stringProp> + <stringProp name="HTTPSampler.monitor">false</stringProp> + <stringProp name="HTTPSampler.domain"></stringProp> + <stringProp name="HTTPSampler.FILE_NAME"></stringProp> + <boolProp name="HTTPSampler.auto_redirects">true</boolProp> + </HTTPSampler> + <hashTree/> + <ResultCollector> + <stringProp name="TestElement.gui_class">org.apache.jmeter.visualizers.GraphVisualizer</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</stringProp> + <stringProp name="TestElement.name">Graph</stringProp> + <objProp> + <value class="org.apache.jmeter.samplers.SampleSaveConfiguration"> + <time>true</time> + <latency>true</latency> + <timestamp>true</timestamp> + <success>true</success> + <label>true</label> + <code>true</code> + <message>true</message> + <threadName>true</threadName> + <dataType>true</dataType> + <encoding>false</encoding> + <assertions>true</assertions> + <subresults>true</subresults> + <responseData>false</responseData> + <samplerData>false</samplerData> + <xml>true</xml> + <fieldNames>false</fieldNames> + <responseHeaders>false</responseHeaders> + <requestHeaders>false</requestHeaders> + <responseDataOnError>false</responseDataOnError> + <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage> + <assertionsResultsToSave>0</assertionsResultsToSave> + <delimiter>,</delimiter> + <printMilliseconds>true</printMilliseconds> + </value> + <name>saveConfig</name> + </objProp> + <boolProp name="TestElement.enabled">true</boolProp> + <stringProp name="filename"></stringProp> + <boolProp name="ResultCollector.error_logging">false</boolProp> + </ResultCollector> + <hashTree/> + </hashTree> + <ThreadGroup> + <longProp name="ThreadGroup.start_time">1148151181000</longProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.threads.ThreadGroup</stringProp> + <stringProp name="ThreadGroup.delay"></stringProp> + <stringProp name="ThreadGroup.duration"></stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <stringProp name="ThreadGroup.num_threads">10</stringProp> + <boolProp name="ThreadGroup.scheduler">false</boolProp> + <stringProp name="TestElement.gui_class">org.apache.jmeter.threads.gui.ThreadGroupGui</stringProp> + <elementProp name="ThreadGroup.main_controller" elementType="org.apache.jmeter.control.LoopController"> + <stringProp name="TestElement.gui_class">org.apache.jmeter.control.gui.LoopControlPanel</stringProp> + <intProp name="LoopController.loops">-1</intProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.control.LoopController</stringProp> + <stringProp name="TestElement.name">Loop Controller</stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <boolProp name="LoopController.continue_forever">false</boolProp> + </elementProp> + <stringProp name="TestElement.name">MixedRequests</stringProp> + <longProp name="ThreadGroup.end_time">1148151181000</longProp> + <stringProp name="ThreadGroup.on_sample_error">continue</stringProp> + <stringProp name="ThreadGroup.ramp_time">1</stringProp> + </ThreadGroup> + <hashTree> + <HTTPSampler> + <stringProp name="HTTPSampler.path">/cayenne-regression-profiler/profile/nosession/RandomOperationCase</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.protocol.http.sampler.HTTPSampler</stringProp> + <stringProp name="HTTPSampler.method">GET</stringProp> + <boolProp name="HTTPSampler.use_keepalive">true</boolProp> + <stringProp name="HTTPSampler.protocol"></stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + <boolProp name="HTTPSampler.follow_redirects">true</boolProp> + <stringProp name="HTTPSampler.port"></stringProp> + <elementProp name="HTTPsampler.Arguments" elementType="org.apache.jmeter.config.Arguments"> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.gui.HTTPArgumentsPanel</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.config.Arguments</stringProp> + <collectionProp name="Arguments.arguments"/> + <stringProp name="TestElement.name">User Defined Variables</stringProp> + <boolProp name="TestElement.enabled">true</boolProp> + </elementProp> + <stringProp name="HTTPSampler.mimetype"></stringProp> + <stringProp name="TestElement.gui_class">org.apache.jmeter.protocol.http.control.gui.HttpTestSampleGui</stringProp> + <stringProp name="HTTPSampler.FILE_FIELD"></stringProp> + <stringProp name="TestElement.name">RandomOperationNoSession</stringProp> + <stringProp name="HTTPSampler.monitor">false</stringProp> + <stringProp name="HTTPSampler.domain"></stringProp> + <stringProp name="HTTPSampler.FILE_NAME"></stringProp> + <boolProp name="HTTPSampler.auto_redirects">true</boolProp> + </HTTPSampler> + <hashTree/> + </hashTree> + <ResultCollector> + <stringProp name="TestElement.gui_class">org.apache.jmeter.visualizers.TableVisualizer</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</stringProp> + <stringProp name="TestElement.name">Table Results</stringProp> + <objProp> + <value class="org.apache.jmeter.samplers.SampleSaveConfiguration"> + <time>true</time> + <latency>true</latency> + <timestamp>true</timestamp> + <success>true</success> + <label>true</label> + <code>true</code> + <message>true</message> + <threadName>true</threadName> + <dataType>true</dataType> + <encoding>false</encoding> + <assertions>true</assertions> + <subresults>true</subresults> + <responseData>false</responseData> + <samplerData>false</samplerData> + <xml>true</xml> + <fieldNames>false</fieldNames> + <responseHeaders>false</responseHeaders> + <requestHeaders>false</requestHeaders> + <responseDataOnError>false</responseDataOnError> + <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage> + <assertionsResultsToSave>0</assertionsResultsToSave> + <delimiter>,</delimiter> + <printMilliseconds>true</printMilliseconds> + </value> + <name>saveConfig</name> + </objProp> + <boolProp name="TestElement.enabled">true</boolProp> + <stringProp name="filename"></stringProp> + <boolProp name="ResultCollector.error_logging">false</boolProp> + </ResultCollector> + <hashTree/> + <ResultCollector> + <stringProp name="TestElement.gui_class">org.apache.jmeter.visualizers.StatVisualizer</stringProp> + <stringProp name="TestElement.test_class">org.apache.jmeter.reporters.ResultCollector</stringProp> + <stringProp name="TestElement.name">Aggregate Report</stringProp> + <objProp> + <value class="org.apache.jmeter.samplers.SampleSaveConfiguration"> + <time>true</time> + <latency>true</latency> + <timestamp>true</timestamp> + <success>true</success> + <label>true</label> + <code>true</code> + <message>true</message> + <threadName>true</threadName> + <dataType>true</dataType> + <encoding>false</encoding> + <assertions>true</assertions> + <subresults>true</subresults> + <responseData>false</responseData> + <samplerData>false</samplerData> + <xml>true</xml> + <fieldNames>false</fieldNames> + <responseHeaders>false</responseHeaders> + <requestHeaders>false</requestHeaders> + <responseDataOnError>false</responseDataOnError> + <saveAssertionResultsFailureMessage>false</saveAssertionResultsFailureMessage> + <assertionsResultsToSave>0</assertionsResultsToSave> + <delimiter>,</delimiter> + <printMilliseconds>true</printMilliseconds> + </value> + <name>saveConfig</name> + </objProp> + <boolProp name="TestElement.enabled">true</boolProp> + <stringProp name="filename"></stringProp> + <boolProp name="ResultCollector.error_logging">false</boolProp> + </ResultCollector> + <hashTree/> + </hashTree> + </hashTree> +</jmeterTestPlan>