<?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>aimee daniells &#187; tdd</title>
	<atom:link href="http://edendevelopment.co.uk/blogs/aimee/tag/tdd/feed/" rel="self" type="application/rss+xml" />
	<link>http://edendevelopment.co.uk/blogs/aimee</link>
	<description>apprentice to Enrique Comba Riepenhausen</description>
	<lastBuildDate>Wed, 25 Aug 2010 16:20:09 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Using Cucumber to test concurrency issues</title>
		<link>http://edendevelopment.co.uk/blogs/aimee/2010/08/12/using-cucumber-to-test-concurrency-issues/</link>
		<comments>http://edendevelopment.co.uk/blogs/aimee/2010/08/12/using-cucumber-to-test-concurrency-issues/#comments</comments>
		<pubDate>Thu, 12 Aug 2010 14:34:20 +0000</pubDate>
		<dc:creator>aimee</dc:creator>
				<category><![CDATA[i use tags, not categories]]></category>
		<category><![CDATA[concurrency]]></category>
		<category><![CDATA[cucumber]]></category>
		<category><![CDATA[pair programming]]></category>
		<category><![CDATA[tdd]]></category>

		<guid isPermaLink="false">http://edendevelopment.co.uk/blogs/aimee/?p=101</guid>
		<description><![CDATA[Recently i encountered a concurrency problem of the type where there is a queue of things to do, and users press a button to be automatically assigned the next item in the queue. The bug report was that two users could get assigned the same item.
My pair programmer and i tried to reproduce the problem [...]]]></description>
			<content:encoded><![CDATA[<p>Recently i encountered a concurrency problem of the type where there is a queue of things to do, and users press a button to be automatically assigned the next item in the queue. The bug report was that two users could get assigned the same item.</p>
<p>My pair programmer and i tried to reproduce the problem using two computers, but we couldn&#8217;t. We were only running one Rails instance, but we know that in the production environment there are multiple load-balanced servers pointing to one database, so we had an inkling that we&#8217;d be able to produce it using multi-threading.</p>
<p>To give it a test, we wrote a Rake task which we ran in two terminal windows to mimic the simultaneous access. The Rake task looked something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#CC0066; font-weight:bold;">require</span> <span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">join</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#CC00FF; font-weight:bold;">File</span>.<span style="color:#9900CC;">dirname</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF; font-weight:bold;">__FILE__</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#996600;">'..'</span>, <span style="color:#996600;">'..'</span>, <span style="color:#996600;">'config'</span>, <span style="color:#996600;">'environment.rb'</span><span style="color:#006600; font-weight:bold;">&#41;</span>
namespace <span style="color:#ff3333; font-weight:bold;">:test</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  task <span style="color:#ff3333; font-weight:bold;">:take_next_for</span>, <span style="color:#ff3333; font-weight:bold;">:login</span> <span style="color:#9966CC; font-weight:bold;">do</span> <span style="color:#006600; font-weight:bold;">|</span>t, args<span style="color:#006600; font-weight:bold;">|</span>
    user = User.<span style="color:#9900CC;">find_by_login</span><span style="color:#006600; font-weight:bold;">&#40;</span>args<span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#ff3333; font-weight:bold;">:login</span><span style="color:#006600; font-weight:bold;">&#93;</span><span style="color:#006600; font-weight:bold;">&#41;</span>
    user.<span style="color:#9900CC;">take_next_item</span>
    <span style="color:#CC0066; font-weight:bold;">puts</span> user.<span style="color:#9900CC;">item</span>.<span style="color:#9900CC;">inspect</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>This is easily called by running:</p>

<div class="wp_syntax"><div class="code"><pre class="bash" style="font-family:monospace;">rake <span style="color: #7a0874; font-weight: bold;">test</span>:take_next_for<span style="color: #7a0874; font-weight: bold;">&#91;</span><span style="color: #ff0000;">'ann'</span><span style="color: #7a0874; font-weight: bold;">&#93;</span></pre></div></div>

<p>We ran it for two users simultaneously and inspected the output. Sure enough they were being assigned the same item.</p>
<p>Since there is only one database, we knew that we could fix it with a carefully placed transaction and lock on the database. But we wanted to add a Cucumber feature so that we could be sure it was working, and to give us confidence that the bug would not come back again in the future.</p>

<div class="wp_syntax"><div class="code"><pre class="cucumber" style="font-family:monospace;">  Scenario: Two users take next item simultaneously
    Given a user with login &quot;ann&quot;
    And a user with login &quot;bob&quot;
    And an available item called &quot;Item 1&quot;
    And an available item called &quot;Item 2&quot;
    When two users attempt to take the next item at the same time
    Then they should each have taken different items</pre></div></div>

<p>Notice we can&#8217;t actually say who gets which item &#8211; it&#8217;s a race condition. We can only check that both of them have an item and that they are not the same item. We could alternatively check that both of the items have successfully been taken.</p>
<p>Testing this concurrency issue in Cucumber turned out to be somewhat tricky. We tried using simple Ruby threads in Cucumber, but it wasn&#8217;t properly simultaneously. I guess the single Cucumber environment still only does one thing at a time. So it was back to the Rake task.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">When</span> <span style="color:#006600; font-weight:bold;">/</span>^two users attempt to take the <span style="color:#9966CC; font-weight:bold;">next</span> item at the same time$<span style="color:#006600; font-weight:bold;">/</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  t1 = <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">`RAILS_ENV=cucumber rake test:take_next_for['ann']`</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  t2 = <span style="color:#CC00FF; font-weight:bold;">Thread</span>.<span style="color:#9900CC;">new</span> <span style="color:#006600; font-weight:bold;">&#123;</span> <span style="color:#996600;">`RAILS_ENV=cucumber rake test:take_next_for['bob']`</span> <span style="color:#006600; font-weight:bold;">&#125;</span>
  t1.<span style="color:#9900CC;">join</span>
  t2.<span style="color:#9900CC;">join</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>We &#8216;join&#8217; the two threads to make sure they&#8217;ve both finished before carrying on.</p>
<p>It&#8217;s slow because it loads up a whole new Rails environment for each of the Rake tasks, but that is exactly what we want to do, to mimic the concurrency of the production system.</p>
<p>The next problem we encountered was that Cucumber scenarios are run inside a transaction which means that a Rake task running outside of it cannot see the users and items we just created. So we had to tag the scenario as <code>@no-txn</code> so that they would be available externally and <code>@clean-up-afterwards</code> so that we could remove them from the database.</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;">After <span style="color:#996600;">&quot;@clean-up-afterwards&quot;</span> <span style="color:#9966CC; font-weight:bold;">do</span>
  User.<span style="color:#9900CC;">destroy_all</span>
  Item.<span style="color:#9900CC;">destroy_all</span>
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>With this in place the Cucumber scenario failed as we hoped it would! Then it was simply a matter of creating a transaction from the moment we find the next item (with a database lock) until we have successfully assigned the item. This is a simplified version of what we ended up with:</p>

<div class="wp_syntax"><div class="code"><pre class="ruby" style="font-family:monospace;"><span style="color:#9966CC; font-weight:bold;">class</span> User <span style="color:#006600; font-weight:bold;">&lt;</span> <span style="color:#6666ff; font-weight:bold;">ActiveRecord::Base</span>
  has_one <span style="color:#ff3333; font-weight:bold;">:item</span>
&nbsp;
  <span style="color:#9966CC; font-weight:bold;">def</span> take_next_item
    transaction <span style="color:#9966CC; font-weight:bold;">do</span>
      item = Item.<span style="color:#9900CC;">available</span>.<span style="color:#9900CC;">by_priority</span>.<span style="color:#9900CC;">find</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#ff3333; font-weight:bold;">:first</span>, <span style="color:#ff3333; font-weight:bold;">:lock</span> <span style="color:#006600; font-weight:bold;">=&gt;</span> <span style="color:#0000FF; font-weight:bold;">true</span><span style="color:#006600; font-weight:bold;">&#41;</span>
      <span style="color:#0000FF; font-weight:bold;">self</span>.<span style="color:#9900CC;">item</span> = item
    <span style="color:#9966CC; font-weight:bold;">end</span>
  <span style="color:#9966CC; font-weight:bold;">end</span>
&nbsp;
<span style="color:#9966CC; font-weight:bold;">end</span></pre></div></div>

<p>The Cucumber scenario passed and the problem was solved. In the live system, if two users now try to take an item at the same time, one of them has to wait a moment until the database has finished assigning to the first user so that it can assign a different item to the second user.</p>
<p>How would you have tested a concurrency issue like this? Are there better ways of imitating a multi-server production environment than the solution we came up with?</p>
]]></content:encoded>
			<wfw:commentRss>http://edendevelopment.co.uk/blogs/aimee/2010/08/12/using-cucumber-to-test-concurrency-issues/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Presentation of my apprenticeship task</title>
		<link>http://edendevelopment.co.uk/blogs/aimee/2010/02/21/presentation-of-my-apprenticeship-task/</link>
		<comments>http://edendevelopment.co.uk/blogs/aimee/2010/02/21/presentation-of-my-apprenticeship-task/#comments</comments>
		<pubDate>Sun, 21 Feb 2010 08:44:17 +0000</pubDate>
		<dc:creator>aimee</dc:creator>
				<category><![CDATA[i use tags, not categories]]></category>
		<category><![CDATA[apprenticeship]]></category>
		<category><![CDATA[bdd]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[design patterns]]></category>
		<category><![CDATA[presentation]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[wiki]]></category>

		<guid isPermaLink="false">http://edendevelopment.co.uk/blogs/aimee/?p=54</guid>
		<description><![CDATA[Here is a presentation i made to some of my colleagues on friday explaining my first apprenticeship task, my wiki, how i went about it, the problems i encountered and what i learnt from the whole experience.
See my Apprenticeship task presentation on youtube.
]]></description>
			<content:encoded><![CDATA[<p>Here is a presentation i made to some of my colleagues on friday explaining my first apprenticeship task, my wiki, how i went about it, the problems i encountered and what i learnt from the whole experience.</p>
<p>See my <a href="http://www.youtube.com/watch?v=0EcMcAv_k3w">Apprenticeship task presentation</a> on youtube.</p>
]]></content:encoded>
			<wfw:commentRss>http://edendevelopment.co.uk/blogs/aimee/2010/02/21/presentation-of-my-apprenticeship-task/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Licky wiki news</title>
		<link>http://edendevelopment.co.uk/blogs/aimee/2010/02/04/licky-wiki-news/</link>
		<comments>http://edendevelopment.co.uk/blogs/aimee/2010/02/04/licky-wiki-news/#comments</comments>
		<pubDate>Thu, 04 Feb 2010 21:27:53 +0000</pubDate>
		<dc:creator>aimee</dc:creator>
				<category><![CDATA[i use tags, not categories]]></category>
		<category><![CDATA[apprenticeship]]></category>
		<category><![CDATA[coding]]></category>
		<category><![CDATA[tdd]]></category>
		<category><![CDATA[wiki]]></category>

		<guid isPermaLink="false">http://edendevelopment.co.uk/blogs/aimee/?p=46</guid>
		<description><![CDATA[Just a quick update on licky, my little wiki apprenticeship task i&#8217;m doing. I realise that time has gone on and i haven&#8217;t talked about it as much as i might, plus i actually have some quite encouraging news to report now!
Last time i wrote, i was just starting to work on Pages and a [...]]]></description>
			<content:encoded><![CDATA[<p>Just a quick update on <a href="http://github.com/sermoa/licky">licky</a>, my little wiki apprenticeship task i&#8217;m doing. I realise that time has gone on and i haven&#8217;t talked about it as much as i might, plus i actually have some quite encouraging news to report now!</p>
<p>Last time i wrote, i was just starting to work on Pages and a PageFactory to find them or create them as necessary. Since then i&#8217;ve added a persistence strategy which saves wiki pages to the filesystem. I pass the desired directory to the strategy so that test pages can be kept separate from real pages. This was necessary as i wanted to clear out the test directory every time after use and i didn&#8217;t want to accidentally delete real pages.</p>
<p>After that little burst of progress i stalled for a long time as i knew i needed to start writing the web interface and i didn&#8217;t know where to begin. <a href="http://ohthatjames.github.com/">James</a> gave me a good idea which was to set up a simple Webserver class that would wrap around the web server of my choice. I have chosen WEBrick for the time being, but it shouldn&#8217;t be too difficult to swap in another one later, probably with another strategy pattern. James suggested i start by visiting a page and looking for the text &#8216;Hello world&#8217;. I thought this was a good idea and so i started finding out about WEBrick servlets.</p>
<p>With that start i was suddenly able to leap ahead, testing and implementing everything i need so that my wiki is now able to create, show and edit pages through the web interface. I feel as if i am very close now. Possibly the only thing left to do is add a way to link between pages and then i can truly call it a wiki.</p>
<p>Test driving the development of this whole project has been extremely educational. I know i started off getting too involved in writing a test framework, so Enrique pulled me back and made me think of the simplest thing that could possibly work. I began with one method: <code>assert_equal</code>. That was enough in the beginning. As time went on i added two more methods: <code>assert_true</code> and <code>assert_contains</code>. When necessary i added useful debugging information to report failures. At the appropriate time i refactored the testing framework into a module that could be included into multiple test classes.</p>
<p>I know i also started thinking about the web server too early. I started off trying to work with ERB and templates, as i am familiar with Rails, and in the end all i needed was a few servlets. As Enrique made me realise, the most important part of a wiki is not that it runs on a web server. The most important thing is content. Pages, with content, saved to a file system. Having focussed on that and got a real solid, well tested mechanism for saving and retrieving pages, i knew that the WEBrick servlets could rely on the underlying framework, and when the time came, it did not let me down.</p>
]]></content:encoded>
			<wfw:commentRss>http://edendevelopment.co.uk/blogs/aimee/2010/02/04/licky-wiki-news/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
