<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/css" href="/stylesheets/rss.css"?>
<rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
  <channel>
    <title>Floehopper: Tag continuous</title>
    <link>http://blog.floehopper.org/articles/tag/continuous?tag=continuous</link>
    <language>en-us</language>
    <ttl>40</ttl>
    <description>thoughts on the bergy bits of life</description>
    <item>
      <title>Nasty Ruby Bug Affecting Test::Unit</title>
      <description>&lt;h3 id="introduction"&gt;Introduction&lt;/h3&gt;


	&lt;p&gt;Some time ago, while I was pair-programming with him, &lt;a href="http://blog.seagul.co.uk"&gt;Chris&lt;/a&gt; alerted me to a &lt;a href="http://www.ruby-lang.org/"&gt;Ruby&lt;/a&gt; bug he&amp;#8217;d come across which was interfering with the diagnosis of a bug in our application. Since then I&amp;#8217;ve tried to find out more about it, but couldn&amp;#8217;t find much, so I&amp;#8217;ve done a bit of investigation and thought I&amp;#8217;d post it here in case it&amp;#8217;s useful to anyone else. The bug has long since been fixed, but I&amp;#8217;m sure there are still people our there with the &lt;a href="#affected-versions"&gt;affected versions&lt;/a&gt; of Ruby 1.8.6.&lt;/p&gt;


	&lt;h3 id="ruby-bug"&gt;Ruby bug&lt;/h3&gt;


	&lt;p&gt;As far as I understand it, the bug is in Ruby&amp;#8217;s &lt;a href="http://ruby-doc.org/core/classes/Kernel.html#M005958"&gt;&lt;code&gt;Kernel.at_exit&lt;/code&gt;&lt;/a&gt; hook. A call to &lt;a href="http://ruby-doc.org/core/classes/Kernel.html#M005956"&gt;&lt;code&gt;Kernel.exit(false)&lt;/code&gt;&lt;/a&gt; should cause the process to exit with an &lt;strong&gt;exit status of 1&lt;/strong&gt; indicating the process did not complete successfully. The bug means that calling &lt;a href="http://ruby-doc.org/core/classes/Kernel.html#M005956"&gt;&lt;code&gt;Kernel.exit(false)&lt;/code&gt;&lt;/a&gt; from within &lt;a href="http://ruby-doc.org/core/classes/Kernel.html#M005958"&gt;&lt;code&gt;Kernel.at_exit&lt;/code&gt;&lt;/a&gt; incorrectly causes the process to exit with an &lt;strong&gt;exit status of 0&lt;/strong&gt;.&lt;/p&gt;


	&lt;p&gt;The most relevant bug report is &lt;a href="http://rubyforge.org/tracker/?func=detail&amp;#38;atid=1698&amp;#38;aid=9300&amp;#38;group_id=426"&gt;#9300&lt;/a&gt; and the most relevant mailing list thread is made up of:- &lt;a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/10746"&gt;[ruby-core:10746]&lt;/a&gt;, &lt;a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/10748"&gt;[ruby-core:10748]&lt;/a&gt;, &lt;a href="http://blade.nagaokaut.ac.jp/cgi-bin/scat.rb/ruby/ruby-core/10760"&gt;[ruby-core:10760]&lt;/a&gt;.&lt;/p&gt;


The fix seems to be in changeset 12126&amp;#8230;
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_default "&gt;r12126 | nobu | 2007-03-23 16:53:42 +0000 (Fri, 23 Mar 2007) | 9 lines

* eval.c (ruby_cleanup): exit by SystemExit and SignalException in END
  block.  [ruby-core:10609]

* test/ruby/test_beginendblock.rb (test_should_propagate_exit_code):
  test for exit in END block.  [ruby-core:10760]

* test/ruby/test_beginendblock.rb (test_should_propagate_signaled):
  test for signal in END block.&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;h3 class="implications"&gt;Implications for Test::Unit &amp;#38; Rake::TestTask&lt;/h3&gt;


	&lt;p&gt;The &lt;a href="#ruby-bug"&gt;bug&lt;/a&gt; has some important consequences. &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html"&gt;&lt;code&gt;Test::Unit&lt;/code&gt;&lt;/a&gt; makes use of this mechanism to report test failures. Unfortunately, the bug means that a &lt;a href="http://www.ruby-doc.org/stdlib/libdoc/test/unit/rdoc/classes/Test/Unit.html"&gt;&lt;code&gt;Test::Unit&lt;/code&gt;&lt;/a&gt; process will always return an &lt;strong&gt;exit status of 0&lt;/strong&gt; even when there have been test failures.&lt;/p&gt;


