<?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>Brickyard Blog</title>
	<atom:link href="http://www.brickyardtech.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.brickyardtech.com/blog</link>
	<description></description>
	<lastBuildDate>Thu, 09 Feb 2012 22:07:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>CAS, Grails, and custom attributes</title>
		<link>http://www.brickyardtech.com/blog/2012/02/cas-grails-and-custom-attributes/</link>
		<comments>http://www.brickyardtech.com/blog/2012/02/cas-grails-and-custom-attributes/#comments</comments>
		<pubDate>Thu, 09 Feb 2012 22:02:01 +0000</pubDate>
		<dc:creator>Andy Hawkes</dc:creator>
				<category><![CDATA[Grails]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[attributes]]></category>
		<category><![CDATA[cas]]></category>
		<category><![CDATA[grails]]></category>
		<category><![CDATA[jasig]]></category>
		<category><![CDATA[spring-security]]></category>

		<guid isPermaLink="false">http://www.brickyardtech.com/blog/?p=113</guid>
		<description><![CDATA[Recently my buddy Juan and I have been helping a client customize Jasig CAS, to provide single sign-on and identity management for various client systems that are written in Grails, Java, Ruby and PHP. I&#8217;m new to the CAS, so &#8230;<p class="read-more"><a href="http://www.brickyardtech.com/blog/2012/02/cas-grails-and-custom-attributes/">Continue to article...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Recently my buddy Juan and I have been helping a client customize Jasig CAS, to provide single sign-on and identity management for various client systems that are written in Grails, Java, Ruby and PHP. I&#8217;m new to the CAS, so it took a while to piece together what&#8217;s possible and what isn&#8217;t. I relied pretty heavily on <a title="this post" href="http://bowerstudios.com/node/645" target="_blank">this post</a> by Daniel Bower (thanks Daniel!) as well as some code that was in his Grails plugin. We didn&#8217;t actually use the plugin itself because it&#8217;s not official yet, and it was easy to just borrow some tips from the plugin source.</p>
<p><em>If you&#8217;re not interested in CAS, Grails, Spring Security, and passing custom attributes then I advise you to stop reading now!</em></p>
<p><span id="more-113"></span></p>
<p>Our situation was different from Daniel&#8217;s because we aren&#8217;t using LDAP, but we still have a need to &#8220;piggy back&#8221; some custom attributes on the CAS 2.0 ticket validation response. It&#8217;s actually less involved than what Daniel had to do. Here&#8217;s the gist of it, quick and dirty.</p>
<h4>Configuring the CAS to pass custom attributes</h4>
<p>I&#8217;m assuming you are already doing your customizations via the &#8220;overlay&#8221; approach with Maven, so I will assume that&#8217;s already up and running. You&#8217;ll need to overlay (at a minimum, I think) 3 files:</p>
<ol>
<li>src/main/webapp/WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp</li>
<li>src/main/webapp/WEB-INF/cas.properties</li>
<li>src/main/webapp/WEB-INF/deployerConfigContext.xml</li>
</ol>
<p>First of all, in your CAS overlay source tree, overlay the file src/main/webapp/WEB-INF/view/jsp/protocol/2.0/casServiceValidationSuccess.jsp and add the following content as a child element of &lt;cas:authenticationSuccess/&gt;:</p>
<pre><code>&lt;c:if test="${fn:length(assertion.chainedAuthentications) &gt; 0}"&gt; &lt;cas:attributes&gt; &lt;c:forEach var="auth" items="${assertion.chainedAuthentications}"&gt; &lt;c:forEach var="attr" items="${auth.principal.attributes}" &gt; &lt;cas:${fn:escapeXml(attr.key)}&gt;${fn:escapeXml(attr.value)}&lt;/cas:${fn:escapeXml(attr.key)}&gt; &lt;/c:forEach&gt; &lt;/c:forEach&gt; &lt;/cas:attributes&gt; &lt;/c:if&gt;</code></pre>
<p>The attributes themselves are provided by a bean in deployerConfigContext.xml called &#8220;attributeRepository&#8221;. It defaults to some kind of stub with a hard-coded map of attributes. You don&#8217;t need to change these for now, but later of course you will want to implement your own &#8220;attributeRepository&#8221; to fetch the real attributes from your database/LDAP/whatever.</p>
<p>The final step on the CAS side requires that you log into the Services Management section of CAS. To do this, you&#8217;ll need to:</p>
<ol>
<li>Make sure to configure cas.properties with your correct HTTPS server URL.</li>
<li>Add yourself as a valid user with ROLE_ADMIN in the userDetailsService section of deployerConfigContext.xml.</li>
<li>Restart the CAS and open your browser to https://localhost/cas/services/ or whatever is the equivalent URL for your CAS installation.</li>
<li>Once logged in, go to the &#8220;Attributes&#8221; section and shift-click to select all the attributes. Click &#8220;Save Changes&#8221;.</li>
<li>Verify that the multi-select shows all these attributes are still selected.</li>
</ol>
<h4>Making a Grails app work with CAS</h4>
<p>Create a Grails project. We used Grails 2.0 but any of the recent 1.3.x versions should also be fine.</p>
<p>Install the Grails plugins &#8220;spring-security-core&#8221; and &#8220;spring-security-cas&#8221;. Take your normal steps to configure Spring Security for Grails; I won&#8217;t go into that here. Then, add something like the following to the bottom of Config.groovy:</p>
<pre>grails.plugins.springsecurity.cas.active = true
grails.plugins.springsecurity.cas.serverUrlPrefix = 'https://localhost:8443/cas'
grails.plugins.springsecurity.cas.loginUri = "/login"
grails.plugins.springsecurity.cas.serviceUrl = "http://localhost:7000/cas-spike/j_spring_cas_security_check"
grails.plugins.springsecurity.cas.key = "balderdash"
grails.plugins.springsecurity.cas.proxyCallbackUrl = "http://localhost:7000/cas-spike/secure/receptor"
grails.plugins.springsecurity.cas.proxyReceptorUrl = "http://localhost:7000/cas-spike/secure/receptor"</pre>
<p>Of course you&#8217;ll want to use real ports and URLs as befits your environment.</p>
<p>Also in Config.groovy, turn up the debugs so you can see traffic from the CAS! This was extremely valuable in debugging why attributes weren&#8217;t coming across earlier.</p>
<pre>log4j = {
    ...
    debug   'grails.plugins.springsecurity'
    debug   'org.codehaus.groovy.grails.plugins.springsecurity'
    debug   'org.springframework.security'
    debug   'org.jasig.cas.client'
}</pre>
<p>Create a test controller that&#8217;s protected, to force a login through CAS. I made mine grails-app/controllers/FooController.groovy:</p>
<pre>import grails.plugins.springsecurity.Secured
import grails.plugins.springsecurity.SpringSecurityService

@Secured(["IS_AUTHENTICATED_FULLY"])
class FooController {
    SpringSecurityService springSecurityService

    def index() {
        render "Howdy"
    }
}</pre>
<p>Bounce your Grails app so the configs take effect. Then try to hit your new controller. With any luck, you should see it redirect to CAS, where you will have to sign in. If your sign-in is successful you&#8217;ll see &#8220;Howdy&#8221; in your web browser. Great success!</p>
<h4>Consuming the custom attributes in your Grails app</h4>
<p>Don&#8217;t get too excited just yet! You might be totally stoked to see CAS working, but you aren&#8217;t yet accessing the custom attributes are you?</p>
<p>Let me step back for a moment and say that half the battle (at least) was getting the custom attributes to be passed in the first place. This seems to be a dark area of the CAS 2.0 protocol. As far as I could gather, the custom attributes that we so painstakingly enabled in the earlier sections are not really part of the CAS specification at all! Fortunately it seems to be a common enough hack that both Spring Security and PHP support it (and maybe Rails and others&#8230;?).</p>
<p>Look in your Grails logs for a debug message that looks something like this:</p>
<pre>&lt;cas:serviceResponse xmlns:cas='http://www.yale.edu/tp/cas'&gt;
    &lt;cas:authenticationSuccess&gt;
        &lt;cas:user&gt;andy&lt;/cas:user&gt;
        &lt;cas:proxyGrantingTicket&gt;PGTIOU-1-Erm9JGxwDD7YJ1GCsqa0-cas&lt;/cas:proxyGrantingTicket&gt;
<span style="color: #339966;">        &lt;cas:attributes&gt;</span>
<span style="color: #339966;">            &lt;cas:uid&gt;uid&lt;/cas:uid&gt;</span>
<span style="color: #339966;">            &lt;cas:eduPersonAffiliation&gt;eduPersonAffiliation&lt;/cas:eduPersonAffiliation&gt; </span>
<span style="color: #339966;">            &lt;cas:groupMembership&gt;groupMembership&lt;/cas:groupMembership&gt;</span>
<span style="color: #339966;">          &lt;/cas:attributes&gt;</span>
    &lt;/cas:authenticationSuccess&gt;
&lt;/cas:serviceResponse&gt;</pre>
<p>Got it? Good, that means the CAS is configured correctly and passing some custom attributes. If not, don&#8217;t proceed, go back and figure out what went wrong.</p>
<p>The only thing we have to do now is make Spring Security look for the CAS attributes returned by the client, and map them to your &#8220;principal&#8221; once logged in. This is where Daniel Bower&#8217;s plugin source was super helpful. Our approach (closely based on Daniel&#8217;s plugin) was to implement a class in src/groovy/CasUserDetailsService.groovy with the following contents:</p>
<pre>class CasUserDetailsService extends AbstractCasAssertionUserDetailsService {
    private static final List NO_ROLES = [new GrantedAuthorityImpl(SpringSecurityUtils.NO_ROLE)]

    // Custom attribute names that should be mapped over into Spring Security roles
    private static final String[] authorityAttribNamesFromCas = ["cas_authority"]

    private GrantedAuthorityFromAssertionAttributesUserDetailsService grantedAuthoritiesService = new GrantedAuthorityFromAssertionAttributesUserDetailsService(authorityAttribNamesFromCas)

    @Override
    protected UserDetails loadUserDetails(Assertion casAssert) {
<span style="color: #339966;">        casAssert.principal.attributes.each { key, value -&gt;</span>
<span style="color: #339966;">            log.info("CUSTOM ATTRIBUTE FROM CAS: ${key} = ${value}")</span>
<span style="color: #339966;">            // TODO - do something intelligent with the attributes</span>
<span style="color: #339966;">        }</span>

        def casUsername = casAssert.getPrincipal().getName()
        def localUser = User.findByUsername(casUsername)

        //Create the user profile if it does not already exist
        if (!localUser) {
            localUser = new User(username: casUsername)
        }

        // Load the authorities from CAS
        def casUser = grantedAuthoritiesService.loadUserDetails(casAssert)
        def casAuthorities = casUser.authorities ?: NO_ROLES

        return new GrailsUser(casUser.username, "no_password", true, true, true, true, casAuthorities, localUser.id)
    }
}</pre>
<p>Wire in this bean in Grails by making your grails-app/conf/spring/resources.groovy something like this:</p>
<pre>// Place your Spring DSL code here
beans = {
    authenticationUserDetailsService(CasUserDetailsService)
}</pre>
<p>Restart the app and try again to login through CAS. You should now see the custom attributes printed in the Grails log.</p>
<h4>Next steps</h4>
<p>Now that you&#8217;re getting attributes, you&#8217;ll want to do two things:</p>
<ol>
<li>Store and pass useful attributes from your CAS. For us, this is stuff like firstName, lastName, email, etc. as well as role/permissions stuff.</li>
<li>Do something useful with the attributes in your client app(s). For us, this is mostly centered on synchronizing data with the authoritative CAS data.</li>
</ol>
<p>Wow, what a long and boring blog post this was. But I sure wish I had it a week ago, it would have saved me a lot of time and frustration. If you find it useful, drop me a note in the comments below to restore my sense of purpose and accomplishment!</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
<p>&nbsp;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brickyardtech.com/blog/2012/02/cas-grails-and-custom-attributes/feed/</wfw:commentRss>
		<slash:comments>28</slash:comments>
		</item>
		<item>
		<title>Whatever happened to static typing?</title>
		<link>http://www.brickyardtech.com/blog/2012/02/whatever-happened-to-static-typing/</link>
		<comments>http://www.brickyardtech.com/blog/2012/02/whatever-happened-to-static-typing/#comments</comments>
		<pubDate>Fri, 03 Feb 2012 16:44:45 +0000</pubDate>
		<dc:creator>Andy Hawkes</dc:creator>
				<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://www.brickyardtech.com/blog/?p=98</guid>
		<description><![CDATA[When I actually sit down to work on Loadster, I&#8217;ve noticed the work goes extremely fast compared with a lot of other projects I have built. There are a few obvious advantages: clean, pristine code base; well-defined scope; one person &#8230;<p class="read-more"><a href="http://www.brickyardtech.com/blog/2012/02/whatever-happened-to-static-typing/">Continue to article...</a></p>]]></description>
			<content:encoded><![CDATA[<p>When I actually sit down to work on Loadster, I&#8217;ve noticed the work goes extremely fast compared with a lot of other projects I have built. There are a few obvious advantages: clean, pristine code base; well-defined scope; one person handling the roadmap and development. It&#8217;s pretty much the most efficient I have ever been.</p>
<p>But there&#8217;s another important advantage that I have noticed lately: everything is written in <strong>plain old Java code</strong>.</p>
<p><span id="more-98"></span></p>
<p>There&#8217;s no applicationContext.xml. No Hibernate. No Maven. No large suite of unit and integration tests that must be run to make sure stuff is &#8220;wired up&#8221; correctly. In fact, there&#8217;s almost no XML at all (the app itself does utilize XML for storing user data, but that&#8217;s a data store, not a project artifact).</p>
<p>When I make a code change in my IDE, it immediately informs me if I&#8217;ve broken something. <strong>Compile time checking FTW!</strong> And when I want to run the app, you know how long it takes? <strong>Less than one second.</strong> That&#8217;s right folks, I click the launch button and in one second Loadster is up and running. It doesn&#8217;t have to fire up a bunch of containers, parse XML, build a dependency tree or any of that. It doesn&#8217;t have to generate meta-class wrappers with CGLib or anything. The code just runs.</p>
<h3>Modern Web Frameworks</h3>
<p>Compare that to the web frameworks you&#8217;ve probably been using. As far as I can reckon, it all went off the rails (no pun intended) with the advent of Struts and Spring and the like. <strong>They threw away compile-time checking at the application level, and replaced it with loose XML wiring.</strong> No doubt it seemed like a great idea at the time (mock objects? reusability? loose coupling?). But what did we give up? Compile time checking. Now almost everything becomes a runtime error. You have to actually run the app &#8212; walk the minefield &#8212; in order to find out what you broke.</p>
<p>Software teams responded to this problem by creating lots of automated unit and integration tests. Now, how do you know if you&#8217;ve mis-wired something? You run a big suite of tests and wait for the outcome! Then you hope your test coverage is good enough that you didn&#8217;t miss something. Unit tests aren&#8217;t a bad thing, but they should be used sparingly, for testing critical <em>units</em> of code.</p>
<p>The next generation of web/MVC frameworks (probably starting with Rails) took it a step further. They responded to the bloated, out of control XML artifacts by pushing &#8220;convention over configuration&#8221;. I&#8217;m a Grails fan, and I see how this is a huge improvement. As long as the conventions are consistent, it works really nicely.</p>
<p>But these next-gen frameworks also switched from static to dynamic languages (Ruby, Groovy, etc). Dynamic languages are really great for writing &#8220;glue&#8221; code. They&#8217;re generally a good fit for web apps. But as soon as I have to write serious back-end application logic, I feel the pain. Again, I miss the compile time checking. The encapsulation. The static typing. I don&#8217;t want to have to write and run a series of unit tests, only to find that I&#8217;m improperly treating a string as a number somewhere deep in the bowels of the application. These are all things the compiler (and IDE) used to do for us!</p>
<p>Everything&#8217;s a trade-off I guess. The newer web frameworks really aren&#8217;t bad. <strong>But if you want a breath of fresh air, try writing a static Java app again. </strong>You might be surprised how quick and easy it is.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brickyardtech.com/blog/2012/02/whatever-happened-to-static-typing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Review of cloud-based load testing services</title>
		<link>http://www.brickyardtech.com/blog/2011/11/review-of-cloud-based-load-testing-services/</link>
		<comments>http://www.brickyardtech.com/blog/2011/11/review-of-cloud-based-load-testing-services/#comments</comments>
		<pubDate>Tue, 29 Nov 2011 16:26:27 +0000</pubDate>
		<dc:creator>Andy Hawkes</dc:creator>
				<category><![CDATA[Load Testing]]></category>
		<category><![CDATA[Reviews]]></category>

		<guid isPermaLink="false">http://www.brickyardtech.com/blog/?p=68</guid>
		<description><![CDATA[Just thought I&#8217;d explore some of the cloud-based load testing services out there. This is mostly for my own benefit, to see what impact if any it will have on Loadster&#8217;s market share, but I thought it might be of &#8230;<p class="read-more"><a href="http://www.brickyardtech.com/blog/2011/11/review-of-cloud-based-load-testing-services/">Continue to article...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Just thought I&#8217;d explore some of the cloud-based load testing services out there. This is mostly for my own benefit, to see what impact if any it will have on Loadster&#8217;s market share, but I thought it might be of general interest so I am sharing my findings. Since Loadster is a client-side app, I don&#8217;t view these cloud offerings as direct competitors, but still&#8230; take my reviews with a grain of salt if you want.</p>
<p>There are 3 main services for cloud-based load testing that I am aware of: <a title="LoadStorm" rel="nofollow" href="http://www.loadstorm.com" target="_blank">LoadStorm</a>, <a title="LoadImpact" rel="nofollow" href="http://www.loadimpact.com" target="_blank">LoadImpact</a>, and <a title="BrowserMob" rel="nofollow" href="http://www.browsermob.com" target="_blank">BrowserMob</a>.</p>
<p><span id="more-68"></span></p>
<p><strong>1. LoadStorm</strong></p>
<p>The self-titled &#8220;lowest cost cloud load testing tool&#8221;. Very competitively priced and straightforward to get started. Within a couple minutes, I was signed up on the free plan which allows load tests of up to 25 virtual users for up to 30 minutes.</p>
<p>The UI is easy enough to navigate but no frills. There are a few places where I had to stop and think about what a particular control meant. There is help text off to the side which could be expanded and collapsed, and I never got lost.</p>
<p>Before you can configure tests against a particular server, you have to verify it by placing a file in the root directory or adding a verification tag to the index page. Since this is a load testing tool, this seems pretty crucial to prevent abuse (DoS attacks). The verification process was easy and about what I&#8217;d expect. Surprisingly, LoadStorm was the only one of the three that required site verification.</p>
<p>Unlike some of the client-side load testing tools, LoadStorm doesn&#8217;t have a way to record steps. You have to add steps manually, each step being either &#8220;Open a page&#8221;, &#8220;Click a link&#8221;, or &#8220;Submit a form&#8221;. While I missed the recording, the tool at least does a good job of parsing out links and forms to facilitate these last two options.</p>
<p>I had one hiccup with submitting the login form into my app. It seemed like the session/login cookie wasn&#8217;t being persisted, so the subsequent step had a login failure. Eventually this resolved itself though, not sure if it was something I did.</p>
<p>One other thing that seemed odd: &#8220;wait times&#8221; aka &#8220;think times&#8221; are done at the test plan level as a min/max, rather than between steps. It enforces a minimum wait time of 10 seconds between pages. In the real world, it&#8217;s not uncommon at all for users to linger less than 10 seconds on a page before clicking to the next one, so this minimum seemed a bit unrealistic to me.</p>
<p>Once you have created a test plan (scenario), running the test is easy. While the test is running you only get 2 live graphs, each with a couple series. They basically amount to throughput (kb/s and requests/s), response time (average and peak), and error rates.</p>
<p>Unfortunately there&#8217;s no further diagnostics or ability to tell what <em>type</em> of errors are happening, or see a breakdown of statistics for a particular step/page only during test runtime. As a result I felt a little bit out of touch with how the test was progressing.</p>
<p>After the test is finished, a few more reporting options do become available, along with CSV export.</p>
<p><em>Pros: Low price, easy to get started.</em></p>
<p><em>Cons: Limited reporting during and after a test, lacks recording so scripting is a bit labor intensive.</em></p>
<p><strong>2. LoadImpact</strong></p>
<p>Nice, pretty site and app. Easy to register.</p>
<p>Their pricing model is based on &#8220;credits&#8221; rather than a subscription. As far as I can tell, 1 credit lets you run 10 simulated browser users, or 40 virtual users, for up to 1 hour. LoadImpact&#8217;s simulated browser users don&#8217;t actually seem to use Selenium or any real web browser; they just have multi-threading that allows ~4 resources at a time to be downloaded, somewhat like a real browser. Their virtual users, on the other hand, are single-threaded.</p>
<p>They have nice charts and graphs throughout the application. When configuring a test, they let you choose one from about 5 &#8220;load zones&#8221; (data centers from which the traffic will be generated).</p>
<p>They actually DO let you record browser steps using a proxy server, by manually configuring your browser. Unfortunately, when I tried it nothing was recorded in either Chrome or Firefox (it proxied my browser&#8217;s requests, but nothing showed up in the script). Since recording didn&#8217;t work for me, I had to edit the script by hand.</p>
<p>Editing the script by hand can be done in either a text or graphical editor. The text editor requires that you type the script in Lua. The graphical one is not really as graphical as we would have hoped; it is in fact just like Lua but with little icons instead of curly braces and stuff like that. Lua syntax is really easy, so I ended up just coding the script manually.</p>
<p>Once you finally figure it out, their scripts are fairly powerful, definitely more so than LoadStorm. Upon starting a test, it tells you how many credits it will cost ahead of time. My 10 minute, 10 user test cost me 1 credit, or roughly $2.10, so still quite cheap. A 60 minute, 100 user test would cost 15 credits, or $45.</p>
<p>The runtime dashboard has a lot more stuff than LoadStorm. It has a really swell Google map showing the location of their data centers, and your server, and where the traffic is coming from. The runtime dashboard uses HighCharts which are pretty nice, and you can add more graphs for certain metrics on the fly.</p>
<p>Once a test is finished, you have a URL to the test report, which is exactly the same dashboard that was shown at runtime. I was hoping for a bit more in-depth reporting after the test is run, but since the runtime dashboard was fairly powerful, I was not too disappointed.</p>
<p><em>Pros: Pretty UI, powerful scripting once you get the hang of it, nice dashboard and reporting.</em></p>
<p><em>Cons: Recording didn&#8217;t work for me, and the graphical script editor didn&#8217;t really offer any advantage. I ended up hand-coding my script in Lua.</em></p>
<p><strong>3. BrowserMob</strong></p>
<p>BrowserMob&#8217;s claim to fame is that they use Selenium scripts and real web browsers to generate the load, which allows for more realistic results, some AJAX support, and better error reporting. They also offer &#8220;virtual users&#8221; (VUs) which in their parlance is a single-threaded, single-connection HTTP client. They cost 1/10 of what you pay for &#8220;real browser users&#8221; (RBUs).</p>
<p>Overall, BrowserMob&#8217;s pricing strikes me as a lot higher than its competitors, with the basic plan starting at $499 a week for up to 100 RBUs or 500 VUs. There is a free plan for smaller load tests, though, with no weekly price but you have to buy &#8220;cloud dollars&#8221; once your 10 trial dollars run out.</p>
<p>They have a nice, modern website and registration process, with good marketing.</p>
<p>For script recording, they give you two choices. You can create a basic script that just loads one or more URLs in a browser, with no programming required. Or you can upload a Selenium script that you record yourself using Selenium. Not a bad approach really. Unfortunately if you upload a Selenium script, you can only use RBUs, not VUs. To use it for VUs, you have to use their converter which simplifies it into GET and POST, and loses any validation logic you might have put in there.</p>
<p>On to running a test. First thing, I tried to do a small test with 50% RBU and 50% VU, but it wouldn&#8217;t let me, saying all the users in a test must be of the same type. Bummer. Oh well, I went with the RBU one because that&#8217;s more interesting. Like the other cloud-based services, there is a few minutes wait before the test can start, while they get things fired up.</p>
<p>The runtime dashboard doesn&#8217;t have as many features as LoadImpact did, but the features they do have make sense. At least you can see total throughput, failures, and response time by &#8220;step&#8221; (Step 1, Step 2, &#8230;). I wish it were easier to see what URL each step consisted of, instead of having to cross reference it back to the script. The other thing that&#8217;s unfortunate is that the dashboard stats only show one-minute increments, so it doesn&#8217;t feel very &#8220;alive&#8221;. It&#8217;s definitely adequate though.</p>
<p>I was expecting some really nice reports after the test finished, but unfortunately they were the same as the dashboard. Given the high price and the degree of polish elsewhere in the app, I was hoping for some nice reports to make sense of your test data. No dice. But if you&#8217;re determined enough, they do let you download a MySQL dump with your raw test data!</p>
<p><em>Pros: Great marketing and website, Selenium scripts with real browsers are powerful.</em></p>
<p><em>Cons: Pricey, runtime dashboard is nothing special, and reporting is pretty bare bones.</em></p>
<p><strong>Conclusion</strong></p>
<p>Assuming you are looking for a cloud-based load testing tool, all three of these services have their appeal. If you really care about using Selenium scripts, then BrowserMob is your only choice. For the most full-featured reporting, go with LoadImpact. If cost is a big deal to you, LoadStorm may be the safest bet. Personally I think I would be drawn most to LoadImpact, if their recording had worked properly.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brickyardtech.com/blog/2011/11/review-of-cloud-based-load-testing-services/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Some thoughts on cloud-based load testing</title>
		<link>http://www.brickyardtech.com/blog/2011/11/thoughts-on-cloud-based-load-testing/</link>
		<comments>http://www.brickyardtech.com/blog/2011/11/thoughts-on-cloud-based-load-testing/#comments</comments>
		<pubDate>Sat, 26 Nov 2011 16:17:15 +0000</pubDate>
		<dc:creator>Andy Hawkes</dc:creator>
				<category><![CDATA[Load Testing]]></category>

		<guid isPermaLink="false">http://www.brickyardtech.com/blog/?p=58</guid>
		<description><![CDATA[I&#8217;m finally jumping back into Loadster after a long, busy hiatus working on some other big projects. The market for load testing tools has changed a bit lately, but not as much as I expected. The biggest change I noticed &#8230;<p class="read-more"><a href="http://www.brickyardtech.com/blog/2011/11/thoughts-on-cloud-based-load-testing/">Continue to article...</a></p>]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m finally jumping back into Loadster after a long, busy hiatus working on some other big projects. The market for load testing tools has changed a bit lately, but not as much as I expected.</p>
<p>The biggest change I noticed is (no surprise here) a big push to The Cloud. Unless you&#8217;ve been living under a rock, of course, you&#8217;ve noticed that everybody and their former roommate is making their apps run on the cloud.</p>
<p>There are some fairly compelling reasons for this. Treating hardware, bandwidth, and processing power in general as a commodity has some huge advantages for any company that wants to focus on core competencies. And there are economies of scale to be had by paying a big cloud provider such as Amazon or Microsoft to handle everything, and pay only for what you use.</p>
<p>As far as load testing is concerned, the cloud is appealing because it represents a cheap way to scale up simulated users as high as you want. One of the big barriers to entry of load testing (besides the shockingly high cost of licensing the software itself) is infrastructure. If you&#8217;re going to simulate 10,000 or so users hitting your production-like test servers, you need a decent amount of hardware and network throughput at your disposal to do so. Solutions like LoadStorm and BrowserMob seem to be gathering a lot of steam in this area.</p>
<p>There are a couple notable disadvantages to cloud-based load testing services, though:</p>
<ul>
<li>They tend to be weaker on the scripting/recording features than the client-side tools. Sure, HTTP load testing just boils down to a bunch of GET and POST requests anyway, but for testing complex transactional systems it&#8217;s helpful to record realistic user flows, rather than just sending the same few requests over and over. If you are actually meticulous enough to hand-code each GET and POST request for a cloud-based tool, then more power to you.</li>
<li>The cloud can only generate traffic on sites that are publicly accessible. This is great for load testing your new WordPress blog or whatever, but most companies that are making serious web apps develop and test them in-house. It&#8217;s not realistic to put your new application in production before running load tests, and having a shadow production environment for this purpose (while ideal) can sometimes get expensive.</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://www.brickyardtech.com/blog/2011/11/thoughts-on-cloud-based-load-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Finding the bottleneck</title>
		<link>http://www.brickyardtech.com/blog/2011/05/finding-the-bottleneck/</link>
		<comments>http://www.brickyardtech.com/blog/2011/05/finding-the-bottleneck/#comments</comments>
		<pubDate>Thu, 05 May 2011 16:50:36 +0000</pubDate>
		<dc:creator>Andy Hawkes</dc:creator>
				<category><![CDATA[Load Testing]]></category>
		<category><![CDATA[Performance Tuning]]></category>

		<guid isPermaLink="false">http://www.loadsterperformance.com/blog/?p=42</guid>
		<description><![CDATA[A question that often comes up is: Once I determine my site has a performance problem, how do I know what to fix? Since there are dozens of potential bottlenecks, how should I best decide where to spend my time? &#8230;<p class="read-more"><a href="http://www.brickyardtech.com/blog/2011/05/finding-the-bottleneck/">Continue to article...</a></p>]]></description>
			<content:encoded><![CDATA[<p>A question that often comes up is: <em>Once I determine my site has a performance problem, how do I know what to fix? Since there are dozens of potential bottlenecks, how should I best decide where to spend my time?</em></p>
<p>I was reminded of this when I came across <a href="http://samsaffron.com/archive/2011/05/02/A+day+in+the+life+of+a+slow+page+at+Stack+Overflow">this post</a> on performance tuning of SQL queries by Sam Saffron at Stack Overflow.</p>
<p>Sam talks in a lot of detail about the tools, queries, and specific optimizations he used to achieve a 10x improvement in baseline performance for some of their pages. That was useful, but not as interesting to me as his general methodology.</p>
<p>First of all, they were logging each query&#8217;s execution time through their own database connection class. So from the very beginning it was really easy to see how much of the page&#8217;s total load time was spent in database queries vs all the other factors (processing data, rendering, network latency, etc). Turns out in their case, as with many applications, the database access was the biggest chunk.</p>
<p>Once he realized this, he didn&#8217;t immediately start tweaking SQL. He looked at a month&#8217;s worth of production logs to see the impact <em>in aggregate</em>. Since this was one page in the system, it made sense to see the total impact over a period of time, to avoid wasting his time on a single page if there are bigger fish to fry.</p>
<p>Turns out over the course of 1 month, that slow page really did have a signifiant impact on site averages. So he proceeded to tune it. As an added bonus, some of the improvements he made had positive ripples through the rest of the application.</p>
<p>So, a couple little morals of the story:</p>
<ol>
<li>Measure everything! Track performance for all the key layers of your application, as well as total response times.</li>
<li>Do a little cost-benefit analysis in your head before diving down rabbit holes. Before tweaking things, first determine where your time is best spent. Attack the worst bottlenecks first.</li>
</ol>
<p>Of course, baseline performance is one thing but performance often changes unpredictably under heavy load. Most bottlenecks are non-linear. Something might do just fine for a while, and suddenly become exponentially slower once a certain load threshold is reached.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brickyardtech.com/blog/2011/05/finding-the-bottleneck/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>SWT drop shadow effect</title>
		<link>http://www.brickyardtech.com/blog/2011/04/swt-drop-shadow-effect/</link>
		<comments>http://www.brickyardtech.com/blog/2011/04/swt-drop-shadow-effect/#comments</comments>
		<pubDate>Thu, 28 Apr 2011 17:19:31 +0000</pubDate>
		<dc:creator>Andy Hawkes</dc:creator>
				<category><![CDATA[SWT]]></category>

		<guid isPermaLink="false">http://www.loadsterperformance.com/blog/?p=22</guid>
		<description><![CDATA[Loadster uses SWT for its user interface. Mostly we&#8217;ve been really happy with it &#8212; while it&#8217;s not as slick as some of the newer non-Java frameworks like Adobe AIR, we&#8217;ve been able to do quite a bit with it &#8230;<p class="read-more"><a href="http://www.brickyardtech.com/blog/2011/04/swt-drop-shadow-effect/">Continue to article...</a></p>]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.loadsterperformance.com/loadster">Loadster</a> uses SWT for its user interface. Mostly we&#8217;ve been really happy with it &#8212; while it&#8217;s not as slick as some of the newer non-Java frameworks like Adobe AIR, we&#8217;ve been able to do quite a bit with it and not much effort. It feels a lot more &#8220;native&#8221; and less clunky than other Java UI toolkits (*cough* Swing *cough*).</p>
<p>For our fancy new graphical script editor (<b>coming soon</b>) I was doing a custom drop shadow effect. Here&#8217;s what it boiled down to:</p>
<pre>

public static void fillRoundRectangleDropShadow(GC gc, Rectangle bounds, int xOffset, int yOffset, int radius) {
	gc.setAdvanced(true);
	gc.setAntialias(SWT.ON);
	gc.setBackground(Display.getCurrent().getSystemColor(SWT.COLOR_BLACK));
	gc.setAlpha(0x8f / radius);

	for (int i = 0; i < radius; i++) {
		Rectangle shadowBounds = new Rectangle(bounds.x + xOffset, bounds.y + yOffset, bounds.width - i, bounds.height - i);

		gc.fillRoundRectangle(shadowBounds.x, shadowBounds.y, shadowBounds.width, shadowBounds.height, radius, radius);
	}

	gc.setAlpha(0xff);
}
</pre>
<p>We could certainly get a lot fancier with the options; I use an arbitrary 0x8f for the shadow alpha because that looks good where we are using it. But you could parameterize that as "intensity" or something.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brickyardtech.com/blog/2011/04/swt-drop-shadow-effect/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Querying for result in a map (Grails/Hibernate/HQL)</title>
		<link>http://www.brickyardtech.com/blog/2011/04/querying-for-result-in-a-map-grailshibernatehql/</link>
		<comments>http://www.brickyardtech.com/blog/2011/04/querying-for-result-in-a-map-grailshibernatehql/#comments</comments>
		<pubDate>Wed, 27 Apr 2011 00:46:22 +0000</pubDate>
		<dc:creator>Andy Hawkes</dc:creator>
				<category><![CDATA[Grails]]></category>

		<guid isPermaLink="false">http://www.loadsterperformance.com/blog/?p=11</guid>
		<description><![CDATA[We use Grails for a lot of web stuff (not related to the Loadster tool itself), and sometimes we end up with rather funky collection types on our Hibernate entities. In this case, we had a domain class called &#8220;Task&#8221; &#8230;<p class="read-more"><a href="http://www.brickyardtech.com/blog/2011/04/querying-for-result-in-a-map-grailshibernatehql/">Continue to article...</a></p>]]></description>
			<content:encoded><![CDATA[<p>We use Grails for a lot of web stuff (not related to the Loadster tool itself), and sometimes we end up with rather funky collection types on our Hibernate entities.</p>
<p>In this case, we had a domain class called &#8220;Task&#8221; with a Map collection called &#8220;attributes&#8221;. The idea is to be able to shove rather unstructured metadata into that map, without polluting the domain class itself with a lot of extra fields that are seldom used.</p>
<p>Today I had to query for all tasks with a certain key in their &#8220;attributes&#8221; map, and was pleasantly surprised at how easy it is:</p>
<pre>
return Task.findAll(
    "from Task t where t.attributes['resident'] = :c",
    [c: resident.id]
)</pre>
<p>No doubt you could do the same with the Criteria API. Another win for Grails/Hibernate!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.brickyardtech.com/blog/2011/04/querying-for-result-in-a-map-grailshibernatehql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Here we go! Announcing Loadster 1.1.1</title>
		<link>http://www.brickyardtech.com/blog/2011/04/hello-world/</link>
		<comments>http://www.brickyardtech.com/blog/2011/04/hello-world/#comments</comments>
		<pubDate>Mon, 18 Apr 2011 22:36:49 +0000</pubDate>
		<dc:creator>Andy Hawkes</dc:creator>
				<category><![CDATA[Loadster Features]]></category>
		<category><![CDATA[Miscellaneous]]></category>

		<guid isPermaLink="false">http://www.loadsterperformance.com/blog/?p=1</guid>
		<description><![CDATA[Just got done releasing Loadster 1.1.1, which is the first version intended for really wide distribution. While we still have a list a mile long, this version is already a full-featured load testing tool by the usual standards: HTTP scripting, parameterized &#8230;<p class="read-more"><a href="http://www.brickyardtech.com/blog/2011/04/hello-world/">Continue to article...</a></p>]]></description>
			<content:encoded><![CDATA[<p>Just got done releasing Loadster 1.1.1, which is the first version intended for really wide distribution. While we still have a list a mile long, this version is already a full-featured load testing tool by the usual standards: HTTP scripting, parameterized data, scenarios with multiple populations and schedules for ramping up/down, automated reports, etc.</p>
<p>But the next few months are going to be really exciting &#8212; a new visual approach to test scripting, really big load engines, monitors, and a couple other surprises. All these will be in the Loadster 1.x branch, so customers who purchase 1.1 will get the future updates for free.</p>
<p>Now comes the big publicity game: targeted ads, social media, blah blah blah. Not as fun as actually building software, but a necessary evil. <img src='http://www.brickyardtech.com/blog/wp-includes/images/smilies/icon_smile.gif' alt=':)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://www.brickyardtech.com/blog/2011/04/hello-world/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
