<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/rss2full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><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:slash="http://purl.org/rss/1.0/modules/slash/" xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" version="2.0">

<channel>
	<title>//FIXME</title>
	
	<link>http://eraserhead.net</link>
	<description>Jason Felice's blog</description>
	<lastBuildDate>Mon, 15 Mar 2010 13:00:25 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.9.2</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" type="application/rss+xml" href="http://feeds.feedburner.com/eraserhead/ADNx" /><feedburner:info uri="eraserhead/adnx" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><item>
		<title>Making MSVC6 Crash</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/xZcIlSq5d_g/</link>
		<comments>http://eraserhead.net/2010/03/making-msvc6-crash/#comments</comments>
		<pubDate>Mon, 15 Mar 2010 13:00:25 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[MSVC6]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=116</guid>
		<description><![CDATA[I&#8217;ve been collecting these for a little while.  Since we are now well under way in migrating to VS2005, now is a good time to post them.
.\Components/CommComponents/FDMSInterleaveTcpipComm/Test_FDMSInterleaveTcpipComm.h(106) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1794)
         [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been collecting these for a little while.  Since we are now well under way in migrating to VS2005, now is a good time to post them.</p>
<pre>.\Components/CommComponents/FDMSInterleaveTcpipComm/Test_FDMSInterleaveTcpipComm.h(106) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1794)
         Please choose the Technical Support command on the Visual C++
         Help menu, or open the Technical Support help file for more information
</pre>
<p>was caused by:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">typename</span> VersionPolicy<span style="color: #000080;">&gt;</span> <span style="color: #0000ff;">class</span> SVDotPacketProductionPolicy<span style="color: #008080;">;</span>
    <span style="color: #0000ff;">class</span> SVDotPacketProductionPolicy<span style="color: #000080;">&lt;</span>SV24VersionPolicy<span style="color: #000080;">&gt;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">friend</span> <span style="color: #0000ff;">class</span> SVDotPacketProductionPolicy<span style="color: #000080;">&lt;</span>SV24VersionPolicy<span style="color: #000080;">&gt;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">class</span> SVDotPacketProductionPolicy<span style="color: #000080;">&lt;</span>SV40VersionPolicy<span style="color: #000080;">&gt;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">friend</span> <span style="color: #0000ff;">class</span> SVDotPacketProductionPolicy<span style="color: #000080;">&lt;</span>SV40VersionPolicy<span style="color: #000080;">&gt;</span><span style="color: #008080;">;</span></pre></div></div>

<hr />
<pre>Include\boost/bind/arg.hpp(25) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1794)
         Please choose the Technical Support command on the Visual C++
         Help menu, or open the Technical Support help file for more information
</pre>
<p>This one started after I added</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #339900;">#include &lt;boost/bind.hpp&gt;</span></pre></div></div>

<p> to a file and a simple, every-day use of <tt>boost::bind()</tt>.  Moving the <tt>#include</tt> directive up before a number of other standard includes resolved the issue.</p>
<pre>
C:\projects\DASV2>scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
cl /FoComponents\AuthComponents\Credit\CCMps\Release\Tests.obj /c Components\AuthComponents\Credit\CCMps\Release\Tests.cpp /nologo /
TP /nologo /MT /W2 /GX /GR /O2 /Zi /Zm200 /D "WIN32" /D "_WINDOWS" /D "NDEBUG" /D "_MBCS" /FD /D "_WIN32_WINNT=0x0400" /D "_WIN32_DC
OM" /IWindowsSDK\Include /IInclude /Icryptlib /IXML\Xerces\src /I. /IComponents\AuthComponents\Credit\CCMps
Tests.cpp
Include\boost/function/function_template.hpp(514) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1794)
         Please choose the Technical Support command on the Visual C++
         Help menu, or open the Technical Support help file for more information
scons: *** [Components\AuthComponents\Credit\CCMps\Release\Tests.obj] Error 2
scons: building terminated because of errors.
</pre>
<p>06/01/2009 &#8211; This one was the result of passing a pointer to a static member function to <tt>boost::function1&lt;&gt;</tt>.</p>
<pre>
C:\projects\DASV2>scons
scons: Reading SConscript files ...
scons: done reading SConscript files.
scons: Building targets ...
python.exe Utilities/CxxTest/cxxtestgen.py --runner=XmlPrinter --have-eh --have-std --check-memory -o CBase\ISOMsg\Debug\Tests.cpp CBase\ISOMsg\Test_Fields.h
cl /FoCBase\ISOMsg\Debug\Tests.obj /c CBase\ISOMsg\Debug\Tests.cpp /nologo /TP /nologo /MTd /Od /W2 /GX /GR /Zi /Zm200 /D "WIN32" /D "_WINDOWS" /D "_MBCS" /FD /D "_WIN32_WINNT=0x0400" /D "_WIN32_DCOM" /D "DEBUG" /D "_DEBUG" /IWindowsSDK\Include /IInclude /Icryptlib /IXML\Xerces\src /I. /ICBase\ISOMsg
Tests.cpp
.\CBase/ISOMsg/Test_Fields.h(157) : fatal error C1001: INTERNAL COMPILER ERROR
        (compiler file 'msc1.cpp', line 1794)
         Please choose the Technical Support command on the Visual C++
         Help menu, or open the Technical Support help file for more information
