<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/rss2full.xsl" type="text/xsl" media="screen"?><?xml-stylesheet href="http://feeds.feedburner.com/~d/styles/itemcontent.css" type="text/css" media="screen"?><rss 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:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>David Laing's blog</title>
	
	<link>http://davidlaing.com</link>
	<description>Craftmanship over crap</description>
	<pubDate>Mon, 29 Dec 2008 18:11:01 +0000</pubDate>
	<generator>http://wordpress.org/?v=2.8-bleeding-edge</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" href="http://feeds.feedburner.com/DavidLaing" type="application/rss+xml" /><item>
		<title>Selenium gotcha - selenium.GetHtmlSource() returns processed HTML</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/497940156/</link>
		<comments>http://davidlaing.com/2008/12/29/selenium-gotcha-seleniumgethtmlsource-returns-processed-html/#comments</comments>
		<pubDate>Mon, 29 Dec 2008 18:11:01 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[TDD]]></category>

		<category><![CDATA[agile]]></category>

		<category><![CDATA[acceptance test]]></category>

		<category><![CDATA[c#]]></category>

		<category><![CDATA[selenium]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=142</guid>
		<description><![CDATA[Whilst writing some Selenium based acceptance tests today; I bumped into a hair pulling gotcha.  Hopefully this post will prevent you from the same pain.
The test was to check whether some tracking tag javascript was being inserted into the page correctly or not.
I assumed that I could get the page source as it was being [...]]]></description>
			<content:encoded><![CDATA[<p>Whilst writing some Selenium based acceptance tests today; I bumped into a hair pulling gotcha.  Hopefully this post will prevent you from the same pain.</p>
<p>The test was to check whether some tracking tag javascript was being inserted into the page correctly or not.</p>
<p>I assumed that I could get the page source as it was being delivered to the browser by calling selenium.GetHtmlSource(); and then check that for the javascript string I was expected.</p>
<p>Unfortunately, GetHtmlSource is just a proxy for the browsers DOM.InnerHTML method; and that returns the Html <strong>after</strong> it has been preprocessed by the browser.</p>
<p>Turns out that preprocessing does a couple of funky things, including</p>
<ul>
<li>Changing line-endings (Firefox)</li>
<li>Changing capitalization (IE6)</li>
<li>Seemingly random removal / insertion of &#8221; &amp; &#8216;  (IE6)</li>
</ul>
<p>So, when I was expecting a string like this:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p1424');">[<span id="p1424_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p142code4'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p1424"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p142code4"><pre class="javascript"><span style="color: #339933;">&lt;</span>script language<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;javascript&quot;</span> type<span style="color: #339933;">=</span><span style="color: #3366CC;">&quot;text/javascript&quot;</span><span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;!--</span>
   <span style="color: #003366; font-weight: bold;">var</span> amPid <span style="color: #339933;">=</span> <span style="color: #3366CC;">'206'</span><span style="color: #3366CC;">';
   var amPPid = '</span><span style="color: #CC0000;">4803</span><span style="color: #3366CC;">';
   if (document.location.protocol=='</span>https<span style="color: #339933;">:</span><span style="color: #3366CC;">')
...[snip]...
</span</pre></td></tr></table></div>

<p>IE6 was presenting me with:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p1425');">[<span id="p1425_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p142code5'); return false;">View Code</a> JAVASCRIPT</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p1425"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
</pre></td><td class="code" id="p142code5"><pre class="javascript"><span style="color: #339933;">&lt;</span>SCRIPT language<span style="color: #339933;">=</span>javascript type<span style="color: #339933;">=</span>text<span style="color: #339933;">/</span>javascript<span style="color: #339933;">&gt;</span>
<span style="color: #339933;">&lt;!--</span>
   <span style="color: #003366; font-weight: bold;">var</span> amPid <span style="color: #339933;">=</span> <span style="color: #3366CC;">'206'</span><span style="color: #3366CC;">';
   var amPPid = '</span><span style="color: #CC0000;">4803</span><span style="color: #3366CC;">';
   if (document.location.protocol=='</span>https<span style="color: #339933;">:</span><span style="color: #3366CC;">')
...[snip]...
</span</pre></td></tr></table></div>

<p>A possible solution is to ignore case, whitespace and quotes when doing the comparison, with a helper method like this:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p1426');">[<span id="p1426_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p142code6'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p1426"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
</pre></td><td class="code" id="p142code6"><pre class="csharp"><span style="color: #008080; font-style: italic;">/// &lt;summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// Use this to compare strings to those returned from selenium.GetHtmlSource for an Internet Explore instance</span>
        <span style="color: #008080; font-style: italic;">/// (IE6 seems to change case and inclusion of quotes, especially for Javascript.?)</span>
        <span style="color: #008080; font-style: italic;">/// &lt;/summary&gt;</span>
        <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;expected&quot;&gt;&lt;/param&gt;</span>
        <span style="color: #008080; font-style: italic;">/// &lt;param name=&quot;actual&quot;&gt;&lt;/param&gt;</span>
        <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> AssertStringContainsIgnoreCaseWhiteSpaceAndQuotes<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">string</span> expected, <span style="color: #FF0000;">string</span> actual<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #FF0000;">string</span> expectedClean <span style="color: #008000;">=</span> Regex.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span>expected, <span style="color: #666666;">@&quot;\s&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">ToLower</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\&quot;</span>&quot;</span>,<span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;'&quot;</span>,<span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #FF0000;">string</span> actualClean <span style="color: #008000;">=</span> Regex.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span>actual, <span style="color: #666666;">@&quot;\s&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">ToLower</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;<span style="color: #008080; font-weight: bold;">\&quot;</span>&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">Replace</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;'&quot;</span>, <span style="color: #666666;">&quot;&quot;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            StringAssert.<span style="color: #0000FF;">Contains</span><span style="color: #000000;">&#40;</span>expectedClean,actualClean,
                                  <span style="color: #FF0000;">string</span>.<span style="color: #0000FF;">Format</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;Expected string <span style="color: #008080; font-weight: bold;">\n</span><span style="color: #008080; font-weight: bold;">\n</span>{0} <span style="color: #008080; font-weight: bold;">\n</span><span style="color: #008080; font-weight: bold;">\n</span>is not contained within <span style="color: #008080; font-weight: bold;">\n</span><span style="color: #008080; font-weight: bold;">\n</span>{1}&quot;</span>, expected, actual<span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>It was the line endings that really floored me; because they were automatically normalized/corrected by my test runner when displaying the error.  Aaargh!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/12/29/selenium-gotcha-seleniumgethtmlsource-returns-processed-html/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/12/29/selenium-gotcha-seleniumgethtmlsource-returns-processed-html/</feedburner:origLink></item>
		<item>
		<title>Apache2 on Ubuntu 8.04LTS; restrict access to PAM authenticated users</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/496585071/</link>
		<comments>http://davidlaing.com/2008/12/27/apache2-on-ubuntu-804lts-restrict-access-to-pam-authenticated-users/#comments</comments>
		<pubDate>Sat, 27 Dec 2008 19:40:26 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[apache2]]></category>

		<category><![CDATA[pam]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=140</guid>
		<description><![CDATA[I have a couple of static pages that I want to restrict access to.
I don&#8217;t want to manage another set of usernames &#38; passwds, so I&#8217;d like apache2 to authenticate off the standard users on my system, via PAM.
To get this to work, you need to install and configure mod_auth_pam and mod_auth_shadow
aptitude install libapache2-mod-auth-pam libapache2-mod-auth-shadow
Ensure [...]]]></description>
			<content:encoded><![CDATA[<p>I have a couple of static pages that I want to restrict access to.</p>
<p>I don&#8217;t want to manage another set of usernames &amp; passwds, so I&#8217;d like apache2 to authenticate off the standard users on my system, via PAM.</p>
<p>To get this to work, you need to install and configure mod_auth_pam and mod_auth_shadow</p>
<pre>aptitude install libapache2-mod-auth-pam libapache2-mod-auth-shadow</pre>
<p>Ensure the <a href="http://ubuntuforums.org/showthread.php?t=275996" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://ubuntuforums.org/showthread.php?t=275996');">www-data user is part of the shadow group</a>, so apache2 can read the passwords</p>
<pre>usermod -G shadow www-data</pre>
<p>And set up the relevent virtual host:</p>
<pre>
<Directory />
                AuthPAM_Enabled On
                AuthShadow on
                AuthPAM_FallThrough Off
                AuthBasicAuthoritative Off
                AuthType Basic
                AuthName "Restricted to group: sysadmins"
                AuthUserFile /dev/null
                Require group sysadmins</pre>
<p>Restart apache, and you&#8217;re done!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/12/27/apache2-on-ubuntu-804lts-restrict-access-to-pam-authenticated-users/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/12/27/apache2-on-ubuntu-804lts-restrict-access-to-pam-authenticated-users/</feedburner:origLink></item>
		<item>
		<title>Self Cert SSL certificate for Apache2 on Ubuntu 8.04LTS</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/495946367/</link>
		<comments>http://davidlaing.com/2008/12/27/self-cert-ssl-certificate-for-apache2-on-ubuntu-804lts/#comments</comments>
		<pubDate>Sat, 27 Dec 2008 00:42:02 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[ssl]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=136</guid>
		<description><![CDATA[Generate a self cert certificate:
https://help.ubuntu.com/8.04/serverguide/C/certificates-and-security.html
Create a new virtual host (you can only have one SSL virtual host / IP)
sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ssl
Edit ssl sothat it looks like this:
NameVirtualHost *:443

        ServerName webangle-www1.everyangle.co.uk
        ServerAdmin webmaster@localhost
        DocumentRoot [...]]]></description>
			<content:encoded><![CDATA[<p>Generate a self cert certificate:</p>
<p><a href="https://help.ubuntu.com/8.04/serverguide/C/certificates-and-security.html" onclick="javascript:pageTracker._trackPageview('/outbound/article/https://help.ubuntu.com/8.04/serverguide/C/certificates-and-security.html');">https://help.ubuntu.com/8.04/serverguide/C/certificates-and-security.html</a></p>
<p>Create a new virtual host (you can only have one SSL virtual host / IP)</p>
<pre>sudo cp /etc/apache2/sites-available/default /etc/apache2/sites-available/ssl</pre>
<p>Edit ssl sothat it looks like this:<br />
<code>NameVirtualHost *:443<br />
<VirtualHost *:443><br />
        ServerName webangle-www1.everyangle.co.uk<br />
        ServerAdmin webmaster@localhost</p>
<p>        DocumentRoot /var/www/</p>
<p>        SSLEngine on</p>
<p>        SSLOptions +StrictRequire</p>
<p>        SSLCertificateFile /etc/ssl/certs/server.crt<br />
        SSLCertificateKeyFile /etc/ssl/private/server.key<br />
</code></p>
<p>Finally, if you want to force redirect of all traffic to a certain folder via SSL (e.g, /phpmyadmin), add the following to /etc/apache2/sites-available/default</p>
<pre>
#Redirect traffic to /phpmyadmin through https
        RewriteEngine   on
        RewriteCond     %{SERVER_PORT} ^80$
        RewriteRule     ^/phpmyadmin(.*)$ https://%{SERVER_NAME}/phpmyadmin$1 [L,R]
</pre>
<p>Enable it:</p>
<pre>sudo a2ensite ssl
sudo /etc/init.d/apache2 reload
</pre>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/12/27/self-cert-ssl-certificate-for-apache2-on-ubuntu-804lts/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/12/27/self-cert-ssl-certificate-for-apache2-on-ubuntu-804lts/</feedburner:origLink></item>
		<item>
		<title>Automount remote filesystem over SSH</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/495900754/</link>
		<comments>http://davidlaing.com/2008/12/27/automount-remote-filesystem-over-ssh/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 23:08:31 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[autofs]]></category>

		<category><![CDATA[sshfs]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=132</guid>
		<description><![CDATA[Previously I posted on how I backup my server&#8217;s data to rsync.net&#8217;s remote storage.
A convienient way to access that remote storage is to configure rsync over sshfs:
sudo aptitude install sshfs
mkdir /mnt/sshfs
mkdir /mnt/sshfs/rsync.net
sshfs **username**@ch-s011.rsync.net: /mnt/rsync.net
Now, test that you can access /mnt/rsync.net, and copy a few files to your remote storage.  if all works well, the next step [...]]]></description>
			<content:encoded><![CDATA[<p>Previously I posted on how I backup my server&#8217;s data to rsync.net&#8217;s remote storage.</p>
<p>A convienient way to access that remote storage is to configure rsync over sshfs:</p>
<pre>sudo aptitude install sshfs
mkdir /mnt/sshfs
mkdir /mnt/sshfs/rsync.net
sshfs **username**@ch-s011.rsync.net: /mnt/rsync.net</pre>
<div>Now, test that you can access /mnt/rsync.net, and copy a few files to your remote storage.  if all works well, the next step is to <a href="http://www.tjansson.dk/?p=84" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.tjansson.dk/?p=84');">have sshfs automatically connect whenever we try to access the directory</a></div>
<p>First, unmount</p>
<pre>fusermount -u /mnt/rsync.net</pre>
<p>Then, install autofs, and edit the config file</p>
<pre>sudo aptitude install autofs
sudo vi /etc/auto.master</pre>
<p>Add the following line </p>
<pre>/mnt/sshfs /etc/auto.sshfs --timeout=30,--ghost</pre>
<p>Then,  </p>
<pre>sudo vi /etc/auto.sshfs</pre>
<p>Add</p>
<pre>rsync.net -fstype=fuse,rw,nodev,nonempty,noatime,allow_other,max_read=65536 :sshfs\#**username**@ch-s011.rsync.net\:</pre>
<p> </p>
<p>And finally restart autofs </p>
<pre>sudo /etc/init.d/autofs restart</pre>
<p> </p>
<p>Now, when you cd /mnt/sshfs/rsync.net, after a short delay you will automatically be connected to the remote filesystem over SSH.  After 30 seconds of inactivity, the connection will be closed.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/12/27/automount-remote-filesystem-over-ssh/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/12/27/automount-remote-filesystem-over-ssh/</feedburner:origLink></item>
		<item>
		<title>Backup Ubuntu 8.04LTS to rsync.net using backup-manager (at linode.com)</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/495866806/</link>
		<comments>http://davidlaing.com/2008/12/26/backup-ubuntu-804lts-to-amazon-s3-using-backup-manager-at-linodecom/#comments</comments>
		<pubDate>Fri, 26 Dec 2008 22:09:21 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[Ubuntu]]></category>

		<category><![CDATA[backup]]></category>

		<category><![CDATA[backup-manager]]></category>

		<category><![CDATA[rsync.net]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=116</guid>
		<description><![CDATA[I&#8217;m setting up a new linode360 VPS, based of the Ubuntu 8.04LTS image.
For backups, I want to do weekly backups and daily incrementals of the data files, and sync these off to an external backup location.
Broadly, there are two parts to the backup, creating the backed up files, and then copying them offsite.
Creating the backups
I&#8217;m [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m setting up a new linode360 VPS, based of the Ubuntu 8.04LTS image.</p>
<p>For backups, I want to do weekly backups and daily incrementals of the data files, and sync these off to an external backup location.</p>
<p>Broadly, there are two parts to the backup, creating the backed up files, and then copying them offsite.</p>
<p><strong>Creating the backups</strong></p>
<p>I&#8217;m using backup-manager 0.7.6-debian1, which handles backing up sets of files and MySQL databases to tar.gz files.</p>
<pre>sudo aptitude install backup-manager
sudo /usr/sbin/backup-manager --version</pre>
<p>The comments in the config file make editing it quite straight forward.</p>
<pre>sudo vi /etc/backup-manager.conf</pre>
<p>One minor points:</p>
<ul>
<li>Separate multiple backup methods with a space, eg:
<pre>export BM_ARCHIVE_METHOD="tarball-incremental mysql"</pre>
</li>
</ul>
<p>To test:</p>
<pre>sudo /usr/sbin/backup-manager --verbose</pre>
<p>The output folder you specified (/var/archives) should now contain some .tar.gz versions of your data.  Hurrah!</p>
<p><strong>Getting the files offsite</strong></p>
<p>Originally I intended to use Amazon&#8217;s S3 as a backup store, following <a href="http://www.zepan.org/2007/02/10/installing-backup-manager-with-the-s3-upload-method-on-debianubuntu/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.zepan.org/2007/02/10/installing-backup-manager-with-the-s3-upload-method-on-debianubuntu/');">Michael Zehrer&#8217;s instructions on how to rsync with S3</a>.  However, I couldn&#8217;t get this to work reliably; so I opted instead for <a href="http://rsync.net" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://rsync.net');">rsync.net</a> which offers standard scp, ftp, WebDav and sshfs access to their geographic backup locations.</p>
<p>Backup-manager can rsync over ssh, which is a quick and efficient way to sync changes over to the remote host..</p>
<p>The first step is get your <a href="http://rsync.net" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://rsync.net');">rsync.net</a> account setup; and <a href="http://rsync.net/resources/howto/ssh_keys.txt" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://rsync.net/resources/howto/ssh_keys.txt');">set up your ssh so you can access without typing in a password</a></p>
<p>Then, set the BM_UPLOAD_METHOD to rsync, and configure both the scp <em>and </em>the rsync settings in /etc/backup-manager.conf (pay attention not to prefix remote folders with / ).</p>
<p>Test with:</p>
<pre>sudo /usr/sbin/backup-manager --verbose</pre>
<p>Once its all working, set up a cron job to call backup-manager daily.</p>
<pre>crontab -e</pre>
<p>I run backup-manager once per day in the wee hours, and log output to /root/crontab/daily_backup-manager.logs</p>
<pre>  0 3   *   *   *    /usr/sbin/backup-manager -v &gt; /root/cronlogs/daily_backup-manager.log</pre>
<p>Viola!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/12/26/backup-ubuntu-804lts-to-amazon-s3-using-backup-manager-at-linodecom/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/12/26/backup-ubuntu-804lts-to-amazon-s3-using-backup-manager-at-linodecom/</feedburner:origLink></item>
		<item>
		<title>Farside re-enactment group</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/493565106/</link>
		<comments>http://davidlaing.com/2008/12/24/farside-re-enactment-group/#comments</comments>
		<pubDate>Tue, 23 Dec 2008 23:48:11 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[Humour]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=114</guid>
		<description><![CDATA[
The evolution of the giraffe.
In case you were wondering.  More sidesplitting stuff at http://www.flickr.com/groups/farside/pool/
  
]]></description>
			<content:encoded><![CDATA[<p><img src="http://farm4.static.flickr.com/3001/2731127418_611284bf43.jpg?v=0" alt="The Evolution of the Giraffe" /></p>
<p><em>The evolution of the giraffe</em>.</p>
<p>In case you were wondering.  More sidesplitting stuff at <a href="http://www.flickr.com/groups/farside/pool/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.flickr.com/groups/farside/pool/');">http://www.flickr.com/groups/farside/pool/</a></p>
<p> <img src='http://davidlaing.com/wp-includes/images/smilies/icon_biggrin.gif' alt=':-D' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/12/24/farside-re-enactment-group/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/12/24/farside-re-enactment-group/</feedburner:origLink></item>
		<item>
		<title>The Correlation between Schedule Pressure &amp; Low Quality</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/467555776/</link>
		<comments>http://davidlaing.com/2008/11/27/the-correlation-between-schedule-pressure-low-quality/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 18:15:21 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<category><![CDATA[agile]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=72</guid>
		<description><![CDATA[Research suggests that

40% of all software errors are caused by pressure on developers to complete quicker (Glass 2004)
Under extreme schedule pressure, code defects increase by 400% (Jones 2004)
Projects which aim to have the lowest number of defects also have the shortest schedules (Jones 2000)

This makes sense is you consider that good engineering practises are the [...]]]></description>
			<content:encoded><![CDATA[<p>Research suggests that</p>
<ul>
<li>40% of all software errors are caused by pressure on developers to complete quicker (Glass 2004)</li>
<li>Under extreme schedule pressure, code defects increase by 400% (Jones 2004)</li>
<li>Projects which aim to have the lowest number of defects also have the shortest schedules (Jones 2000)</li>
</ul>
<p>This makes sense is you consider that good engineering practises are the first to leave the building under pressure to finish, and most teams will revert to quick &amp; dirty hacks to get things implemented, without complete testing etc.</p>
<p>My personal opinion is that the only way to shorted development cycles is to reduce the feature set.  Its pleasing for me to see that the research seems to back this up.</p>
<p>When deciding which features will be dropped; I think its worth revisiting the business requirements that are driving a particular set of features.  In many cases a simpler &#8220;design&#8221; could suffice; for example a fancy calendar widget could be replaced with a simple textbox; a little used settings screen could be retired in favour of manually changing config files; or overly complex but little used workflows could be put on the back burner.</p>
<p>I maintain that a lot of &#8220;features&#8221; can be dropped, without actually impairing the business functionality of the system.  </p>
<p>Just remember, what every you do DON&#8217;T consider dropping testing or QA in an effort to meet your deadline; unless you want to guarantee that you will continue to miss all future deadlines until the project gets cancelled!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/11/27/the-correlation-between-schedule-pressure-low-quality/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/11/27/the-correlation-between-schedule-pressure-low-quality/</feedburner:origLink></item>
		<item>
		<title>ASP.NET MVC Beta - Setting properties on ViewControls</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/467113103/</link>
		<comments>http://davidlaing.com/2008/11/27/aspnet-mvc-beta-setting-properties-on-viewcontrols/#comments</comments>
		<pubDate>Thu, 27 Nov 2008 08:49:52 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[ASP.NET MVC]]></category>

		<category><![CDATA[ViewData]]></category>

		<category><![CDATA[ViewUserControl]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=102</guid>
		<description><![CDATA[In ASP.NET MVC Beta, it isn&#8217;t possible to set properties on partials when calling them with Html.RenderPartial.
Rusty Zarse blogged about a useful ViewData helper class, which allows you to set properties by passing values to the partial through the ViewData.
I&#8217;ve extended this slightly to enable the following syntax:

[-]?View Code CSHARP1
2
3
4
5
6
7
8
&#60;% Html.RenderPartial&#40;&#34;YUIDataTable&#34;,
      [...]]]></description>
			<content:encoded><![CDATA[<p>In ASP.NET MVC Beta, it isn&#8217;t possible to set properties on partials when calling them with Html.RenderPartial.</p>
<p><a href="http://www.vitaminzproductions.com/technology-blog/index.php/2008/11/12/setting-properties-using-aspnet-mvc/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.vitaminzproductions.com/technology-blog/index.php/2008/11/12/setting-properties-using-aspnet-mvc/');">Rusty Zarse</a> blogged about a useful ViewData helper class, which allows you to set properties by passing values to the partial through the ViewData.</p>
<p>I&#8217;ve extended this slightly to enable the following syntax:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p10210');">[<span id="p10210_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p102code10'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p10210"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
</pre></td><td class="code" id="p102code10"><pre class="csharp"><span style="color: #008000;">&lt;%</span> Html.<span style="color: #0000FF;">RenderPartial</span><span style="color: #000000;">&#40;</span><span style="color: #666666;">&quot;YUIDataTable&quot;</span>,
               ViewDataDictionaryBuilder.<span style="color: #0000FF;">Create</span><span style="color: #000000;">&#40;</span>
                      <span style="color: #008000;">new</span>
                      <span style="color: #000000;">&#123;</span>
                        DataTableId <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;QuoteDataTable&quot;</span>,
                        ConfigNamespace <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;QuoteDataTableConfig&quot;</span>,
                        HideFilter <span style="color: #008000;">=</span> <span style="color: #0600FF;">true</span>
                       <span style="color: #000000;">&#125;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;%&gt;</span></pre></td></tr></table></div>

<p>Which sets properties on a ViewUserControl like this:</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p10211');">[<span id="p10211_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p102code11'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p10211"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
</pre></td><td class="code" id="p102code11"><pre class="csharp">     <span style="color: #0600FF;">public</span> partial <span style="color: #FF0000;">class</span> YUIDataTable <span style="color: #008000;">:</span> ViewUserControl
    <span style="color: #000000;">&#123;</span>
        <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> ConfigNamespace <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
        <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> DataTableId <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
        <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">bool</span> HideFilter <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF;">protected</span> <span style="color: #0600FF;">void</span> Page_Load<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> sender, EventArgs e<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            ViewDataDictionaryBuilder.<span style="color: #0000FF;">SetPropertiesToViewDataValues</span><span style="color: #000000;">&#40;</span><span style="color: #0600FF;">this</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
    <span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>Here is the full helper code.</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p10212');">[<span id="p10212_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p102code12'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p10212"><td width="1%" 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
</pre></td><td class="code" id="p102code12"><pre class="csharp"><span style="color: #0600FF;">using</span> <span style="color: #008080;">System</span><span style="color: #008000;">;</span>
&nbsp;
<span style="color: #0600FF;">namespace</span> MvcHelpers
<span style="color: #000000;">&#123;</span>
    <span style="color: #008080; font-style: italic;">///</span>
    <span style="color: #008080; font-style: italic;">/// With thanks to http://www.vitaminzproductions.com/technology-blog/index.php/2008/11/12/setting-properties-using-aspnet-mvc/</span>
    <span style="color: #008080; font-style: italic;">///</span>
    <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #FF0000;">class</span> ViewDataDictionaryBuilder
    <span style="color: #000000;">&#123;</span>
        <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span> Create<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> data, ModelType model<span style="color: #000000;">&#41;</span> where ModelType <span style="color: #008000;">:</span> <span style="color: #FF0000;">class</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #0600FF;">return</span> <span style="color: #000000;">&#40;</span><span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span><span style="color: #000000;">&#41;</span>CreateInternal<span style="color: #000000;">&#40;</span><span style="color: #008000;">new</span> <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span><span style="color: #000000;">&#40;</span>model<span style="color: #000000;">&#41;</span>, data<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span> Create<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> data, <span style="color: #FF0000;">object</span> model<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #0600FF;">return</span> CreateInternal<span style="color: #000000;">&#40;</span><span style="color: #008000;">new</span> <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span><span style="color: #000000;">&#40;</span>model<span style="color: #000000;">&#41;</span>, data<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span> Create<span style="color: #000000;">&#40;</span><span style="color: #FF0000;">object</span> data<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #0600FF;">return</span> CreateInternal<span style="color: #000000;">&#40;</span><span style="color: #008000;">new</span> <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>, data<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span> CreateInternal<span style="color: #000000;">&#40;</span><span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span> dictionary, <span style="color: #FF0000;">object</span> data<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            AddPropertiesToViewData<span style="color: #000000;">&#40;</span>dictionary, data<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #0600FF;">return</span> dictionary<span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF;">private</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> AddPropertiesToViewData<span style="color: #000000;">&#40;</span><span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewDataDictionary</span> dictionary, <span style="color: #FF0000;">object</span> data<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>data <span style="color: #008000;">==</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span> return<span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #000000;">System</span>.<span style="color: #0000FF;">Reflection</span>.<span style="color: #0000FF;">PropertyInfo</span><span style="color: #000000;">&#91;</span><span style="color: #000000;">&#93;</span> properties <span style="color: #008000;">=</span> data.<span style="color: #0000FF;">GetType</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">GetProperties</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span>var property <span style="color: #0600FF;">in</span> properties<span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#123;</span>
                dictionary.<span style="color: #0000FF;">Add</span><span style="color: #000000;">&#40;</span>property.<span style="color: #0000FF;">Name</span>, property.<span style="color: #0000FF;">GetValue</span><span style="color: #000000;">&#40;</span>data, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span>
        <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">static</span> <span style="color: #0600FF;">void</span> SetPropertiesToViewDataValues<span style="color: #000000;">&#40;</span><span style="color: #000000;">System</span>.<span style="color: #0000FF;">Web</span>.<span style="color: #0000FF;">Mvc</span>.<span style="color: #0000FF;">ViewUserControl</span> viewUserControl<span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            <span style="color: #0600FF;">foreach</span> <span style="color: #000000;">&#40;</span>var property <span style="color: #0600FF;">in</span> viewUserControl.<span style="color: #0000FF;">GetType</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>.<span style="color: #0000FF;">GetProperties</span><span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span><span style="color: #000000;">&#41;</span>
            <span style="color: #000000;">&#123;</span>
                <span style="color: #0600FF;">if</span> <span style="color: #000000;">&#40;</span>viewUserControl.<span style="color: #0000FF;">ViewData</span><span style="color: #000000;">&#91;</span>property.<span style="color: #0000FF;">Name</span><span style="color: #000000;">&#93;</span> <span style="color: #008000;">!=</span> <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span>
                    property.<span style="color: #0000FF;">SetValue</span><span style="color: #000000;">&#40;</span>viewUserControl, Convert.<span style="color: #0000FF;">ChangeType</span><span style="color: #000000;">&#40;</span>viewUserControl.<span style="color: #0000FF;">ViewData</span><span style="color: #000000;">&#91;</span>property.<span style="color: #0000FF;">Name</span><span style="color: #000000;">&#93;</span>, property.<span style="color: #0000FF;">PropertyType</span><span style="color: #000000;">&#41;</span>, <span style="color: #0600FF;">null</span><span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
            <span style="color: #000000;">&#125;</span>
        <span style="color: #000000;">&#125;</span>
&nbsp;
    <span style="color: #000000;">&#125;</span>
<span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>Hope that&#8217;s useful to you!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/11/27/aspnet-mvc-beta-setting-properties-on-viewcontrols/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/11/27/aspnet-mvc-beta-setting-properties-on-viewcontrols/</feedburner:origLink></item>
		<item>
		<title>Announcing the TDD TestHelpers opensource project</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/465968078/</link>
		<comments>http://davidlaing.com/2008/11/26/announcing-the-tdd-testhelpers-opensource-project/#comments</comments>
		<pubDate>Wed, 26 Nov 2008 08:45:08 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[.NET]]></category>

		<category><![CDATA[TDD]]></category>

		<category><![CDATA[agile]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=98</guid>
		<description><![CDATA[Whenever I start working on a project; I invariably find myself writing a collection of TDD test helper methods.  I quick survey of other TDDers reveals the same; and thus the birth of my latest opensource project, TestHelpers (http://code.google.com/p/testhelpers/).
The aim of the project is to centralise all those little test helper methods you end up [...]]]></description>
			<content:encoded><![CDATA[<p>Whenever I start working on a project; I invariably find myself writing a collection of TDD test helper methods.  I quick survey of other TDDers reveals the same; and thus the birth of my latest opensource project, <a href="http://code.google.com/p/testhelpers/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/testhelpers/');">TestHelpers</a> (<a href="http://code.google.com/p/testhelpers/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/testhelpers/');">http://code.google.com/p/testhelpers/</a>).</p>
<p>The aim of the project is to centralise all those little test helper methods you end up creating into a useful assembly you can use to jumpstart your next project.  Things like:</p>
<ul>
<li>Comparers
<ul>
<li>Generic object comparers</li>
<li>DataSet comparers</li>
</ul>
</li>
<li>Test Data generators
<ul>
<li>Builder pattern</li>
</ul>
</li>
<li>Automocking containers</li>
</ul>
<p>For example, I&#8217;ve just added an &#8220;AssertValues&#8221; functor; which helps you check whether the values of who object instances are the same. </p>
<p>One area I keep using asserts like this is in integration tests; where I want to check that the objects I&#8217;m persisting to the database via my ORM actually end up in the database in a non-mangled form.  In this case, I new up entityA, persist it, reload it into entityB and then need to check that all the values in entityB are the same as those in entityA.</p>
<p>A standard Assert.AreEqual will fail, because entityA and entityB are different instances.  But, my helper method AssertValues.AreEqual will pass, because it checks the (serialized) string values of entityA and entityB.</p>
<p>Here is another, simpler example to illustrate the concept.</p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p9814');">[<span id="p9814_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p98code14'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p9814"><td width="1%" class="line_numbers"><pre>1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
</pre></td><td class="code" id="p98code14"><pre class="csharp">    <span style="color: #000000;">&#91;</span>TestFixture<span style="color: #000000;">&#93;</span>
    <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> StandardObjectsTests
    <span style="color: #000000;">&#123;</span>
        <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">class</span> StringContainer
        <span style="color: #000000;">&#123;</span>
            <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> String1 <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
            <span style="color: #0600FF;">public</span> <span style="color: #FF0000;">string</span> String2 <span style="color: #000000;">&#123;</span> get<span style="color: #008000;">;</span> set<span style="color: #008000;">;</span> <span style="color: #000000;">&#125;</span>
        <span style="color: #000000;">&#125;</span>
&nbsp;
        <span style="color: #000000;">&#91;</span>Test<span style="color: #000000;">&#93;</span>
        <span style="color: #0600FF;">public</span> <span style="color: #0600FF;">void</span> ObjectsWithSameValue_ShouldBeEqual<span style="color: #000000;">&#40;</span><span style="color: #000000;">&#41;</span>
        <span style="color: #000000;">&#123;</span>
            var stringContainer1 <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> StringContainer <span style="color: #000000;">&#123;</span>String1 <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Test String1&quot;</span>, String2 <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Test String 2&quot;</span><span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
            var stringContainer2 <span style="color: #008000;">=</span> <span style="color: #008000;">new</span> StringContainer <span style="color: #000000;">&#123;</span>String1 <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Test String1&quot;</span>, String2 <span style="color: #008000;">=</span> <span style="color: #666666;">&quot;Test String 2&quot;</span><span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span>
&nbsp;
            Assert.<span style="color: #0000FF;">AreNotEqual</span><span style="color: #000000;">&#40;</span>stringContainer1, stringContainer2<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
&nbsp;
            AssertValues.<span style="color: #0000FF;">AreEqual</span><span style="color: #000000;">&#40;</span>stringContainer1, stringContainer2<span style="color: #000000;">&#41;</span><span style="color: #008000;">;</span>
        <span style="color: #000000;">&#125;</span>
   <span style="color: #000000;">&#125;</span></pre></td></tr></table></div>

<p>I&#8217;m sure you have a bunch of similar helper methods lying about your projects.</p>
<p>How about contributing them to the TestHelper project?</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/11/26/announcing-the-tdd-testhelpers-opensource-project/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/11/26/announcing-the-tdd-testhelpers-opensource-project/</feedburner:origLink></item>
		<item>
		<title>DDD7 - Nov 21, Microsoft campus, Reading UK</title>
		<link>http://feeds.feedburner.com/~r/DavidLaing/~3/461987303/</link>
		<comments>http://davidlaing.com/2008/11/22/ddd7-nov-21-microsoft-campus-reading-uk/#comments</comments>
		<pubDate>Sat, 22 Nov 2008 16:54:46 +0000</pubDate>
		<dc:creator>mrdavidlaing</dc:creator>
		
		<category><![CDATA[Uncategorized]]></category>

		<guid isPermaLink="false">http://davidlaing.com/?p=88</guid>
		<description><![CDATA[Wow.  DDD, the community conference for UK MS developers, hosted by Microsoft, but completly driven by the community continues to go from strength to strength.  This year, the 400 places were filled within 4 hours of this annoucement that registration was open via twitter.
I really enjoyed Mike Hadlow&#8217;s talk on IOC injection; with specific reference [...]]]></description>
			<content:encoded><![CDATA[<p>Wow.  DDD, the community conference for UK MS developers, hosted by Microsoft, but completly driven by the community continues to go from strength to strength.  This year, the 400 places were filled within 4 hours of this annoucement that registration was open via twitter.</p>
<p>I really enjoyed <a href="http://mikehadlow.blogspot.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://mikehadlow.blogspot.com/');">Mike Hadlow</a>&#8217;s <a href="http://static.mikehadlow.com/Using%20an%20Inversion%20of%20Control%20Container%20in%20a.pptx" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://static.mikehadlow.com/Using%20an%20Inversion%20of%20Control%20Container%20in%20a.pptx');">talk on IOC injection</a>; with specific reference to his opensource eCommerce application, <a href="http://sutekishop.co.uk/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://sutekishop.co.uk/');">SutekiShop</a>.  Clearly an expert on the subject on ASP.NET MVC, Onion architecture, Repositories &amp; Services,  and binding it all together with IOC; he is also a gifted presenter.   If you&#8217;re looking for a reference implementation of an ASP.NET MVC application (or indeed just a loosely coupled, TDD driven web application); I&#8217;d strongly advise you to check out <a href="http://code.google.com/p/sutekishop/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://code.google.com/p/sutekishop/');">Mike&#8217;s SVN repo</a>.</p>
<p><a href="http://holytshirt.blogspot.com" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://holytshirt.blogspot.com');">Toby Henderson</a> gave an interesting demo of how you can run .NET apps under Linux (Ubuntu) using Mono.  Worth bearing in mind when considering your hosting &amp; deployment options.</p>
<p><a href="http://serialseb.blogspot.com/" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://serialseb.blogspot.com/');">Sebastien Lambla</a> gave a highly entertaining (if opinionated) presentation of a series of WFP tips and tricks.  My favourite tip (which isn&#8217;t really WPF related)</p>
<p><em>Tired of always checking if your event delegates are null before calling them?  Just declare them with a standard empty delegate.  Then they are never null!</em></p>

<div id="wp_codebox_msgheader"><span class="right"><a href="javascript:;" onclick="toggle_collapse('p8816');">[<span id="p8816_symbol">-</span>]</a><sup><a href="http://www.ericbess.com/ericblog/2008/03/03/wp-codebox/#examples" target="_blank" title="WP-CodeBox HowTo?"><span style="color: #99cc00">?</span></a></sup></span><span class="left"><a href="javascript:;" onclick="javascript:showCodeTxt('p88code16'); return false;">View Code</a> CSHARP</span><div class="codebox_clear"></div></div><div id="wp_codebox"><table width="100%" ><tr id="p8816"><td width="1%" class="line_numbers"><pre>1
</pre></td><td class="code" id="p88code16"><pre class="csharp">  <span style="color: #0600FF;">event</span> MyEvent <span style="color: #008000;">=</span> <span style="color: #FF0000;">delegate</span> <span style="color: #000000;">&#123;</span><span style="color: #000000;">&#125;</span><span style="color: #008000;">;</span></pre></td></tr></table></div>

<p>Recommended book: <a href="http://www.amazon.co.uk/Windows-Presentation-Foundation-Unleashed-WPF/dp/0672328917/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1227808736&#038;sr=8-17" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.amazon.co.uk/Windows-Presentation-Foundation-Unleashed-WPF/dp/0672328917/ref=sr_1_1?ie=UTF8&#038;s=books&#038;qid=1227808736&#038;sr=8-17');">WPF Unleashed</a> by Adam Nathan</p>
<p>As always it was a great event - remember, if you want to be at DDD8 (2009); sign up early!</p>
<p>See <a href="http://www.developerday.co.uk" onclick="javascript:pageTracker._trackPageview('/outbound/article/http://www.developerday.co.uk');">www.developerday.co.uk</a> for slides &amp; videos from all sessions</p>
]]></content:encoded>
			<wfw:commentRss>http://davidlaing.com/2008/11/22/ddd7-nov-21-microsoft-campus-reading-uk/feed/</wfw:commentRss>
		<feedburner:origLink>http://davidlaing.com/2008/11/22/ddd7-nov-21-microsoft-campus-reading-uk/</feedburner:origLink></item>
	</channel>
</rss><!-- Dynamic Page Served (once) in 1.754 seconds --><!-- Cached page generated by WP-Super-Cache on 2008-12-29 19:11:31 -->
