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

<channel>
	<title>bitplane.net</title>
	<atom:link href="http://bitplane.net/feed/" rel="self" type="application/rss+xml" />
	<link>http://bitplane.net</link>
	<description>Rants, ramblings, free software</description>
	<lastBuildDate>Sun, 14 Feb 2010 21:33:24 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>code_swarm</title>
		<link>http://bitplane.net/2010/02/code_swarm/</link>
		<comments>http://bitplane.net/2010/02/code_swarm/#comments</comments>
		<pubDate>Sun, 14 Feb 2010 21:33:24 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[Graphics]]></category>
		<category><![CDATA[Irrlicht]]></category>
		<category><![CDATA[irrlicht]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=572</guid>
		<description><![CDATA[I&#8217;ve been playing with code_swarm and made this video of the Irrlicht Engine&#8217;s development history:

Since the video is generated from the SVN version history it starts at the point where Niko gave hybrid and I SVN access (June 2006), so misses out years of development leading up to the 1.0 release.
code_swarm is a really cool [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">I&#8217;ve been playing with <a href="http://code.google.com/p/codeswarm">code_swarm</a> and made this video of the Irrlicht Engine&#8217;s development history:</p>
<p style="text-align: center;"><object classid="clsid:d27cdb6e-ae6d-11cf-96b8-444553540000" width="425" height="350" codebase="http://download.macromedia.com/pub/shockwave/cabs/flash/swflash.cab#version=6,0,40,0"><param name="src" value="http://www.youtube.com/v/v6j5U-pC8YE" /><embed type="application/x-shockwave-flash" width="425" height="350" src="http://www.youtube.com/v/v6j5U-pC8YE"></embed></object></p>
<p style="text-align: left;">Since the video is generated from the SVN version history it starts at the point where Niko gave hybrid and I SVN access (June 2006), so misses out years of development leading up to the 1.0 release.</p>
<p style="text-align: left;">code_swarm is a really cool tool, one thing which is exciting is the fact it supports MediaWiki. It would be really nice to show a small wiki coming together.. or maybe one day Wikipedia&#8217;s entire changelog (we can dream!)</p>
]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2010/02/code_swarm/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My first ascention!</title>
		<link>http://bitplane.net/2010/01/my-first-ascention/</link>
		<comments>http://bitplane.net/2010/01/my-first-ascention/#comments</comments>
		<pubDate>Thu, 21 Jan 2010 00:45:29 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[Uncategorized]]></category>
		<category><![CDATA[nethack]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=569</guid>
		<description><![CDATA[After playing nethack for about three years, bitplane the wizard finally ascended to the status of Demigod.
Nethack is by far the most difficult yet addictive game I have ever played and although I rate it highly, I don&#8217;t recommend it unless you&#8217;re a glutton for punishment.
My three year addiction isn&#8217;t over yet, I think I&#8217;ll [...]]]></description>
			<content:encoded><![CDATA[<p>After playing <a href="http://nethack.org/">nethack</a> for about three years, bitplane the wizard finally <a href="http://alt.org/nethack/userdata/bitplane/dumplog/1262912879.nh343.txt">ascended to the status of Demigod</a>.<br />
Nethack is by far the most difficult yet addictive game I have ever played and although I rate it highly, I don&#8217;t recommend it unless you&#8217;re a glutton for punishment.<br />
My three year addiction isn&#8217;t over yet, I think I&#8217;ll play another role next time I have a spare few.. uh.. days.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2010/01/my-first-ascention/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>Website update</title>
		<link>http://bitplane.net/2009/12/website-update/</link>
		<comments>http://bitplane.net/2009/12/website-update/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 00:10:53 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[bitplane.net]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=550</guid>
		<description><![CDATA[I&#8217;ve finally got around to editing the Simplish template and adding pages for some of my old software projects. There&#8217;s some links at the top up there, hover over them and you get a nice drop-down menu with a list of projects.
The meat of this is JavaScript stolen from another theme and some PHP code [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve finally got around to editing the Simplish template and adding pages for some of my old software projects. There&#8217;s some links at the top up there, hover over them and you get a nice drop-down menu with a list of projects.</p>
<p>The meat of this is JavaScript stolen from another theme and some PHP code gratuitously pasted into my header, this isn&#8217;t IP theft, and not just because it&#8217;s the season of sharing! This is what&#8217;s great about free software licenses.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2009/12/website-update/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>More Sidewiki Leaks</title>
		<link>http://bitplane.net/2009/12/more-sidewiki-leaks/</link>
		<comments>http://bitplane.net/2009/12/more-sidewiki-leaks/#comments</comments>
		<pubDate>Mon, 14 Dec 2009 01:26:38 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[censorship]]></category>
		<category><![CDATA[freedom of speech]]></category>
		<category><![CDATA[internet]]></category>
		<category><![CDATA[Politics]]></category>
		<category><![CDATA[sidewiki leaks]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=377</guid>
		<description><![CDATA[Apparently the British press have been barred from publishing any of Tiger Woods&#8217; sex pictures, and the block somehow extends to Internet news sites. They aren&#8217;t even allowed to mention what the block is about, so I&#8217;ve taken the liberty of filling in the blanks on Google SidewikiLeaks and will update it to include links [...]]]></description>
			<content:encoded><![CDATA[<p style="text-align: left;">Apparently the British press have been barred from publishing any of Tiger Woods&#8217; sex pictures, and the block somehow extends to <a title="No Tiger Woods -------------, ----------------- for Brits" href="http://www.theregister.co.uk/2009/12/12/tiger_woods_accenture_ads/">Internet news sites</a>. They aren&#8217;t even allowed to mention what the block is about, so I&#8217;ve taken the liberty of filling in the blanks on Google SidewikiLeaks and will update it to include links to pictures when they are inevitably released:</p>
<p style="text-align: left;"><a href="http://bitplane.net/wp-content/uploads/2009/12/SideWikiLeaks.png"><img class="aligncenter size-full wp-image-378" title="Google SideWiki Leaks" src="http://bitplane.net/wp-content/uploads/2009/12/SideWikiLeaks.png" alt="Google SideWiki Leaks" width="517" height="246" /></a></p>
<p style="text-align: left;">It makes you glad that America has freedom of the press, even if Britain doesn&#8217;t.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2009/12/more-sidewiki-leaks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Interpolated list class for Python</title>
		<link>http://bitplane.net/2009/12/interpolist/</link>
		<comments>http://bitplane.net/2009/12/interpolist/#comments</comments>
		<pubDate>Sat, 12 Dec 2009 03:25:25 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[python]]></category>
		<category><![CDATA[statistics]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=362</guid>
		<description><![CDATA[While messing with Python to output some better graphs for my Facebook group scraper I stumbled upon an interesting problem. What happens if you have missing samples, or want to change the sampling frequency half way through your log? Well, you could use a proper math library and have extra dependencies or generate the missing [...]]]></description>
			<content:encoded><![CDATA[<p>While messing with Python to output some better graphs for my <a href="http://bitplane.net/2009/12/bash-for-xmas-number-one/">Facebook group scraper</a> I stumbled upon an interesting problem. What happens if you have missing samples, or want to change the sampling frequency half way through your log? Well, you could use a proper math library and have extra dependencies or generate the missing data manually, but the simplest answer I could think of was to write a list class which interpolates between missing values, so you can do something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="python" style="font-family:monospace;"><span style="color: #66cc66;">&gt;&gt;&gt;</span> a = InterpoList<span style="color: black;">&#40;</span><span style="color: black;">&#41;</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: black;">&#91;</span><span style="color: #ff4500;">0</span><span style="color: black;">&#93;</span>   = <span style="color: #ff4500;">0</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: black;">&#91;</span><span style="color: #ff4500;">100</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">200</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: black;">&#91;</span><span style="color: #ff4500;">200</span><span style="color: black;">&#93;</span> = <span style="color: #ff4500;">0</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: black;">&#91;</span><span style="color: #ff4500;">50</span><span style="color: black;">&#93;</span>
<span style="color: #ff4500;">100.0</span>
<span style="color: #66cc66;">&gt;&gt;&gt;</span> a<span style="color: black;">&#91;</span><span style="color: #ff4500;">125</span><span style="color: black;">&#93;</span>
<span style="color: #ff4500;">150.0</span></pre></div></div>

<p>And then store the time values as seconds past the epoch. Now I can inject data from multiple sources taken at different frequencies and retrieve an interpolated value for any time, which means more nice graphs like this:</p>
<p><center><img src="http://chart.apis.google.com/chart?chtt=Members+per+minute&#038;chs=500x150&#038;cht=ls&#038;chxt=x,y&#038;chg=25.000,20&#038;chxl=0:|11:10|12:10|13:10|14:10|15:10|1:|0|25|50|75|100|125&#038;chds=0,125&#038;chd=t:51.20,48.00,48.00,50.60,50.60,57.40,57.40,55.00,55.00,46.00,46.00,49.60,49.60,28.60,28.60,43.80,43.80,45.40,45.40,45.65,45.65,46.50,46.60,50.01,51.20,48.70,46.96,50.25,54.20,55.05,57.00,56.31,52.43,52.43,39.93,39.93,8.80,8.80,14.60,14.60,66.00,66.00,58.80,58.80,50.83,50.83,16.25,16.25,43.26,43.26,60.20,60.20,2.80,2.80,1.71,1.60,5.82,7.18,4.60,2.81,2.62,2.40,2.58,3.00,4.55,13.20,13.20,3.20,3.20,3.60,3.60,7.00,7.00,4.78,4.78,3.61,3.61,8.40,8.40,9.40,9.40,13.40,13.40,20.60,20.60,5.40,5.40,34.13,37.00,11.70,3.60,14.99,22.40,36.77,54.02,52.05,47.16,48.28,54.60,54.60"/></center></p>
<p>As usual I also decided to share it with the Internet, because I&#8217;m nice like that! You can get a copy of the InterpoList module <a href="http://svn.bitplane.net/misc/trunk/py/InterpoList.py">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2009/12/interpolist/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Chart Against The X Factor</title>
		<link>http://bitplane.net/2009/12/bash-for-xmas-number-one/</link>
		<comments>http://bitplane.net/2009/12/bash-for-xmas-number-one/#comments</comments>
		<pubDate>Sun, 06 Dec 2009 22:30:33 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[Music]]></category>
		<category><![CDATA[News]]></category>
		<category><![CDATA[bash]]></category>
		<category><![CDATA[facebook]]></category>
		<category><![CDATA[google charts]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=342</guid>
		<description><![CDATA[For the last four years running Simon Cowell&#8217;s plastic karaoke acts have held the Christmas #1 spot in the UK singles charts thanks to ITV&#8217;s hit show The X Factor. People have been complaining that this has ruined the great British tradition of betting on which artist will take the number one slot, as it&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<p>For the last four years running Simon Cowell&#8217;s plastic karaoke acts have held the Christmas #1 spot in the UK singles charts thanks to ITV&#8217;s hit show <a href="http://xfactor.itv.com/">The X Factor</a>. People have been complaining that this has ruined the great British tradition of betting on which artist will take the number one slot, as it&#8217;s traditionally the only time of year when the chart is dominated by wacky Christmas songs rather than the latest boy bands and whoever else thirteen year old girls spend their pocket money on.</p>
<p>I&#8217;m not too bothered about popular music, the singles chart or who gets the Xmas #1 slot, but last week I was invited to join a growing <a href="http://www.facebook.com/group.php?gid=2228594104">group on Facebook</a> who are campaigning to knock the X Factor winner from the top spot by mass purchasing Rage Against The Machine&#8217;s classic track <a href="http://www.youtube.com/watch?v=fkuOAY-S6OY">Killing in the Name</a>. The sound of rebellion to conquer the airwaves, political rap metal on future Christmas compilation albums, all for the princely sum of 79p? I don&#8217;t usually buy digital downloads but this time you can count me in!</p>
<p>According to <a href="http://news.sky.com/skynews/Home/Showbiz-News/X-Factor-Could-Be-Beaten-To-Christmas-Number-One-By-Anti-Simon-Cowell-Facebook-Campaign/Article/200912115491121">Sky News</a> the group had 43,000 members sometime on Friday, but by the time I got home on Saturday night there were 180,000 members and rising. As the media coverage increases so do the new members, which made me interested: how does a phenomenon like this evolve, how will it turn out next Sunday? What happens when the UK Charts people decide that it&#8217;s against the rules and disqualify the single?</p>
<p>So I decided to log and graph the group&#8217;s membership, every fifteen minutes I grab the page using wget, I extract the number of users and dump that into a text file along with the current date and time. Then I cut through it using a couple of awk and sed one liners, dump the results into an HTML file, graph it using Google Charts and upload the output to my file dump.</p>
<p><strong>Update: These graphs are no longer live! Click for the <a href="http://dump.bitplane.net/ratm/index.html">live versions</a> which are updated much more often using a different script</strong> </p>
<a href="http://dump.bitplane.net/ratm/index.html"><img class="size-full wp-image-345" title="Members" src="http://dump.bitplane.net/ratm/members.png" alt="Click for the source data" width="600" height="300" /></a>
<a href="http://dump.bitplane.net/ratm/index.html"><img class="size-full wp-image-345" title="Members/hr" src="http://dump.bitplane.net/ratm/perhr.png" alt="Members per hour" width="600" height="300" /></a>
<p>Here&#8217;s the scraping script:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #7a0874; font-weight: bold;">cd</span> <span style="color: #000000; font-weight: bold;">/</span>home<span style="color: #000000; font-weight: bold;">/</span>gaz<span style="color: #000000; font-weight: bold;">/</span>ratm<span style="color: #000000; font-weight: bold;">/</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># get the timestamp</span>
<span style="color: #007800;">timestamp</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">date</span> <span style="color: #ff0000;">&quot;+20%y/%m/%d %H:%M:%S&quot;</span><span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># get the file</span>
<span style="color: #c20cb9; font-weight: bold;">wget</span> <span style="color: #660033;">--max-redirect</span> <span style="color: #000000;">2</span> <span style="color: #660033;">-O</span> temp.html http:<span style="color: #000000; font-weight: bold;">//</span>www.facebook.com<span style="color: #000000; font-weight: bold;">/</span>group.php?<span style="color: #007800;">gid</span>=<span style="color: #000000;">2228594104</span> <span style="color: #660033;">--user-agent</span>=<span style="color: #ff0000;">&quot;Mozilla/5.0 (X11; U; Linux i686; en-GB; rv:1.9.1.5) Gecko/20091109 Ubuntu/9.10 (karmic) Firefox/3.5.5&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># extract user count from the file</span>
<span style="color: #007800;">usercount</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-n</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/.* of \(.*\) members.*/\1/p&quot;</span> temp.html<span style="color: #000000; font-weight: bold;">`</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># remove any commas from the string</span>
<span style="color: #007800;">usercount</span>=<span style="color: #800000;">${usercount//[,]/}</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># it must have a length, or it will cause problems when Facebook is having problems!</span>
<span style="color: #666666; font-style: italic;"># in this case, we just give a -1 (not good practice from a stats PoV, but it keeps it simple) </span>
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">${#usercount}</span>&quot;</span> <span style="color: #660033;">-eq</span> <span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #007800;">usercount</span>=<span style="color: #ff0000;">&quot;-1&quot;</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># remove the temporary file</span>
<span style="color: #c20cb9; font-weight: bold;">rm</span> temp.html
&nbsp;
<span style="color: #666666; font-style: italic;"># write the output in CSV format</span>
<span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$timestamp</span>,<span style="color: #007800;">$usercount</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;&gt;</span> data.dat
&nbsp;
<span style="color: #666666; font-style: italic;"># next I run the graph generating script</span></pre></div></div>

<p>And this one (no longer in use) creates the two above charts from the data:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;"><span style="color: #666666; font-style: italic;">#!/bin/bash</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># gets a column from a line of a CSV file. The first index is 1, not 0.</span>
getElement<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #7a0874; font-weight: bold;">&#123;</span>
    <span style="color: #007800;">RESULT</span>=<span style="color: #000000;">0</span>
    <span style="color: #7a0874; font-weight: bold;">local</span> <span style="color: #007800;">p</span>=<span style="color: #000000; font-weight: bold;">`</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;$1&quot;</span>p<span style="color: #000000; font-weight: bold;">`</span>
    <span style="color: #007800;">RESULT</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> $<span style="color: #000000;">2</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #ff0000;">'s/,/\n/g'</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-n</span> <span style="color: #007800;">$p</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #7a0874; font-weight: bold;">&#125;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># get the start and end times</span>
&nbsp;
getElement <span style="color: #000000;">1</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tail -1 data.dat)</span>&quot;</span>
<span style="color: #007800;">end</span>=<span style="color: #007800;">$RESULT</span>
getElement <span style="color: #000000;">1</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(sed -n '1p' data.dat)</span>&quot;</span>
<span style="color: #007800;">start</span>=<span style="color: #007800;">$RESULT</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># get the current minimum and maximum values</span>
<span style="color: #007800;">min</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> minval<span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">max</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">cat</span> maxval<span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># get the last value</span>
getElement <span style="color: #000000;">2</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$(tail -1 data.dat)</span>&quot;</span>
<span style="color: #007800;">lastval</span>=<span style="color: #007800;">$RESULT</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># set new max value</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$lastval</span>&quot;</span> <span style="color: #660033;">-gt</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$max</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$lastval</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> maxval
    <span style="color: #007800;">maxval</span>=<span style="color: #007800;">$lastval</span>
    <span style="color: #7a0874; font-weight: bold;">echo</span> New maximum, <span style="color: #007800;">$lastval</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># and the new min value</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$lastval</span>&quot;</span> <span style="color: #660033;">-gt</span> <span style="color: #000000;">0</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
<span style="color: #000000; font-weight: bold;">then</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$lastval</span>&quot;</span> <span style="color: #660033;">-lt</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$min</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
    <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$lastval</span>&quot;</span> <span style="color: #000000; font-weight: bold;">&gt;</span> minval
        <span style="color: #007800;">min</span>=<span style="color: #007800;">$lastval</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
<span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># get values for the Y axis</span>
<span style="color: #007800;">quart</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$max</span> - <span style="color: #007800;">$min</span><span style="color: #7a0874; font-weight: bold;">&#41;</span> <span style="color: #000000; font-weight: bold;">/</span> <span style="color: #000000;">4</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">q1</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$min</span> + <span style="color: #007800;">$quart</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000;">1</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">q2</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$min</span> + <span style="color: #007800;">$quart</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000;">2</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #007800;">q3</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$min</span> + <span style="color: #007800;">$quart</span> <span style="color: #000000; font-weight: bold;">*</span> <span style="color: #000000;">3</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># extract the data using regexp:</span>
<span style="color: #666666; font-style: italic;"># 1. get every 4th line of the file, meaning hourly</span>
<span style="color: #666666; font-style: italic;"># 2. take all the values from the file</span>
<span style="color: #666666; font-style: italic;"># 3. remove the trailing comma</span>
&nbsp;
<span style="color: #007800;">data</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'NR%4==0'</span> data.dat <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-n</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/.*,\([0-9]*\)/\1/p&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">tr</span> <span style="color: #ff0000;">&quot;<span style="color: #000099; font-weight: bold;">\n</span>&quot;</span> <span style="color: #ff0000;">&quot;,&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/\(.*\),/\1/&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># build the URL to the total members chart</span>
<span style="color: #007800;">total_members</span>=<span style="color: #ff0000;">&quot;http://chart.apis.google.com/chart?chtt=Total+Members&amp;chs=600x300&amp;cht=ls&amp;chxt=x,y&amp;chxl=0:|<span style="color: #007800;">$start</span>|<span style="color: #007800;">$end</span>|1:|<span style="color: #007800;">$min</span>|<span style="color: #007800;">$q1</span>|<span style="color: #007800;">$q2</span>|<span style="color: #007800;">$q3</span>|<span style="color: #007800;">$max</span>&amp;chds=<span style="color: #007800;">$min</span>,<span style="color: #007800;">$max</span>&amp;chd=t:<span style="color: #007800;">$data</span>&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># now let's do members per hour</span>
&nbsp;
<span style="color: #007800;">lastval</span>=<span style="color: #007800;">$min</span>
<span style="color: #007800;">min</span>=<span style="color: #000000;">0</span>
<span style="color: #007800;">max</span>=<span style="color: #000000;">0</span>
<span style="color: #007800;">data</span>=<span style="color: #ff0000;">&quot;&quot;</span>
<span style="color: #007800;">inputList</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #c20cb9; font-weight: bold;">awk</span> <span style="color: #ff0000;">'NR%4==0'</span> data.dat <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-n</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/.*,\([0-9]*\)/\1/p&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
<span style="color: #000000; font-weight: bold;">while</span> <span style="color: #c20cb9; font-weight: bold;">read</span> line; <span style="color: #000000; font-weight: bold;">do</span>
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$line</span>&quot;</span> <span style="color: #660033;">-gt</span> <span style="color: #ff0000;">&quot;0&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
    <span style="color: #000000; font-weight: bold;">then</span> 
        <span style="color: #007800;">val</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #007800;">$line</span> - <span style="color: #007800;">$lastval</span><span style="color: #7a0874; font-weight: bold;">&#41;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
        <span style="color: #007800;">lastval</span>=<span style="color: #007800;">$line</span>
    <span style="color: #000000; font-weight: bold;">else</span>
        <span style="color: #007800;">val</span>=<span style="color: #000000;">0</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
    <span style="color: #000000; font-weight: bold;">if</span> <span style="color: #7a0874; font-weight: bold;">&#91;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$val</span>&quot;</span> <span style="color: #660033;">-gt</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$max</span>&quot;</span> <span style="color: #7a0874; font-weight: bold;">&#93;</span>
    <span style="color: #000000; font-weight: bold;">then</span>
        <span style="color: #007800;">max</span>=<span style="color: #007800;">$val</span>
    <span style="color: #000000; font-weight: bold;">fi</span>
&nbsp;
    <span style="color: #007800;">data</span>=<span style="color: #ff0000;">&quot;<span style="color: #007800;">$data</span>,<span style="color: #007800;">$val</span>&quot;</span>
<span style="color: #000000; font-weight: bold;">done</span> <span style="color: #000000; font-weight: bold;">&lt;&lt;&lt;</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$inputList</span>&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># remove comma prefix</span>
<span style="color: #007800;">data</span>=$<span style="color: #7a0874; font-weight: bold;">&#40;</span><span style="color: #7a0874; font-weight: bold;">echo</span> <span style="color: #ff0000;">&quot;<span style="color: #007800;">$data</span>&quot;</span> <span style="color: #000000; font-weight: bold;">|</span> <span style="color: #c20cb9; font-weight: bold;">sed</span> <span style="color: #660033;">-e</span> <span style="color: #ff0000;">&quot;s/,\(.*\)/\1/g&quot;</span><span style="color: #7a0874; font-weight: bold;">&#41;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># build the per hour chart</span>
<span style="color: #007800;">members_per_hr</span>=<span style="color: #ff0000;">&quot;http://chart.apis.google.com/chart?chtt=Members+per+hr&amp;chs=600x300&amp;cht=ls&amp;chxt=x,y&amp;chxl=0:|<span style="color: #007800;">$start</span>|<span style="color: #007800;">$end</span>|1:|<span style="color: #007800;">$min</span>|<span style="color: #007800;">$max</span>&amp;chds=<span style="color: #007800;">$min</span>,<span style="color: #007800;">$max</span>&amp;chd=t:<span style="color: #007800;">$data</span>&quot;</span>
&nbsp;
<span style="color: #666666; font-style: italic;"># I then create an HTML file from some templates and upload everything to my dump</span></pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2009/12/bash-for-xmas-number-one/feed/</wfw:commentRss>
		<slash:comments>17</slash:comments>
		</item>
		<item>
		<title>LoadRunner Controller &#8211; Invalid Action Window</title>
		<link>http://bitplane.net/2009/11/loadrunner-invalid-action/</link>
		<comments>http://bitplane.net/2009/11/loadrunner-invalid-action/#comments</comments>
		<pubDate>Fri, 27 Nov 2009 16:50:19 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[loadrunner]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=335</guid>
		<description><![CDATA[LoadRunner 9.5&#8217;s VUGen sometimes gets its undergarments in a twist and messes up the actions in one of its INI files. You don&#8217;t notice this until you get the dreaded &#8220;Invalid Action&#8221; error message while running a test, which appears once for each virtual user and prevents other users from loading.
Thankfully, Sameh Abdelhamid found and [...]]]></description>
			<content:encoded><![CDATA[<p>LoadRunner 9.5&#8217;s VUGen sometimes gets its undergarments in a twist and messes up the actions in one of its INI files. You don&#8217;t notice this until you get the dreaded &#8220;Invalid Action&#8221; error message while running a test, which appears once for each virtual user and prevents other users from loading.</p>
<p>Thankfully, <a href="http://mishmashmoo.com/blog/?p=12">Sameh Abdelhamid</a> found and documented a proper fix for this problem:</p>
<blockquote><p>Find a file called default.usp and edit it in your favorite text editor. I use ScITE which comes with ruby. You will notice a parameter called [Profile Actions].<br />
That will list your actions. If you cross check this with the actions in your script you will notice that in my example, I only have 3 actions, whereas, the default.ups has 4.</p></blockquote>
<p>Which is great, but no good for me <em>right now</em> as it started happening half way into a test which I can&#8217;t cancel. If like me, you need that horrible, dirty, reactive solution <em>right now</em>, here&#8217;s a little VB Script to send a Y key to the messagebox every time it appears.</p>

<div class="wp_syntax"><div class="code"><pre class="vbs" style="font-family:monospace;">Dim Wsh
Set Wsh = Wscript.CreateObject(&quot;Wscript.Shell&quot;)
&nbsp;
While True
  If Wsh.AppActivate(&quot;Invalid Action&quot;) Then
    Wsh.SendKeys &quot;y&quot;
    WScript.echo &quot;go away!&quot;
  End if
&nbsp;
  WScript.Sleep 1000
Wend</pre></div></div>

]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2009/11/loadrunner-invalid-action/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Ubuntu 9.10: works for me!</title>
		<link>http://bitplane.net/2009/11/cuddly-karmic-koalas/</link>
		<comments>http://bitplane.net/2009/11/cuddly-karmic-koalas/#comments</comments>
		<pubDate>Sun, 08 Nov 2009 22:07:11 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[News]]></category>
		<category><![CDATA[Ubuntu]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=320</guid>
		<description><![CDATA[I was a bit worried about upgrading to Ubuntu 9.10 after El Reg&#8217;s scare stories claimed that nine out of ten people had problems with the automatic upgrade.
I guess their stats were skewed, nine out of ten people who are complaining on the Ubuntu forums were complaining about the upgrade, which is nothing like nine [...]]]></description>
			<content:encoded><![CDATA[<p>I was a bit worried about upgrading to Ubuntu 9.10 after El Reg&#8217;s <a href="http://www.theregister.co.uk/2009/11/03/karmic_koala_frustration/">scare stories</a> claimed that nine out of ten people had problems with the automatic upgrade.<br />
I guess their stats were skewed, nine out of ten people who are complaining on the Ubuntu forums were complaining about the upgrade, which is nothing like nine in ten people having problems.</p>
<p>Worked fine for me on two different machines, my only problem is that the battery charge profile on my laptop was lost.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2009/11/cuddly-karmic-koalas/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Stripping snapshot files from LoadRunner Citrix scripts</title>
		<link>http://bitplane.net/2009/10/strip-lr-citrix-scripts/</link>
		<comments>http://bitplane.net/2009/10/strip-lr-citrix-scripts/#comments</comments>
		<pubDate>Thu, 29 Oct 2009 02:41:54 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[citrix]]></category>
		<category><![CDATA[loadrunner]]></category>
		<category><![CDATA[performance testing]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=307</guid>
		<description><![CDATA[After several re-records of a Citrix script in LoadRunner, thousands of PNG snapshot files build up in the data dir. Over time they can build up to make your script eat up over a hundred megabytes of disk space, which is a little excessive given that the useful parts are only a few megs in [...]]]></description>
			<content:encoded><![CDATA[<p>After several re-records of a Citrix script in LoadRunner, thousands of PNG snapshot files build up in the data dir. Over time they can build up to make your script eat up over a hundred megabytes of disk space, which is a little excessive given that the useful parts are only a few megs in total.</p>
<p>These snapshots are used to make the script tree-view useful, so you can&#8217;t delete all of them in case you need a reference image when inserting a new sync, keypress or some other event. So, I squirted out this little VB script which will remove unused stuff from the data directory, I&#8217;m sharing it with the Internet because I&#8217;m nice like that.</p>
<p>You can download it <a href="http://svn.bitplane.net/misc/trunk/vbs/strip%20loadrunner%20citrix%20script.vbs">here</a>.</p>
<p>To run it, just copy to the dir which contains your scripts (back them up first, I offer no warranty or compensation in case things go wrong) and click it. Be prepared to wait a long time, enumerating forty thousand bitmaps will always take some time.</p>
<p>When archiving your scripts you might also want to delete any results data, which also costs a few megs.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2009/10/strip-lr-citrix-scripts/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Citrix of the Trade</title>
		<link>http://bitplane.net/2009/10/loadrunner-citrix-tricks/</link>
		<comments>http://bitplane.net/2009/10/loadrunner-citrix-tricks/#comments</comments>
		<pubDate>Fri, 23 Oct 2009 17:29:15 +0000</pubDate>
		<dc:creator>Gaz Davidson</dc:creator>
				<category><![CDATA[Performance]]></category>
		<category><![CDATA[Tutorials]]></category>
		<category><![CDATA[citrix]]></category>
		<category><![CDATA[loadrunner]]></category>
		<category><![CDATA[performance testing]]></category>

		<guid isPermaLink="false">http://bitplane.net/?p=280</guid>
		<description><![CDATA[I&#8217;ve been using LoadRunner for Citrix for about a week now, it&#8217;s a new protocol for me and I guess I&#8217;m starting to get the hang of it because I&#8217;ve created a list of tips and tricks to share with the Internet.
I&#8217;m assuming you&#8217;ve read the other guides, about using the keyboard where possible, making [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using LoadRunner for Citrix for about a week now, it&#8217;s a new protocol for me and I guess I&#8217;m starting to get the hang of it because I&#8217;ve created a list of tips and tricks to share with the Internet.</p>
<p>I&#8217;m assuming you&#8217;ve read the other guides, about using the keyboard where possible, making sure your colour settings and screen sizes are the same on each injector, using bitmap and text checks for synchronization, clicking on menus because mouse movements don&#8217;t work and so on.</p>
<h2>Don&#8217;t trust LoadRunner to get your transactions right</h2>
<p>As of version 9.5, LoadRunner records Citrix scripts which look like this:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">lr_start_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Receive bacon&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctrx_sync_window<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Bacon dispenser&quot;</span><span style="color: #339933;">,</span> ACTIVE<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> etc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// push button</span>
ctrx_mouse_click<span style="color: #009900;">&#40;</span> <span style="color: #0000dd;">50</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">50</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> CTRX_LAST<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lr_end_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Receive bacon&quot;</span><span style="color: #339933;">,</span> LR_AUTO<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
lr_start_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Enjoy bacon&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctrx_sync_window<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Bacon&quot;</span><span style="color: #339933;">,</span> ACTIVE<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> etc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>In this case, at recording we put transactions around the time taken to push the button and get some bacon, not how long it takes to focus the bacon dispenser and then push the button. A transaction is all about timing something, which means you do something and then wait for a response; a transaction should <strong>never</strong> <em>start</em> with a sync and should almost always end with one. So, we need to edit the <em>Receive bacon</em> transaction to look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">lr_start_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Receive bacon&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// push button</span>
ctrx_mouse_click<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">50</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">50</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> CTRX_LAST<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctrx_sync_window<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Bacon&quot;</span><span style="color: #339933;">,</span> ACTIVE<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> etc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lr_end_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Receive bacon&quot;</span><span style="color: #339933;">,</span> LR_AUTO<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<h2>Don&#8217;t trust LoadRunner to insert think-times of the correct length, nor in the correct places.</h2>
<p>This one is an even more painful schoolboy error, let&#8217;s use the <a href="http://gallery.bitplane.net/v/misc/junk/push_button_receive_bacon_enjoy_bacon.jpg.html">bacon meme</a> as an example again and a more realistic recording including recorded thinking time, LR would generate something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">lr_start_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Receive bacon&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctrx_sync_window<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Bacon dispenser&quot;</span><span style="color: #339933;">,</span> ACTIVE<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> etc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// push button</span>
ctrx_mouse_click<span style="color: #009900;">&#40;</span> <span style="color: #0000dd;">50</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">50</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> CTRX_LAST<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lr_think_time<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">15</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lr_end_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Receive bacon&quot;</span><span style="color: #339933;">,</span> LR_AUTO<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
lr_start_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Enjoy bacon&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctrx_sync_window<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Bacon&quot;</span><span style="color: #339933;">,</span> ACTIVE<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> etc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Did you spot it? Firstly the think time is incredibly large because LoadRunner&#8217;s Citrix client recorder is obscenely slow, so you&#8217;ll have to adjust the value to the amount of time the user would actually spend marvelling at their delicious bacon before eating it. This would be far less than 15 seconds. Let&#8217;s also apply the fix from above:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;">lr_start_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Receive bacon&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
<span style="color: #666666; font-style: italic;">// push button</span>
ctrx_mouse_click<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">50</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">50</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">0</span><span style="color: #339933;">,</span> CTRX_LAST<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lr_think_time<span style="color: #009900;">&#40;</span><span style="color: #0000dd;">3</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
ctrx_sync_window<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Bacon&quot;</span><span style="color: #339933;">,</span> ACTIVE<span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">100</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> <span style="color: #0000dd;">200</span><span style="color: #339933;">,</span> etc<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
lr_end_transaction<span style="color: #009900;">&#40;</span><span style="color: #ff0000;">&quot;Receive bacon&quot;</span><span style="color: #339933;">,</span> LR_AUTO<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span></pre></div></div>

<p>Now the glaring error becomes obvious: The think-time and the sync are the wrong way around! If you don&#8217;t strip think times from the results, you can only report on timings of 3 seconds and over. That&#8217;s just sloppy, but much worse than that, if you do strip the think time then you&#8217;ll report timings 3 seconds <em>shorter</em> than the system actually takes to respond:</p>
<p><img class="aligncenter" title="Lern 2 measurement" src="http://gallery.bitplane.net/d/714-1/lr+citrix+record.png" alt="" width="404" height="160" /><br />
Yeah that means that if your scripters don&#8217;t know what they&#8217;re doing then you run the risk of reporting great timings for an abysmally slow system. So <acronym title="Service Level Agreements">SLA</acronym>s aren&#8217;t met, your company receives huge fines, or in the case of the system I&#8217;m working on lives may even be lost.</p>
<h2>Ignore the replay guidelines published by Citrix.</h2>
<p>Do not replay think-time when debugging scripts, this will force you to write robust scripts that measure rather than relying on the system response times. You won&#8217;t be tempted to resort to extending the think-times to fudge synchronisation when you get a huge number of users running.</p>
<h2>When you can&#8217;t trust a bitmap, cheat with events</h2>
<p>Sometimes you can&#8217;t trust a bitmap synchronization because the application has painted, but is still processing and will not respond to mouse input. Keyboard input isn&#8217;t so much of a problem as it will queue up, but mouse events may be discarded. Thankfully we know that <acronym title="Microsoft Foundation Classes">MFC</acronym>, <acronym title="Microsoft Visual Basic">VB</acronym> and Java applications are event driven. This means we can use bitmaps synchronizations on things triggered by mouse movement and hover events, then do a click after that.</p>
<p>For example, move the mouse back and forth across a toolbar button, wait for a short period of time (use sleep(), not think time!), then do a check (not a sync) on the bevel which is drawn around it. The same applies to other mouse-over events, if it can take a mouse-over it can probably take a click event. Unfortunately <acronym title="LoadRunner">LR</acronym> can&#8217;t detect mouse cursor changes, which would be a great tool for this purpose.</p>
<p>Another similar idea is to use the text buffer; input a character or set the focus with the tab key, then wait for the change in state.</p>
<h2>You can&#8217;t sync on a context menu</h2>
<p>They don&#8217;t have a name so they get an obscure number at record time, which cannot be found at playback. Use bitmap checks on the screen area for these instead. Of course, you should really be using the keyboard where possible, but this isn&#8217;t always possible (accessawhatability?)</p>
<h2>The pixel-sync trick</h2>
<p>Record a 3&#215;3 pixel bitmap check for white, grey and declare or #define them as functions like so:</p>

<div class="wp_syntax"><div class="code"><pre class="c" style="font-family:monospace;"><span style="color: #339933;">#define Sync3x3(x,y,hash) ctrx_sync_on_bitmap(x, y, 3, 3, hash, CTRX_LAST)</span>
<span style="color: #339933;">#define WHITE(x,y) Sync3x3(x,y,&quot;794f0585be94ed32b0fe3d42f8917eea&quot;)</span>
<span style="color: #339933;">#define GREY(x,y) Sync3x3(x,y,&quot;2e32a138b3fee935c6efabeb24c05733&quot;)</span>
<span style="color: #339933;">#define BLUE(x,y) Sync3x3(x,y,&quot;7c7ebab71cd7ebeab3f0aa710501fa07&quot;)</span></pre></div></div>

<p>Then, providing you&#8217;ve been a good boy and remembered to maximize your window before recording, you can avoid re-recording when you need a new sync point. Just insert an object click via the GUI tree-view and replace it with one of the macros above in the code. Please note, your grey colour may be different to mine, it&#8217;s best to record your own pixels. Also don&#8217;t bother with a 1&#215;1 pixel, LoadRunner always fails those checks. (I didn&#8217;t try a 2&#215;2 check)</p>
<h2>Remove those rogue mouse-up events</h2>
<p>After drawing the rectangle for a bitmap or text synchronization point, you&#8217;ll often get a rogue mouse-up event. Remove those, they&#8217;re a confusing waste of processing time and won&#8217;t happen in the real world.</p>
<h2>Conclusion</h2>
<p>The industry standard load testing tool is simple enough for trained monkeys to use, but its default Citrix settings suck to the point of being dangerous. Handle with care!</p>
<p>That&#8217;s all I&#8217;ve learned this week, hopefully it&#8217;s enough for me me to help deliver this project on time. Expect more similar rants and tips over the coming months.</p>
]]></content:encoded>
			<wfw:commentRss>http://bitplane.net/2009/10/loadrunner-citrix-tricks/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