scons: *** [CBase\ISOMsg\Debug\Tests.obj] Error 2
scons: building terminated because of errors.
</pre>
<p>06/18/2009 &#8211; This one is the result of attempting to use a template member of template class.  Here&#8217;s the (abbreviated) code:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">typename</span> C, C v<span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">struct</span> ThreeArgConstructor
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span><span style="color: #0000ff;">class</span> BaseT<span style="color: #000080;">&gt;</span>
    <span style="color: #0000ff;">struct</span> Type <span style="color: #008080;">:</span> <span style="color: #0000ff;">public</span> BaseT
    <span style="color: #008000;">&#123;</span>
        Type<span style="color: #008000;">&#40;</span><span style="color: #0000ff;">int</span> length<span style="color: #008000;">&#41;</span>
            <span style="color: #008080;">:</span> BaseT<span style="color: #008000;">&#40;</span>length, <span style="color: #FF0000;">&quot;TEST FIELD PACKAGER&quot;</span>, v<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span><span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">template</span><span style="color: #000080;">&lt;</span>
      BaseT
    , ConstructorT
    <span style="color: #000080;">&gt;</span>
<span style="color: #0000ff;">class</span> Foo
<span style="color: #008000;">&#123;</span>
    <span style="color: #0000ff;">typedef</span> <span style="color: #0000ff;">typename</span> ConstructorT<span style="color: #008080;">::</span><span style="color: #0000ff;">template</span> Type<span style="color: #000080;">&lt;</span>BaseT<span style="color: #000080;">&gt;</span> TestPackager<span style="color: #008080;">;</span>
&nbsp;
    <span style="color: #0000ff;">void</span> run<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
        TestPackager<span style="color: #008000;">&#40;</span><span style="color: #0000dd;">10</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span>
<span style="color: #008000;">&#125;</span><span style="color: #008080;">;</span>
&nbsp;
<span style="color: #0000ff;">int</span> main<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span> <span style="color: #008000;">&#123;</span>
    Foo<span style="color: #000080;">&lt;</span>Bar, ThreeArgConstructor<span style="color: #000080;">&lt;</span><span style="color: #0000ff;">bool</span>, <span style="color: #0000ff;">false</span><span style="color: #000080;">&gt;</span> <span style="color: #000080;">&gt;</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">run</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #0000ff;">return</span> <span style="color: #0000dd;">0</span><span style="color: #008080;">;</span>
<span style="color: #008000;">&#125;</span></pre></div></div>

