Saturday, October 30, 2010

Workbench not coming while running UI tests for eclipse plugins in Hudson CI in windows

We planned to do CI setup for a project that involved eclipse plugins and decided to go to tycho for achieving that. The reason is simple as we were bit familiar with Maven and also saw that configuring to use tycho is easy (atleast we haven't used Ant before, so PDE build with Ant tasks, the usual way, is not gonna be easy as well).
This mini article is not about tycho but about overcoming the hurdle you might face when running eclipse UI integration tests written via WindowTester when setting up CI in Hudson in windows machine.

We first wrote a windows batch that does this -


a. Checkout projects from SVN
b. Trigger maven build, that builds plugins, runs unit tests followed by UI tests (that requires a launched workbench).

Tycho is brilliant is bringing up workbench right before running tests so things were going fine.
But when we moved to Hudson to set up, all happened except bringing up workbench. However an eclipse instance was created which was evident as seen in Task Manager but somehow workbench didn't come up which failed all UI tests.

Googling and googling finally fetched solutions in form of posts - UI tests in a CI env  - here, here and there and though they are not directly related to stated problem, the concept applies..

Read them? Fine, so what was the problem really?
We used to do the Hudson setup in a remote box which we used to login via mstsc console. As mentioned in above posts, doing remote login itself would lock the desktop and hence Hudson won't be able to interact natively with OS to bring up the workbench. This won't occur if you configure Hudson directly in your local machine i.e. when you logged directly into the machine where you are configuring Hudson. But this won't be the case as usually we configure Hudson in a remote box or one in a CI farm..

These are the points to note
a. Have a VNC server installed in the machine where Hudson has to be configured. We used RealVNC free edition.
b. Now in the remote machine (where we just installed VNC) where Hudson has to be configured disconnect all user sessions. Do it by going to Task Manager -> Users. No entry should be present and just disconnect all users. This implies that the machine should not be a normal box which is shared among users. Better disable remote session for the box.
c. Now remember this 'never use mstsc console to launch Hudson instance'. So connect to remote machine via VNC viewer installed in your local box. (you should give something like hostname:display to connect)
d. Once connected via VNC viewer, launch Hudson via command prompt; yes, not via Windows Service!
e. Now just trigger the build from local box or the remote box itself and see the workbench being shown up!

We haven't done any configuration in Hudson itself so far and things will be fine unless you would like have multiple builds being done in parallel by Hudson in same above machine and each build having to run UI tests as well..
Interesting..
Actually we came to know about a Hudson plugin named XVnc to satisfy exactly this purpose, but wait, we didn't play with it, as luckily we got a dedicated box for our project - so only one build at a time - so no prob..
The notion X protocol that the plugin talks about is specific to Linux based systems so not sure how easy to set it up in windows. We also contacted the plugin creator and got that the plugin was tested only in Linux systems (atleast until the time of this writing) but it doesn't mean that its not possible to set it up in windows. However we heard that minor tweaking might be required to see that the scripts that the plugin executes are intact in windows based machines too.. Anyways, hope we get a chance to experiment that too..

Monday, October 25, 2010

Adding test suites to a test suite in Junit 3.x

Normally in a junit 3.x test suite we will add test classes (that has our test methods) as entries. 
As an example,

public class AllTests {

    public static Test suite() {

        TestSuite suite = new TestSuite(
                "All tests wrapped in a suite");
        // $JUnit-BEGIN$
        suite.addTestSuite(SampleTest.class);
        suite.addTestSuite(AnotherSampleTest.class);
        // $JUnit-END$
        return suite;
    }

}

But what if we want to put several test suites into a master test suite.
It can be done in this way:

public static Test suite() throws Exception {
         TestSuite suite = new TestSuite(
                "Master test suite that has all test suites");
        // $JUnit-BEGIN$
        suite.addTest(AllTests.suite());
        suite.addTest(AnotherAllTests.suite());       
        // $JUnit-END$
        return suite;
    }


And last but not least, you can mix and match both.