The title of this is probably unfair, as its not grails itself I’m writing about. I thought I’d share with the world the recent pain of a Grails 1.2 to 1.3 app upgrade.
Leading off from my previous post, I’d just finished doing the upgrade of a mavenised grails app. This is a fairly weighty beast, worked on by mybe 20+ peeps on and off. I’s a Grails/ GWT combo, with pretty good test coverage and an extensive set of webdriver tests (more on these further down!)
So, I start the application up, it breaks straight away, complaining about a tomcat ‘SESSIONS.ser’ file.. a quick read around indicates a tomcat version change, caused by the updated dependencies.
I forgot to clean, ah well, an inauspicious start!
Grails clean sorts me out and the app starts up.
I flick to the one of the main screens of the app (GWT remember), and it renders correctly. I click a button to request some data (a GET request to a controller) and nothing happens.. nada.
I trace the usual suspects, db changes, security filtering, bad http requests. All seems fine, until I notice that a a query parameter going into the db looks odd. (I was an hour in by this point).
Its there, but different. It often includes a space, the user selecting it. eg ‘Some Items’. When it gets into the service its now ‘Some+Items’.
Strange, obviously some form of URL encoding. Not the normal kind though, which would render as ‘Some%20Item’
I’m hiding something. I’ll admit it.
The URL being requested by GWT looked like this /workItemController/getItems/Some+Item?blah=blah
Its the grails params.id that is the problem. In 1.2.2 the above URL would mean that in your controller you could have ‘params.id == “Some Item”‘
In 1.3.4, you can’t. Slightly upsetting.
Changing the url to /workItemController/getItems?id=Some+Item&blah=blah means that the behaviour is the same in both cases.
No, I don’t think so either. Small, minute, even, but a little annoying. Moving on.
In the same controller there was some code that used the ‘as JSON’ construct to serialise some objects to JSON. This stopped working.
All the googling I could find said that the as JSON operator can’t be used on arbitrary objects. Well, that may be true in 1.3. It wasn’t in 1.2.
I may pluck up the energy to investigate why, but likely not… as the testing below soaked up most of it :-S
Lots of fun and games with the tests.
The unit and integration tests were mostly ok I thought, nothing special about them. However on running them I noticed that there were a bunch of failures. Classes that I hadn’t seen before.
It turns out that some of the devs had felt constrained by Grails testing infrastructure, being junit 3 based. So they decided to slip some junit 4 tests in there for their own personal use.
Now, I like Junit 4, its much nicer than Junit 3. I do, however, think that unless the tests are run in CI, they should not be in source control. If they are then they will start rotting. Rotten tests are an abomination, and cause untold headaches for whover is the maintenance programmer, ie me. So, all these tests you are tempted to write, be they performance checks, static data population, or just something in a special style that doesn’t integrate well; delete them. Go on…. do it now…
It’s not big, and it’s not clever. Don’t do it again or I’ll track you down with my pet bear. He doesn’t like them either, and he is capable of rippiing your arms off.
So, I think to myself, its a Junit 4 test, grails now supports junit 4… @Ignore??
Nope. doesn’t work. Grails then decides that its a junit 3 test suit and runs it anyway…
So I butcher up the rotten test classes and leave them with @Ignore as a marker for anyone else passing by.
Moving onto the webdriver tests. What fun!
We’ve had lots of trouble with this. Mostly boiling down to distinct differences in behaviour between an eclipse invocation of a test and via a test-app call.
Most are harmless; eg like lots of the tests have the assert keyword in them. With grails 1.2/ groovy 1.6 this meant that tests would have the most useless errors I’ve seen in a unit test. The cause? The Eclipse Groovy plugin imports Groovy 1.7, making the tests useful. Ah well, fixed in in the upgrade!
No, the real issue is that the maven invocation kept on leaving firefox windows hanging around, causing the integration server to eventually crash. This is caused by a resource leak in the handling of the webdriver instances. We had this once before, caused by our code having lazy instantiations of the driver. Not a good idea.
This time changes to the grails test infrastructure meant that all the resource cleanup code was being ignored.
Be aware, Grails does its best to handle both junit 3 and 4 tests at the same time, but there are foibles. We were overriding the runBare() method in TestCase to do the resource cleanup (pulled from a heavily forked grails webdriver plugin, actually).
This stopped working in 1.3.4, so instead I’ve moved all the functional tests to junit 4 and created a @BeforeClass and @AfterClass to manage the driver. This works well enough.
So ended my saga…..