<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/xZcIlSq5d_g" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2010/03/making-msvc6-crash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2010/03/making-msvc6-crash/</feedburner:origLink></item>
		<item>
		<title>Make Work Visible</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/EA_vG_ktwx4/</link>
		<comments>http://eraserhead.net/2010/03/make-work-visible/#comments</comments>
		<pubDate>Wed, 10 Mar 2010 04:24:34 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Guerilla Software Recovery]]></category>
		<category><![CDATA[Patterns]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=497</guid>
		<description><![CDATA[Context
A significant portion of your activities aren&#8217;t visible to your management, possibly because

you have become the &#8220;product expert&#8221; which consults with others or
your products&#8217; production deployments require significant developer attention
  
Therefore,
Divide your whiteboard up into columns representing your work flow (e.g. &#8220;Backlog,&#8221; &#8220;Ready&#8221;, &#8220;Develop&#8221;, &#8220;QA&#8221;, &#8220;Done&#8221;) and obtain a large supply of Post-It(tm) notes. [...]]]></description>
			<content:encoded><![CDATA[<h2>Context</h2>
<p>A significant portion of your activities aren&#8217;t visible to your management, possibly because
<ul>
<li>you have become the &#8220;product expert&#8221; which consults with others or
<li>your products&#8217; production deployments require significant developer attention
  </ul>
<h2>Therefore,</h2>
<p>Divide your whiteboard up into columns representing your work flow (e.g. &#8220;Backlog,&#8221; &#8220;Ready&#8221;, &#8220;Develop&#8221;, &#8220;QA&#8221;, &#8220;Done&#8221;) and obtain a large supply of Post-It(tm) notes.  Use separate colors for the items assigned to you by your management and the items which come to you as the domain expert.  If necessary, track enough information to build a cumulative flow diagram.</p>
<h2>Discussion</h2>
<p>There is something visceral about this approach that conveys understanding in a way which is not possible by explanation or discussion.  It may be the case that your management <em>knows</em> what is happening but doesn&#8217;t quite &#8220;<em>get it</em>.&#8221;</p>
<p>This is a minimum useful subset of <a href="http://limitedwipsociety.org/">software kanban</a> and an instance of &#8220;Information Radiator.&#8221;</p>
<p>A cumulative flow diagram can be created by simply counting the number of tickets in each bucket each morning and entering these into a spreadsheet in backwards order.  You can read your average work-in-process (WIP) and cycle time from this diagram, making it an incredibly inexpensive way to measure the amount of effort spent on visible work versus other work.</p>
<h2>Observed Instances</h2>
<h3>One</h3>
<p>[to be filled in]</p>
<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/EA_vG_ktwx4" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2010/03/make-work-visible/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2010/03/make-work-visible/</feedburner:origLink></item>
		<item>
		<title>Automate Release Checks</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/Ixv4i0IyKRs/</link>
		<comments>http://eraserhead.net/2010/03/automate-release-checks/#comments</comments>
		<pubDate>Mon, 08 Mar 2010 13:00:58 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Guerilla Software Recovery]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Process]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=485</guid>
		<description><![CDATA[Context

Each release of your product has some unique aspect to it, for example an intended customer-specific configuration.
Releases of your product are frequently made which fail in some, though not necessarily always the same, downstream step.
Verifying correct operation of each build empirically is time consuming or costly.

Therefore

Write a program which is the simplest possible wrapper for [...]]]></description>
			<content:encoded><![CDATA[<h2>Context</h2>
<ul>
<li>Each release of your product has some unique aspect to it, for example an intended customer-specific configuration.
<li>Releases of your product are frequently made which fail in some, though not necessarily always the same, downstream step.
<li>Verifying correct operation of each build empirically is time consuming or costly.
</ul>
<h2>Therefore</h2>
<ol>
<li>Write a program which is the simplest possible wrapper for your release of the artifact consumed downstream.
<li>Each time a failure causes a flow interruption, modify the program to detect this problem with the artifact and fail loudly, refusing to produce the artifact.
</ol>
<h2>Discussion</h2>
<p>This pattern operates on the general principle that a shorter feedback loop for failures will have less negative effect on effort hours and throughput.  This is the same principle embodied by test-driven development applied in a slightly different context.  To build on the analogy, consider instituting a policy of adding the automated release check to your artifact-builder <em>before</em> correcting the downstream problem, and verifying the release check by attempting to release a new build without correcting the original problem.</p>
<p>This is a kind of test-driven development which is fed by downstream regressions.  It is an attempt to introduce a positive <a href="http://en.wikipedia.org/wiki/Ratchet_effect">rachet effect</a>.</p>
<p>If you do not have some unique aspect to each release, you could simply add unit tests which fail the build if in-repository artifacts are somehow inconsistent or incorrect.  Even though we don&#8217;t usually think to add unit tests to verify, say, properties of configuration files stored in the repository, these unit tests provide a tighter feedback loop than this pattern and should be preferred.</p>
<h2>Observed Instances</h2>
<h3>One</h3>
<p>We have a product where frequent, customer-specific releases are made to an independent QA department.  Two files are delivered, an installer exe and an ini file.  The ini file is read by the installer exe and causes the installer to install the correct components and install the proper configuration into the registry.  The install is a lengthy process (twenty minutes) on machines which have a lot of software installed, discouraging developers from running the installer.  Also, verifying correct operation requires setting up a protocol emulator which may not be available.</p>
<p>The ini file layout is very brittle.  It contains many options which must be consistent with other options.  There are also many options which must be specified for every component in the configuration.  Yet other options can cause some other options to be ignored entirely.  The install itself rarely fails, it leaves the machine configured in an unusable state instead.</p>
<p>A significant portion of my time was spent in the QA lab troubleshooting failed installs.  When I first started maintaining this software, it seemed like one third of a typical day might be spent in the QA lab.  Since QA is on an isolated network, I went through many thumb drives, not remembering which machine I had last left it in.</p>
<p>I wrote a wrapper for building the install after reading the ini file.  This also had the benefit of allowing us to remove unused components from an install.  For each failure found in QA, I made it fail loudly and abort before building an install if the problem was detected with the ini file.</p>
<p>I haven&#8217;t been in the QA lab in more than four months.  I have kept the same thumb drive for perhaps a year, though I&#8217;m no longer sure what&#8217;s on it.</p>
<p>This has had an unexpected compounding positive effect:  The most likely causes of an install failing are now either procedural or due to configuration changes made for testing in QA.  Previously, the most likely cause of an install failing was that it had been packaged incorrectly.  As a result of this shift, development is no longer the first on the scene of a failed install.  Instead, the techs responsible for deploying the software to the customer handle most QA installation issues.</p>
<p>It might seem that a more fundamental problem in this occurrence is the brittleness of the configuration format, that it admits self-inconsistency.  This is probably true; however, I could not determine a way to re-engineering the format piecemeal, and customer commitments (as well as time logged in the QA lab!) made such a large project unlikely on a maintenance-mode product.  Also, the current installer has all sorts of difficult-to-understand logic with undocumented intent.  This solution was truly cheap to get running.</p>
<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/Ixv4i0IyKRs" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2010/03/automate-release-checks/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2010/03/automate-release-checks/</feedburner:origLink></item>
		<item>
		<title>Super High-Performance Networking Code</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/HWI_wEYgWAg/</link>
		<comments>http://eraserhead.net/2010/01/super-high-performance-networking-code/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 16:00:00 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Anti-Patterns]]></category>
		<category><![CDATA[Networking]]></category>
		<category><![CDATA[Sockets]]></category>
		<category><![CDATA[TCP]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=477</guid>
		<description><![CDATA[I&#8217;ve encountered a faulty assumption about how TCP works, actually in multiple code bases I&#8217;ve maintained.  Interestingly, my colleague Jeff and perhaps soon-to-be colleague Dane have also encountered this more than once and have dubbed it &#8220;Super High-Performance Networking Code.&#8221;
In Super High-Performance Networking Code, the sending side might look something like this:

   [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve encountered a faulty assumption about how TCP works, actually in multiple code bases I&#8217;ve maintained.  Interestingly, my colleague Jeff and perhaps soon-to-be colleague Dane have also encountered this more than once and have dubbed it &#8220;Super High-Performance Networking Code.&#8221;</p>
<p>In Super High-Performance Networking Code, the sending side might look something like this:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">void</span> OnFooEvent<span style="color: #008000;">&#40;</span>Event e<span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">char</span> <span style="color: #000040;">*</span>ptr <span style="color: #000080;">=</span> e.<span style="color: #007788;">GetVariableLengthPayloadDataAsBytes</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">int</span> len <span style="color: #000080;">=</span> e.<span style="color: #007788;">GetLengthOfPayloadData</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #0000ff;">int</span> rc <span style="color: #000080;">=</span> send<span style="color: #008000;">&#40;</span>m_socket, ptr, len, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
        <span style="color: #666666;">// handle error.</span>
    <span style="color: #008000;">&#125;</span></pre></div></div>

<p>&#8230; and the receiving side might look like this &#8230;</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">void</span> ReceiveLoop<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        <span style="color: #0000ff;">while</span> <span style="color: #008000;">&#40;</span><span style="color: #000040;">!</span>m_bDone<span style="color: #008000;">&#41;</span>
        <span style="color: #008000;">&#123;</span>
            <span style="color: #0000ff;">char</span> buf<span style="color: #008000;">&#91;</span>REALLY_BIG<span style="color: #008000;">&#93;</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">int</span> len <span style="color: #000080;">=</span> recv<span style="color: #008000;">&#40;</span>m_socket, buf, <span style="color: #0000dd;">sizeof</span><span style="color: #008000;">&#40;</span>buf<span style="color: #008000;">&#41;</span>, <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #0000ff;">if</span> <span style="color: #008000;">&#40;</span>len <span style="color: #000080;">&gt;</span> <span style="color: #0000dd;">0</span><span style="color: #008000;">&#41;</span>
            <span style="color: #008000;">&#123;</span>
                HandleExactlyOneFooEventWithVariableLengthData<span style="color: #008000;">&#40;</span>buf, len<span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
            <span style="color: #008000;">&#125;</span>
        <span style="color: #008000;">&#125;</span>
    <span style="color: #008000;">&#125;</span></pre></div></div>

<p>The fatal assumption is that read sizes on the receiving end are coincident with the write sizes on the sending end.</p>
<p>TCP networking is a stream-based protocol and it makes NO guarantees that the read and write sizes are coincident.  In fact, it has a few mechanisms which will actively thwart this, including <a href="http://en.wikipedia.org/wiki/Nagle%27s_algorithm">Nagle&#8217;s algorithm</a>.  Also, all TCP networks have an <a href="http://en.wikipedia.org/wiki/Maximum_transmission_unit">MTU</a>, and packets larger than this will be sliced up for delivery (although without affecting the data contained within or the guaranteed order of delivery).  There is some handshaking to discover the minimum MTU along a route, though this is intended to allow client systems to adapt for maximum throughput and is <em>not</em> a guarantee that slicing won&#8217;t happen.  It&#8217;s more like a guarantee that slicing won&#8217;t happen frequently. Additionally, loaded routers may well choose to split transmit units or collect and concatenate them in order to meet quality of service and throughput requirements.</p>
<p>Unfortunately, though, making this assumption will work often enough with small packet sizes to lull some developers into believing they&#8217;ve confirmed that assuming read and write sizes are coincident is sound.</p>
<p>If you are making this assumption, you need to redesign your wire protocol to include within it a mechanism for delineation of the data, such as sending the data size up front, or using some sort of end-of-data marker.  You then need to collect the reads on the receiving side until you&#8217;ve reached the demarcation or expected data size.</p>
<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/HWI_wEYgWAg" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2010/01/super-high-performance-networking-code/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2010/01/super-high-performance-networking-code/</feedburner:origLink></item>
		<item>
		<title>Rules for Commenting</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/kUV-CeAHVXM/</link>
		<comments>http://eraserhead.net/2009/12/rules-for-commenting/#comments</comments>
		<pubDate>Wed, 30 Dec 2009 14:00:20 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Comments]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=446</guid>
		<description><![CDATA[It&#8217;s been a little while since I wrote Comments Unhelpful, and two recent events bring me back to the topic.  The first event is discussion brought up by a colleague about implementing commenting requirements in our coding standard.  The second event is Mark Schumann&#8217;s recent post including explanation of what would have helped [...]]]></description>
			<content:encoded><![CDATA[<p>It&#8217;s been a little while since I wrote <a href="http://eraserhead.net/2009/03/comments-unhelpful/">Comments Unhelpful</a>, and two recent events bring me back to the topic.  The first event is discussion brought up by a colleague about implementing commenting requirements in our coding standard.  The second event is <a href="http://criticalresults.com/">Mark Schumann&#8217;s</a> recent <a href="http://blog.criticalresults.com/2009/12/28/coding-sideways/">post</a> including explanation of what would have helped him crack the codes of a physicist.</p>
<p>Since I&#8217;ve ranted about what doesn&#8217;t work, perhaps I should post what I&#8217;ve found that does work.</p>
<h2>Rule One: Prefer &#8220;Rename Class,&#8221; <a href="http://www.refactoring.com/catalog/renameMethod.html">Rename Method</a>, and <a href="http://www.refactoring.com/catalog/extractMethod.html">Extract Method</a> Over Comments</h2>
<p>The code itself is durable.  Comments are not.  If you can obsolete the need for a comment by renaming a class or method, do it.</p>
<p>A note on <a href="http://www.refactoring.com/catalog/extractMethod.html">Extract Method</a>.  If you haven&#8217;t read Fowler&#8217;s <a href="http://www.amazon.com/exec/obidos/ASIN/0201485672">Refactoring</a>, this was a particularly enlightening &#8220;Aha!&#8221; for me.</p>
<p>When you are writing a function, and those little one-line comments come up that explain the next little logical block of code, you should extract that little block of code into a method, name it so that it conveys the information from the comment, and kill the comment.  This is good design as well as good documentation.</p>
<h2>Rule Two: Don&#8217;t Put Anything in a Comment which has Already Been Expressed</h2>
<p>This simply means that you should apply <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a> to comments like you would apply it to any other piece of the system.  Many of my points in <a href="http://eraserhead.net/2009/03/comments-unhelpful/">Comments Unhelpful</a> are directly related to this rule.</p>
<p>Do not include any part of your function or class signature, such as return type, parameter types, exception names &#8211; and certainly don&#8217;t repeat the function or class&#8217;s name.  The only exception is referring to an item to add more documentation.  Also, do not feel compelled to add documentation for every parameter if you have no non-obvious information to add.</p>
<p>Do not include any information available from version control, such as author, modification date, or revision number.  Version control is much better at tracking this information than you are.</p>
<h2>Rule Three: Class and Method Comments Should Contain a One-Sentence Summary</h2>
<p>This is not an argument for adding a comment to every method and class, but every method and class which has a comment should start with a one-sentence summary.  This enables programmers to understand the code more quickly, as well as supports tools like Javadoc and Doxygen.</p>
<p>The one-sentence summary should clearly document the item&#8217;s <a href="http://en.wikipedia.org/wiki/Single_responsibility_principle">single responsibility</a>.  I can&#8217;t find reference to it now for proper attribution, but I once read that every class in the system should be describable in one sentence, and the sentence should always be simple (as opposed to compound) and have no qualifying clauses.  This works to expose design problems with new and refactored code.  You may not be able to apply this if you are documenting existing code without refactoring.</p>
<p>Use first-person active voice to help clarify your thoughts.  For example, &#8220;I sort a list into an order suitable for presentation.&#8221; instead of &#8220;Sort a list for presentation&#8221; or &#8220;Sorts a list for presentation&#8221; or &#8220;This method sorts a list for presentation.&#8221;  This is a sort of a commenting-by-rote jamming mechanism.  I don&#8217;t know why, but personifying classes and methods seems to reify them better.  I first encountered this in emacs lisp code.</p>
<h2>Rule Four: Synopsis Over Exposition</h2>
<p>&#8220;Synopsis&#8221; is the contribution of perldoc to my commenting rules.  Exposition is hard to write, hard to read, and harder to maintain.  A short synopsis of how the class or method is intended to be used is much easier to read and understand.  You can add comments to your synopsis to clarify non-obvious points.  You also receive the additional benefit that when you rename a method or class with a text search-and-replace, it does not invalidate your synopsis.</p>
<p>For example:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;"><span style="color: #ff0000; font-style: italic;">/**
 * I manage a pool of devices.
 *
 * Synopsis:
 *   DeviceContainer* p = new DeviceContainer();
 *   p-&gt;AddDevice(&quot;COM1:&quot;);
 *   p-&gt;AddDevice(&quot;COM2:&quot;);
 *   if (!p-&gt;Check()) fail(&quot;Don't have all devices!&quot;);    
 */</span>
<span style="color: #0000ff;">class</span> DeviceContainer <span style="color: #008000;">&#123;</span></pre></div></div>

<h2>Rule Five: Why, What, and Not How</h2>
<p>This is the &#8220;Linus Torvalds&#8221; rule.  From the Linux kernel CodingStyle document:</p>
<blockquote><p>
Comments are good, but there is also a danger of over-commenting.  NEVER try to explain HOW your code works in a comment: it&#8217;s much better to write the code so that the _working_ is obvious, and it&#8217;s a waste of time to explain badly written code.</p>
<p>Generally, you want your comments to tell WHAT your code does, not HOW.  Also, try to avoid putting comments inside a function body: if the function is so complex that you need to separately comment parts of it, you should probably go back to chapter 6 for a while.  You can make small comments to note or warn about something particularly clever (or ugly), but try to avoid excess.  Instead, put the comments at the head of the function, telling people what it does, and possibly WHY it does it.
</p></blockquote>
<h2>Rule Six: Astonishment</h2>
<p>Anything which would <a href="http://en.wikipedia.org/wiki/Principle_of_least_astonishment">astonish</a> a programmer attempting to use the entity should be documented if it can&#8217;t be corrected.</p>
<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/kUV-CeAHVXM" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2009/12/rules-for-commenting/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2009/12/rules-for-commenting/</feedburner:origLink></item>
		<item>
		<title>Binary iostreams in C++</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/it3A5jUuIxU/</link>
		<comments>http://eraserhead.net/2009/12/binary-iostreams-in-cpp/#comments</comments>
		<pubDate>Mon, 28 Dec 2009 14:00:08 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Boost]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[I/O]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=429</guid>
		<description><![CDATA[In the past, I&#8217;ve reached for the C stdio library when I need to do binary file I/O in C++.  Why?  Well, much of the C++ iostreams interface is designed for character- rather than byte-based I/O:

I/O is generally done through the &#60;&#60; and &#62;&#62; operators, which format types to a character representation.
Stream objects [...]]]></description>
			<content:encoded><![CDATA[<p>In the past, I&#8217;ve reached for the C stdio library when I need to do binary file I/O in C++.  Why?  Well, much of the C++ iostreams interface is designed for character- rather than byte-based I/O:</p>
<ul>
<li>I/O is generally done through the <tt>&lt;&lt;</tt> and <tt>&gt;&gt;</tt> operators, which format types to a character representation.
<li>Stream objects can be &#8220;imbued&#8221; with C++ <tt>locale</tt> objects, affecting various aspects of I/O, including how numbers are formatted and how bytes are translated into characters.
<li>The <tt>ios::binary</tt> flag only affects line-ending conversion, not character conversion.
<li>Stream objects&#8217; locales are inherited from the global locale.
</ul>
<p>I figured this would make binary I/O difficult, but I never researched it.</p>
<p>The opportunity to figure this out has just come up.  I wrote a class which builds a <a href="http://en.wikipedia.org/wiki/Tar_(file_format)">tar file</a> on the fly by writing it to a generic iterator.  Its <tt>AddFile()</tt> also reads the contents of the file to store from an iterator.</p>
<p>I wrote this under test without hitting the disk, but the last step is to supply binary file input and output iterators. After successfully implementing a binary file input iterator, I thought, &#8220;It&#8217;s hard to believe that <a href="http://www.boost.org/">Boost</a> doesn&#8217;t already have these.&#8221; I posted on the list and quickly received an answer:</p>
<blockquote><p>Use the standard streambuf iterators, istreambuf_iterator and ostreambuf_iterator.</p></blockquote>
<p>Can we do that?  What about locales and character set translation?</p>
<p>So finally I looked into this locale thing. It seems the ISO C++ specification guarantees that <tt>codecvt&lt;&gt;</tt>, which is the facet of the locale that translates characters, performs no translation in the case of converting from a narrow char buffer to a narrow char buffer.  The specification considers this a &#8220;degenerate case.&#8221;</p>
<p>Conclusion: The C++ language specification guarantees that <em>narrow</em> iostreams will pass through untranslated bytes regardless of the current locale.</p>
<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/it3A5jUuIxU" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2009/12/binary-iostreams-in-cpp/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2009/12/binary-iostreams-in-cpp/</feedburner:origLink></item>
		<item>
		<title>Yet Another “Singletons Are Evil” Rant</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/ZWCG_xQrXs0/</link>
		<comments>http://eraserhead.net/2009/12/yet-another-singletons-are-evil-rant/#comments</comments>
		<pubDate>Tue, 22 Dec 2009 04:23:22 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Dependency Injection]]></category>
		<category><![CDATA[Evil]]></category>
		<category><![CDATA[Patterns]]></category>
		<category><![CDATA[Singleton]]></category>
		<category><![CDATA[TDD]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=413</guid>
		<description><![CDATA[The issue with Singletons is twofold. First, it is not a problem that you&#8217;d like to enforce only one instance of something within a system. It is a problem that you are enforcing only one instance of something within a system using the Singleton pattern. Why?
1. You are coupling every client of the class with [...]]]></description>
			<content:encoded><![CDATA[<p>The issue with Singletons is twofold. First, it is <em>not</em> a problem that you&#8217;d like to enforce only one instance of something within a system. It <em>is</em> a problem that you are enforcing only one instance of something within a system using the Singleton pattern. Why?</p>
<p>1. You are coupling every client of the class with the <em>knowledge</em> the class has only one instance.  This comes from C++&#8217;s distinct syntax for obtaining the instance of a Singleton. This (a) very much violates the intent of encapsulation in object-oriented systems, (b) is a violation of <a href="http://en.wikipedia.org/wiki/Don%27t_repeat_yourself">DRY</a>, and (c) is a violation of the <a href="http://c2.com/cgi/wiki?UniformAccessPrinciple">Uniform Access Principle</a> (or a slight generalization of it in any case).</p>
<p>2. In order to unit test effectively, you need to exercise different states. With some common usages of singletons, not all interesting states are reachable. Even the states which are reachable are more difficult to reach.</p>
<p>To give an example, I maintain a Java application which uses Singleton pattern for its configuration data object. You might think this is reasonable, since an application can have only one configuration, and that is an <em>essential</em> property of the system&#8217;s configuration, correct? The object&#8217;s <tt>getInstance()</tt> method deserializes the configuration object from some XML on disk on the first invocation, and reuses the object on subsequent invocations.</p>
<p>Now, how do I unit test this system? Let&#8217;s say I have some configurable object that can exhibit two kinds of behavior. I can write the XML in our testing directory one way, and test one kind of behavior, or I can write it the other way and test the other kind of behavior. Alternately, I can add a <tt>reset()</tt> or <tt>setInstance()</tt> to the Singleton, making it no longer a Singleton, and write machinery which modifies the config then essentially reboots the system. This is a lot of extra work. If you pay careful attention to what you&#8217;ve just done, you&#8217;ve replaced Singleton with something that I am now dubbing &#8220;Service Injection by Global Variable.&#8221;</p>
<p>It gets worse: Even for classes in the system where I can inject parameters, the parameters themselves, or far removed dependencies of them or the object, may depend on other global mutable state. If I have a system where Singletons are common, this erodes my confidence that my unit tests guarantee correct execution of my program. This is just the same old &#8220;global variables&#8221; argument &#8211; it is more difficult to reason about programs because you need to know not just the interface of an object and its liftetime, but also the global mutable state on which it depends to predict its behavior.</p>
<p>Solutions:</p>
<p>1. There are dependency-injection frameworks (e.g. Spring, in Java-land) that allow you to declare singleton instances in a way such that the same instance is injected to every object that requests the instance. This is <em>not</em> a problem, even though the word &#8220;singleton&#8221; appears: (a) the client code is not coupled with the knowledge that such an object is singleton, and (b) the knowledge that an object is singleton is expressed in a single place, and (c) the client code is identical regardless of whether the object is a singleton.</p>
<p>2. When you aren&#8217;t using a dependency-injection framework, injection (either by constructor or setter) is still the &#8220;right&#8221; route. I know that it seems hard, but there are plenty of tricks to make it easier, especially in C++ &#8211; the simplest of which is aggregating the most commonly used of the system&#8217;s services into a parameter object. In addition to what I&#8217;ve said above, this is the &#8220;right&#8221; choice because the application&#8217;s <em>application object</em> (for example) rather than the class providing some service should be the single point of knowledge deciding whether some service should be singleton across the application.</p>
<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/ZWCG_xQrXs0" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2009/12/yet-another-singletons-are-evil-rant/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2009/12/yet-another-singletons-are-evil-rant/</feedburner:origLink></item>
		<item>
		<title>Using “git bisect” to find the GOOD patch</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/KzJlcr0oaiA/</link>
		<comments>http://eraserhead.net/2009/12/using-git-bisect-to-find-the-good-patch/#comments</comments>
		<pubDate>Thu, 17 Dec 2009 16:10:42 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[Git]]></category>
		<category><![CDATA[Workflow]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=411</guid>
		<description><![CDATA[I&#8217;ve been using git as my Subversion client at work lately.  I&#8217;ve promised myself that I will blog more about this, but I still need to work out some kinks in my work flow and bootstrapping the process.
In any case, git bisect has turned out to be an invaluable tool for isolating the cause [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been using <a href="http://www.git-scm.org/">git</a> as my Subversion client at work lately.  I&#8217;ve promised myself that I will blog more about this, but I still need to work out some kinks in my work flow and bootstrapping the process.</p>
<p>In any case, <a href="http://www.kernel.org/pub/software/scm/git/docs/git-bisect.html">git bisect</a> has turned out to be an invaluable tool for isolating the cause of reproducible failures when you are starting with a known good build and a known bad build.  I&#8217;ve isolated three failures in the last couple weeks.  All were subtle race condition or other threading issues which appear apparently at random &#8211; the worst kind!</p>
<p>Prior to this, we were doing what my coworker <a href="http://cranksters.org/">Jeff Messner</a> calls &#8220;debugging by epiphany&#8221; &#8211; stare at the logs, then the code, then the logs, then the code, then the logs&#8230; until in a Zen koan moment you are enlightened.</p>
<p>Perhaps this is why the Linux kernel is so reliable.  Linus advocating the identification of failures by bisection since the very first kernel documentation I ever read.  Curiously, Linus himself authored the &#8220;git bisect&#8221; command.</p>
<p>In any case, I encountered a scenario yesterday where a recent build of a component resolved a customer&#8217;s issue; however, it wasn&#8217;t obvious which change was the actual resolution.  I&#8217;m documenting this information these days in machine-readable format so that our program which builds customer installs will flag bad combinations of components before we ship to QA.</p>
<p>I tried to reverse the &#8220;good&#8221; and &#8220;bad&#8221; patches with bisect, hoping it would be smart enough to deduce that I was looking for the patch which introduced the <em>fixing</em> change, rather than the usual <em>breaking</em> change.  It was no go &#8211; git tells me there is a problem with the patch ancestry; it absolutely requires the good change to appear before the bad.</p>
<p>It turns out that it wasn&#8217;t too difficult to just tell git that the good builds were bad and the bad builds were good in order to isolate the change which resolved the customer issue.</p>
<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/KzJlcr0oaiA" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2009/12/using-git-bisect-to-find-the-good-patch/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2009/12/using-git-bisect-to-find-the-good-patch/</feedburner:origLink></item>
		<item>
		<title>Write a Test Driver Class</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/02nHyr9WzFI/</link>
		<comments>http://eraserhead.net/2009/12/write-a-test-driver-class/#comments</comments>
		<pubDate>Wed, 02 Dec 2009 11:00:38 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Coding]]></category>
		<category><![CDATA[C++]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[TDD]]></category>
		<category><![CDATA[xUnit]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=113</guid>
		<description><![CDATA[&#8220;Conventional xUnit wisdom&#8221; holds that one should organize tests into groups and implement these tests in one class, factoring common set up and tear down operations into the class&#8217;s setUp() and tearDown() methods.  I think this wisdom is perpetuated mostly by the apparently intentional design of xUnit testing frameworks for this kind of usage. [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Conventional <a href="http://en.wikipedia.org/wiki/XUnit">xUnit</a> wisdom&#8221; holds that one should organize tests into groups and implement these tests in one class, factoring common set up and tear down operations into the class&#8217;s <tt>setUp()</tt> and <tt>tearDown()</tt> methods.  I think this wisdom is perpetuated mostly by the apparently intentional design of xUnit testing frameworks for this kind of usage.  (Note that <a href="http://www.boost.org/doc/libs/1_41_0/libs/test/doc/html/index.html">Boost.Test</a> is fundamentally different, and people absolutely <em>hate</em> it when they first encounter it just because of this, even though it seems to work better in the long run for reasons we shall shortly see.)</p>
<p>This pattern quickly becomes problematic.  For the first few quick hack tests, it works wonderfully.  As the code under test evolves, you&#8217;ll usually add small batches of one, two or three tests each.</p>
<p>As you add the sixth test to a class, you notice that you did a pretty similar kind of set up for two tests.  You can&#8217;t move this code into setUp(), since the other tests in the suite have the opposite precondition. So you factor this code out into a separate private method and call it in both places.</p>
<p>As you write your tenth test, you notice that checking the result from a particular method under test requires three repeated lines of code for each test.  Being a diligent coder, you factor this out into an <tt>assertFoo()</tt> method and replace all the existing instances of the repetition.</p>
<p>As the design evolves, your class under test becomes one of two, then three, different strategies for dealing with a problem.  As you start your third test suite, and start retyping the suite of methods you&#8217;ve written for testing this sort of class, you think, &#8220;This is getting crazy &#8211; I need to reuse those methods.&#8221;  At this point, the first thing you think is, &#8220;Let&#8217;s create a superclass for this set of test cases, and pull up all these methods we&#8217;ve written so they can be reused.</p>
<p>Of course, <a href="http://www.artima.com/lejava/articles/designprinciples4.html">this is usually a bad design practice</a>, even outside of our xUnit test suites.  But it is still a common one, because aggregation is just so darned painful in most common, modern, production-ready languages.  In terms of design and reuse, it&#8217;s all downhill from here.</p>
<p>Why do we keep getting ourselves into this trap?</p>
<h3>xUnit frameworks enforce the use of classes for structural grouping</h3>
<p>I&#8217;m sure we probably all remember that &#8220;neato!&#8221; feeling we had when we first saw an xUnit suite and realized that the framework was utilizing reflection or some other language trick to run all the tests.  &#8220;Hey, that&#8217;s pretty cool, and it saves a lot of work!&#8221;  Well, sure it does.</p>
<p>It may not dawn on us right away that this is not what classes are for!</p>
<h3>Normal object oriented design principles suggest that classes are for encapsulation and code reuse</h3>
<p><em>&#8230;not</em> for structural grouping of similar objects (in this case, tests), or to provide mechanisms to run lists of objects!  We could say that our xUnit suite runners are a historic record of some shortcomings of Smalltalk and Java.</p>
<h3>These two uses of classes are at cross-purposes</h3>
<p>Showing that these two design patterns are <em>not</em> at cross-purposes would require showing that any logical structural grouping of tests would coincide with (or could be made to coincide with) useful patterns of encapsulation.  This seems like a proof too difficult to attempt; however, I can say that my own experience suggests that logical structural grouping of tests does <em>not</em> coincide with useful patterns of encapsulation.</p>
<h2>The xUnit Design Heuristic</h2>
<p>Stated formally:</p>
<blockquote><p>Since xUnit&#8217;s use of classes to group tests is in conflict with the use of classes for encapsulation and reuse in object oriented design, regard the use of test suites for reusable code or encapsulation as a code smell and prefer creating a driver class.
</p></blockquote>
<p>The driver class encapsulates all or part of a test run and serves as a target for <a href="http://www.refactoring.com/catalog/moveMethod.html">Move Method</a> for those assertions and helper methods.  These classes should follow a number of design principles:</p>
<h3>Make the driver class own all references to the class under test, fake and mock objects, and other state needed to run the test.</h3>
<p>This is simply restating that our driver class&#8217;s purpose is encapsulation.</p>
<h3>Defer construction of the test&#8217;s state to the last possible moment</h3>
<p>For our tests to be thorough, they need to be able to test our class under test under many different preconditions.  Setting up a lot of state in the class&#8217;s constructor may make it difficult or time-consuming to override later.  Consider making the various methods set flags or other fields indicating how the test should be run, and having a runner method (or even method object) use these flags for running the test.</p>
<h3>Use Builder Pattern to construct test specifications</h3>
<p>If designed well, this can greatly improve the readability and the re-usability of the testing code:</p>

<div class="wp_syntax"><div class="code"><pre class="cpp" style="font-family:monospace;">    <span style="color: #0000ff;">void</span> test_Does_not_indicate_balance_receptive_if_balance_return_flag_is_N<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
    <span style="color: #008000;">&#123;</span>
        BasicRequest<span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
            .<span style="color: #007788;">With</span><span style="color: #008000;">&#40;</span>FID_CARDID<span style="color: #008000;">&#41;</span>.<span style="color: #007788;">Of</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;MAS&quot;</span><span style="color: #008000;">&#41;</span>
            .<span style="color: #007788;">With</span><span style="color: #008000;">&#40;</span>FID_BALANCE_RETURN_CAPABLE<span style="color: #008000;">&#41;</span>.<span style="color: #007788;">Of</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;N&quot;</span><span style="color: #008000;">&#41;</span>
            .<span style="color: #007788;">SendsMessageWhere</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>
                .<span style="color: #007788;">SPIField</span><span style="color: #008000;">&#40;</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">Substring</span><span style="color: #008000;">&#40;</span><span style="color: #0000dd;">1</span>,<span style="color: #0000dd;">1</span><span style="color: #008000;">&#41;</span>.<span style="color: #007788;">Equals</span><span style="color: #008000;">&#40;</span><span style="color: #FF0000;">&quot;N&quot;</span><span style="color: #008000;">&#41;</span><span style="color: #008080;">;</span>
    <span style="color: #008000;">&#125;</span></pre></div></div>

<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/02nHyr9WzFI" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2009/12/write-a-test-driver-class/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2009/12/write-a-test-driver-class/</feedburner:origLink></item>
		<item>
		<title>New Project: ehnet-spc</title>
		<link>http://feedproxy.google.com/~r/eraserhead/ADNx/~3/AYfdQqgwUas/</link>
		<comments>http://eraserhead.net/2009/11/new-project-ehnet-spc/#comments</comments>
		<pubDate>Mon, 30 Nov 2009 01:59:03 +0000</pubDate>
		<dc:creator>Jason</dc:creator>
				<category><![CDATA[Ehnet SPC]]></category>
		<category><![CDATA[Github]]></category>
		<category><![CDATA[Scala]]></category>
		<category><![CDATA[SPC]]></category>

		<guid isPermaLink="false">http://eraserhead.net/?p=405</guid>
		<description><![CDATA[I&#8217;ve just started ehnet-spc, a new Scala project on github for plotting Statistical Process Control (SPC) charts.  It&#8217;s very bare-bones, but it can produce SVG charts.  It only does subgroup size 1 with moving average ranges at the moment.
Here is a sample control chart.
]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve just started <a href="http://github.com/eraserhd/ehnet-spc">ehnet-spc</a>, a new Scala project on <a href="http://github.com/eraserhd">github</a> for plotting Statistical Process Control (SPC) charts.  It&#8217;s very bare-bones, but it can produce SVG charts.  It only does subgroup size 1 with moving average ranges at the moment.</p>
<p><a href="http://eraserhead.net/files/sample-spc.svg">Here</a> is a sample control chart.</p>
<img src="http://feeds.feedburner.com/~r/eraserhead/ADNx/~4/AYfdQqgwUas" height="1" width="1"/>]]></content:encoded>
			<wfw:commentRss>http://eraserhead.net/2009/11/new-project-ehnet-spc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		<feedburner:origLink>http://eraserhead.net/2009/11/new-project-ehnet-spc/</feedburner:origLink></item>
	</channel>
</rss>
