Monday, October 31, 2011

Hello Specs2 JUnit, Farewell Henkelmann TestListener

Out of the box, SBT 10.1 doesn't give you test results in JUnit output. This is a problem for anyone using Jenkins to process test results. Fortunately, last November, Christoph Henkelmann released a plugin to SBT that plugs in to the test execution life cycle of SBT, http://henkelmann.eu/junit_xml_listener.  This was great, but had a few bugs with inconsistent results and JUnit data ending up in the wrong file or XML being badly formatted. These bugs occurred inconsistently and infrequently enough to be only a minor annoyance.

Over this past summer, specs2 added a JUnit output option for its test results. At the time, the documentation didn't fully explain the necessary integration points. So I'll explain what I did to get it working. Most of this information is now available at, http://etorreborre.github.com/specs2/guide/org.specs2.guide.Runners.html if you search for "junit".

// Put this in your SBT build file to output to both console
// ...and junit files console is helpful so that you can see the
// ...output in jenkins build history
testOptions in Test += Tests.Argument("junitxml", "console")

If you're running on the command line, you can provide SBT system arguments straight up, like

bash $> sbt junitxml

Finally, on the SBT command line, it won't work with the SBT "test" command, but it will work with the SBT "test-only" command.

sbt-command-line>test-only com.company.class.specs -- junitxml

The other cool learning that I experienced at this time, was with using SBT collections. We have several scala projects and we need to share common SBT properties between them. To accomplish this, we made our own SBT plugin and import all of its settings at the top of each project. One of the settings is the testListener SBT setting, which attaches the junitXmlListener to all our unit test output. Since, I wanted to test out the junitxml flag in only one project before fully committing to it, I couldn't outright remove the test listener for all the projects. So in order to remove only in one project, I used the SBT filter syntax: ~=


testListeners ~= { (listeners: Seq[TestReportListener]) =>
    listeners filterNot ( _.isInstanceOf[JUnitXmlTestsListener] )
  }




Wednesday, October 26, 2011

Gerrit Code Review - Unpack error Missing unknown

We use the Gerrit code review tool at my company; currently version 2.1.8. Gerrit gives us a lot of tools and is an extremely useful tool for code quality and knowledge sharing (i.e. code reviewing). However, Gerrit can often require some TLC. Today was one of those days.

While I was doing some maintenance on our git host today, I noticed that git suggested I prune one of our repos. So, I went ahead and pruned. About half an hour later, one of our developers reported that he couldn't create a new patch set in Gerrit -- neither update or create were working. Pretty soon, I was getting several reports of this from the team. They were all getting the same error:


error: unpack failed: error Missing unknown 3061766be9c324fa47fb4832399b34db5a186276
fatal: Unpack error, check server log
To ssh://git.dev:29418/webapp
 ! [remote rejected] HEAD -> refs/for/master/master (n/a (unpacker error))

The key part of this message is the git object that's missing, 3061766. The git prune must have identified that the object was dangling, no longer necessary, and removed it. However, for some reason, JGit inside of Gerrit still felt the object served some purpose important enough to throw an exception. I tried to find the object in the remote repo and locally, but to no avail, it was history.

After trying pretty much everything I could find on the internet (http://code.google.com/p/gerrit/issues/detail?id=585http://groups.google.com/group/repo-discuss/browse_thread/thread/cf7095d3dc364c7e/f2c11756a5a0396f?) and replacing the jgit jar in my tmp .gerritcodereview directory, I finally found a solution.

The solution was to restore a backup of our git repository to a temp directory and use git cat-file to first verify the object 3061766 was valid. Then, I used git verify-pack to find the pack file that contained the commit. Then I copied the pack and its index file (http://progit.org/book/ch9-4.html) into our real repo. Shazzam! Gerrit started accepting change sets again!

In more detail:

  1. tar -xf backup.tar ./path-to-git-dir
  2. cd path-to-git-dir
  3. git cat-file -t 3061766be9c324fa47fb4832399b34db5a186276
  4. cd objects/pack
  5. ls | xargs git verify-pack -v | grep 3061766be9c324fa47fb4832399b34db5a186276
  6. # back track until you find the pack that contains the commit
  7. cd /git/path-to-git-dir/objects/pack
  8. cp /untarred-repo/objects/pack/...{idx,pack} .



Vim Registers Current File Name

So you guys may remember how I was all obsessed with vim registers a few months ago. Well, today I was typing away at some things and while in insert mode, I wanted to splat the name of the file I was currently editing. So I took a risk:

Ctrl+R %     # i.e. Access register %, which holds the name of the current file.

result: the name of the file pasted in!

Pretty cool.