<?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/"
	xmlns:georss="http://www.georss.org/georss" xmlns:geo="http://www.w3.org/2003/01/geo/wgs84_pos#" xmlns:media="http://search.yahoo.com/mrss/"
	>

<channel>
	<title>Performance Testing @ the Frontline</title>
	<atom:link href="http://ptfrontline.wordpress.com/feed/" rel="self" type="application/rss+xml" />
	<link>http://ptfrontline.wordpress.com</link>
	<description>A hidden world where small things make a big difference</description>
	<lastBuildDate>Wed, 18 Jan 2012 21:30:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.com/</generator>
<cloud domain='ptfrontline.wordpress.com' port='80' path='/?rsscloud=notify' registerProcedure='' protocol='http-post' />
<image>
		<url>http://1.gravatar.com/blavatar/5c32c918eb1f88f25ceabbe0efc4a700?s=96&#038;d=http%3A%2F%2Fs2.wp.com%2Fi%2Fbuttonw-com.png</url>
		<title>Performance Testing @ the Frontline</title>
		<link>http://ptfrontline.wordpress.com</link>
	</image>
	<atom:link rel="search" type="application/opensearchdescription+xml" href="http://ptfrontline.wordpress.com/osd.xml" title="Performance Testing @ the Frontline" />
	<atom:link rel='hub' href='http://ptfrontline.wordpress.com/?pushpress=hub'/>
		<item>
		<title>Syntax Highlighting for custom functions in LoadRunner VuGen</title>
		<link>http://ptfrontline.wordpress.com/2011/11/03/syntax-highlighting-for-custom-functions-in-loadrunner-vugen/</link>
		<comments>http://ptfrontline.wordpress.com/2011/11/03/syntax-highlighting-for-custom-functions-in-loadrunner-vugen/#comments</comments>
		<pubDate>Thu, 03 Nov 2011 12:43:16 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[LoadRunner]]></category>
		<category><![CDATA[Syntax Highlught]]></category>
		<category><![CDATA[vugen]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=317</guid>
		<description><![CDATA[Sometimes when you have a function that you use alot, it might be nice to have it color coded in code like the other lr_* commands. I looked for a solution to this for awhile but didn&#8217;t find anything relating to VuGen and Syntax Highlight things, so I started digging a little deeper into VuGen&#8217;s [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=317&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Sometimes when you have a function that you use alot, it might be nice to have it color coded in code like the other lr_* commands.</p>
<p>I looked for a solution to this for awhile but didn&#8217;t find anything relating to VuGen and Syntax Highlight things, so I started digging a little deeper into VuGen&#8217;s configs and came up with a half-way solution to this.</p>
<p><span id="more-317"></span>To start with I discovered that VuGen uses the <a title="slickedit.com" href="http://www.slickedit.com/">SlickEdit OEM text editor</a> as the basis for code editing. This in turn lead to looking for .vlx files with the keywords definitions.</p>
<p>I found a file called vugen.vlx that seemed to contain the right data, and lo and behold, changing the file made a difference!</p>
<p>So to add <a title="My &quot;lr_save_float&quot; article" href="http://ptfrontline.wordpress.com/2010/01/27/lr_save_float-function-for-loadrunner/">lr_save_float();</a> as a lr_* syntax highlighted command you should edit the <strong>vugen.vlx</strong> file found in <strong>C:\Program Files\HP\LoadRunner\bin\vslick</strong> as follows:</p>
<p>1. Open the file in your favorite (UltraEdit32) text editor<br />
2. Go to the end of the file<br />
3. Add the following line as the last just above last ;// line:<br />
<em>; Added custom LR keywords</em><br />
<em>userkeywords=lr_save_float</em></p>
<p>Here&#8217;s a snip of how it should look:</p>
<p><pre class="brush: cpp;">
...
userkeywords=soa_xml_validate ws_sign_saml_assertion
userkeywords=lr_db_connect lr_db_disconnect lr_db_dataset_action lr_checkpoint lr_db_getvalue lr_db_executeSQLStatement
userkeywords=nca_system_command

; Added custom LR keywords (multiple function names can be separate with space)
userkeywords=lr_save_float lr_replace

;// please save 1 empty line for SDK Protocol merge

</pre></p>
<p>And why this is half-way is that I still have to figure out how to change the actual color and assign a different keyword group to my custom commands &#8230;</p>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/317/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/317/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/317/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/317/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/317/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/317/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/317/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/317/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/317/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/317/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/317/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/317/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/317/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/317/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=317&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2011/11/03/syntax-highlighting-for-custom-functions-in-loadrunner-vugen/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>Installing &amp; Patching LoadRunner v11 (ALM) from scratch on Win7 64bit</title>
		<link>http://ptfrontline.wordpress.com/2011/09/29/installing-patching-loadrunner-v11-alm-from-scratch-on-win7-64bit/</link>
		<comments>http://ptfrontline.wordpress.com/2011/09/29/installing-patching-loadrunner-v11-alm-from-scratch-on-win7-64bit/#comments</comments>
		<pubDate>Thu, 29 Sep 2011 10:10:56 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[LoadRunner]]></category>
		<category><![CDATA[Tips and Q&A]]></category>
		<category><![CDATA[Installtion]]></category>
		<category><![CDATA[LoadRunner v11]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=314</guid>
		<description><![CDATA[Today I did this exercise with the Official HP LoadRunner v11 package. And as was to be expected it wasn&#8217;t a simple click-click-go thing The steps to install are pretty straight forward. Worth mentioning here is that I installed the FULL package, controller and all. If you install the StandAlone versions, the procedure and problems [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=314&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Today I did this exercise with the Official HP LoadRunner v11 package.</p>
<p>And as was to be expected it wasn&#8217;t a simple click-click-go thing <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><span id="more-314"></span></p>
<p>The steps to install are pretty straight forward. Worth mentioning here is that I installed the FULL package, controller and all. If you install the StandAlone versions, the procedure and problems may be different.</p>
<p><strong>Installing LoadRunner v11</strong></p>
<p>So here are the steps:</p>
<ol>
<li>Install the FULL loadrunner package from the installer (setup.exe)</li>
<li>Install the following patches:</li>
</ol>
<ul>
<li>Analysis_lr11_pr_9790 patch. (a zip file that is extracted on top of existing .\bin directory)</li>
<li>LR_03014 &#8211; Patch 03014 (imaginative name as always <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  )</li>
<li>LR_03017 &#8211; Patch 1</li>
<li>LR_03044 &#8211; Patch 2</li>
<li>LR_03063 &#8211; Patch 3 (Adds IE9 support)</li>
</ul>
<p>The manual work involved when installing the patches is to go and cleanup after the installer. Each time a patch is installed it leave a %EXTRACTPATH% folder under the .\HP\LoadRunner\ directory that contains folders like Bin, Help, Tutorial etc.</p>
<p>After each patch installation you need to go into the %EXTRACTPATH% folder and move all the folders in there to the .\HP\LoadRunner\ directory.</p>
<p>Also for each Patch that I installed I got a couple of errors with Online.exe and a few OCX registration failures. I pressed OK for the dialogs, and the installation continued.</p>
<p>All of this took about 2h to do, and now I have a fully working LoadRunner v11 installation ready to go. If you do not have a license then the controller will work for 10 days.</p>
<p><strong>A note for Win7 users</strong></p>
<p>When starting your controller you might receive a &#8220;Cannot initialize driver dll, Exiting &#8230;&#8221; message. If you do the remedy is to run the application (controller) as Administrator (right click icon and choose Run As Administrator).</p>
<p><strong>Downloading the patches from HP</strong></p>
<p>To download the patches from the HP support site you can use the following URL as a template:</p>
<p><a title="Download LR_03063.EXE patch" href="http://support.openview.hp.com/downloadAPatch.jsp?patchName=LR_03063.EXE&amp;prodName=lr&amp;prodRelease=11.00" target="_blank">http://support.openview.hp.com/downloadAPatch.jsp?patchName=<span style="text-decoration:underline;"><span style="color:#ff0000;text-decoration:underline;">LR_03063.EXE</span></span>&amp;prodName=lr&amp;prodRelease=11.00</a></p>
<p>See the red underlined part? Replace with the proper LR patch name to download&#8230;</p>
<p>&nbsp;</p>
<p>Enjoy!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/314/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/314/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/314/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=314&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2011/09/29/installing-patching-loadrunner-v11-alm-from-scratch-on-win7-64bit/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>More about the online-ticket system &#8230;</title>
		<link>http://ptfrontline.wordpress.com/2011/09/27/more-about-the-online-ticket-system/</link>
		<comments>http://ptfrontline.wordpress.com/2011/09/27/more-about-the-online-ticket-system/#comments</comments>
		<pubDate>Tue, 27 Sep 2011 07:36:54 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[defects]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=304</guid>
		<description><![CDATA[It&#8217;s now been two weeks, and the on-line ticket sales system is still not working as it should. All the sales kiosks in the whole country are now closed until further notice and the system is still slow, and has serious defects. During these two weeks there has been some more information released to the [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=304&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s now been two weeks, and the on-line ticket sales system is still not working as it should. All the sales kiosks in the whole country are now closed until further notice and the system is still slow, and has serious defects.</p>
<p>During these two weeks there has been some more information released to the public, both from the vendor (<a title="Accenture" href="http://www.accenture.com" target="_blank">Accenture</a>), the customer (<a title="VR" href="http://www.vr.fi" target="_blank">VR</a>) and the hosting company <a title="Tieto" href="http://www.tieto.com" target="_blank">Tieto</a>.</p>
<p>Among the more interesting ones: <em></em></p>
<ul>
<li>The system was tested by the vendor in India. (<a title="Link to article (Finnish)" href="http://www.iltalehti.fi/uutiset/2011092714462985_uu.shtml" target="_blank">Link</a>)</li>
<li>Tickets have been &#8220;lost&#8221; and not delivered even when money has been charged (<a title="Link to article (Finnish)" href="http://www.iltalehti.fi/uutiset/2011092714463245_uu.shtml" target="_blank">Link</a>)<span id="more-304"></span></li>
</ul>
<p><strong>Lets consider the first one</strong></p>
<p>What&#8217;s wrong with that first one? In my opinion the VENDOR of the software must never ever, under any circumstances, be allowed to do the final testing of the software. If I where in the paying customers shoes, I would not be able to trust the vendor to do proper testing, and even if I demanded test results I would consider them even less trustworthy than the testing itself.</p>
<p>The fact it was tested in India means nothing in itself. The people over there are as competent as anywhere. The problem is that they are working for the vendor.</p>
<p>In reality the business is usually setup so that the project is budgeted beforehand, and the sales agreement probably does not include testing with more than a few words, nor much about the fixing of defects. And to top off the weird things: In some cases if the vendor makes the deal and the vendors sales people get their bonuses even before the actual system is even created, installed, or tested.</p>
<p>After the deal is made, a different group of people actually start to design, code and build the final system. It is often also this same group of people that are later charged with the testing of the software. The project has a &#8220;test group&#8221; to test what the &#8220;development group&#8221; have produced, and all this managed under the same &#8220;project&#8221;, and the same people responsible in the end.</p>
<p>The project is most probably bound by release deadlines. And remember that the bonuses are also tied to these deadlines. I do not think the project lead wants to delay the project release dates just because of a few bugs? Very often then thinking is: <em>&#8220;We can put them on the defects list and schedule to fix them later. The important thing is to get a release done before the deadline so we get our bonuses.&#8221;</em></p>
<p>I would say that the focus and goal the the project is a little skewed here?</p>
<p>Also considering that a separate agreement is often in place, stating that &#8220;bugs&#8221; and &#8220;issues&#8221; in the delivered system are taken care of in the next release. Of course this &#8220;maintenance release&#8221; or &#8220;update release&#8221; is not free of charge! This setup is perhaps the most ideal setup ever to produce the worst quality software ever. In every place the focus is on the wrong thing.</p>
<p><span style="text-decoration:underline;">How should they have done the testing then?</span></p>
<p>This is a hard question, and often both the customer and the vendor are reluctant to admit that testing is costly and takes a lot of time. Proper testing may also delay the release dates and in the worst case cause serious redesign of the whole system.</p>
<p>In truth, even proper testing will never be able to save a badly designed, ill implemented system after it has been done.</p>
<p>Proper testing however CAN prevent a bad design and prevent ill implementation.</p>
<p>In this specific case I would have, from the Customer side, chosen to buy the quality assurance as a whole from a third party that specializes in quality assurance. There are several of these companies around, and they have nothing to GAIN nor LOSE by doing proper testing.</p>
<p>The testing team (QA) should be separated from the development team (vendor) in regards to money. This will ensure that the QA team has no problem with reporting the errors they find. It should also make the developers want to produce better quality since they now have an independent testing authority. <span style="text-decoration:underline;">Side note: Never tie the QA teams money to the number of defects either!</span></p>
<p>And as this was a large project I would suggest several experienced quality guys (Functional, Automated and Performance) to work WITH the developers during the development, to prevent the bad designs and ill implementations before they are even done.</p>
<p><strong>And what about the second point (remeber, up there the two bullet points)?</strong></p>
<p>In addition to all the above there has been discovered a serious bug in the way the system handles payments and tickets.</p>
<p>It seems there have been several (read hundreds) of cases where people have been charged for a ticket, but have never received the ticket! I even heard about a mom that bought a family ticket twice, and was promptly charged and never received either of the tickets.</p>
<p>VR officially says that to get a refund for a &#8220;lost&#8221; ticket: &#8220;You must call our non-free customer service, queue for your turn and then we&#8217;ll look into it&#8221;.</p>
<p>Say what? Call a customer service number that COSTS you even MORE money than you have already lost, not counting the TIME spent on this, and the frustration?? Just gobsmacking how they treat their customers!</p>
<p>The system was thoroughly tested according to the vendors spokespersons. So what did they really test? And How? These are questions we may never get answers to, but we sure do know the results of the testing <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p><strong>What are the effects of all of this?</strong></p>
<p>Now what are the effects of all of this, besides the obvious vendor PR?</p>
<p>There have been reports of the people in the customer service department of VR saying that they want more money because of the increased workload. Not to mention they have to listen to all the people calling in and shouting at them for a failed system! The customer service people are definitely not to blame for all of this.</p>
<p>I say that brave souls sit there and answer the phone these days.</p>
<p>VR&#8217;s reputation has been tarnished for a long time by this. They have never been very good at keeping the timetables, especially during winter with the French train carts, but this new scandal with the tickets really puts them in a bad light. This ultimately leads to less people using the trains, meaning less money for VR, leading to higher ticket prices &#8230;</p>
<p>So, from all the people who use the trains daily: <span style="text-decoration:underline;">Thank You for a well managed project, well built and well tested system. (NOOOT)</span></p>
<p><strong>PS.</strong></p>
<p>Did you know that a one-time 1h ticket costs 4€ in Helsinki. This gives you the option to travel with Bus, Train or Tram inside Helsinki, Espoo and Vantaa areas for free for 1h after the purchase of the ticket.</p>
<p>If I drive my car to the center of Helsinki an park it for 8h (workday) I pay 8€ (1€/hour).</p>
<p>So, WTF? 2 times 4€ with commuter traffic is THE SAME PRICE as parking my car for 8h? Which one do you think I choose to use, especially with the problems of late!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/304/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/304/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/304/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=304&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2011/09/27/more-about-the-online-ticket-system/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>A real story about an online-ticket system failing under load &#8230;</title>
		<link>http://ptfrontline.wordpress.com/2011/09/15/a-real-story-about-an-online-ticket-system-failing-under-load/</link>
		<comments>http://ptfrontline.wordpress.com/2011/09/15/a-real-story-about-an-online-ticket-system-failing-under-load/#comments</comments>
		<pubDate>Wed, 14 Sep 2011 21:01:39 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[Main]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=295</guid>
		<description><![CDATA[When I read the news today, I just had to share this with the Blog &#8211; This is such a good example of when things don&#8217;t go as planned. Today there&#8217;s been big news-flashes on several Finnish news sites about the local train monopoly firm and their new web-based ticket sales system crashing under a [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=295&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>When I read the news today, I just had to share this with the Blog &#8211; This is such a good example of when things don&#8217;t go as planned.</p>
<p>Today there&#8217;s been big news-flashes on several Finnish news sites about the <a title="VR" href="http://www.vr.fi" target="_blank">local train monopoly firm</a> and their new web-based ticket sales system crashing under a heavy load. They had introduced a new online ticket sales system, and where literally overrun. The official comment from the company was (translated) &#8220;we where surprised to see such traffic amounts&#8221;.</p>
<p>Two of the articles: <a title="Iltalehti" href="http://www.iltalehti.fi/uutiset/2011091414382691_uu.shtml" target="_blank">here</a>, and <a title="Kauppalehti" href="http://www.kauppalehti.fi/5/i/talous/uutiset/etusivu/uutinen.jsp?oid=20110992281" target="_blank">here</a></p>
<p><span id="more-295"></span></p>
<p>A very welcome small detail in the official apology about the crashing system:</p>
<p><strong>&#8220;The new ticket system got a 20 times higher than usual rate of sales, resulting in some 800 clicks per second&#8221; </strong></p>
<p>They also said that it was fixed 2 hours later by adding more hardware, but at 10pm (~12 hours later) I still wait for <strong>1m 16s</strong> (<a title="Firebug" href="http://getfirebug.com/" target="_blank">according to firebug</a>) to load the page, something I think is WAY too slow.</p>
<p>Assuming a click is a page-load, it would mean that 800 page loads/sec x (1+68) page+resources = 54 400 HITS/SEC !! <strong>I think not.</strong></p>
<p>What they probably mean is 800 HITS/sec, and that would make roughly 800/68 = 11 page loads/second. <strong>But Wait a minute, Only 11??</strong></p>
<p>As I have no idea of how the system is built, other than it&#8217;s running on NGIX web-servers, I can&#8217;t comment on how fast/slow it should be, but from my experience 11 page loads per sec seems to be a little low. Also if 11 page-loads/sec was peak traffic at 20 times the normal, it means the Normal traffic is only 11/20 = 0.55 page-loads/sec (37 hits/sec).</p>
<p>EDIT:  Got more info on the sales figures. They have sold 10K tickets/day (peak), where normally selling around 5000/day.</p>
<p>Calculating Tickets per sec:  10K/day = 416/h = 7/m = <strong>0.11/sec</strong></p>
<p><strong>My conclusions about all of this</strong></p>
<p>So my conclusion is that the system was probably more or less built according to specs given, specs that most probably lacked any performance requirements in any meaningful way. The reason for the Perf reqs missing is most probably inexperience on the part of the people who wrote the specs, specifically of what performance is and what it really means. I&#8217;ve seen this in almost all the new projects I&#8217;ve been involved in.</p>
<p>I also suspect that proper performance testing of the system has not been done.</p>
<p>In another news-article I read that the system has been developed for 2 years, and during that time there should have been plenty of time to performance-, stress- and load -test the system. Fix the problems and retest again until it reaches a performance that is acceptable.</p>
<p><strong>Estimating the Expected Load</strong></p>
<p>The following calculations are based on rough guesses on my part.</p>
<p>As a base rule of thumb I usually use the following formulas for estimating pages/sec (when it&#8217;s a public web site, or the interface is used by the public (pay booths etc.)):</p>
<p>Average Concurrent Users (ACU) = Total Expected User Base (all potential users) * 1%</p>
<p>Average Concurrent Pages (ACP) = ACU * 1%</p>
<p>So I can only speculate, but in Finland we have 5.3 Million people, of which 15-65 year old people are ~3.5million, of which 1% is 35000 potential concurrent people wanting to buy tickets. I assume that about 1/3 of these people would use the trains and about 1/3 would by tickets online (there are about 2 million privately registered vehicles in Finland).</p>
<p>So ACU becomes 3.5Million*0.01 = 35000*0.33*0.33 = ~3811</p>
<p>ACP then becomes 3811*0.01 =~38 pages/sec. (1% of online users are there clicking at the same time)</p>
<p><em>These numbers may seem high to some, but remember the potential user base really is 3.5 million users.</em></p>
<p>In comparison, using 0.55 pages/sec would give us: 0.55/0.01 = 55/0.33/0.33 = 505/0.01 = ~50505.</p>
<p>My way of estimating the average load probably gives a little higher result than theirs .. but remember, it&#8217;s just estimations &#8230; <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>So how much more should the system be able to handle at peak hour? This is a really difficult question and is totally dependent on the system and how it&#8217;s used. I estimate that the an online train-ticket system should be able to withstand a 30 fold short time peak, since some seasonal tickets come on sale on specific dates (We now know that the actual peak load was at least 20 times, and the system crashed after that).</p>
<p>So my estimation would be (worst case scenarios):</p>
<p>Avg load = ~38 pages/sec</p>
<p>Peak load = ~1140 pages/sec</p>
<p><strong>And the Solution?</strong></p>
<p>The only real solution to this is to get specialized  professional help from the real pros. People like architects, performance testers, and test managers, who know what they are doing. It may be more costly than doing it in-house or with a larger consultant vendor, but if and when the results of a go-live launch are as described above, I think the money spent on pro&#8217;s would have been far less than the money now needed to roll back to the old system in production, retest the new system in QA, find and fix the issues, and perhaps even redesign parts or all of how it works internally.</p>
<p>At the very minimum the people doing the specs should get the pros to help out during the specification phase.</p>
<p>And where to get the professional help? Especially f the large consultant vendors don&#8217;t seem to be able to provide?</p>
<p>Answer: Find smaller specialized consultant companies that are experts in the field &#8211; My company<a title="Celarius" href="http://www.celarius.com" target="_blank"> Celarius</a> is one such company <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
<p>If you read this far, then perhaps you would like to comment:  How would YOU have estimated the load?</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/295/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/295/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/295/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=295&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2011/09/15/a-real-story-about-an-online-ticket-system-failing-under-load/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>LoadRunner VuGen v9.52 on Win7 x64 &#8211; 100% Working (Updated)</title>
		<link>http://ptfrontline.wordpress.com/2011/04/18/loadrunner-v9-52-or-windows-7-x64-100-working/</link>
		<comments>http://ptfrontline.wordpress.com/2011/04/18/loadrunner-v9-52-or-windows-7-x64-100-working/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 10:37:03 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[LoadRunner]]></category>
		<category><![CDATA[Performance]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=275</guid>
		<description><![CDATA[I recently got Windows 7 x64 installed on my laptop, and as per information from HP LoadRunner v9.52 does NOT work with Windows 7, let alone x64 &#8211; So I got myself a Virtual Machine installed, where I have Win XP x86 for LoadRunner work. Beeing a person who believes software should work in diverse [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=275&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>I recently got Windows 7 x64 installed on my laptop, and as per information from HP LoadRunner v9.52 does NOT work with Windows 7, let alone x64 &#8211; So I got myself a Virtual Machine installed, where I have Win XP x86 for LoadRunner work.</p>
<p>Beeing a person who believes software should work in diverse environments, I also tried installing LoadRunner on the Win 7 machine, specifically Analysis and VuGen <span id="more-275"></span> as I do scripting with the laptop, no controller was needed. So I set out to install it and also did a few tricks on the way, things I knew would not work or had to be changed.</p>
<p>In short the following actions where taken during installation:</p>
<ul>
<li>Install v9.50  into C:\USERS\[Username]\HP instead of standard Program Files directory</li>
<ul>
<li>This because VuGen writes to INI files etc. all the time it needs write access to the install folder</li>
</ul>
<li>Install v9.51 upgrade patch</li>
<li>After v9.51 upgrade patch, modify registry as per <a title="Installing LoadRunner on 64 bit Windows" href="http://bish.co.uk/index.php?option=com_content&amp;view=article&amp;id=95%3Ainstalling-loadrunner-on-64-bit-windows&amp;catid=34%3Arecent&amp;Itemid=1">Richard Bishops blog entry Installing LoadRunner on 64 bit Windows</a></li>
<ul>
<li><strong>In addition to Bishops instructions:</strong></li>
<li>Make sure the<em>&#8220;HKLM\Software\WOW6432Node\Mercury interactive&#8221;</em> key is NOT MOVED but COPIED to the <em>&#8220;HKLM\Software\Mercury Interactive&#8221;</em> key !! If moved v9.52 patching won&#8217;t work as it checks BOTH keys for the existence of v9.51!</li>
<li>Also make sure the values in both keys <em>&#8220;&#8230;\Mercury Interactive\LoadRunner\CurrentVersion&#8221;</em> are as follows:</li>
<li>DisplayName = &#8220;HP LoadRunner Software 9.51&#8243;</li>
<li>Minor = &#8220;51&#8243;</li>
</ul>
<li>Install v9.52 upgrade patch</li>
<li>Install IE8 upgrade Patch</li>
<li>When starting VuGen it complained about the WebAEDUI.DLL. I replaced this with another older version of the DLL from v9.51 .. <img src='http://s0.wp.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' />  And the complaints where gone!</li>
</ul>
<p>At this point to Analysis worked 100%, and VuGen worked all the way to the point where a web function was called. The call itself worked, and the result was retrieved but alas, the HTML parser failed with a critical exception error. So still I had not achieved 100% VuGen, but I was able to record, and replay non-html pages fine.</p>
<p>Now last Tuesday, Microsoft released a massive patch pack (some 29 fixes I think it was) and just by accident I was demonstrating Analysis and VuGen to a friend &#8211; and TO MY GREAT SURPRISE VuGen now replayed and parsed text/html content 100% ! So now I have myself a fully working LR v9.52 installation, and no longer see any immediate need to upgrade to the new ALM v11 just because people switch to Win 7.</p>
<p><strong>EDIT:</strong></p>
<ul>After having tried installing VuGen on other Win7 machines, both x32 and x64 I&#8217;ve experienced that the Reply still does not work as it should, and fails with an Exception. I think the problem is related somehow with the registration of the &#8220;RTBComm.dll&#8221; and &#8220;LrwRTBSyncObject.DLL&#8221; components.</ul>
<ul>In the original installation also had these problems, but as the patch-set from Microsoft was applied it apparently fixed this registration issue.. So now I&#8217;m still not able to get it working on most machines. Only one other Win7 x32 has gotten it working so far (was not done by me)..</ul>
<ul>If you people out there get it working, please let me know HOW it was done and WHAT was done to make it work! Thank You!</ul>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/275/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/275/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/275/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=275&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2011/04/18/loadrunner-v9-52-or-windows-7-x64-100-working/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>Overriding LR functions with custom code</title>
		<link>http://ptfrontline.wordpress.com/2010/06/22/overriding-lr-functions-with-custom-code/</link>
		<comments>http://ptfrontline.wordpress.com/2010/06/22/overriding-lr-functions-with-custom-code/#comments</comments>
		<pubDate>Tue, 22 Jun 2010 07:49:09 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[LoadRunner]]></category>
		<category><![CDATA[vugen]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=267</guid>
		<description><![CDATA[Most people do not know that LR supports overriding existing functions with custom ones in a very easy way. I had a situation where I had a pre-made script that had fixed think-time values for the lr_think_time() calls, and they of course were completely wrong. So my problem was that I had a lot of [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=267&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Most people do not know that LR supports overriding existing functions with custom ones in a very easy way.</p>
<p>I had a situation where I had a pre-made script that had fixed think-time values for the lr_think_time() calls, and they of course were completely wrong. So my problem was that I had a lot of lr_think_time() places and I didn&#8217;t want to go through them all myself.<span id="more-267"></span></p>
<p>In most cases a search-and-replace would do the trick, but I stumbled upon the overriding of functions and implemented it that way instead, making my changes to the script stay in one place only instead of manipulating all the actions in the script.</p>
<p><em>Remember: <span style="text-decoration:underline;">DO NOT CALL THE OVERRIDDEN FUNCTION INSIDE THE NEW CODE!!!</span> &#8211; You&#8217;ll just end up with an endless loop, and terminate in stack-errors or similar&#8230;<br />
</em></p>
<p>Here&#8217;s an empty script where I&#8217;ve overridden the lr_think_time() function with a custom one:</p>
<p><pre class="brush: cpp;">
#define lr_think_time my_think_time  // This define overrides lr_think_time() with my_think_time()

double my_think_time(double sec)
// This simulates the 50% to 150% think-time randomness ...
{
	double x;

	x = ((50.0+rand()%100)/100)*sec; // 50% to 150% randomness

	lr_force_think_time( x ); // force the think time (this is undocumented command)

	return x; // return how many seconds we waited
}

///////////////////////////////////////////////////////////////////////////////

Action()
{
	lr_think_time(10); // This will use the my_think_time() function !!

	return 0;
}
</pre></p>
<p>One could get creative and start overriding all sorts of functions with this. An example would be to set specific headers for specific web_url() calls depending on the params. You could override the web_url() call, examine the parameters and add any needed HTTP headers before doing a web_custom_request() instead ..</p>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/267/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/267/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/267/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=267&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2010/06/22/overriding-lr-functions-with-custom-code/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>Creating a DLL with Delphi for LoadRunner</title>
		<link>http://ptfrontline.wordpress.com/2010/04/13/creating-a-dll-with-delphi-for-loadrunner/</link>
		<comments>http://ptfrontline.wordpress.com/2010/04/13/creating-a-dll-with-delphi-for-loadrunner/#comments</comments>
		<pubDate>Tue, 13 Apr 2010 08:07:18 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[Delphi]]></category>
		<category><![CDATA[LoadRunner]]></category>
		<category><![CDATA[dll]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=230</guid>
		<description><![CDATA[This article extends my previous post on Using a Custom DLL in LoadRunner and now shows by example how a DLL is actually created in Delphi and used from LoadRunner. The DLL I&#8217;ll create here is a simple stub with a few basic functions and can serve as a template for any type of DLL [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=230&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>This article extends my previous post on <a title="View post" href="http://ptfrontline.wordpress.com/2009/02/24/using-a-custom-dll-in-loadrunner/" target="_self">Using a Custom DLL in LoadRunner</a> and now shows by example how a DLL is actually created in <a href="http://embarcadero.com/">Delphi</a> and used from <a href="http://www.hp.com/">LoadRunner</a>.</p>
<p>The DLL I&#8217;ll create here is a simple stub with a few basic functions and can serve as a template for any type of DLL that you want to create.</p>
<p>I&#8217;ll show how to avoid the most common problems of sending/retrieving strings to/from the DLL as well as how to handle the Unicode situation with D2009 and D2010 (LR is not Unicode enabled).<span id="more-230"></span></p>
<p>Some of the things a LR DLL developer needs to remember are:</p>
<ul>
<li>LR is Muti-Threaded and Multi-processed, make the DLL thread-safe</li>
<li>When using LoadGenerators the DLL must be distributed to several machines</li>
<li>When using Performance Center the lr_load_dll() function needs to be white-listed on every LoadGenerator. The file to manipulate is &#8220;C:\Program Files\HP\Load Generator\merc_asl\lrun_api.asl&#8221;</li>
<li>The DLL may be unloaded at any time, if the script fails/aborts (=&gt; YOU must release allocated memory)</li>
<li>If eternal loops or lockups inside the DLL occur, the whole controller/loadgenerator is lost until rebooted (really bad when under PerfCenter)</li>
</ul>
<p>Keeping the above in mind, also remember the following general rules</p>
<ul>
<li>LR script makers make mistakes too by sending INVALID input to functions or using them in an unintended way. This means that you as a DLL developer NEED TO VERIFY the input params for every function call!</li>
<li>The DLL may be installed on a variety of windows platforms (Win2000-&gt;Win7) so make sure you check the OS Version if you are using Windows API calls that are version dependent</li>
<li>There is no guarantee that the DLL has Administrator privilidges!</li>
<li>The DLL is restricted to the same Win32 memory as the host process (2 Gig max allocation)</li>
</ul>
<h2><strong>Creating the DLL in Delphi</strong></h2>
<p>Close all projects and then choose &#8220;<em>FILE | OTHER &#8230;</em>&#8220;, select &#8220;<em>DELPHI PROJECTS</em>&#8221; and then &#8220;<em>Dynamic Link Library</em>&#8220;. You should now have the following skeleton (excluding all comments):</p>
<p><pre class="brush: delphi;">
  library Project1;

  uses
    SysUtils,
    Classes;

  {$R *.res}

  begin
  end.
</pre></p>
<p>Now copy &amp; paste the following instead of the above:</p>
<p><pre class="brush: delphi;">
library MyDLL;

uses
  SysUtils, Classes, Windows,
  VUManager in 'VUManager.pas';

Const
  { Version Constants }
  DLLVer_Major                 = 1;
  DLLVer_Minor                 = 0;
  DLLVer_Copyright             = 'Copyright (C) by Celarius Oy';

  { DLL Errors - Negatives are errors }
  ERR_None                     =  0;
  ERR_Unknown                  = -1;
  ERR_Unknown_Object           = -2;
  ERR_Insufficient_Buffer      = -3;

////////////////////////////////////////////////////////////////////////////////

Var
  VUMgr : TVUManager;

{$R *.res}

////////////////////////////////////////////////////////////////////////////////

function dll_Initialize( VUserID: Cardinal ): Integer; stdcall;
// Initialize DLL, Adds the Vuser with the ID
//
// Returns
//    Integer    The Error code
begin
     If VUMgr.AddVUser( VUserID ) then
        Result := ERR_None
     Else
        Result := ERR_Unknown_Object;
end;

////////////////////////////////////////////////////////////////////////////////

function dll_Finalize( VUserID: Cardinal ): Integer; stdcall;
// Finalize DLL, removes the VUser with the ID
//
// Returns
//    Integer    Error code
begin
     If VUMgr.RemoveVUser( VUserID ) then
        Result := ERR_None
     Else
        Result := ERR_Unknown_Object;
end;

////////////////////////////////////////////////////////////////////////////////

function dll_GetVersion: Integer; stdcall;
// Get Library version
//
// Returns
//    Integer    Version Number
begin
     Result := (DLLVer_Major SHL 16) + DLLVer_Minor;
end;

////////////////////////////////////////////////////////////////////////////////

function dll_GetCopyright( DestStr: PAnsiChar; DestSize: Integer): Integer; stdcall;
// Get Library Copyright String
//
// Returns
//    Integer    Version Number
begin
     if (DestSize&gt;Length(DLLVer_Copyright)) then
     Begin
          StrCopy( DestStr, PAnsiChar(DLLVer_Copyright) );
          Result := ERR_None;
     End Else Result := ERR_Insufficient_Buffer;
end;

////////////////////////////////////////////////////////////////////////////////

function dll_TrimStr(ID:Cardinal; SourceStr: PAnsiChar; DestStr: PAnsiChar; DestSize: Integer): Integer; stdcall;
// Trims a String (removes special chars in beginning/end)
//
// Returns
//    Integer    Error Code
Var
   VU : TVirtualUser;
   S  : AnsiString;
begin
     { Find the Virtual User }
     VU := VUMgr.FindVU(ID);
     if Assigned(VU) then
     Begin
          S := VU.TrimString( SourceStr ); // process the string

          if (DestSize&gt;Length(S)) then
          Begin
               StrCopy( DestStr, PAnsiChar(S) );
               Result := ERR_None;
          End Else Result := ERR_Insufficient_Buffer;

     End Else Result := ERR_Unknown_Object;
end;

////////////////////////////////////////////////////////////////////////////////

{ Export functions }
exports
  { General Functions }
  dll_Initialize       name 'dll_Initialize',
  dll_Finalize         name 'dll_Finalize',
  dll_GetVersion       name 'dll_GetVersion',
  dll_GetCopyright     name 'dll_GetCopyright',
  dll_TrimStr          name 'dll_TrimStr'
  ;

////////////////////////////////////////////////////////////////////////////////

procedure DLLEntryProc(EntryCode: integer);
//
// DLL Entry/Exit, Process and Thread Attach/Detach procedures }
//
Var
   Buf           : Array[0..MAX_PATH] of Char;
   LoaderProcess : String;
   DLLPath       : String;
begin
     Try
        Case EntryCode of
             { The DLL has just been loaded with LoadLibrary()               }
             { either by the main process, or by a vuser - we do not know    }
             { which one                                                     }
             DLL_PROCESS_ATTACH:
             Begin
                  { Get the Path where the DLL is }
                  GetModuleFileName(HInstance, buf, Length(buf)) ;
                  DLLPath := ExtractFilePath(StrPas(buf));
                  { Get the name of the module that loaded us }
                  GetModuleFileName(HInstance, buf, Length(buf)) ;
                  LoaderProcess := StrPas(buf);
                  { Create handler }
                  VUMgr:= TVUManager.Create( NIL );
             End;

             { The Process Detached the DLL - Once per MMDRV Process }
             { Application called Unload - Perform Cleanup }
             DLL_PROCESS_DETACH:
             Begin
                  If Assigned(VUMgr) then FreeAndNil(VUMgr);
             End;

             { A Thread has just loaded the DLL }
             DLL_THREAD_ATTACH:
             Begin
                  { This occures when a VUser calls lr_load_dll() }
             End;

             { A Thread has just unloaded the DLL }
             DLL_THREAD_DETACH:
             Begin
                  { This occures when a VUser exits }
             End;
        End;
     Except
        // TODO: Write an Exception Handler
        On E: Exception do ;
     End;
end;

////////////////////////////////////////////////////////////////////////////////
//
// DLL Initialization - When DLL is loaded the first time by any process }
//
////////////////////////////////////////////////////////////////////////////////
begin
{$IFDEF Debug}
          { True means Delphi checks &amp;amp; reports memleaks }
          ReportMemoryLeaksOnShutdown := True;
{$ENDIF}
          { Make the Memory-Manager aware that this DLL is used in Thread-environments }
          IsMultiThread := True;
          VUMgr:= NIL;

          { If we have not already set te DLLProc, do it }
          if NOT Assigned(DllProc) then
          begin
               DLLProc := @DLLEntryProc;         // install custom exit procedure
               DLLEntryProc(DLL_PROCESS_ATTACH);
          end;
end.
</pre></p>
<p>You can now save the project as &#8220;MyDLL&#8221; in a folder of your choice.</p>
<p>Now we&#8217;ll need to create the VUManager unit with &#8220;<em>FILE | NEW UNIT</em>&#8221; and save the new unit as  &#8220;VUManager.pas&#8221; in the same directory as the rest of the Delphi files. Copy &amp; Paste the following into the new unit.</p>
<p><pre class="brush: delphi;">
unit VUManager;

Interface

Uses SysUtils, Classes, Windows;

Type
  { Forward Declarations }
  TVirtualUser = class;
  TVUManager = class;

////////////////////////////////////////////////////////////////////////////////

  TVirtualUser = class(TComponent)
  private
    { Private declarations }
  protected
    { Protected declarations }
  public
    { Public declarations }
    VUserID               : Cardinal;
    Constructor Create(AOwner:TComponent; ID:Cardinal); ReIntroduce;
    Destructor Destroy; Override;
    Function TrimString(InStr: AnsiString): AnsiString;
  end;

////////////////////////////////////////////////////////////////////////////////

  TVUManager = class(TComponent)
  private
    { Private declarations }
    fVirtualUsers          : TThreadList;
  protected
    { Protected declarations }
  public
    { Public declarations }
    Constructor Create(AOwner:TComponent); Override;
    Destructor Destroy; Override;
    { Methods }
    Function FindVU(ID:Cardinal):TVirtualUser;
    Function AddVUser(ID: Cardinal): Boolean;
    Function RemoveVUser(ID: Cardinal): Boolean;
  end;

////////////////////////////////////////////////////////////////////////////////

Implementation

////////////////////////////////////////////////////////////////////////////////

{ TVirtualUser }

constructor TVirtualUser.Create(AOwner: TComponent; ID:Cardinal);
begin
     inherited Create(AOwner);
     VUserID := ID;
end;

destructor TVirtualUser.Destroy;
begin
     Try
        { Cleanup anything that is allocated by the VUser }
     Finally
        inherited;
     End;
end;

function TVirtualUser.TrimString(InStr: AnsiString): AnsiString;
begin
     Result := Trim(InStr);
end;

////////////////////////////////////////////////////////////////////////////////

{ TVUManager }

constructor TVUManager.Create(AOwner: TComponent);
begin
     Try
        inherited;
        fVirtualUsers  := TThreadList.Create();
     Finally
     End;
end;

destructor TVUManager.Destroy;
Var
   I : Integer;
begin
     Try
        { Clear and Free the VUsers List }
        If Assigned(fVirtualUsers) then
        Begin
             With fVirtualUsers.LockList do
             Try
                for I := 0 to Count - 1 do
                    TVirtualUser(Items[I]).Free;
                Clear;
             Finally
                fVirtualUsers.UnLockList;
             End;
             FreeAndNil(fVirtualUsers);
        End;
     Finally
        inherited;
     End;
end;

function TVUManager.FindVU(ID: Cardinal): TVirtualUser;
Var
   I : Cardinal;
begin
     Result := NIL;
     With fVirtualUsers.LockList do
     Try
        for I := 0 to Count - 1 do
        Begin
             if TVirtualUser(Items[I]).VUserID=ID then
             Begin
                  Result := TVirtualUser(Items[I]);
                  Break;
             End;
        End;
     Finally
        fVirtualUsers.UnlockList;
     End;
end;

function TVUManager.AddVUser(ID: Cardinal): Boolean;
Var
   VU : TVirtualUser;
begin
     Result := False;
     With fVirtualUsers.LockList do
     Try
        VU := TVirtualUser.Create(NIL, ID);
        Add( VU );
        Result := True;
     Finally
        fVirtualUsers.UnlockList;
     End;end;

function TVUManager.RemoveVUser(ID: Cardinal): Boolean;
Var
   I : Cardinal;
   VU : TVirtualUser;
begin
     Result := False;
     With fVirtualUsers.LockList do
     Try
        VU := NIL;
        for I := 0 to Count - 1 do
            if TVirtualUser(Items[I]).VUserID = ID then
            Begin
                 VU := TVirtualUser(Items[I]);
                 Delete(I);
                 Break;
            End;
     Finally
        fVirtualUsers.UnlockList;
        if Assigned(VU) then
        Begin
             FreeAndNil(VU);
             Result := True;
        End;
     End;
end;

// END OF SOURCE
End.
</pre></p>
<h2>An short explanation of what&#8217;s going on &#8230;</h2>
<p>The main project file contains the functions that are exported by the  DLL. These are available to the LR script. These in turn call methods  from the VUManager object where the actual magic of the DLL will happen.</p>
<p>The VUManager has several useful methods (Find/Add/Remove vuser) and then the TVirtualUser object contains the actual methods that perform VUser specific stuff. To extend the DLL one can add methods to the TVirtualUser object and create a small Export interface in the main project file for the method (see the dll_TrimStr() for more details).</p>
<p>The <span style="color:#ff0000;">dll_GetVersion()</span> and <span style="color:#ff0000;">dll_GetCopyright()</span> functions are there only to provide the script with details of the DLL, and are not mandatory to use when a script uses the DLL.</p>
<h3>The dll_Initialize() function</h3>
<p>This function is responsible for allocating an instance of a VUser in the VUManager object. It accepts the VUserID that is a unique identifier across all running vusers in a test.</p>
<h3>The dll_Finalize() function</h3>
<p>The finalize function deallocates (or frees) the VUser instance in the VUManager object. It  accepts the VUserID. After this call any dll functions that depend on a valid VUserID will fail with the corresponding error code.</p>
<h3>The dll_TrimStr() function</h3>
<p>The TrimStr function demonstrates how to &#8220;read&#8221; a string sent from  LoadRunner, manipulate it and then return it to LoadRunner. The  PAnsiChar is important here to make Delphi handle the string as an 8-bit  null-terminated string, instead of a Unicode string.</p>
<h2>How LoadRunner uses the DLL (in theory)</h2>
<p>As soon as the MMDRV.EXE process loads the DLL, the DLL creates the VUManager object. This object is responsible for &#8220;Managing&#8221; the actual VUsers we are going to be servicing. Each VUser Thread also &#8220;loads&#8221; the DLL but in reality it only gets a copy of it in memory (this is not 100% accurate but good enough for now).</p>
<p>The actual LR script then uses the <span style="color:#ff0000;">dll_Initialize(VUserID)</span> function to initialize a VUser in the VUManager, that will allocate an TVirtualUser object for it, with the given ID. This way we can &#8220;keep track&#8221; of the individual VUsers later when needed. The <span style="color:#ff0000;">dll_TrimStr()</span> function takes the ID as the first parameter to identify the VUser.</p>
<h2>A LoadRunner script using the DLL</h2>
<p>The <span style="color:#ff0000;">vuser_init() </span>action:</p>
<p><pre class="brush: cpp;">
int VuserID; // Script Global Variable
vuser_init()
{
	int ret;

	// Get VUserID (Needs to be created as parameter)
    VUserID = atoi(lr_eval_string(&quot;{VUserID&quot;));

	// Load the DLL
    ret = lr_load_dll(&quot;MyDLL.dll&quot;);
	if (!ret==0)
	{
		lr_error_message(&quot;Could not load DLL&quot;);
		lr_abort;
	}

	// Initialize the VUser object inside the DLL
    dll_Initialize( VUserID );

	return 0;
}
</pre></p>
<p>The <span style="color:#ff0000;">Action()</span> action:</p>
<p><pre class="brush: cpp;">
Action()
{
	char buf[1024];

	// Trim a string
	dll_TrimStr( VUserID, &quot;  this string will be trimmed!!  &quot;, buf, sizeof(buf) );

	lr_output_message(&quot;Trimmed String='%s'&quot;, buf);

	return 0;
}
</pre></p>
<p>The <span style="color:#ff0000;">vuser_end()</span> action:</p>
<p><pre class="brush: cpp;">
vuser_end()
{
	// Finalize the VUser (free the VUser object inside the DLL)
    dll_Finalize( VUserID );

	return 0;
}
</pre></p>
<p>I hope this brief introduction to DLL writing for LoadRunner is of help to those who seek information regarding this subject.</p>
<p>Enjoy!</p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/230/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/230/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/230/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=230&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2010/04/13/creating-a-dll-with-delphi-for-loadrunner/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>Handle HTTP Re-Directions in LoadRunner Scripts yourself</title>
		<link>http://ptfrontline.wordpress.com/2010/04/11/handle-http-re-directions-in-loadrunner-scripts-yourself/</link>
		<comments>http://ptfrontline.wordpress.com/2010/04/11/handle-http-re-directions-in-loadrunner-scripts-yourself/#comments</comments>
		<pubDate>Sun, 11 Apr 2010 14:41:33 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[LoadRunner]]></category>
		<category><![CDATA[LoadRunner HTTP Reirect]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=228</guid>
		<description><![CDATA[Sometimes you want to grab a Session-Cookie or something else from the HTTP Header&#8217;s during a redirection, but normally LoadRunner does not allow you to web_reg_save() those if there are multiple re-directions, and the same &#8220;variable&#8221; appears multiple times. I&#8217;ve solved this problem by handling the re-directions myself in-script by doing a DO WHILE loop [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=228&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Sometimes you want to grab a Session-Cookie or something else from the HTTP Header&#8217;s during a redirection, but normally LoadRunner does not allow you to web_reg_save() those if there are multiple re-directions, and the same &#8220;variable&#8221; appears multiple times.<span id="more-228"></span></p>
<p>I&#8217;ve solved this problem by handling the re-directions myself in-script by doing a DO WHILE loop that keeps running till the end of re-directions, or error for that matter.</p>
<p>Here&#8217;s the code for a simple redirection loop (tries to go to mercury.com, but gets re-directed to hp.com instead):</p>
<p><pre class="brush: cpp;">
Action()
{
	int HttpRetCode=0;

	// Set redirection depth to 0
	web_set_option(&quot;MaxRedirectionDepth&quot;, &quot;0&quot;, LAST);

	// Initial Location where we want to go
	lr_save_string(&quot;http://www.mercury.com&quot;, &quot;Location&quot;);

	do
	{
		// Save new Redirection Info (Location: header)
		web_reg_save_param(&quot;Location&quot;,
						   &quot;LB=Location: &quot;,
						   &quot;RB=\r\n&quot;,
						   &quot;Ord=1&quot;,
						   &quot;NotFound=Warning&quot;,
						   &quot;Search=Headers&quot;,
						   LAST );

		// do any web call (This needs to be modified to suit your needs)
		web_url(&quot;my_req&quot;,
		  &quot;URL={Location}&quot;,
		  LAST );

		// Get HTTP response Code
		HttpRetCode = web_get_int_property(HTTP_INFO_RETURN_CODE);

	} while ((HttpRetCode&gt;=300) &amp; (HttpRetCode&lt;400));

	return 0;
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/228/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/228/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/228/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=228&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2010/04/11/handle-http-re-directions-in-loadrunner-scripts-yourself/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>SHA-1 hash for LoadRunner</title>
		<link>http://ptfrontline.wordpress.com/2010/03/02/sha-1-hash-for-loadrunner/</link>
		<comments>http://ptfrontline.wordpress.com/2010/03/02/sha-1-hash-for-loadrunner/#comments</comments>
		<pubDate>Tue, 02 Mar 2010 14:21:48 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[LoadRunner]]></category>
		<category><![CDATA[SHA-1]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=218</guid>
		<description><![CDATA[One of my colleagues at work was testing a solution that obfuscated passwords using the SHA1 algorithm, and was looking for a suitable solution to replicate this with LoadRunner. As I&#8217;ve used SHA1 before for other things, I promised to look around and see if I could help out. As it turns out a suitable [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=218&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>One of my colleagues at work was testing a solution that obfuscated passwords using the SHA1 algorithm, and was looking for a suitable solution to replicate this with LoadRunner. As I&#8217;ve used SHA1 before for other things, I promised to look around and see if I could help out.</p>
<p>As it turns out a suitable source was found and I made the necessary changes to the code to make it work in LoadRunner. A big thank you to <a title="Visit Paul's SHA1 page" href="http://www.packetizer.com/security/sha1/" target="_blank">Paul E. Jones</a> for providing a free SHA1 implementation.<span id="more-218"></span></p>
<p>I created an include file names &#8220;lr_sha1.c&#8221; that can easily be included in any C based LoadRunner script or VUser type.</p>
<p><strong>Example of usage (vuser_init.c):</strong></p>
<p><pre class="brush: cpp;">
#include &quot;lr_sha1.c&quot;
vuser_init()
{
	//
	// HASH the string &quot;The quick brown fox jumps over the lazy dog&quot;,
	// The result should be &quot;2FD4E1C67A2D28FCED849EE1BB76E7391B93EB12&quot;
	//
	sha1_hash(&quot;The quick brown fox jumps over the lazy dog&quot;, &quot;_sha1&quot;);

	lr_output_message( &quot;SHA1 Hash: %s&quot;, lr_eval_string(&quot;{_sha1}&quot;) );

	return 0;
}
</pre></p>
<p>And here is the lr_sha1.c file:</p>
<p><pre class="brush: cpp;">
/*
 *****************************************************************************
 *
 *  March 2010
 *
 *    Small changes by Kim Sandell to make the source work in LoadRunner
 *    - Changed &quot;const unsigned char&quot; to &quot;const char&quot; in function params
 *    - Combined sha1.h and sha1.c into one file (for ease of use in LR)
 *    - Added sha1_hash() function to ease use in LR
 *    - Included Paul's license in comments
 *
 *****************************************************************************
 *
 *  Freeware Public License (FPL)
 *
 *  This software is licensed as &quot;freeware.&quot;  Permission to distribute
 *  this software in source and binary forms, including incorporation
 *  into other products, is hereby granted without a fee.  THIS SOFTWARE
 *  IS PROVIDED 'AS IS' AND WITHOUT ANY EXPRESSED OR IMPLIED WARRANTIES,
 *  INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
 *  AND FITNESS FOR A PARTICULAR PURPOSE.  THE AUTHOR SHALL NOT BE HELD
 *  LIABLE FOR ANY DAMAGES RESULTING FROM THE USE OF THIS SOFTWARE, EITHER
 *  DIRECTLY OR INDIRECTLY, INCLUDING, BUT NOT LIMITED TO, LOSS OF DATA
 *  OR DATA BEING RENDERED INACCURATE.
 *
 *****************************************************************************
 *
 *  sha1.h
 *
 *  Copyright (C) 1998, 2009
 *  Paul E. Jones &lt;paulej@packetizer.com&gt;
 *  All Rights Reserved
 *
 *****************************************************************************
 *  $Id: sha1.h 12 2009-06-22 19:34:25Z paulej $
 *****************************************************************************
 *
 *  Description:
 *      This class implements the Secure Hashing Standard as defined
 *      in FIPS PUB 180-1 published April 17, 1995.
 *
 *      Many of the variable names in the SHA1Context, especially the
 *      single character names, were used because those were the names
 *      used in the publication.
 *
*/

#ifndef _SHA1_H_
#define _SHA1_H_

/*
 *  This structure will hold context information for the hashing
 *  operation
 */
typedef struct SHA1Context
{
 unsigned Message_Digest[5];       /* Message Digest (output)          */
 unsigned Length_Low;              /* Message length in bits           */
 unsigned Length_High;             /* Message length in bits           */
 unsigned char Message_Block[64];  /* 512-bit message blocks      */
 int Message_Block_Index;          /* Index into message block array   */
 int Computed;                     /* Is the digest computed?          */
 int Corrupted;                    /* Is the message digest corruped?  */
} SHA1Context;

/*
 *  Function Prototypes
 */
void SHA1Reset(SHA1Context *);
int SHA1Result(SHA1Context *);
void SHA1Input( SHA1Context *,
 const char *,
 unsigned);
#endif

/*
 *****************************************************************************
 *
 *  sha1.c
 *
 *  Copyright (C) 1998, 2009
 *  Paul E. Jones &lt;paulej@packetizer.com&gt;
 *  All Rights Reserved
 *
 *****************************************************************************
 *  $Id: sha1.c 12 2009-06-22 19:34:25Z paulej $
 *****************************************************************************
 *
 *  Description:
 *      This file implements the Secure Hashing Standard as defined
 *      in FIPS PUB 180-1 published April 17, 1995.
 *
 *      The Secure Hashing Standard, which uses the Secure Hashing
 *      Algorithm (SHA), produces a 160-bit message digest for a
 *      given data stream.  In theory, it is highly improbable that
 *      two messages will produce the same message digest.  Therefore,
 *      this algorithm can serve as a means of providing a &quot;fingerprint&quot;
 *      for a message.
 *
 *  Portability Issues:
 *      SHA-1 is defined in terms of 32-bit &quot;words&quot;.  This code was
 *      written with the expectation that the processor has at least
 *      a 32-bit machine word size.  If the machine word size is larger,
 *      the code should still function properly.  One caveat to that
 *      is that the input functions taking characters and character
 *      arrays assume that only 8 bits of information are stored in each
 *      character.
 *
 *  Caveats:
 *      SHA-1 is designed to work with messages less than 2^64 bits
 *      long. Although SHA-1 allows a message digest to be generated for
 *      messages of any number of bits less than 2^64, this
 *      implementation only works with messages with a length that is a
 *      multiple of the size of an 8-bit character.
 *
 *****************************************************************************
 */

/*
 *  Define the circular shift macro
 */
#define SHA1CircularShift(bits,word) \
 ((((word) &lt;&lt; (bits)) &amp; 0xFFFFFFFF) | \
 ((word) &gt;&gt; (32-(bits))))

/* Function prototypes */
void SHA1ProcessMessageBlock(SHA1Context *);
void SHA1PadMessage(SHA1Context *);

/*
 *  SHA1Reset
 *
 *  Description:
 *      This function will initialize the SHA1Context in preparation
 *      for computing a new message digest.
 *
 *  Parameters:
 *      context: [in/out]
 *          The context to reset.
 *
 *  Returns:
 *      Nothing.
 *
 *  Comments:
 *
 */
void SHA1Reset(SHA1Context *context)
{
 context-&gt;Length_Low             = 0;
 context-&gt;Length_High            = 0;
 context-&gt;Message_Block_Index    = 0;

 context-&gt;Message_Digest[0]      = 0x67452301;
 context-&gt;Message_Digest[1]      = 0xEFCDAB89;
 context-&gt;Message_Digest[2]      = 0x98BADCFE;
 context-&gt;Message_Digest[3]      = 0x10325476;
 context-&gt;Message_Digest[4]      = 0xC3D2E1F0;

 context-&gt;Computed   = 0;
 context-&gt;Corrupted  = 0;
}

/*
 *  SHA1Result
 *
 *  Description:
 *      This function will return the 160-bit message digest into the
 *      Message_Digest array within the SHA1Context provided
 *
 *  Parameters:
 *      context: [in/out]
 *          The context to use to calculate the SHA-1 hash.
 *
 *  Returns:
 *      1 if successful, 0 if it failed.
 *
 *  Comments:
 *
 */
int SHA1Result(SHA1Context *context)
{

 if (context-&gt;Corrupted)
 {
 return 0;
 }

 if (!context-&gt;Computed)
 {
 SHA1PadMessage(context);
 context-&gt;Computed = 1;
 }

 return 1;
}

/*
 *  SHA1Input
 *
 *  Description:
 *      This function accepts an array of octets as the next portion of
 *      the message.
 *
 *  Parameters:
 *      context: [in/out]
 *          The SHA-1 context to update
 *      message_array: [in]
 *          An array of characters representing the next portion of the
 *          message.
 *      length: [in]
 *          The length of the message in message_array
 *
 *  Returns:
 *      Nothing.
 *
 *  Comments:
 *
 */
void SHA1Input(     SHA1Context  *context,
 const char   *message_array,
 unsigned     length)
{
 if (!length)
 {
 return;
 }

 if (context-&gt;Computed || context-&gt;Corrupted)
 {
 context-&gt;Corrupted = 1;
 return;
 }

 while(length-- &amp;&amp; !context-&gt;Corrupted)
 {
 context-&gt;Message_Block[context-&gt;Message_Block_Index++] =
 (*message_array &amp; 0xFF);

 context-&gt;Length_Low += 8;
 /* Force it to 32 bits */
 context-&gt;Length_Low &amp;= 0xFFFFFFFF;
 if (context-&gt;Length_Low == 0)
 {
 context-&gt;Length_High++;
 /* Force it to 32 bits */
 context-&gt;Length_High &amp;= 0xFFFFFFFF;
 if (context-&gt;Length_High == 0)
 {
 /* Message is too long */
 context-&gt;Corrupted = 1;
 }
 }

 if (context-&gt;Message_Block_Index == 64)
 {
 SHA1ProcessMessageBlock(context);
 }

 message_array++;
 }
}

/*
 *  SHA1ProcessMessageBlock
 *
 *  Description:
 *      This function will process the next 512 bits of the message
 *      stored in the Message_Block array.
 *
 *  Parameters:
 *      None.
 *
 *  Returns:
 *      Nothing.
 *
 *  Comments:
 *      Many of the variable names in the SHAContext, especially the
 *      single character names, were used because those were the names
 *      used in the publication.
 *
 *
 */
void SHA1ProcessMessageBlock(SHA1Context *context)
{
 const unsigned K[] =            /* Constants defined in SHA-1   */
 {
 0x5A827999,
 0x6ED9EBA1,
 0x8F1BBCDC,
 0xCA62C1D6
 };
 int         t;                  /* Loop counter                 */
 unsigned    temp;               /* Temporary word value         */
 unsigned    W[80];              /* Word sequence                */
 unsigned    A, B, C, D, E;      /* Word buffers                 */

 /*
 *  Initialize the first 16 words in the array W
 */
 for(t = 0; t &lt; 16; t++)
 {
 W[t] = ((unsigned) context-&gt;Message_Block[t * 4]) &lt;&lt; 24;
 W[t] |= ((unsigned) context-&gt;Message_Block[t * 4 + 1]) &lt;&lt; 16;
 W[t] |= ((unsigned) context-&gt;Message_Block[t * 4 + 2]) &lt;&lt; 8;
 W[t] |= ((unsigned) context-&gt;Message_Block[t * 4 + 3]);
 }

 for(t = 16; t &lt; 80; t++)
 {
 W[t] = SHA1CircularShift(1,W[t-3] ^ W[t-8] ^ W[t-14] ^ W[t-16]);
 }

 A = context-&gt;Message_Digest[0];
 B = context-&gt;Message_Digest[1];
 C = context-&gt;Message_Digest[2];
 D = context-&gt;Message_Digest[3];
 E = context-&gt;Message_Digest[4];

 for(t = 0; t &lt; 20; t++)
 {
 temp =  SHA1CircularShift(5,A) +
 ((B &amp; C) | ((~B) &amp; D)) + E + W[t] + K[0];
 temp &amp;= 0xFFFFFFFF;
 E = D;
 D = C;
 C = SHA1CircularShift(30,B);
 B = A;
 A = temp;
 }

 for(t = 20; t &lt; 40; t++)
 {
 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[1];
 temp &amp;= 0xFFFFFFFF;
 E = D;
 D = C;
 C = SHA1CircularShift(30,B);
 B = A;
 A = temp;
 }

 for(t = 40; t &lt; 60; t++)
 {
 temp = SHA1CircularShift(5,A) +
 ((B &amp; C) | (B &amp; D) | (C &amp; D)) + E + W[t] + K[2];
 temp &amp;= 0xFFFFFFFF;
 E = D;
 D = C;
 C = SHA1CircularShift(30,B);
 B = A;
 A = temp;
 }

 for(t = 60; t &lt; 80; t++)
 {
 temp = SHA1CircularShift(5,A) + (B ^ C ^ D) + E + W[t] + K[3];
 temp &amp;= 0xFFFFFFFF;
 E = D;
 D = C;
 C = SHA1CircularShift(30,B);
 B = A;
 A = temp;
 }

 context-&gt;Message_Digest[0] =
 (context-&gt;Message_Digest[0] + A) &amp; 0xFFFFFFFF;
 context-&gt;Message_Digest[1] =
 (context-&gt;Message_Digest[1] + B) &amp; 0xFFFFFFFF;
 context-&gt;Message_Digest[2] =
 (context-&gt;Message_Digest[2] + C) &amp; 0xFFFFFFFF;
 context-&gt;Message_Digest[3] =
 (context-&gt;Message_Digest[3] + D) &amp; 0xFFFFFFFF;
 context-&gt;Message_Digest[4] =
 (context-&gt;Message_Digest[4] + E) &amp; 0xFFFFFFFF;

 context-&gt;Message_Block_Index = 0;
}

/*
 *  SHA1PadMessage
 *
 *  Description:
 *      According to the standard, the message must be padded to an even
 *      512 bits.  The first padding bit must be a '1'.  The last 64
 *      bits represent the length of the original message.  All bits in
 *      between should be 0.  This function will pad the message
 *      according to those rules by filling the Message_Block array
 *      accordingly.  It will also call SHA1ProcessMessageBlock()
 *      appropriately.  When it returns, it can be assumed that the
 *      message digest has been computed.
 *
 *  Parameters:
 *      context: [in/out]
 *          The context to pad
 *
 *  Returns:
 *      Nothing.
 *
 *  Comments:
 *
 */
void SHA1PadMessage(SHA1Context *context)
{
 /*
 *  Check to see if the current message block is too small to hold
 *  the initial padding bits and length.  If so, we will pad the
 *  block, process it, and then continue padding into a second
 *  block.
 */
 if (context-&gt;Message_Block_Index &gt; 55)
 {
 context-&gt;Message_Block[context-&gt;Message_Block_Index++] = 0x80;
 while(context-&gt;Message_Block_Index &lt; 64)
 {
 context-&gt;Message_Block[context-&gt;Message_Block_Index++] = 0;
 }

 SHA1ProcessMessageBlock(context);

 while(context-&gt;Message_Block_Index &lt; 56)
 {
 context-&gt;Message_Block[context-&gt;Message_Block_Index++] = 0;
 }
 }
 else
 {
 context-&gt;Message_Block[context-&gt;Message_Block_Index++] = 0x80;
 while(context-&gt;Message_Block_Index &lt; 56)
 {
 context-&gt;Message_Block[context-&gt;Message_Block_Index++] = 0;
 }
 }

 /*
 *  Store the message length as the last 8 octets
 */
 context-&gt;Message_Block[56] = (context-&gt;Length_High &gt;&gt; 24 ) &amp; 0xFF;
 context-&gt;Message_Block[57] = (context-&gt;Length_High &gt;&gt; 16 ) &amp; 0xFF;
 context-&gt;Message_Block[58] = (context-&gt;Length_High &gt;&gt; 8 ) &amp; 0xFF;
 context-&gt;Message_Block[59] = (context-&gt;Length_High) &amp; 0xFF;
 context-&gt;Message_Block[60] = (context-&gt;Length_Low &gt;&gt; 24 ) &amp; 0xFF;
 context-&gt;Message_Block[61] = (context-&gt;Length_Low &gt;&gt; 16 ) &amp; 0xFF;
 context-&gt;Message_Block[62] = (context-&gt;Length_Low &gt;&gt; 8 ) &amp; 0xFF;
 context-&gt;Message_Block[63] = (context-&gt;Length_Low) &amp; 0xFF;

 SHA1ProcessMessageBlock(context);
}

int sha1_hash(const char *source, char *lrvar)
// ----------------------------------------------------------------------------
// HASH:es a string with SHA1 and stores resulting hash in lrvar variable
//
// Parameters:
//        source    Pointer to source string to HASH
//        lrvar     LR variable where base64 encoded string is stored
//
// Result
//        -1        Error
//        &gt;0        Success. Actual value is length of HASH string
//
// Example:
//        sha1_hash( &quot;abc&quot;, &quot;sha1&quot; )  // sha1=A9993E364706816ABA3E25717850C26C9CD0D89D
// ----------------------------------------------------------------------------
{
 SHA1Context sha;
 char buf[128];

 SHA1Reset(&amp;sha);
 SHA1Input(&amp;sha, source, strlen(source));

 if (!SHA1Result(&amp;sha))
 {
 lr_error_message(&quot;SHA1 ERROR: Could not compute message digest&quot;);

 return -1;
 }
 else
 {
 // Clear Buffer
 memset(buf,0,sizeof(buf));

 // Store HASH in buffer
 sprintf(buf, &quot;%08X%08X%08X%08X%08X&quot;, sha.Message_Digest[0],sha.Message_Digest[1],
 sha.Message_Digest[2],sha.Message_Digest[3],sha.Message_Digest[4]);

 // Save to LR variable
 lr_save_string(buf, lrvar);

 // Return length of string (&gt;0 = success)
 return strlen(buf);
 }
}

</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/218/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/218/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/218/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=218&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2010/03/02/sha-1-hash-for-loadrunner/feed/</wfw:commentRss>
		<slash:comments>7</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
		<item>
		<title>lr_save_float() function for LoadRunner</title>
		<link>http://ptfrontline.wordpress.com/2010/01/27/lr_save_float-function-for-loadrunner/</link>
		<comments>http://ptfrontline.wordpress.com/2010/01/27/lr_save_float-function-for-loadrunner/#comments</comments>
		<pubDate>Wed, 27 Jan 2010 20:12:13 +0000</pubDate>
		<dc:creator>Kim</dc:creator>
				<category><![CDATA[LoadRunner]]></category>

		<guid isPermaLink="false">http://ptfrontline.wordpress.com/?p=209</guid>
		<description><![CDATA[Just a quick post of a potentially useful function for LoadRunner. LoadRunner has lr_save_int() and lr_save_string() but the float saving function is missing so I just quickly whipped up the following code. It&#8217;s by no means perfect when it comes to checking for errors, but it will work &#62;90% of the times (as long as [...]<img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=209&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></description>
			<content:encoded><![CDATA[<p>Just a quick post of a potentially useful function for LoadRunner.<span id="more-209"></span></p>
<p>LoadRunner has <span style="color:#800000;"><em>lr_save_int()</em></span> and <span style="color:#800000;"><em>lr_save_string()</em></span> but the float saving function is missing so I just quickly whipped up the following code. It&#8217;s by no means perfect when it comes to checking for errors, but it will work &gt;90% of the times (as long as the scripter knows what he/she is doing).. Enjoy.</p>
<p><pre class="brush: cpp;">
void lr_save_float(const float value, const char *param, const int decimals)
// ----------------------------------------------------------------------------
// Saves a float into a lr variable, much like lr_save_int() saves an integer
//
// Parameters:
//   value       Float value to store
//   param       Loadrunner variable name
//   decimals    Number of decimals in the result string
//
// Returns:
//   N/A
//
// Example:
//   lr_save_float(123.456, &quot;myVar&quot;, 2);  // myVar = 123.46 (includes rounding)
//
// ----------------------------------------------------------------------------
{
  char buf[64];                              // if more&gt;63 digits -&gt; your problem :)
  char formatbuf[16];                        // 16 chars should be adequate

  sprintf( formatbuf, &quot;%%.%df&quot;, decimals);   // Build the &quot;%?.f&quot; format string
  sprintf( buf, formatbuf, value);           // sprintf the value
  lr_save_string( buf, param);               // store in variable
}
</pre></p>
<br />  <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gocomments/ptfrontline.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/comments/ptfrontline.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godelicious/ptfrontline.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/delicious/ptfrontline.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gofacebook/ptfrontline.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/facebook/ptfrontline.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gotwitter/ptfrontline.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/twitter/ptfrontline.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/gostumble/ptfrontline.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/stumble/ptfrontline.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/godigg/ptfrontline.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/digg/ptfrontline.wordpress.com/209/" /></a> <a rel="nofollow" href="http://feeds.wordpress.com/1.0/goreddit/ptfrontline.wordpress.com/209/"><img alt="" border="0" src="http://feeds.wordpress.com/1.0/reddit/ptfrontline.wordpress.com/209/" /></a> <img alt="" border="0" src="http://stats.wordpress.com/b.gif?host=ptfrontline.wordpress.com&amp;blog=3385845&amp;post=209&amp;subd=ptfrontline&amp;ref=&amp;feed=1" width="1" height="1" />]]></content:encoded>
			<wfw:commentRss>http://ptfrontline.wordpress.com/2010/01/27/lr_save_float-function-for-loadrunner/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
	
		<media:content url="http://0.gravatar.com/avatar/048d611d434cda8968e902b7ab82234f?s=96&#38;d=http%3A%2F%2F0.gravatar.com%2Favatar%2Fad516503a11cd5ca435acc9bb6523536%3Fs%3D96&#38;r=G" medium="image">
			<media:title type="html">Kim</media:title>
		</media:content>
	</item>
	</channel>
</rss>
