<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>NULL.in &#187; java</title>
	<atom:link href="http://www.nullin.com/tag/java/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.nullin.com</link>
	<description>Nalin's Labyrinth</description>
	<lastBuildDate>Mon, 04 Jul 2011 16:45:16 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>Logging tests to separate files</title>
		<link>http://www.nullin.com/2010/07/28/logging-tests-to-separate-files/</link>
		<comments>http://www.nullin.com/2010/07/28/logging-tests-to-separate-files/#comments</comments>
		<pubDate>Thu, 29 Jul 2010 04:07:34 +0000</pubDate>
		<dc:creator>Nalin</dc:creator>
				<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[logback]]></category>
		<category><![CDATA[logging]]></category>
		<category><![CDATA[testng]]></category>

		<guid isPermaLink="false">http://www.nalinmakar.com/?p=655</guid>
		<description><![CDATA[We have been using TestNG to run our tests for a while now. When we initially started, our code was written using Log4J and we were able to configure it to log all the tests to a single file. This made the logs very unwieldy and looking for issues very difficult. Looking at 100+ MB [...]]]></description>
			<content:encoded><![CDATA[<p>We have been using TestNG to run our tests for a while now. When we initially started, our code was written using Log4J and we were able to configure it to log all the tests to a single file. This made the logs very unwieldy and looking for issues very difficult. Looking at 100+ MB of logs isn&#8217;t an easy task. Changing this to rolling files only made the matters worse. So, I started looking for ways to log each test case into a separate file (meaning a test named foo, would be logged to foo.log).</p>
<p>My first attempt was to do this using log4j itself. Log4J doesn&#8217;t provide an easy way of doing this. It&#8217;s possible if you follow certain conventions in declaring your loggers and how you use MDC, but I wasn&#8217;t able to get it working with all my code. On looking a bit further, I found <a href="http://logback.qos.ch/">Logback</a>. And <a href="http://logback.qos.ch/manual/appenders.html#SiftingAppender">SiftingAppender</a> in Logback is just what I needed.</p>
<p>So, using <a href="http://www.slf4j.org/">slf4j</a>, <a href="http://logback.qos.ch/">logback</a>, <a href="http://logback.qos.ch/manual/mdc.html">MDC</a> and a few simple coding conventions, I was able to get per test log files working. Here&#8217;s what you need to do:</p>
<ol>
<li>Start using SLF4J for your logging. If you are using Log4J, <a href="http://www.slf4j.org/migrator.html">moving from L0g4J to SLF4J</a> is pretty simple</li>
<li>Write functions to set MDC at start of a test and unset it at the end of a test</li>
<li>Update the test cases, such that the MDC set/unset functions are invoked</li>
<li>Configure logback.xml to use the SiftingAppender</li>
</ol>
<p>I&#8217;ll expand a bit more on the above.</p>
<h2>Using SLF4J</h2>
<p>Starting to use SLF4J or moving to SLF4J from other logging frameworks is pretty straightforward. I didn&#8217;t bother using the java application at <a href="http://www.slf4j.org/migrator.html">http://www.slf4j.org/migrator.html</a> and found it much easier to just to regex to do the job. There were some places where <tt>log.xxx(object)</tt> had to be changed to <tt>log.xxx(object.toString())</tt> but that wasn&#8217;t a whole lot of pain.</p>
<h2>Code to set/unset MDC</h2>
<p>Logback&#8217;s documentation on MDC is very extensive and explains the concept quite clearly. Essentially using MDC would allow us to share a key/value across a thread hierarchy. Using MDC is as simple as putting a key/value into a Map. This value will be accessible anytime in the thread and any children of that thread. At the beginning of the test, we&#8217;ll put <tt>&lt;"testname", $test_case_name&gt;</tt> as the key/value into the map. At the end of the test, we&#8217;ll remove this key. This MDC value would be used by the sifting appender to create logs at runtime.  I wrote a simple class to encapsulate this functionality:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">package</span> <span style="color: #006699;">com.nm.examples</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.slf4j.Logger</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.slf4j.LoggerFactory</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">org.slf4j.MDC</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #008000; font-style: italic; font-weight: bold;">/**
 * Class to handle setting/removing MDC on per test case basis. This helps
 * us log each test case into it's own log file. Please see
 * {@link http://logback.qos.ch/manual/appenders.html#SiftingAppender}
 * and {@link http://logback.qos.ch/manual/mdc.html}
 * @author nullin
 */</span>
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> TestLogHelper
<span style="color: #009900;">&#123;</span>
  <span style="color: #000000; font-weight: bold;">private</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> Logger log <span style="color: #339933;">=</span> LoggerFactory.<span style="color: #006633;">getLogger</span><span style="color: #009900;">&#40;</span>TestLogHelper.<span style="color: #000000; font-weight: bold;">class</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000000; font-weight: bold;">final</span> <span style="color: #003399;">String</span> TEST_NAME <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;testname&quot;</span><span style="color: #339933;">;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/**
   * Adds the test name to MDC so that sift appender can use it and log the new
   * log events to a different file
   * @param name name of the new log file
   * @throws Exception
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> startTestLogging<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> name<span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
    MDC.<span style="color: #006633;">put</span><span style="color: #009900;">&#40;</span>TEST_NAME, name<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
&nbsp;
  <span style="color: #008000; font-style: italic; font-weight: bold;">/**
   * Removes the key (log file name) from MDC
   * @return name of the log file, if one existed in MDC
   */</span>
  <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #003399;">String</span> stopTestLogging<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
    <span style="color: #003399;">String</span> name <span style="color: #339933;">=</span> MDC.<span style="color: #006633;">get</span><span style="color: #009900;">&#40;</span>TEST_NAME<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    MDC.<span style="color: #006633;">remove</span><span style="color: #009900;">&#40;</span>TEST_NAME<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
    <span style="color: #000000; font-weight: bold;">return</span> name<span style="color: #339933;">;</span>
  <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<h2>Update test cases</h2>
<p>Now, you just need to make sure that you invoke <tt>TestLogHelper.startTestLogging(String testname)</tt> as early as possible during the test execution. Eventually, by the end of the test you should invoke <tt>TestLogHelper.stopTestLogging()</tt> to ensure that no extra logs get logged into this log file.</p>
<p>As we are using TestNG, for us it was a very simple matter of creating a method annotated @BeforeClass or @BeforeMethod as per requirements and put this code in there. For example, I use the following two methods in the base class for all our tests:</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;">   @BeforeClass
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testSetUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #666666; font-style: italic;">//start logging to test specific log file</span>
      TestLogHelper.<span style="color: #006633;">startTestLogging</span><span style="color: #009900;">&#40;</span>getTestId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
&nbsp;
      <span style="color: #666666; font-style: italic;">//</span>
      <span style="color: #666666; font-style: italic;">//Do some setup specific stuff here</span>
      <span style="color: #666666; font-style: italic;">//</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   @AfterClass
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> testCleanUp<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #000000; font-weight: bold;">throws</span> <span style="color: #003399;">Exception</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//</span>
         <span style="color: #666666; font-style: italic;">//Do some cleanup specific stuff here</span>
         <span style="color: #666666; font-style: italic;">//</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">finally</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #666666; font-style: italic;">//stop test logging to test specific file</span>
         TestLogHelper.<span style="color: #006633;">stopTestLogging</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #000066; font-weight: bold;">true</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #003399;">String</span> getTestId<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">return</span> <span style="color: #009900;">&#40;</span><span style="color: #009900;">&#40;</span>testId <span style="color: #339933;">==</span> <span style="color: #000066; font-weight: bold;">null</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">?</span> <span style="color: #009900;">&#40;</span><span style="color: #000000; font-weight: bold;">this</span>.<span style="color: #006633;">getClass</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span>.<span style="color: #006633;">getName</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #339933;">:</span> testId<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span></pre></div></div>

<h2>Configure logback.xml with SiftingAppender</h2>
<p>The last part is to configure the logback.xml to use a SiftingAppender. You can look at the <a href="http://logback.qos.ch/manual/appenders.html#SiftingAppender">documentation for SiftingAppender</a> to see the different examples. Following is a snippet of the configuration that I am using:</p>

<div class="wp_syntax"><div class="code"><pre class="xml" style="font-family:monospace;">   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;appender</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;RootSiftAppender&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;ch.qos.logback.classic.sift.SiftingAppender&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;discriminator<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Key<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;strong<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>testname<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/strong<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/Key<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;DefaultValue<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;strong<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>testrun<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/strong<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/DefaultValue<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/discriminator<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;sift<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;appender</span> <span style="color: #000066;">name</span>=<span style="color: #ff0000;">&quot;FILE-${testname}&quot;</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;ch.qos.logback.core.rolling.RollingFileAppender&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;File<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${testname}.log<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/File<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;rollingPolicy</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;ch.qos.logback.core.rolling.FixedWindowRollingPolicy&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;FileNamePattern<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;strong<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>${testname}.%i.log<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/strong<span style="color: #000000; font-weight: bold;">&gt;</span></span><span style="color: #000000; font-weight: bold;">&lt;/FileNamePattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;MinIndex<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>1<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/MinIndex<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;MaxIndex<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>100<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/MaxIndex<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/rollingPolicy<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;triggeringPolicy</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;MaxFileSize<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>5MB<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/MaxFileSize<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/triggeringPolicy<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;layout</span> <span style="color: #000066;">class</span>=<span style="color: #ff0000;">&quot;ch.qos.logback.classic.PatternLayout&quot;</span><span style="color: #000000; font-weight: bold;">&gt;</span></span>
               <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;Pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>%d{ISO8601} %-5level %C{1} [%M:%L] [%thread] - %msg%n<span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/Pattern<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
            <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/layout<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
         <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/appender<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
      <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/sift<span style="color: #000000; font-weight: bold;">&gt;</span></span></span>
   <span style="color: #009900;"><span style="color: #000000; font-weight: bold;">&lt;/appender<span style="color: #000000; font-weight: bold;">&gt;</span></span></span></pre></div></div>

<p>This configuration says that the test cases would specify the MDC value using a key &#8220;testname&#8221; and if logback finds no such key, it&#8217;ll just log the statements into <tt>testrun.log</tt>.</p>
<p>And that&#8217;s it. You should be good to go.</p>
<h3  class="related_post_title">Related Posts</h3><ul class="related_post"><li><a href="http://www.nullin.com/2010/03/26/hudson-ci-for-testing/" title="Hudson CI for Testing">Hudson CI for Testing</a></li><li><a href="http://www.nullin.com/2009/12/23/running-single-test-or-class-using-testng-and-ant/" title="Running single test or class using TestNG and Ant">Running single test or class using TestNG and Ant</a></li><li><a href="http://www.nullin.com/2008/12/13/connect-to-ms-sql-server-using-jdbc/" title="Connect to MS SQL Server using JDBC">Connect to MS SQL Server using JDBC</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.nullin.com/2010/07/28/logging-tests-to-separate-files/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Hudson CI for Testing</title>
		<link>http://www.nullin.com/2010/03/26/hudson-ci-for-testing/</link>
		<comments>http://www.nullin.com/2010/03/26/hudson-ci-for-testing/#comments</comments>
		<pubDate>Sat, 27 Mar 2010 06:17:44 +0000</pubDate>
		<dc:creator>Nalin</dc:creator>
				<category><![CDATA[Applications]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[Linux/Unix]]></category>
		<category><![CDATA[ci]]></category>
		<category><![CDATA[hudson]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[qa]]></category>
		<category><![CDATA[testing]]></category>

		<guid isPermaLink="false">http://www.nalinmakar.com/?p=696</guid>
		<description><![CDATA[We are heavily using Hudson for testing a product we are working on. Other than maintenance and some instability issues, it&#8217;s been a great experience working with Hudson. We started out with just a single machine running Hudson server and then soon moved to a master-slave configuration where we have setup one master connected to [...]]]></description>
			<content:encoded><![CDATA[<p>We are heavily using <a title="Hudson CI" href="http://hudson-ci.org/">Hudson</a> for <em><strong>testing</strong></em> a product we are working on. Other than maintenance and some instability issues, it&#8217;s been a great experience working with Hudson. We started out with just a single machine running Hudson server and then soon moved to a master-slave configuration where we have setup one master connected to four slaves. We are currently running about 10-15 jobs on this setup at one point or another during the day and use it to run pre-checkins (well in a way *post*-checkins), BATs and regression runs.</p>
<p>Here are a couple of screenshots that I took  when we were just getting started and were stabilizing Hudson and the product.</p>

<a href='http://www.nullin.com/2010/03/26/hudson-ci-for-testing/hudson_all_jobs/' title='hudson_all_jobs'><img width="150" height="150" src="http://www.nullin.com/blog/wp-content/uploads/2010/03/hudson_all_jobs-150x150.png" class="attachment-thumbnail" alt="hudson_all_jobs" title="hudson_all_jobs" /></a>
<a href='http://www.nullin.com/2010/03/26/hudson-ci-for-testing/hudson_main_branch/' title='hudson_main_branch'><img width="150" height="150" src="http://www.nullin.com/blog/wp-content/uploads/2010/03/hudson_main_branch-150x150.png" class="attachment-thumbnail" alt="hudson_main_branch" title="hudson_main_branch" /></a>

<p>We have the following kinds of jobs running on this system:</p>
<ol>
<li><em>Pre-checkins</em>: We provide development team with a set of tests that they are supposed to run before they commit any code. To ensure that the development team was doing this, we have a job that runs pre-checkins tests on every commit. This helps us ensure that things remain green though out the day and we come to know of failures asap.</li>
<li><em>BATs</em>: Basic Acceptance Tests as another category of tests that help us ascertain the daily quality of builds. Before the QA picks up a build for testing, we run the BATs against the daily official build and make sure that all tests pass.</li>
<li><em>Regression runs</em>: We also use hudson to run regression tests. At time of taking this screenshots, we had only about a 1000 tests and hence had a single job which would run all the tests and would take about 6-7 hours to complete. Now, we have split up that job into multiple jobs by <a title="Splitting a big job into multiple=" href="http://wiki.hudson-ci.org/display/HUDSON/Splitting+a+big+job+into+smaller+jobs">using multiple build stages</a> that Hudson supports. I will talk more about this in a later post.</li>
<li><em>Helper jobs</em>: We have <a href="http://wiki.hudson-ci.org/display/HUDSON/Parameterized+Build">parameterized jobs</a> setup that help any one (dev or QA) to start any kind of test run against an official or sandbox build.</li>
<li><em>CI jobs</em>: This is how Hudson was originally intended to be used. For each branch that we work on, we poll the SCM every 5 minutes to check for checkins and build the dev and QA code. This helps us ensure that the code any checkin hasn&#8217;t broken the QA build and that users have access to the latest artifacts/distributions at all times.</li>
</ol>
<p>For the project, we had invested time into providing infrastructure to pick up official/sandbox builds and then using these builds to setup environment, configure tests and then execute the tests. We just had to put in some more time to change or add features to make it all work easier with Hudson. Now, instead of letting everyone fend for themselves when it comes to setting up environments for testing and then reporting the results, we use Hudson to automate that process to a very large extent and make these tasks more manageable and the product quality more visible.</p>
<h3  class="related_post_title">Related Posts</h3><ul class="related_post"><li><a href="http://www.nullin.com/2010/07/28/logging-tests-to-separate-files/" title="Logging tests to separate files">Logging tests to separate files</a></li><li><a href="http://www.nullin.com/2008/12/13/connect-to-ms-sql-server-using-jdbc/" title="Connect to MS SQL Server using JDBC">Connect to MS SQL Server using JDBC</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.nullin.com/2010/03/26/hudson-ci-for-testing/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Connect to MS SQL Server using JDBC</title>
		<link>http://www.nullin.com/2008/12/13/connect-to-ms-sql-server-using-jdbc/</link>
		<comments>http://www.nullin.com/2008/12/13/connect-to-ms-sql-server-using-jdbc/#comments</comments>
		<pubDate>Sun, 14 Dec 2008 00:51:56 +0000</pubDate>
		<dc:creator>Nalin</dc:creator>
				<category><![CDATA[Miscellaneous]]></category>
		<category><![CDATA[code]]></category>
		<category><![CDATA[java]]></category>
		<category><![CDATA[jdbc]]></category>
		<category><![CDATA[SQL]]></category>

		<guid isPermaLink="false">http://www.nalinmakar.com/?p=537</guid>
		<description><![CDATA[The following example shows a java class that can be used to verify if you connection to MS SQL Server using JDBC is working properly. The following code establishes a connection to MS SQL server and then executes a query to print system tables. You need to get Microsoft&#8217;s JDBC drivers or jTDS JDBC drivers. [...]]]></description>
			<content:encoded><![CDATA[<p>The following example shows a java class that can be used to verify if you connection to MS SQL Server using JDBC is working properly. The following code establishes a connection to MS SQL server and then executes a query to print system tables. You need to get <a href="http://msdn.microsoft.com/en-us/data/aa937724.aspx">Microsoft&#8217;s JDBC drivers</a> or <a href="http://jtds.sourceforge.net/">jTDS JDBC drivers</a>.</p>

<div class="wp_syntax"><div class="code"><pre class="java" style="font-family:monospace;"><span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.Connection</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.DriverManager</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.ResultSet</span><span style="color: #339933;">;</span>
<span style="color: #000000; font-weight: bold;">import</span> <span style="color: #006699;">java.sql.Statement</span><span style="color: #339933;">;</span>
&nbsp;
<span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">class</span> ConnectMSSQLServer
<span style="color: #009900;">&#123;</span>
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000066; font-weight: bold;">void</span> dbConnect<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span> db_connect_string,
            <span style="color: #003399;">String</span> db_userid,
            <span style="color: #003399;">String</span> db_password<span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>
      <span style="color: #000000; font-weight: bold;">try</span> <span style="color: #009900;">&#123;</span>
         <span style="color: #000000; font-weight: bold;">Class</span>.<span style="color: #006633;">forName</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;com.microsoft.sqlserver.jdbc.SQLServerDriver&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #003399;">Connection</span> conn <span style="color: #339933;">=</span> <span style="color: #003399;">DriverManager</span>.<span style="color: #006633;">getConnection</span><span style="color: #009900;">&#40;</span>db_connect_string,
                  db_userid, db_password<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;connected&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #003399;">Statement</span> statement <span style="color: #339933;">=</span> conn.<span style="color: #006633;">createStatement</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #003399;">String</span> queryString <span style="color: #339933;">=</span> <span style="color: #0000ff;">&quot;select * from sysobjects where type='u'&quot;</span><span style="color: #339933;">;</span>
         <span style="color: #003399;">ResultSet</span> rs <span style="color: #339933;">=</span> statement.<span style="color: #006633;">executeQuery</span><span style="color: #009900;">&#40;</span>queryString<span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #000000; font-weight: bold;">while</span> <span style="color: #009900;">&#40;</span>rs.<span style="color: #006633;">next</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
            <span style="color: #003399;">System</span>.<span style="color: #006633;">out</span>.<span style="color: #006633;">println</span><span style="color: #009900;">&#40;</span>rs.<span style="color: #006633;">getString</span><span style="color: #009900;">&#40;</span><span style="color: #cc66cc;">1</span><span style="color: #009900;">&#41;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
         <span style="color: #009900;">&#125;</span>
      <span style="color: #009900;">&#125;</span> <span style="color: #000000; font-weight: bold;">catch</span> <span style="color: #009900;">&#40;</span><span style="color: #003399;">Exception</span> e<span style="color: #009900;">&#41;</span> <span style="color: #009900;">&#123;</span>
         e.<span style="color: #006633;">printStackTrace</span><span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      <span style="color: #009900;">&#125;</span>
   <span style="color: #009900;">&#125;</span>
&nbsp;
   <span style="color: #000000; font-weight: bold;">public</span> <span style="color: #000000; font-weight: bold;">static</span> <span style="color: #000066; font-weight: bold;">void</span> main<span style="color: #009900;">&#40;</span><span style="color: #003399;">String</span><span style="color: #009900;">&#91;</span><span style="color: #009900;">&#93;</span> args<span style="color: #009900;">&#41;</span>
   <span style="color: #009900;">&#123;</span>
      ConnectMSSQLServer connServer <span style="color: #339933;">=</span> <span style="color: #000000; font-weight: bold;">new</span> ConnectMSSQLServer<span style="color: #009900;">&#40;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
      connServer.<span style="color: #006633;">dbConnect</span><span style="color: #009900;">&#40;</span><span style="color: #0000ff;">&quot;jdbc:sqlserver://&amp;lt;hostname&amp;gt;&quot;</span>, <span style="color: #0000ff;">&quot;&amp;lt;user&amp;gt;&quot;</span>,
               <span style="color: #0000ff;">&quot;&amp;lt;password&amp;gt;&quot;</span><span style="color: #009900;">&#41;</span><span style="color: #339933;">;</span>
   <span style="color: #009900;">&#125;</span>
<span style="color: #009900;">&#125;</span></pre></div></div>

<p>Change <code>&lt;hostname&gt;</code>, <code>&lt;user&gt;</code> and <code>&lt;password&gt;</code> to the correct values. Also, if you use the jTDS drivers, the driver class should be set to <code>net.sourceforge.jtds.jdbc.Driver</code>.</p>
<h3  class="related_post_title">Related Posts</h3><ul class="related_post"><li><a href="http://www.nullin.com/2010/07/28/logging-tests-to-separate-files/" title="Logging tests to separate files">Logging tests to separate files</a></li><li><a href="http://www.nullin.com/2010/03/26/hudson-ci-for-testing/" title="Hudson CI for Testing">Hudson CI for Testing</a></li><li><a href="http://www.nullin.com/2009/11/28/what-is-wrong-with-me/" title="What is wrong with me?">What is wrong with me?</a></li><li><a href="http://www.nullin.com/2008/12/06/removing-tags-from-posts-contents-in-wordpress/" title="Removing tags from Wordpress posts content">Removing tags from Wordpress posts content</a></li><li><a href="http://www.nullin.com/2006/08/01/mass-string-replace-in-mysql/" title="Mass string replace in MySQL">Mass string replace in MySQL</a></li></ul>]]></content:encoded>
			<wfw:commentRss>http://www.nullin.com/2008/12/13/connect-to-ms-sql-server-using-jdbc/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

