<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Altentee &#187; Performance &#38; Test Automation Experts &#187; jmeter</title>
	<atom:link href="http://altentee.com/tag/jmeter/feed/" rel="self" type="application/rss+xml" />
	<link>http://altentee.com</link>
	<description>Performance and Test Automation Experts</description>
	<lastBuildDate>Sat, 12 Jun 2010 00:35:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Dynamic Data from JMeter JDBC Requests</title>
		<link>http://altentee.com/2010/dynamic-data-from-jmeter-jdbc-requests/</link>
		<comments>http://altentee.com/2010/dynamic-data-from-jmeter-jdbc-requests/#comments</comments>
		<pubDate>Tue, 05 Jan 2010 06:45:17 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[jmeter]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://altentee.com/?p=731</guid>
		<description><![CDATA[<p>A common requirement when load testing is to populate subsequent requests with dynamic data from previous requests. If you&#8217;re thinking about using a database to store static test data, such as usernames, paswords, credit card numbers etc then read on to find out how to extract this data at runtime and populate JMeter variables.</p>
<p>In this [...]]]></description>
			<content:encoded><![CDATA[<p>A common requirement when load testing is to populate subsequent requests with dynamic data from previous requests. If you&#8217;re thinking about using a database to store static test data, such as usernames, paswords, credit card numbers etc then read on to find out how to extract this data at runtime and populate JMeter variables.</p>
<p><span id="more-731"></span>In this example we&#8217;ll need to add a JDBC Connection Configuration to our test plan. This will define and control the way in which JMeter will access your database.</p>
<p><a href="http://altentee.com/wp-content/uploads/Screen-shot-2010-01-05-at-5.28.18-PM.png"><img class="alignleft size-full wp-image-732" title="Screen shot 2010-01-05 at 5.28.18 PM" src="http://altentee.com/wp-content/uploads/Screen-shot-2010-01-05-at-5.28.18-PM.png" alt="" width="647" height="423" /></a></p>
<p>Notice I&#8217;ve left the defaults for connection pool properties, although you may need to tweak this depending on how you&#8217;ll access the data. I&#8217;ve used a JDBC connection URL that accesses a local mysql server listening on port 3306. The database in use is called watirgrid</p>
<p>I&#8217;ve also defined the JDBC Driver class and specified the username / password to connect with.</p>
<p>Now we can make a JDBC request using the JDBC Request sampler. It will look something like this:<a href="http://altentee.com/wp-content/uploads/Screen-shot-2010-01-05-at-5.31.52-PM.png"><img class="alignleft size-full wp-image-733" title="Screen shot 2010-01-05 at 5.31.52 PM" src="http://altentee.com/wp-content/uploads/Screen-shot-2010-01-05-at-5.31.52-PM.png" alt="" width="646" height="442" /></a></p>
<p>The Variable Name matches the JDBC Connection Config Variable Name i.e. mysql</p>
<p>I&#8217;m using a select statement that will print out results in a JSON-like format. That query is as follows:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #993333; font-weight: bold;">SELECT</span>
CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;[&quot;</span><span style="color: #66cc66;">,</span>
GROUP_CONCAT<span style="color: #66cc66;">&#40;</span>
CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;{email:'&quot;</span><span style="color: #66cc66;">,</span>email<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;'&quot;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span>
CONCAT<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&quot;,login_count:'&quot;</span><span style="color: #66cc66;">,</span>login_count<span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;'}&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #66cc66;">,</span><span style="color: #ff0000;">&quot;]&quot;</span><span style="color: #66cc66;">&#41;</span>
<span style="color: #993333; font-weight: bold;">AS</span> json <span style="color: #993333; font-weight: bold;">FROM</span> users</pre></div></div>

<p>In doing this, it will return a result set that looks like this:</p>

<div class="wp_syntax"><div class="code"><pre class="sql" style="font-family:monospace;"><span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------------------------------------------------+</span>
<span style="color: #66cc66;">|</span> json                                            <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------------------------------------------------+</span>
<span style="color: #66cc66;">|</span> <span style="color: #66cc66;">&#91;</span><span style="color: #66cc66;">&#123;</span>email:<span style="color: #ff0000;">'tim.koops@gmail.com'</span><span style="color: #66cc66;">,</span>login_count:<span style="color: #ff0000;">'1'</span><span style="color: #66cc66;">&#125;</span><span style="color: #66cc66;">&#93;</span> <span style="color: #66cc66;">|</span>
<span style="color: #66cc66;">+</span><span style="color: #808080; font-style: italic;">-------------------------------------------------+</span>
<span style="color: #cc66cc;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span></pre></div></div>

<p>Now we need to add a Post Processor Regex Extractor to the JDBC request as follows:</p>
<p><a href="http://altentee.com/wp-content/uploads/Screen-shot-2010-01-05-at-5.34.39-PM.png"><img class="alignleft size-full wp-image-734" title="Screen shot 2010-01-05 at 5.34.39 PM" src="http://altentee.com/wp-content/uploads/Screen-shot-2010-01-05-at-5.34.39-PM.png" alt="" width="172" height="40" /></a></p>
<p>The reason we do this is so we can extract the results from the JSON string returned by the database query. For example, to extract and populate a variable called ${email} our PPRE would look like this:</p>
<p><a href="http://altentee.com/wp-content/uploads/Screen-shot-2010-01-05-at-5.36.45-PM.png"><img class="alignleft size-full wp-image-735" title="Screen shot 2010-01-05 at 5.36.45 PM" src="http://altentee.com/wp-content/uploads/Screen-shot-2010-01-05-at-5.36.45-PM.png" alt="" width="652" height="236" /></a></p>
<p>Now we&#8217;re cooking! Add a Debug Sampler to confirm everything works as you&#8217;d expect. You should see results like this in the response data</p>
<pre>email=tim.koops@gmail.com
email_g=1
email_g0=email:'tim.koops@gmail.com'
email_g1=tim.koops@gmail.com
mysql=org.apache.jmeter.protocol.jdbc.config.DataSourceElement$DataSourceComponentImpl@10d69502
</pre>
<p>Attached is a demo test plan: <a href="http://altentee.com/wp-content/uploads/jdbc_example.jmx_.zip">jdbc_example.jmx</a></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2010/dynamic-data-from-jmeter-jdbc-requests/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>A Framework for JMeter using GitHub and Ruby</title>
		<link>http://altentee.com/2009/a-framework-for-jmeter-using-github-and-ruby/</link>
		<comments>http://altentee.com/2009/a-framework-for-jmeter-using-github-and-ruby/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 04:44:05 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2009/a-framework-for-jmeter-using-github-and-ruby/</guid>
		<description><![CDATA[<p>Version control is not something you often associate with performance testing scripts. The reasons generally vary. A significant one is the lack of any version control support in commercial toolsets like LoadRunner. Another reason is the perceived short-term shelf life of test scripts. You tend to write them once and throw them away right?</p>
<p>If you [...]]]></description>
			<content:encoded><![CDATA[<p>Version control is not something you often associate with performance testing scripts. The reasons generally vary. A significant one is the lack of any version control support in commercial toolsets like LoadRunner. Another reason is the perceived short-term shelf life of test scripts. You tend to write them once and throw them away right?</p>
<p>If you work with more agile teams/developers you will probably start to require a lot of re-use out of your scripts, especially when the release cycle increases in terms of frequency. It starts to make sense to use version control and some form of scripting framework.</p>
<p>In this post I&#8217;m going to use JMeter as the tool of choice here and I&#8217;m going to re-introduce concepts which I normally force upon others whilst contracting. That is, use of Application Simulation Models (ASMs) to hep define the load and use of the Application Performance Index (Apdex) to help present results. I&#8217;m also going to use GitHub (or git) as my tool for maintaining version control and implementing a wiki as a dashboard replacement for other test management tools.<br />
<span id="more-246"></span></p>
<p>In short, I&#8217;m hosting version controlled scripts on GitHub. You can view my repository here:<br />
<a href="http://wiki.github.com/90kts/performance_test"><strong>http://wiki.github.com/90kts/performance_test</strong><br />
</a><br />
I&#8217;m using Google Documents to store my ASMs. You can see an example <a href="http://spreadsheets.google.com/ccc?key=0AuXn6ttUcRvbdERrd0lVWFNfLWJEc3RJdXVqenNTSVE&#038;hl=en"><strong>here</strong></a>.</p>
<p>I&#8217;m also using the Wiki functionality of GitHub plus some Ruby scripts as my test runners. In other words, a scripted version of a controller, driven by data from the ASMs.</p>
<p>GitHub can be quite useful. Not only can you version control all your scripts, you can also implement  concepts based around a &#8220;<a href="http://www.satisfice.com/presentations/dashboard.pdf"><strong>low-tech testing dashboard</strong></a>&#8221;  first explored by James Bach. The use of a wiki to support this was recently explored by Matthew at <a href="http://xndev.blogspot.com/2009/09/test-management-tools.html"><strong>Socialtext</strong></a>.  Coupled with that you also get an Issues database which is perfect for tracking those performance defects during test execution. Google Docs is also very useful in that it allows you to centrally store test artifacts like your ASMs which has plenty of <a href="http://roo.rubyforge.org/">neat APIs</a> for programatically accessing content. Start working more with GitHub and less with QualityCentre and watch your circle of geek friends change. <img src='http://altentee.com/wp-includes/images/smilies/icon_wink.gif' alt=';-)' class='wp-smiley' /> </p>
<p><strong>Dashboard</strong><br />
So my <a href="http://wiki.github.com/90kts/performance_test/dashboard"><strong>dashboard</strong></a> is really just a broad sweep of major system and application components that present some level of risk to application stability and performance. It&#8217;s represented in the GitHub wiki as follows:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2009/09/dashboard1.png' title='dashboard 2'><img src='http://90kts.com/blog/wp-content/uploads/2009/09/dashboard1.png' alt='dashboard 2' /></a></p>
<p>Main elements are the areas I wish to test, the estimated effort required to script/prepare those areas, an indication of risk to production stability (carried out separately in risk assessments with appropriate technical/business teams), day to day comments on test readiness and a link to the online ASM. I use the keywords &#8220;run&#8221; or &#8220;draft&#8221; to distinguish between ASM status&#8217;. This helps the test runner determine which tests to execute.</p>
<p><strong>Test Runner</strong><br />
The <a href="http://github.com/90kts/performance_test/blob/master/scripts/test_runner.rb"><strong>test runner</strong></a> is a Ruby script which when executed, queries the Dashboard for ASMs to execute (based on the keyword &#8220;run&#8221;) then fetches the appropriate ASM via Google Documents to parse out relevant volumetrics for the test. Finally, it launches thread groups within JMeter to execute the test according to the ASM. Results are stored in the corresponding logs directory.</p>
<p><strong>Apdex</strong><br />
If you&#8217;d like to find out more about the Application Performance Index please see <a href="http://apdex.org/"><strong>here</strong></a>. I&#8217;ve found Apdex to be a very useful format to communicate application performance consistently to non-tech-heads. There&#8217;s plenty of room to geek out at low level later, but for a 20,000&#8242; view on things, Apdex is often a good start. I&#8217;ve implemented Apdex support for this framework using a <a href="http://github.com/90kts/performance_test/blob/master/scripts/apdex.rb"><strong>Ruby script</strong></a> to parse the results. The <a href="http://googlecharts.rubyforge.org/"><strong>Google chart API for Ruby</strong></a> is used to present sparklines. You can do this during or after a test run has complete. It basically picks up results from the logs directory and parses them against response time targets specified in the ASM. The output of the Apdex script is a html page which looks like this:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2009/09/apdex.png' title='apdex ruby'><img src='http://90kts.com/blog/wp-content/uploads/2009/09/apdex.png' alt='apdex ruby' /></a></p>
<p><strong>Application Simulation Models</strong><br />
The <a href="http://spreadsheets.google.com/ccc?key=0AuXn6ttUcRvbdERrd0lVWFNfLWJEc3RJdXVqenNTSVE&#038;hl=en"><strong>ASM</strong></a> is really the brains behind the JMeter test plan. It looks like this:<br />
 <a href='http://90kts.com/blog/wp-content/uploads/2009/09/asm.png' title='ASM'><img src='http://90kts.com/blog/wp-content/uploads/2009/09/asm.thumbnail.png' alt='ASM' /></a><a href='http://90kts.com/blog/wp-content/uploads/2009/09/asm2.png' title='asm2'><img src='http://90kts.com/blog/wp-content/uploads/2009/09/asm2.thumbnail.png' alt='asm2' /></a></p>
<p>It has two worksheets. The ASM worksheet is intended for business stakeholders. It&#8217;s geared more towards their understanding. I encourage these groups to articulate load in terms of transaction distribution (how many and what types of transactions groups) and user distribution (who are your user groups and what do they consist of). The key metrics I get these groups to enter are highlighted in yellow. Things like different user groups, percentage breakdowns of transactions and transaction/concurrent user quantities. Have a play, it&#8217;s pretty easy to follow. Coincidentally in every contract I&#8217;ve worked, I make this a mandatory test artifact for both my testers and the teams they&#8217;ve engaged with. No ASM = No Performance test&#8230;</p>
<p>The Scenario worksheet is really just the reverse of the first. It breaks down all the metrics that the business have provided into a worksheet to help you plug figures into your test scenarios. It helps cut down user-errors when calculating transaction rates etc and makes it much easier to chop and change figures. Want to do a test run with less concurrent users or higher transaction throughput? Just muck around with the percentages in yellow. I&#8217;ve used this format for both LoadRunner and JMeter gigs, so the terminology is meant to be familiar to both those types of users.</p>
<p><strong>JMeter Test Plan</strong><br />
Through the beauty of JMeter -J command line parameters I&#8217;m able to pass all the relevant metrics from the ASM such as number of threads (vusers), duration, throughput, rampup and action(transaction) distribution percentages. I use this <a href="http://github.com/90kts/performance_test/blob/master/plans/template_load_test.jmx"><strong>template format</strong></a> quite often and have explained some of these concepts previously.<br />
<a href='http://90kts.com/blog/wp-content/uploads/2009/09/jmeter_template.png' title='jmeter template'><img src='http://90kts.com/blog/wp-content/uploads/2009/09/jmeter_template.png' alt='jmeter template' /></a></p>
<p>The test plan gets the required parameters from the command line at run time. You can see the User Defined Variables look something like this:<br />
<code>DURATION = ${__P(duration,60) </code></p>
<p>Which basically sets the ${DURATION} JMeter variable based on the -Jduration command line variable, or defaults to 60 seconds if it is not passed. Other variables are also defined here and get loaded into the main Thread Group.</p>
<p>I use a Runtime Controller to control how long the test plan executes for. I also keep a separate Transaction Controller called Init to execute login actions etc or things I only want to execute once in the test plan.</p>
<p>Nested inside the Runtime Controller I use Throughput Controllers with percent executions tied to action percentages defined in the ASM. For example, action 1 might be a &#8220;view product&#8221; sequence of requests which I execute 50% of the time and so forth. Similar to weighted percentages for transaction blocks in LoadRunner. It is best to calculate these percentages using the Per User mode in JMeter for more accurate results.</p>
<p>Nested inside Throughput Controllers will be further Transaction Controllers, with Generate Parent Sample checked to enable similar functionality to transaction timers in LoadRunner around groups of requests.</p>
<p>The whole Thread Group has its throughput limited with a Constant Throughput Timer which basically tries to make all active threads in the thread group stay at a constant rate (defined by samples per minute). This eliminates the need to figure out pacing or sleep times as you might in LoadRunner.</p>
<p>The Summary Report and Gaussian Random Timers are just used for debugging so don&#8217;t normally include those in the final script&#8230;</p>
<p><strong>Git</strong><br />
Want to get started? Well first you will need a copy of a git client. Have a look at various how-to guides out there to get you started. I&#8217;ve found this <a href="http://www-cs-students.stanford.edu/~blynn/gitmagic/index.html"><strong>site</strong></a> pretty useful for understanding and working with git basics. My public clone URL for all the code used in this post is available here:<br />
git://github.com/90kts/performance_test.git</p>
<p>Enjoy!</p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2009/a-framework-for-jmeter-using-github-and-ruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Testing SAP Web Portals with JMeter</title>
		<link>http://altentee.com/2009/testing-sap-web-portals-with-jmeter/</link>
		<comments>http://altentee.com/2009/testing-sap-web-portals-with-jmeter/#comments</comments>
		<pubDate>Tue, 11 Aug 2009 21:13:01 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>
		<category><![CDATA[SAP]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2009/testing-sap-web-portals-with-jmeter/</guid>
		<description><![CDATA[<p>A colleague recently asked me if it was possible to test SAP portals using JMeter. The short answer is yes.</p>
<p>Some people get confused with the additional protocols that LoadRunner sports for SAP, particularly the SAP GUI. But if your SAP portal uses plain old HTTP (or HTTPS) then JMeter can do the job.</p>
<p>There are a [...]]]></description>
			<content:encoded><![CDATA[<p>A colleague recently asked me if it was possible to test SAP portals using JMeter. The short answer is yes.</p>
<p>Some people get confused with the additional protocols that LoadRunner sports for SAP, particularly the SAP GUI. But if your SAP portal uses plain old HTTP (or HTTPS) then JMeter can do the job.</p>
<p>There are a few gotchas which I will continue to update on this post, namely around correlation. In JMeter, correlation is particularly *easier* because you don&#8217;t have to worry about where to position a correlation rule. The equivalent function to use is a <strong>Post Processor -> Regular Expression Extractor</strong>.<br />
<span id="more-243"></span><br />
I used the following rules to help correlate the SAP portal:</p>
<p>Response Field to check: <strong>Body</strong><br />
Reference Name: <strong>sap-ext-sid</strong><br />
Regular Expression: <strong>sap-ext-sid=&#8221;(.+?)&#8221;</strong><br />
Template: <strong>$1$</strong><br />
Match No.: <strong>1</strong></p>
<p>Response Field to check: <strong>Body</strong><br />
Reference Name: <strong>sap-wd-tstamp</strong><br />
Regular Expression: <strong>name=&#8221;sap-wd-tstamp&#8221; value=&#8221;(.+?)&#8221;</strong><br />
Template: <strong>$1$</strong><br />
Match No.: <strong>1</strong></p>
<p>Response Field to check: <strong>Body</strong><br />
Reference Name: <strong>sap-ep-iviewhandle</strong><br />
Regular Expression: <strong>name=&#8221;sap-ep-iviewhandle&#8221; value=&#8221;(.+?)&#8221;</strong><br />
Template: <strong>$1$</strong><br />
Match No.: <strong>1</strong></p>
<p>Just scope those globally in your thread group and they will find and populate the necessary variables with <strong>${variable_name}</strong><br />
All you need to do to your final script is find and replace all instances of those variables with the JMeter variable in your favourite text editor. On windows I find SciTE is free (normally installed with Ruby) and powerful. e.g.</p>
<p>Replace:<br />
7QQ8jk_TEknhboPm9fmgqw&#8211;Mce5By08HC1RDy9m4LImcA&#8211;<br />
With:<br />
${sap-ext-sid}</p>
<p>In our particular portal a cookie value is used in the context of a query parameter (or form value). So to read a cookie value from the <strong>HTTP Cookie Manager </strong>element at run time (make sure you include it in your Thread Group) you just use another regular expression extractor:</p>
<p>Response Field to check: <strong>Header</strong><br />
Reference Name: <strong>MYSAPS02</strong><br />
Regular Expression: <strong>MYSAPSSO2=(.+?);</strong><br />
Template: <strong>$1$</strong><br />
Match No.: <strong>1</strong></p>
<p>Note in this case I am checking the header rather than the body for this value. Then use the variable as before.</p>
<p>Another tip when recording SAP portals, you might want to use the <a href="http://www.badboy.com.au/">BadBoy </a>recorder which can export to JMeter test plans. I had more success using this over the traditional recording proxy in JMeter.</p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2009/testing-sap-web-portals-with-jmeter/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JMeter Non HTTP response message: Unconnected sockets not implemented</title>
		<link>http://altentee.com/2009/jmeter-non-http-response-message-unconnected-sockets-not-implemented/</link>
		<comments>http://altentee.com/2009/jmeter-non-http-response-message-unconnected-sockets-not-implemented/#comments</comments>
		<pubDate>Tue, 28 Apr 2009 02:26:46 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2009/jmeter-non-http-response-message-unconnected-sockets-not-implemented/</guid>
		<description><![CDATA[<p>If you&#8217;re testing HTTPS with JMeter 2.3.2 and a current version of Java greater than 1.5 e.g.</p>
<p>java -version
java version "1.6.0_11"
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)</p>
<p>Then you are likely to encounter this error when using the standard HTTP Request sampler:</p>
<p>Response code: Non HTTP response code: java.net.SocketException
Response message: Non [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re testing HTTPS with JMeter 2.3.2 and a current version of Java greater than 1.5 e.g.</p>
<p><code>java -version<br />
java version "1.6.0_11"<br />
Java(TM) SE Runtime Environment (build 1.6.0_11-b03)<br />
Java HotSpot(TM) Client VM (build 11.0-b16, mixed mode, sharing)</code></p>
<p>Then you are likely to encounter this <a href="http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6771432">error</a> when using the standard <strong>HTTP Request</strong> sampler:</p>
<p><code>Response code: Non HTTP response code: java.net.SocketException<br />
Response message: Non HTTP response message: Unconnected sockets not implemented</code></p>
<p>If you have the opportunity, use the <strong>HTTP Request HTTPClient</strong> sampler instead and this problem should be resolved. Otherwise use Java 1.5 instead. If you&#8217;ve already recorded your test plan in JMeter or other tools (like <a href="http://www.badboy.com.au/">BadBoy</a>) then some simple regular expressions on the jmx file will fix the problem manually.</p>
<p>Windows:<br />
<code><br />
ruby -pi.bak -e "gsub(/<httpsampler guiclass="\""HttpTestSampleGui"\"" testclass="\""HTTPSampler"\""/, '<httpsampler2 guiclass="\""HttpTestSampleGui2"\"" testclass="\""HTTPSampler2"\""')" *.jmx</p>
<p>ruby -pi.bak -e "gsub(/HTTPSampler>/, 'HTTPSampler2>')" *.jmx<br />
</code></p>
<p>Mac:<br />
<code><br />
ruby -pi.bak -e "gsub(/<httpsampler guiclass=\"HttpTestSampleGui\" testclass=\"HTTPSampler\"/, '<httpsampler2 guiclass=\"HttpTestSampleGui2\" testclass=\"HTTPSampler2\"')" *.jmx</p>
<p>ruby -pi.bak -e "gsub(/HTTPSampler>/, 'HTTPSampler2>')" *.jmx</code><br />
</code></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2009/jmeter-non-http-response-message-unconnected-sockets-not-implemented/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Performance Testing MQ with JMeter</title>
		<link>http://altentee.com/2008/performance-testing-mq-with-jmeter/</link>
		<comments>http://altentee.com/2008/performance-testing-mq-with-jmeter/#comments</comments>
		<pubDate>Fri, 03 Oct 2008 05:45:58 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>
		<category><![CDATA[MQ]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/performance-testing-mq-with-jmeter/</guid>
		<description><![CDATA[<p>This is a relatively new example of how to use JMeter with WebSphere MQ. This approach is a clever way of inserting messages into MQ using a JMS sampler (point to point) with a JNDI binding within MQ.</p>
<p>I had not heard of this approach before and am sure it will be useful in future, provided [...]]]></description>
			<content:encoded><![CDATA[<p>This is a relatively new example of how to use <a href="http://www.ibm.com/developerworks/websphere/library/techarticles/0808_vandekuil/0808_vandekuil.html"><strong>JMeter with WebSphere MQ</strong></a>. This approach is a clever way of inserting messages into MQ using a JMS sampler (point to point) with a JNDI binding within MQ.</p>
<p>I had not heard of this approach before and am sure it will be useful in future, provided you have sufficient access to create the bindings in the first place.</p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/performance-testing-mq-with-jmeter/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Why do I get an &#8220;Error 501/505 &#8211; Not implemented or not supported&#8221; in JMeter?</title>
		<link>http://altentee.com/2008/why-do-i-get-an-error-501505-not-implemented-or-not-supported-in-jmeter/</link>
		<comments>http://altentee.com/2008/why-do-i-get-an-error-501505-not-implemented-or-not-supported-in-jmeter/#comments</comments>
		<pubDate>Thu, 07 Aug 2008 21:51:49 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/why-do-i-get-an-error-501505-not-implemented-or-not-supported-in-jmeter/</guid>
		<description><![CDATA[<p>This is most likely because the JMeter recording proxy does not support the https protocol. If it&#8217;s a screen you can live without, you can just stop/start the proxy recorder around that page (I use the Firefox plugin called FoxyProxy to quickly switch between different proxy configurations).</p>
<p>However, if it is vital to your script (for [...]]]></description>
			<content:encoded><![CDATA[<p>This is most likely because the JMeter recording proxy does not support the https protocol. If it&#8217;s a screen you can live without, you can just stop/start the proxy recorder around that page (I use the Firefox plugin called <a href="http://foxyproxy.mozdev.org/downloads.html"><strong>FoxyProxy</strong></a> to quickly switch between different proxy configurations).</p>
<p>However, if it is vital to your script (for example, a login page) then you can use an alternative recording tool called <a href="http://www.badboy.com.au/"><strong>Badboy Software</strong></a>. I frequently use this to record HTTPS then export the test plan to JMeter. Alternatively you can manually create the HTTPS request sample yourself.</p>
<p>JMeter can run HTTPS request samplers, it just can&#8217;t record them using the native proxy recorder.</p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/why-do-i-get-an-error-501505-not-implemented-or-not-supported-in-jmeter/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JMeter Tips and Tricks &#8211; Correlating with Regular Expressions</title>
		<link>http://altentee.com/2008/jmeter-tips-and-tricks-correlating-with-regular-expressions/</link>
		<comments>http://altentee.com/2008/jmeter-tips-and-tricks-correlating-with-regular-expressions/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 00:02:05 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/jmeter-tips-and-tricks-correlating-with-regular-expressions/</guid>
		<description><![CDATA[<p>Another post in this current theme of JMeter tips and tricks&#8230; You will hear LoadRunner consultants preaching to the converted about the requirement to correlate data accurately. What they&#8217;re referring to, is making sure that dynamic data received by the client from the server (typically in a response body, header or url), which changes from [...]]]></description>
			<content:encoded><![CDATA[<p>Another post in this current theme of JMeter tips and tricks&#8230; You will hear LoadRunner consultants preaching to the converted about the requirement to correlate data accurately. What they&#8217;re referring to, is making sure that dynamic data received by the client from the server (typically in a response body, header or url), which changes from request to request, is accurately correlated. If you don&#8217;t, you will probably &#8216;break&#8217; the application logic with most obvious signs during replay being things like HTTP Server 500 errors.</p>
<p>In practice, correlation requirements relate to things like session ids, viewstate, cookies, date time stamps and other transactional information. So more often than not you will see this data changing following a post back or response from the server. With the introduction of AJAX calls, correlation requirements probably increase (per page) as the number of transactional requests probably increases as well.</p>
<p>In LoadRunner, you typically correlate data manually using the web_reg_save_param function. This in effect is a prepared statement, placed before the request that will return the data in the response you are looking for. For example, your function will specify a left and right boundary of the data that it is looking for before you make the request. Then the request is made and if a match is found, then the data is saved in a parameter which you can later call as a variable in subsequent requests. LoadRunner also has a feature called Correlation Studio which takes affect during recording of your script, using a similar approach (left and right boundaries) and then dynamically swapping corresponding matches with the variabilzed data. All this is quite painful though, and whenever I&#8217;m specifying primitive left and right boundaries or using the flaky Correlation Studio (I can explain if you like), I&#8217;m left wishing I could just use regular expressions &#8230;</p>
<p>The trick to correlating data easily with JMeter is to first know what data it is that needs correlating! (duh&#8230;) Experience will make this easier as a lot of common web apps have common dynamic data requirements as already mentioned. Another trick is to <strong>always</strong> record the script twice (and diff to see differences between unique user sessions), then <strong>more often than not</strong> record 2+ iterations of an action within a single script (and diff to see differences between user transactions/actions). If you do this before anything else, and diff the results, you will save bucketloads of heartache in getting your script harnesses running, no matter which tool you choose.</p>
<p>But back to JMeter, once you do know what data you need to correlate, simply create a Post Processor -> Regular Expression Extractor to &#8216;variablize&#8217; that data. Huh? Read on for a more detailed explanation of this.<br />
<span id="more-189"></span></p>
<p>In my following example, I have 4 dummy pages that return unique jsessionid&#8217;s for each page as follows:</p>
<li>jsessionid=111_CATSNDOGS!50775&#038;</li>
<li>jsessionid=222_BATSNCATS!021278&#038;</li>
<li>jsessionid=333_SHEEPNGOATS!140679&#038;</li>
<li>jsessionid=444_FISHNCHIPS!120880&#038;</li>
<p>I&#8217;ve done this to simulate the changing session information typically found in any jsp based web app. To look for a jsessionid I simply add a new <strong>Post Processor</strong> called the <strong>Regular Expression Extractor</strong>. The following screenshot shows an example:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/regex_extractor.png' title='regex extractor'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/regex_extractor.png' alt='regex extractor' /></a></p>
<p>In the example provided, the reference name is what I can later call upon as a variable within the script, for example, ${jsessionid_trans}. The regular expression is the pattern I am looking for. Note in using a parenthesis I&#8217;m specifying a subexpression which I can get to with the match result number of n(1). If you&#8217;re new to regex, my example is equivalent to saying look for a left boundary of jsessionid= then match any character until you hit an ampersand. Even if you know nothing about regex, this will probably get you out of hot water 90% of the time. The real power in regex though is the ability to manipulate and narrow in on search results, or search for varying patterns (like telephone numbers, alphanumeric sequences and so on). I still find the Perl regular expression tutorials the best:<br />
<a href="http://perldoc.perl.org/perlretut.html">http://perldoc.perl.org/perlretut.html</a></p>
<p>So that&#8217;s it, you&#8217;ve found the jsessionid and to use it later on in your script, you simply call on it as a variable i.e. ~koops/test_jmeter/page2.html?value=${jsessionid}<br />
I often find it is easier to open up your test plan (.jmx) in your favourite text editor and then use the same regular expression to search and replace all instances of that pattern with your newly set variable.</p>
<p>However there is a twist to all this, which I refer to as scope. You really need to understand the scope of your regular expression extractors and how they are applied. By scope I&#8217;m loosely referring to variable scope in a normal programming language (which JMeter is not). I think the best way to understand the scope of your extractors, is to identify which &#8216;container&#8217; they are placed in. For a JMeter test plan, there are multiple containers you might place these extractors in:</p>
<li>The overall Test Plan, which I call &#8216;global&#8217; in scope</li>
<li>An individual Thread Group, which I call &#8216;thread&#8217; in scope</li>
<li>An individual Transaction Controller, which I call &#8216;local&#8217; in scope</li>
<li>An individual Request Sampler, which I call &#8216;trans&#8217; in scope</li>
<p>If you&#8217;re familiar with programming languages and scoping, then you&#8217;ll probably identify the pecking order of the scope I&#8217;ve just mentioned, from global right down to transaction level (I&#8217;ve made up a few names there). Global variables will override local variables and so on down the chain. So you need to be careful where you place your regular expression extractors and what reference (variable) names you use, as these can interfere with each other. Sometimes it is useful to limit your extractor in scope to a particular transaction, thread group or test plan.</p>
<p>In my example listed above, I&#8217;ve written a test plan to explore the different scopes identified. Using the debug sampler, you can see that the <em>trans</em> scope is limited to single request sampler, because it is added as a child element. This means the variable <em>jsessionid_trans</em> gets set only once. The <em>local</em> scope is limited to a transaction controller. I placed it before the second request sampler but not as a child to the first, to highlight how it sets the variable <em>jsessionid_local</em> twice (once for each request contained in that transaction controller). The <em>thread</em> scope is limited to the entire thread group, so you will see the <em>jsessionid_thread</em> variable set three times as each page is requested. The same applies to the <em>global</em> scope in which case the <em>jsessionid_global</em> variable is set on each occurrence of the pattern. I&#8217;ve also added a second thread group with its own debug sampler to highlight how only global variables are accessible by this thread group. You can run <a href='http://90kts.com/blog/wp-content/uploads/2008/07/regex_testjmx.zip' title='regex_test.jmx'>this test plan <strong>(regex_test.jmx)</strong></a> yourself and check out the results as shown below:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/regex_scope.png' title='regex_scope'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/regex_scope.png' alt='regex_scope' /></a></p>
<p>Finally, here are some example regular expressions which have worked well for me for different types of web apps:<br />
<code>jsessionid=(.+?)&#038;<br />
jsessionid=(.+?)'<br />
id="__VIEWSTATE" value="(.+?)"<br />
jsd=(\d+)<br />
strEntry=(.+?)'<br />
CdzSession' value='(.+?)'<br />
WebiSession' value='(.+?)'<br />
DOCTOKEN VALUE='(.+?)'<br />
etc ...</code></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/jmeter-tips-and-tricks-correlating-with-regular-expressions/feed/</wfw:commentRss>
		<slash:comments>10</slash:comments>
		</item>
		<item>
		<title>JMeter Tips and Tricks &#8211; Better (More Pretty) Graphs</title>
		<link>http://altentee.com/2008/jmeter-tips-and-tricks-better-more-pretty-graphs/</link>
		<comments>http://altentee.com/2008/jmeter-tips-and-tricks-better-more-pretty-graphs/#comments</comments>
		<pubDate>Wed, 16 Jul 2008 08:58:07 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/jmeter-tips-and-tricks-better-more-pretty-graphs/</guid>
		<description><![CDATA[<p>This plugin has been around for a while and it&#8217;s definitely worth including in your JMeter library if you want to go for a glossy finish! The  StatAggVisualizer will transform your graphs
from this to this</p>
<p>If you roll-up your transactions into separate transaction controllers as I demonstrated in a previous post, you will get useful [...]]]></description>
			<content:encoded><![CDATA[<p>This <strong><a href="http://rubenlaguna.com/wp/better-jmeter-graphs/">plugin</a></strong> has been around for a while and it&#8217;s definitely worth including in your JMeter library if you want to go for a glossy finish! The  <strong><a href="http://rubenlaguna.com/wp/wp-content/uploads/2007/01/stataggvisualizer.zip">StatAggVisualizer</a></strong> will transform your graphs<br />
from this<a href='http://90kts.com/blog/wp-content/uploads/2008/07/old_graph.png' title='old_graph.png'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/old_graph.thumbnail.png' alt='old_graph.png' /></a> to this<a href='http://90kts.com/blog/wp-content/uploads/2008/07/new_graph.png' title='new_graph.png'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/new_graph.thumbnail.png' alt='new_graph.png' /></a></p>
<p>If you roll-up your transactions into separate transaction controllers as I demonstrated in a <a href="http://90kts.com/blog/2008/jmeter-tips-and-tricks-application-simulation-models/">previous post</a>, you will get useful summary views for all your transactions:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/transaction_summary.png' title='transaction_summary.png'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/transaction_summary.png' alt='transaction_summary.png' /></a></p>
<p>Alternatively, drop a stat agg visualizer listener under a single controller to get a graph for a single transaction, useful if clients are only interested in certain transactions.<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/stat_add_individual.png' title='stat_add_individual.png'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/stat_add_individual.png' alt='stat_add_individual.png' /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/jmeter-tips-and-tricks-better-more-pretty-graphs/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JMeter Tips and Tricks &#8211; Application Simulation Models</title>
		<link>http://altentee.com/2008/jmeter-tips-and-tricks-application-simulation-models/</link>
		<comments>http://altentee.com/2008/jmeter-tips-and-tricks-application-simulation-models/#comments</comments>
		<pubDate>Mon, 07 Jul 2008 09:50:53 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/jmeter-tips-and-tricks-application-simulation-models/</guid>
		<description><![CDATA[<p>I&#8217;ve been working with JMeter of late and after speaking with some people at conferences and the like, I thought it would be good to share what I&#8217;ve learned along the way in building, structuring and executing JMeter test plans.</p>
<p>One of the first things I like to do when performance testing is establish in reasonable [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been working with JMeter of late and after speaking with some people at conferences and the like, I thought it would be good to share what I&#8217;ve learned along the way in building, structuring and executing JMeter test plans.</p>
<p>One of the first things I like to do when performance testing is establish in reasonable detail what the Application Simulation Model (ASM) will entail. You can create an ASM visually using something like <a href="http://www.ibm.com/developerworks/rational/library/5219.html"><strong>UCML</strong></a>. This is a good starting point for performance testers looking to structure their test planning efforts.</p>
<blockquote><p>UCMLâ„¢ is a set of symbols that can be used to create visual system usage models and depict associated parameters. When applied to Performance Testing these symbols can serve to represent the workload distributions, operational profiles, pivot tables, matrixes, and Markov chains that performance testers often employ to determine what activities are to be included in a test and with what frequency they&#8217;ll occur.</p></blockquote>
<p>More often than not though, I create an ASM using a spreadsheet format as I find this easiest to communicate with people from the business teams. If people are interested I will share some of the spreadsheet templates. The following screenshot gives you an idea of what I&#8217;m talking about:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/asm.png' title='example asm'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/asm.png' alt='example asm' /></a></p>
<p>The pertinent points for an ASM, is that it should:</p>
<li> describe the user community distibution in terms the amount of concurrent users and their daily/hourly profiles in terms of concurrent load.</li>
<p>e.g. &#8220;we have 3 user groups with a total of 150 users, 80% of them are helpdesk support, 10% are team leads and 10% are management&#8221;</p>
<li> describe transaction quantities and percentage distibutions. </li>
<p>e.g. &#8220;we&#8217;re aiming for around 240 trans/hour, of which 50% are searches, 25% are updates and 25% are reports&#8221;</p>
<p>Read on to discover how to turn ASMs into working JMeter test plans.<br />
<span id="more-170"></span><br />
One of things I&#8217;m aiming for is to use relative random distributions of transactions within a loop controller which simulates the transaction distributions in real life. The following screenshot shows a Loop Controller, with three children Throughput Controllers (renamed to 20%, 50% and 30%). Each Throughput Controller then has a Transaction Controller, which is the parent container for all subsequent requests that make up that transaction (there are typically tens or hundreds of requests here depending on the complexity of the web application). Note I have also renamed the Transaction Controllers to something more representative of the transactions being simulated.<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/loop_controller.png' title='loop controller jmeter'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/loop_controller.png' alt='loop controller jmeter' /></a></p>
<p>The Loop Controller will effectively control the number of iterations and I often set this to run forever when threads are shut down manually during test runs. I also use a Constant Throughput Timer, which alleviates the need to set iteration counts and pacing between iterations which LoadRunner users would be familiar with. When using a Constant Throughput Timer, you can simply set the targeted transaction rate in terms of samples/minute (in this case it&#8217;s measured on collective Transaction Controller&#8217;s throughput). JMeter will then self-throttle the load to try and match that transaction rate. If you want more granular control, you can move CTT to be child elements of selected Transaction Controllers, thus applying different transaction rates for different transactions. The benefit in using Throughput Controllers with Percent Execution settings specified, is that transactions will be randomly distributed according to those percentages down to each subsequent Transaction Controller. The following screenshot demonstrates those settings used for the 20% Throughput Controller:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/throughput_controller.png' title='throughput controller'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/throughput_controller.png' alt='throughput controller' /></a></p>
<p>This means that if I specified 100 iterations in my Loop Controller, then 20 transactions will be distributed to the 20% Throughput Controller. This is done in a relatively random fashion, it does not process transactions in sequence which is good for random simulations.</p>
<p>Once you&#8217;ve established your transaction groups with percentage distribution, you can then create your user groups using the Thread Group element. In my example I&#8217;m using two user groups (Group A and B), each with differing user quantities. The purpose of these is just to pigeon hole my user groups and quantities as detailed in the corresponding ASM. Each user group is run in parallel, and is subject to the startup (ramp-up) and loop count settings for the threads (users) created. The following screenshot shows some typical settings:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/thread_group.png' title='jmeter thread group'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/thread_group.png' alt='jmeter thread group' /></a></p>
<p>A more complete test plan looks like the following screenshot:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/test_plan.png' title='jmeter simple test plan'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/test_plan.png' alt='jmeter simple test plan' /></a></p>
<p>You can see two user groups in there, along with Loop Controllers and Throughput Controllers. You can also see all the sample requests under each of the Transaction Controllers. In my example I&#8217;m using HTTP request samplers, but this could just as easily be a web service, ftp or some other form of JMeter sampler. I often start with this template in mind, then record and edit transactions in the Workbench before importing back into my Transaction Controllers.</p>
<p>Basically JMeter will run through the test plan from the top to the bottom. For this reason I often keep my configuration elements such as HTTP cookie managers, user parameters and reporting listeners towards the top of the test plan so they get initialized. Then, as it hits the Thread Groups it will launch those according to the settings specified. You can also see in the screenshot some results from the View Results Tree listener for Thread Group A. Essentially this demonstrates the randomized distribution of Transaction Controllers according to their parent Throughput Controllers.</p>
<p>In coming posts I&#8217;ll walk through some other features of JMeter that help you control thread execution and delve deeper into the reporting functionality that comes with JMeter.  You can download a copy of the jmeter test plan referred to in this post <a href='http://90kts.com/blog/wp-content/uploads/2008/07/simpletestplan.txt' title='simple test plan for jmeter'><strong>here</strong></a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/jmeter-tips-and-tricks-application-simulation-models/feed/</wfw:commentRss>
		<slash:comments>30</slash:comments>
		</item>
		<item>
		<title>Performance Testing Flex Remoting (AMF) with JMeter</title>
		<link>http://altentee.com/2008/performance-testing-flex-remoting-amf-with-jmeter/</link>
		<comments>http://altentee.com/2008/performance-testing-flex-remoting-amf-with-jmeter/#comments</comments>
		<pubDate>Wed, 07 May 2008 08:08:13 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/performance-testing-flex-remoting-amf-with-jmeter/</guid>
		<description><![CDATA[<p>[UPDATE] this has since been resolved! JMeter support rocks 
URL: http://svn.apache.org/viewvc?rev=661141&#038;view=rev
Log: Bugs 44808 &#038; 39641 &#8211; Proxy support for binary requests
&#8212;
You may still find the ruby proxy idea interesting &#8230;
&#8212;
The Action Message Format (AMF) is a binary protocol that Flex applications use to remotely communicate with the server. I&#8217;ve tested recording of this using LoadRunner [...]]]></description>
			<content:encoded><![CDATA[<p><strong>[UPDATE]</strong> this has since been resolved! JMeter support rocks <img src='http://altentee.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':D' class='wp-smiley' /><br />
URL: <a href="http://svn.apache.org/viewvc?rev=661141&#038;view=rev">http://svn.apache.org/viewvc?rev=661141&#038;view=rev</a><br />
Log: Bugs 44808 &#038; 39641 &#8211; Proxy support for binary requests<br />
&#8212;<br />
You may still find the ruby proxy idea interesting &#8230;<br />
&#8212;<br />
The Action Message Format (AMF) is a binary protocol that Flex applications use to remotely communicate with the server. I&#8217;ve tested recording of this using LoadRunner which picks up the binary format nicely as part of the HTTP POST.</p>
<p>It will look a little like this:<br />
<code><br />
	web_custom_request("amf_3",<br />
		"URL=http://host.under.test.com/messagebroker/amf",<br />
		"Method=POST",<br />
		"Resource=0",<br />
		"RecContentType=application/x-amf",<br />
		"Referer=http://ost.under.test.com/messagebroker/client/main.swf",<br />
		"Snapshot=t13.inf",<br />
		"Mode=HTML",<br />
		"EncType=application/x-amf",<br />
	"BodyBinary=\\x00\\x03\\x00\\x00\\x00\\x02\\x00\\x04null\\x00\\x02/3\\x00\\x00\\x01\\x0F\n\\x00\\x00\\x00\\x01\\x11\n\\x81\\x13Mflex.messaging.messages.CommandMessage\\x13operation\\x1BcorrelationId\tbody\\x13messageId\\x11clientId\\x15timeToLive\\x13timestamp\\x0Fheaders\\x17destination\\x04\\x08\\x06\\x01x06\r"<br />
		"my-amf\\x01\\x06#labelPrintService",<br />
		LAST);<br />
</code></p>
<p>I understand that <a href="http://www.adobe.com/devnet/flex/articles/amf_perftest.html">Segue Silk Performer</a> also has this capability to natively record binary protocols arbitrarily attached to the POST. Unfortunately the native JMeter proxy (when used for recording) doesn&#8217;t pick up this data reliably.</p>
<p>This defect is current being tracked at the <a href="https://issues.apache.org/bugzilla/show_bug.cgi?id=39641">ASF Bugzilla</a></p>
<p>After looking around for some proxying software that would assist, products such as <a href="http://www.charlesproxy.com/">Charles Proxy</a> looked tempting. But to be honest, if you&#8217;re reading this and using JMeter, you&#8217;re probably not interested in paying any license fees.</p>
<p>Read on for a free alternative when using JMeter.<br />
<span id="more-145"></span></p>
<p>The first thing I wanted to setup was a proxy that could catch the necessary HTTP header requests (and responses), and store a copy of any amf content types to the filesystem when recording a typical user transaction. I did this using Ruby and the webrick/httpproxy gem.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'webrick/httpproxy'</span>
&nbsp;
i= <span style="color:#006666;">1</span>
server = <span style="color:#6666ff; font-weight:bold;">WEBrick::HTTPProxyServer</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span>
  <span style="color:#ff3333; font-weight:bold;">:Port</span><span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#006666;">9090</span>,
  <span style="color:#ff3333; font-weight:bold;">:RequestCallback</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#CC0066; font-weight:bold;">Proc</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#123;</span>
  <span style="color:#006600; font-weight:bold;">|</span>req,res<span style="color:#006600; font-weight:bold;">|</span>
    <span style="color:#9966CC; font-weight:bold;">if</span> req.<span style="color:#9900CC;">raw_header</span>.<span style="color:#9900CC;">to_s</span>.<span style="color:#9900CC;">match</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">/</span>x<span style="color:#006600; font-weight:bold;">-</span>amf<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span> == <span style="color:#0000FF; font-weight:bold;">nil</span>
		  <span style="color:#CC0066; font-weight:bold;">puts</span> req.<span style="color:#9900CC;">request_line</span>,req.<span style="color:#9900CC;">raw_header</span>
		<span style="color:#9966CC; font-weight:bold;">else</span>
	    amf = req.<span style="color:#9900CC;">body</span>
	    file = <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">new</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;./#{i}.amf&quot;</span>,<span style="color:#996600;">&quot;w&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
	    file.<span style="color:#9900CC;">write</span><span style="color:#006600; font-weight:bold;">&#40;</span>amf<span style="color:#006600; font-weight:bold;">&#41;</span>
	    file.<span style="color:#9900CC;">close</span>
		  res<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#996600;">'Content-Type'</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#996600;">&quot;application/x-amf&quot;</span>
		  i = i<span style="color:#006600; font-weight:bold;">+</span><span style="color:#006666;">1</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#996600;">&quot;------------------&quot;</span>
  <span style="color:#006600; font-weight:bold;">&#125;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#CC0066; font-weight:bold;">trap</span> <span style="color:#996600;">&quot;INT&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span> server.<span style="color:#9900CC;">shutdown</span> <span style="color:#9966CC; font-weight:bold;">end</span>
server.<span style="color:#9900CC;">start</span></pre></td></tr></table></div>

<p>So if you run that proxy from a terminal, it will listen on port 9090 (or whatever you like) for any traffic. Then I just use Firefox (with the FoxyProxy add-on for fast proxy switching <img src='http://altentee.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  ) and conduct my normal transactions through the flex app via the browser.</p>
<p>What you will then see in the terminal, is a copy of all the headers for the requests/responses printed to screen. If it sees any headers with an x-amf content type, it will save a copy of the AMF data to a sequentially number file called #{n}.amf</p>
<p>Once you&#8217;ve run the transactions, you can create a thread group in JMeter and start adding all the  HTTP Request samplers that have POST actions with AMF data. You might still want to use the standard JMeter proxy to record all the normal HTTP stuff (minus the AMF) to save time. Then just amend your test plan to include the POST actions with AMF, such that they look something like this.<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/05/httprequestpostamf.png' title='http request post with amf'><img src='http://90kts.com/blog/wp-content/uploads/2008/05/httprequestpostamf.png' alt='http request post with amf' /></a></p>
<p>Of importance is the file that you are sending with the post. This should be the full path to the AMF file previously recorded. Also make sure the MIME type is <strong>applicaton/x-amf</strong>.</p>
<p>Make sure you add the AMF files you saved earlier with the proxy in the correct order to the test plan. That should be all you need to do to test from JMeter. In my case I also had to add standard config elements such as the HTTP Cookie Manager and a User Parameters (to correlate jsessionids).</p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/performance-testing-flex-remoting-amf-with-jmeter/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
	</channel>
</rss>
