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

<channel>
	<title>Altentee &#187; Performance &#38; Test Automation Experts &#187; ruby</title>
	<atom:link href="http://altentee.com/tag/ruby/feed/" rel="self" type="application/rss+xml" />
	<link>http://altentee.com</link>
	<description>Performance and Test Automation Experts</description>
	<lastBuildDate>Sat, 12 Jun 2010 00:35:08 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>A Framework for JMeter using GitHub and Ruby</title>
		<link>http://altentee.com/2009/a-framework-for-jmeter-using-github-and-ruby/</link>
		<comments>http://altentee.com/2009/a-framework-for-jmeter-using-github-and-ruby/#comments</comments>
		<pubDate>Fri, 18 Sep 2009 04:44:05 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[jmeter]]></category>
		<category><![CDATA[ruby]]></category>

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

		<guid isPermaLink="false">http://90kts.com/blog/2009/a-script-to-remotely-parse-a-gc-log/</guid>
		<description><![CDATA[<p>Here&#8217;s a simple Ruby script that will parse a remote GC log using Perl for specific date time entries. The scenario in which you might use this script is where you have rather large remote GC logs sitting on another platform like AIX that doesn&#8217;t have Ruby installed. It&#8217;s useful in the sense you can [...]]]></description>
			<content:encoded><![CDATA[<p>Here&#8217;s a simple Ruby script that will parse a remote GC log using Perl for specific date time entries. The scenario in which you might use this script is where you have rather large remote GC logs sitting on another platform like AIX that doesn&#8217;t have Ruby installed. It&#8217;s useful in the sense you can execute a load test, then just parse the GC log for the entries from the native_stderr.log that represent your test run. YMMV.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#008000; font-style:italic;"># notes: make sure you escape slashes and quotes in the regex</span>
<span style="color:#008000; font-style:italic;"># libs:  you will need to install SSH libraries for Ruby from DOS</span>
<span style="color:#008000; font-style:italic;"># set HTTP_PROXY=http://username:password@proxy.local:80</span>
<span style="color:#008000; font-style:italic;"># gem install net-ssh</span>
<span style="color:#008000; font-style:italic;"># gem install net-sftp</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/ssh'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'net/sftp'</span>
&nbsp;
<span style="color:#0066ff; font-weight:bold;">@HOST</span>  = <span style="color:#996600;">&quot;remote.host&quot;</span>
<span style="color:#0066ff; font-weight:bold;">@USER</span>  = <span style="color:#996600;">&quot;username&quot;</span>
<span style="color:#0066ff; font-weight:bold;">@PASS</span>  = <span style="color:#996600;">&quot;********&quot;</span>
<span style="color:#0066ff; font-weight:bold;">@PATH</span>  =
<span style="color:#996600;">&quot;/opt/websphere/portalserver/6.0/portalserver/native_stderr.log&quot;</span>
<span style="color:#0066ff; font-weight:bold;">@SDATE</span> = <span style="color:#996600;">&quot;Aug 11 10:0<span style="color:#000099;">\\</span>d+&quot;</span>
<span style="color:#0066ff; font-weight:bold;">@EDATE</span> = <span style="color:#996600;">&quot;Aug 11 11:0<span style="color:#000099;">\\</span>d+&quot;</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">Net::SSH</span>.<span style="color:#9900CC;">start</span><span style="color:#006600; font-weight:bold;">&#40;</span>@HOST, <span style="color:#0066ff; font-weight:bold;">@USER</span>, <span style="color:#ff3333; font-weight:bold;">:password</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@PASS</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>ssh<span style="color:#006600; font-weight:bold;">|</span>
   <span style="color:#008000; font-style:italic;"># parse log</span>
   ssh.<span style="color:#CC0066; font-weight:bold;">exec</span> <span style="color:#996600;">&quot;perl -e '
   open(I, <span style="color:#000099;">\&quot;</span>&lt; #{@PATH}<span style="color:#000099;">\&quot;</span>);
   open(O, <span style="color:#000099;">\&quot;</span>&gt; /tmp/native_stderr.log<span style="color:#000099;">\&quot;</span>);
   while(&lt;i&gt;) {
    $found = 1 if /#{@SDATE}/;
    $found = 0 if /#{@EDATE}/;
    print O $_ if $found &gt; 0;
   }
   close(I);
   close(O)'&quot;</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#6666ff; font-weight:bold;">Net::SFTP</span>.<span style="color:#9900CC;">start</span><span style="color:#006600; font-weight:bold;">&#40;</span>@HOST, <span style="color:#0066ff; font-weight:bold;">@USER</span>, <span style="color:#ff3333; font-weight:bold;">:password</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0066ff; font-weight:bold;">@PASS</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>sftp<span style="color:#006600; font-weight:bold;">|</span>
  <span style="color:#008000; font-style:italic;"># download the truncated log</span>
   sftp.<span style="color:#9900CC;">download</span>!<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;/tmp/native_stderr.log&quot;</span>, <span style="color:#996600;">&quot;C:/native_stderr.log&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2009/a-script-to-remotely-parse-a-gc-log/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Establishing Mysql DB Connectivity from Ruby</title>
		<link>http://altentee.com/2008/establishing-mysql-db-connectivity-from-ruby/</link>
		<comments>http://altentee.com/2008/establishing-mysql-db-connectivity-from-ruby/#comments</comments>
		<pubDate>Thu, 03 Jul 2008 01:27:49 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[ruby]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/establishing-mysql-db-connectivity-from-ruby/</guid>
		<description><![CDATA[<p>If you are a rails fan you will probably recommend using active record instead, but if you just want to hack away at your mysql db from within your Ruby code, you may find this handy&#8230;</p>
<p>I&#8217;m currently using a wamp box to serve up content for performance metrics. What I needed was a Ruby script [...]]]></description>
			<content:encoded><![CDATA[<p>If you are a rails fan you will probably recommend using active record instead, but if you just want to hack away at your mysql db from within your Ruby code, you may find this handy&#8230;</p>
<p>I&#8217;m currently using a <strong><a href="http://en.wikipedia.org/wiki/WAMP">wamp</a></strong> box to serve up content for performance metrics. What I needed was a Ruby script which could interrogate data on this installation.</p>
<p>You can download the binary required for this from <a href="http://rubyforge.org/projects/mysql-win">here</a>. After you install the gem (I do this off-line as my command prompt doesn&#8217;t allow me internet access here at work) you may find that you get an error similar to the following:<br />
<code>"NameError: uninitialized constant Mysql"</code></p>
<p>See what&#8217;s happening?<br />
<span id="more-166"></span><br />
To find out what&#8217;s happening, you can jump into an irb terminal and type the following:<br />
<code>irb(main):002:0> require 'mysql'</code></p>
<p>When you do you will probably get a popup dialog like this:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/07/error_dll.jpg' title='error dll mysql'><img src='http://90kts.com/blog/wp-content/uploads/2008/07/error_dll.jpg' alt='error dll mysql' /></a></p>
<p>Basically if you read the README that comes with the gem you will notice:</p>
<blockquote><p> Dependencies &#8230;<br />
For this to work, you must have libmysql.dll in your PATH environmental variable. If you have MySQL installed locally, just make sure that <mysql_install_dir>\bin is in your path. If you don&#8217;t have MySQL installed locally, you can install one or more of the MySQL tools, find the libmysql.dll included in their bin directory, and copy it to the %SystemRoot%\System32 folder.</p></blockquote>
<p>So all you need to do is find out where your <strong>libmysql.dll</strong> lives:<br />
<code>D:\wamp>dir /b /s LIBMYSQL.dll<br />
D:\wamp\bin\apache\apache2.2.8\bin\libmysql.dll<br />
D:\wamp\bin\mysql\mysql5.0.51a\bin\libmySQL.dll<br />
D:\wamp\bin\php\php5.2.5\libmysql.dll</code></p>
<p>And then add that bin directory to your environment path:<br />
<code>D:\wamp\bin\mysql\mysql5.0.51a\bin</code></p>
<p>Hope that saves some of you some time in getting connectivity on your windows boxes!<br />
Attached below is some sample code to test your config.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'mysql'</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">def</span> with_db
    dbh = Mysql.<span style="color:#9900CC;">real_connect</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'localhost'</span>, <span style="color:#996600;">'myuser'</span>, <span style="color:#996600;">'mypass'</span>, <span style="color:#996600;">'mydb'</span>, <span style="color:#006666;">3306</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    <span style="color:#9966CC; font-weight:bold;">begin</span>
        <span style="color:#9966CC; font-weight:bold;">yield</span> dbh
    <span style="color:#9966CC; font-weight:bold;">ensure</span>
        dbh.<span style="color:#9900CC;">close</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
with_db <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>db<span style="color:#006600; font-weight:bold;">|</span>
    res = db.<span style="color:#9900CC;">query</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">'select * from tablename'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    res.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>row<span style="color:#006600; font-weight:bold;">|</span>
        <span style="color:#CC0066; font-weight:bold;">puts</span> row<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006666;">1</span><span style="color:#006600; font-weight:bold;">&#93;</span>
    <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/establishing-mysql-db-connectivity-from-ruby/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Monitoring Weblogic 9.2 with JMX and JRuby</title>
		<link>http://altentee.com/2008/monitoring-weblogic-92-with-jmx-and-jruby/</link>
		<comments>http://altentee.com/2008/monitoring-weblogic-92-with-jmx-and-jruby/#comments</comments>
		<pubDate>Thu, 17 Apr 2008 00:23:53 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[JMX]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[weblogic]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/monitoring-weblogic-92-with-jmx-and-jruby/</guid>
		<description><![CDATA[<p>After getting nowhere with lack luster HP support, I turned to the power of the Open Source community and got a very simple script up and running to remotely monitor Weblogic JVM Performance and JMS queues using JMX and JRuby.</p>
<p>Despite having some initial issues with the code, the author of the jmx4r module turned around [...]]]></description>
			<content:encoded><![CDATA[<p>After getting nowhere with <a href="http://www.sqaforums.com/showthreaded.php?Number=468372">lack luster HP support</a>, I turned to the power of the Open Source community and got a very simple script up and running to remotely monitor Weblogic JVM Performance and JMS queues using JMX and <a href="http://jruby.codehaus.org/Getting+Started">JRuby</a>.</p>
<p>Despite having some initial issues with the code, the author of the <a href="http://jmesnil.net/weblog/2007/06/11/jmx4r-a-jmx-libary-for-jruby/">jmx4r module</a> turned around a fix inside 24 hours so that I could connect to a Weblogic 9.2 server and look at its <a href="http://edocs.bea.com/wls/docs92/wlsmbeanref/core/index.html">domainruntime MBean</a>s. SiteScope can&#8217;t handle domainruntimes of these size (short of being told to &#8216;add more memory&#8217; to a 3GB+ machine!). So exit stage left Mercury, enter stage right JRuby&#8230;<br />
<span id="more-133"></span></p>
<p>This script will enumerate JVM performance and also JMS queue depths in around 65 lines of code and spits those results into a MySQL database using the mysqlimport CLI.<br />
I&#8217;ve <a href="http://90kts.com/blog/2008/formatting-data-for-import-into-loadrunner-analysis/">formatted the output</a> so I can still input the data into LoadRunner Analysis.</p>

<div class="wp_syntax"><table><tr><td class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
</pre></td><td class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'rubygems'</span>
<span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#996600;">'jmx4r'</span>
groupid = <span style="color:#996600;">&quot;mycluster&quot;</span>
<span style="color:#6666ff; font-weight:bold;">JMX::MBean</span>.<span style="color:#9900CC;">establish_connection</span> <span style="color:#ff3333; font-weight:bold;">:url</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;service:jmx:rmi:///jndi/iiop://hostname:7001/weblogic.management.mbeanservers.domainruntime&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:username</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;username&quot;</span>, <span style="color:#ff3333; font-weight:bold;">:password</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#996600;">&quot;password&quot;</span>
&nbsp;
<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">'D:<span style="color:#000099;">\p</span>erf_jvm.csv'</span>, <span style="color:#996600;">'a'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span>
   runtime_mbeans = <span style="color:#6666ff; font-weight:bold;">JMX::MBean</span>.<span style="color:#9900CC;">find_all_by_name</span> <span style="color:#996600;">&quot;com.bea:Type=JRockitRuntime,*&quot;</span>
   runtime_mbeans.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span> mbean <span style="color:#006600; font-weight:bold;">|</span>
		now  = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
		date = <span style="color:#996600;">&quot;#{now.year}-#{now.month}-#{now.day}&quot;</span>
		time = <span style="color:#996600;">&quot;#{now.hour}:#{now.min}:#{now.sec}&quot;</span>
&nbsp;
		data  = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
		<span style="color:#9966CC; font-weight:bold;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span>mbean.<span style="color:#9900CC;">object_name</span>.<span style="color:#9900CC;">get_key_property</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Name&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> =~ <span style="color:#006600; font-weight:bold;">/</span>server<span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">then</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;&quot;</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> date
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> time
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> groupid
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">object_name</span>.<span style="color:#9900CC;">get_key_property</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Name&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">used_physical_memory</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">heap_size_max</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">free_physical_memory</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">total_garbage_collection_time</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">total_garbage_collection_count</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">total_nursery_size</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">heap_free_percent</span>
			file.<span style="color:#CC0066; font-weight:bold;">puts</span> data.<span style="color:#9900CC;">compact</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;, &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
cmd = <span style="color:#996600;">'D:<span style="color:#000099;">\\</span>wamp<span style="color:#000099;">\\</span>bin<span style="color:#000099;">\\</span>mysql<span style="color:#000099;">\\</span>mysql5.0.51a<span style="color:#000099;">\\</span>bin<span style="color:#000099;">\\</span>mysqlimport -h localhost -P 3390 -s -u root --fields-optionally-enclosed-by=&quot;&quot;&quot; --fields-terminated-by=, --lines-terminated-by=&quot;<span style="color:#000099;">\n</span>&quot; --local sensis D:<span style="color:#000099;">\p</span>erf_jvm.csv'</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">%</span>x<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#008000; font-style:italic;">#{cmd}}</span>
cmd = <span style="color:#996600;">'cat D:<span style="color:#000099;">\p</span>erf_jvm.csv &gt;&gt; D:<span style="color:#000099;">\p</span>erf_jvm_archive.csv'</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">%</span>x<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#008000; font-style:italic;">#{cmd}}</span>
<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">delete</span> <span style="color:#996600;">'D:<span style="color:#000099;">\p</span>erf_jvm.csv'</span>
&nbsp;
&nbsp;
<span style="color:#CC0066; font-weight:bold;">open</span><span style="color:#006600; font-weight:bold;">&#40;</span> <span style="color:#996600;">'D:<span style="color:#000099;">\p</span>erf_queues.csv'</span>, <span style="color:#996600;">'a'</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>file<span style="color:#006600; font-weight:bold;">|</span>
   runtime_mbeans = <span style="color:#6666ff; font-weight:bold;">JMX::MBean</span>.<span style="color:#9900CC;">find_all_by_name</span> <span style="color:#996600;">&quot;com.bea:Type=JMSDestinationRuntime,*&quot;</span>
   runtime_mbeans.<span style="color:#9900CC;">each</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span> mbean <span style="color:#006600; font-weight:bold;">|</span>
		now  = <span style="color:#CC00FF; font-weight:bold;">Time</span>.<span style="color:#9900CC;">now</span>
		date = <span style="color:#996600;">&quot;#{now.year}-#{now.month}-#{now.day}&quot;</span>
		time = <span style="color:#996600;">&quot;#{now.hour}:#{now.min}:#{now.sec}&quot;</span>
&nbsp;
		data  = <span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span>
		<span style="color:#9966CC; font-weight:bold;">if</span><span style="color:#006600; font-weight:bold;">&#40;</span>mbean.<span style="color:#9900CC;">object_name</span>.<span style="color:#9900CC;">get_key_property</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Name&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span> =~ <span style="color:#006600; font-weight:bold;">/</span><span style="color:#9966CC; font-weight:bold;">Module</span><span style="color:#006600; font-weight:bold;">/</span><span style="color:#006600; font-weight:bold;">&#41;</span> <span style="color:#9966CC; font-weight:bold;">then</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> <span style="color:#996600;">&quot;&quot;</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> date
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> time
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> groupid
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">object_name</span>.<span style="color:#9900CC;">get_key_property</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;Name&quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">messages_received_count</span>
			data <span style="color:#006600; font-weight:bold;">&lt;&lt;</span> mbean.<span style="color:#9900CC;">messages_high_count</span>
			file.<span style="color:#CC0066; font-weight:bold;">puts</span> data.<span style="color:#9900CC;">compact</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#996600;">&quot;, &quot;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
		<span style="color:#9966CC; font-weight:bold;">end</span>
   <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
cmd = <span style="color:#996600;">'D:<span style="color:#000099;">\\</span>wamp<span style="color:#000099;">\\</span>bin<span style="color:#000099;">\\</span>mysql<span style="color:#000099;">\\</span>mysql5.0.51a<span style="color:#000099;">\\</span>bin<span style="color:#000099;">\\</span>mysqlimport -h localhost -P 3390 -s -u root --fields-optionally-enclosed-by=&quot;&quot;&quot; --fields-terminated-by=, --lines-terminated-by=&quot;<span style="color:#000099;">\n</span>&quot; --local sensis D:<span style="color:#000099;">\p</span>erf_queues.csv'</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">%</span>x<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#008000; font-style:italic;">#{cmd}}</span>
cmd = <span style="color:#996600;">'cat D:<span style="color:#000099;">\p</span>erf_queues.csv &gt;&gt; D:<span style="color:#000099;">\p</span>erf_queues_archive.csv'</span>
<span style="color:#CC0066; font-weight:bold;">puts</span> <span style="color:#006600; font-weight:bold;">%</span>x<span style="color:#006600; font-weight:bold;">&#123;</span><span style="color:#008000; font-style:italic;">#{cmd}}</span>
<span style="color:#CC0066; font-weight:bold;">sleep</span> <span style="color:#006666;">10</span>
<span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">delete</span> <span style="color:#996600;">'D:<span style="color:#000099;">\p</span>erf_queues.csv'</span></pre></td></tr></table></div>

]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/monitoring-weblogic-92-with-jmx-and-jruby/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Monitoring Typical User Transactions with Ruby and SiteScope</title>
		<link>http://altentee.com/2008/monitoring-typical-user-transactions-with-ruby-and-sitescope/</link>
		<comments>http://altentee.com/2008/monitoring-typical-user-transactions-with-ruby-and-sitescope/#comments</comments>
		<pubDate>Thu, 21 Feb 2008 00:26:30 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[90kts]]></category>
		<category><![CDATA[Altentee]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[sitescope]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2008/monitoring-typical-user-transactions-with-ruby-and-sitescope/</guid>
		<description><![CDATA[<p>A colleague asked me the other day if it was possible to setup a workstation with just LoadRunner installed and have it automatically carry out a typical user transaction to determine the &#8216;health&#8217; of the target server. After explaining to him that it would be a clunky approach at best, and currently lacking an installation [...]]]></description>
			<content:encoded><![CDATA[<p>A colleague asked me the other day if it was possible to setup a workstation with just LoadRunner installed and have it automatically carry out a typical user transaction to determine the &#8216;health&#8217; of the target server. After explaining to him that it would be a clunky approach at best, and currently lacking an installation of HP&#8217;s Business Availability Center which could achieve such a thing (Bah, humbug to that) I suggested we write a simple Ruby script, using the &#8216;watir&#8217; gem which can be periodically called by the existing SiteScope installation.</p>
<p>If you didn&#8217;t have SiteScope installed, you could just as easily run this script as a scheduled task within Windows or via cron within a Unix environment, no sweat &#8230;<br />
<span id="more-116"></span></p>
<p><a href="http://wiki.openqa.org/display/WTR/">Watir </a>(pronounced &#8216;water&#8217;) stands for Web Application Testing In Ruby and IMHO it really is starting to kick the pants off heavily licensed tools such as Quick Test Pro. I mean, if you&#8217;re only testing web apps, then why fork out $$$ for licenses? Just pay some decent money for someone to write you a script &#8230; </end soapbox> <img src='http://altentee.com/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>But anyway, a simple Ruby script that uses watir looks like this:<br />
<code><br />
require 'watir'<br />
include Watir<br />
require 'test/unit'</p>
<p>class CustomerSearch < Test::Unit::TestCase</p>
<p>  def test_search<br />
    ie = IE.new<br />
    ie.goto("https://targetwebsite.com.au")</p>
<p>    # Login<br />
    ie.frame(:name, "WORK_SPACE").text_field(:name, "inf_user").set<br />
    ("foxmulder")<br />
    ie.frame(:name, "WORK_SPACE").text_field(:name, "inf_password").set<br />
    ("scully")<br />
    ie.frame(:name, "WORK_SPACE").button(:value, "Submit").click</p>
<p>    # Work Mode<br />
    ie.frame(:name, "WORK_SPACE").select_list(:name, "mode").set<br />
    ("Some Drop Down Menu")<br />
    ie.frame(:name, "WORK_SPACE").button(:name, "submit_button").click</p>
<p>    #Product Search<br />
    ie.frame(:name, "WORK_SPACE").text_field(:name, "NUM_advertiserId").set<br />
    ("123456789")<br />
    ie.frame(:name, "WORK_SPACE").button(:name, "submit_button").click</p>
<p>    #p ie.frame(:name, "WORK_SPACE").text<br />
    assert(ie.frame(:name, "WORK_SPACE").text.include?<br />
    ("Queried by: Advertiser ID: 123456789"))<br />
  end<br />
end<br />
</code></p>
<p>As you can probably read from above, this script logs into a target website, provides user credentials, searches for a product ID then checks (with an assert statement) that some form of expected text exists in the result.</p>
<p>If you ran this script from the command line with<br />
<code>ruby myScript.rb</code></p>
<p>You would see ruby fire up an actual Internet Explorer browser and drive the screen, just like you're probably familiar with in Quick Test Pro.</p>
<p>If you drive it with the -b parameter, it will hide the browser which is what I recommend.</p>
<p>Now to get it running in SiteScope, you just need to add a custom script monitor. I wrote a simple batch file and placed it in the <code><installdir>/scripts</code> directory of the SiteScope server (so that it appears in the drop down list when adding a script monitor). The batch file looked like this:</p>
<p><code><br />
echo ##### ruby_myScript.bat called ##########<br />
ruby "D:\SiteScope\scripts\myScript.rb" -b &#038;&#038; exit 0 || exit 1<br />
</code></p>
<p>The reason I do that is so that I can exit with the appropriate return code. That way, if any of the test components/assertions inside the Ruby script don't pass, they will pass on an exit code of 1 to the batch file, which then feeds that info back to SiteScope so that you get a little red traffic light for script failures.</p>
<p>The script monitor properties in SiteScope ends up looking like this:<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/02/sitescopesetup.jpg' title='Site Scope Setup'><img src='http://90kts.com/blog/wp-content/uploads/2008/02/sitescopesetup.jpg' alt='Site Scope Setup' /></a></p>
<p>The dashboard will end up looking like this (I've demostrated an error, note how it also shows you the script round trip which also equates to the time that it takes for the end-to-end transaction to take place including launching the broswer)<br />
<a href='http://90kts.com/blog/wp-content/uploads/2008/02/sitescopeerror.jpg' title='Site Scope Error'><img src='http://90kts.com/blog/wp-content/uploads/2008/02/sitescopeerror.jpg' alt='Site Scope Error' /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2008/monitoring-typical-user-transactions-with-ruby-and-sitescope/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Custom TextMate commands for ruby and scp</title>
		<link>http://altentee.com/2007/custom-textmate-commands-for-ruby-and-scp/</link>
		<comments>http://altentee.com/2007/custom-textmate-commands-for-ruby-and-scp/#comments</comments>
		<pubDate>Mon, 01 Oct 2007 02:49:19 +0000</pubDate>
		<dc:creator>Tim Koopmans</dc:creator>
				<category><![CDATA[Altentee]]></category>
		<category><![CDATA[ruby]]></category>
		<category><![CDATA[tools]]></category>

		<guid isPermaLink="false">http://90kts.com/blog/2007/custom-textmate-commands-for-ruby-and-scp/</guid>
		<description><![CDATA[<p>If you&#8217;re a Mac user and you&#8217;re not using TextMate, then hurry up and join the bandwagon. This is a powerful text editor for Mac OSX, which I use for just about any type of project be it C#, Java, PHP, Perl or even COBOL. What makes this tool so powerful is your ability to [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re a Mac user and you&#8217;re not using <a href="http://macromates.com/">TextMate</a>, then hurry up and join the bandwagon. This is a powerful text editor for Mac OSX, which I use for just about any type of project be it C#, Java, PHP, Perl or even COBOL. What makes this tool so powerful is your ability to customize it to your heart&#8217;s content.</p>
<p>Take for example the following scenario. I use this editor to code from my sandbox, and use custom bundles to maintain versioning with my CVS server. Most bundles are a command click away, say for example, I need to add a file to the repository, I just hit Ctrl-Shift-Z and I&#8217;m presented with a CVS specific dialog.</p>
<p><span id="more-74"></span><br />
You can also add your own custom commands to the bundles, building on what others in the community have already published. I think this is what makes the tool so powerful! The fact that thousands out there in the development community are adding customizations to TextMate regularly makes this an extremely useful and up to date tool.</p>
<p>I found when editing project files I wanted to be able to scp the current file being worked on up to my development server. To do this, I just added a custom command that invokes some ruby to do the dirty work for me, without ever having to open up a console to do it.</p>
<p><code>"${TM_RUBY:-ruby}" -r "$TM_SUPPORT_PATH/lib/shelltokenize.rb" <<end<br />
  scp_user = ENV['SCP_USER'] || "tim.koopmans"<br />
  scp_port = ENV['SCP_PORT'] || "1234"<br />
  scp_host = ENV['SCP_HOST'] || "10.1.2.3"<br />
  scp_path = ENV['SCP_PATH'] || "/path/to/remote/files"<br />
  TextMate.selected_paths_array.each do |path|<br />
    puts %x{scp -P #{scp_port} "#{File.dirname path}/#{File.basename path}" #{scp_user}@#{scp_host}:#{scp_path}/#{File.basename path} &#038;&#038; echo Finished secure copy! || Problems encountered!}<br />
  end<br />
END</code></p>
<p>The above code simply populates some variables (after first checking for TextMate environment variables, if not exist then populate with defaults in the script), then uses a ruby puts command to scp the file being worked on up to the development server. I'm using ssh key pairs here, so I don't require password authentication. Link that command to a key equivalent e.g. Ctl-Shift-^ and now I'm just a key combo away from synchronizing files on the remote server. What an awesome program ... <img src='http://altentee.com/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://altentee.com/2007/custom-textmate-commands-for-ruby-and-scp/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>