From &lt;code&gt;test/unit.rb&lt;/code&gt;:
&lt;div class="typocode"&gt;&lt;pre&gt;&lt;code class="typocode_ruby "&gt;&lt;span class="ident"&gt;at_exit&lt;/span&gt; &lt;span class="keyword"&gt;do&lt;/span&gt;
  &lt;span class="keyword"&gt;unless&lt;/span&gt; &lt;span class="global"&gt;$!&lt;/span&gt; &lt;span class="punct"&gt;||&lt;/span&gt; &lt;span class="constant"&gt;Test&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Unit&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run?&lt;/span&gt;
    &lt;span class="ident"&gt;exit&lt;/span&gt; &lt;span class="constant"&gt;Test&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;Unit&lt;/span&gt;&lt;span class="punct"&gt;::&lt;/span&gt;&lt;span class="constant"&gt;AutoRunner&lt;/span&gt;&lt;span class="punct"&gt;.&lt;/span&gt;&lt;span class="ident"&gt;run&lt;/span&gt;
  &lt;span class="keyword"&gt;end&lt;/span&gt;
&lt;span class="keyword"&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

	&lt;p&gt;This in turn means that a &lt;a href="http://rake.rubyforge.org/classes/Rake/TestTask.html"&gt;&lt;code&gt;Rake::TestTask&lt;/code&gt;&lt;/a&gt; process will also always return an &lt;strong&gt;exit status of 0&lt;/strong&gt; even when there have been test failures. This is significant, because many &lt;a href="http://martinfowler.com/articles/continuousIntegration.html"&gt;continuous integration&lt;/a&gt; systems rely on &lt;a href="http://rake.rubyforge.org/classes/Rake/TestTask.html"&gt;&lt;code&gt;Rake::TestTask&lt;/code&gt;&lt;/a&gt; processes returning an &lt;strong&gt;exit status of 1&lt;/strong&gt; to indicate that there have been test failures. Thus you will get false positive passing builds &amp;#8211; not good.&lt;/p&gt;


	&lt;h3 id="affected-versions"&gt;Affected versions of Ruby&lt;/h3&gt;


	&lt;p&gt;I&amp;#8217;ve built and installed a number of versions of Ruby and run tests on them to try to establish which ones are affected. Although they aren&amp;#8217;t comprehensive, here are the results&amp;#8230;&lt;/p&gt;


	&lt;table&gt;
		&lt;tr style="background:#ddd;"&gt;
			&lt;td&gt; affected? &lt;/td&gt;
			&lt;td&gt; version &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.4 (2005-12-24) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.5 (2006-08-25) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.5 (2007-03-16 patchlevel 37) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.5 (2008-03-03 patchlevel 115) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr style="color:red;"&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;Y&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-02-17 patchlevel 0) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr style="color:red;"&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;Y&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-03-13 patchlevel 0) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr style="color:red;"&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;Y&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-03-16 patchlevel 2) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr style="color:red;"&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;Y&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-03-19 patchlevel 4) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr style="color:red;"&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;Y&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-05-22 patchlevel 5) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr style="color:red;"&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;Y&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-05-22 patchlevel 6) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr style="color:red;"&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;Y&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-05-22 patchlevel 7) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-05-22 patchlevel 8) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-05-23 patchlevel 9) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-05-23 patchlevel 10) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.8.6 (2007-08-22 patchlevel 50) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
		&lt;tr&gt;
			&lt;td style="text-align:center;"&gt;&lt;code&gt;N&lt;/code&gt; &lt;/td&gt;
			&lt;td&gt; &lt;code&gt;ruby 1.9.0 (2007-11-28 patchlevel 0) [i686-darwin8.10.3]&lt;/code&gt; &lt;/td&gt;
		&lt;/tr&gt;
	&lt;/table&gt;</description>
      <pubDate>Sat, 05 Apr 2008 00:10:06 +0000</pubDate>
      <guid isPermaLink="false">urn:uuid:3aa53475-6a90-4cf6-915b-ff8804ff5d61</guid>
      <author>James Mead</author>
      <link>http://blog.floehopper.org/articles/2008/04/05/nasty-ruby-bug-affecting-test-unit</link>
      <category>ruby</category>
      <category>bug</category>
      <category>test</category>
      <category>unit</category>
      <category>exit</category>
      <category>code</category>
      <category>hook</category>
      <category>testing</category>
      <category>continuous</category>
      <category>integration</category>
    </item>
  </channel>
</rss>
