Closing Feedback Loops with Sonar

Last year my shop began using an application called Sonar.   To over-simplify what Sonar does is to simply say it aggregates all of your static analysis and test results into one view – very, very, easily.

From what I can see most of the code is written Java, and initially it was written for Java – an assumption on my part.  But the community has also provided plug-ins for .NET and other platforms.

I installed this on a Windows Server 2008 R2 x64 VM with modest memory and disk.  The two main pre-requisites were VS2010, I use the Ultimate/Awesome sku, and the Java’s latest version.

I setup Sonar locally on the VM, meaning everything is running locally before I tied into the production version of sonar’s database that the rest of shop is using.

In a nutshell here’s how it works.

1) Your build process runs on a build box or your local box and places the compiled binaries into a folder (bin\debug works fine too) your sonar server can see.

2) You call (manually or automated-ly) the sonar profiler from your root src directory.  The profiler has a configuration file in the root of your source directory where the .sln file lives.  The profiler uses this information to understand where your test directories are *if* they are not part of solution, or recognized in the .sln file, however it will use the .sln file for most of its pointers.

3) Once it knows what it can/can’t do it will execute static analysis (style/fx cops) against your code and run any test.

4) The profile collects the results in xml files and applies the gathered analysis to the database Sonar is using.

5) You open your sonar dashboard (http://localhost:9000/sonar) on the server hosting Sonar and your dashboard displays the analysis it gathered.

The plugins are the bits that do all of the work on the profiler’s behalf, specifically Gallio, but before I get ahead of myself here’s the plugin round-up…

c.sharp.plugin.roundup

There are more plugins and analytics, but right now we’re just going to get started with this lot of plugins.  Gallio is the test runner, so if you are writing tests in any of familiar testing frameworks you’re covered.  I’m using MS-Test for mine, but I was really thinking of using xUnit or NUnit instead to relieve a few of the dependencies.

Here are some of the gotchas I ran into being a Java semi-noob – it’s been a while since I tried to get Java running on a Windows box, so if this is you just follow the docs closely and Bing if you get stuck.

0) Install Visual Studio 2008 or 2010 SP1 first.

1) After you install Java, set the JAVA_HOME var for the server

2) After you install Sonar, that directory effectively becomes your “sonar home”, and lots of stuff needs to know that as well.  So, think about how your build/ci executable directories are arranged before you install sonar, and the sonar profiler

3) After you install the Simple Java Runner aka, the “sonar runner” in the docs, set the SONAR_RUNNER_HOME var for the server.

4) Now, start running the rest of the installs based on this.

Sonar.Required.Tools

I went with the defaults and used the embedded apps, and only installed PartCover and Gallio. The Sonar profiler will look for the directories where FxCop, StyleCop, and your coverage engine is.  This is configurable inside the Sonar web site where you can do further configuration tweaks if you need to move stuff around.

5) This is basically a 32-bit process and running in an x64 environment takes a few extra steps.  The docs cover this, but referring back to item #2, for me I had to install Gallio and PartCover in a different directory (per the docs), outside of “c:\program files” which is the default.  At this point I decided to move everything into directory structure that looked like this:

D:\Build\Gallio; D:\Build\PartCover; D:\Build\Sonar; D:\Build\SonarRunnerHome;

I also needed to run corflags (inside a VS2010 command prompt) on Gallio.Echo, PartCover, and PartCover.Browser executables to force them to run as a 32-bit process, per the documentation.

I think that about covers the gotchas I ran into.  The last thing I still need to sort out is defining the “program directory” dynamically for the sonar runner.  Sonar runner always assumes you’re in the root of the source tree and wants to build a “.sonar” directory if one doesn’t already existing.   To get my local version running, I’ve hard-coded the source directory I was trying to profile for now.

Hope some of this helped.

/ofc