Wednesday, April 27, 2011

Running test on a live test instance of the application

I've faced a unique challenge today: test my json-rest-api plugin. Unique, isn't it? :D

The problem


Well all would be really easy if not for the fact that I wanted to do an end-to-end test just like a client would use the generated API for a domain class. In this case using integration tests was out of the question because the actual http listener is not running. And I wanted to test it all the way through...

After some digging I've found out that there's a number of plugins that provide this kind of functionality where the application starts and tests are being executed. Those plugins are functional-test, easyb-acceptance-test and webtest.

The unhappy seeker


I've tried to play around with those and one thing struck me down the most: they are mostly targeted at testing web pages and not RESTful services. So they were not as nice for my case as I'd like them to be.

What made me wonder though is that all of those plugins do exactly the same thing to actually spawn the application before tests:
eventAllTestsStart = {
if (getBinding().variables.containsKey("functionalTests")) {
functionalTests << "functional"
}
}
Obviously different plugins use different names for their tests but the idea remains the same. So I asked myself what would happen if I'd introduce the same thing in my scripts/_Events.groovy without those plugins installed... Much to my surprise Grails build system started the application right after spitting out "Starting integration test phase ..." :)

The road continues


Now all I had to do was to find out a nice way to actually get the test going. As it turns out there's a fantastic utility called HTTPBuilder that does exactly what I needed! Just a couple of lines in BuildConfig.groovy later...
test('org.codehaus.groovy.modules.http-builder:http-builder:0.5.0') {
excludes "commons-logging", "xml-apis", "groovy"
}
... and testing RESTful services has never been easier!
import groovy.util.GroovyTestCase
import org.junit.Test

import groovyx.net.http.*

class RESTfulTests extends GroovyTestCase {
@Test
void willReturnErrorIfSavingNotSuccessfull() {
def client = new RESTClient("http://localhost:8080/example/api/")
def response = client.post(
path: "person",
body: [ data: [ firstName: 'John', lastName: 'Doe' ] ],
requestContentType : ContentType.JSON.toString())
assert response.status == 200
}
}

If you want to see a more sophisticated usage of this approach with more assertions I encourage you to take a look at the basic application in json-rest-api-examples project.

The obvious


One note to add: if you'd like to run those integration tests as part of your continuous integration it'll most probably fail because the port is already in use by Hudson... To overcome this issue set the server.port parameter to some port value that's not in use. In Hudson it looks more/less like this:



Obviously you need to use this port in your tests instead of the default 8080...

Have fun!

Sunday, April 24, 2011

Hosting a Git repository on Ubuntu 10.04 LTS

I thought I'll post this recipe for anyone having issues hosting their own Git repos via HTTP. It's not that hard but a few things have to happen to actually make it work.

The automated way


If you're as lazy as I am here's a script that you can just download, execute as root and all the steps below will be executed for you. This means that you can turn a plain vanilla Ubuntu 10.04 installation into Git host in a matter of seconds:

https://gist.github.com/1034042 (raw)

The manual way


Install packages

sudo apt-get install apache2 git-core gitweb

Create folder to host your repositories

sudo mkdir /srv/git

Configure Apache to serve the repositories

Add the following to /etc/apache2/conf.d/git (create the file if it does not exist!):

# GIT
SetEnv GIT_PROJECT_ROOT /srv/git/
SetEnv GIT_HTTP_EXPORT_ALL
ScriptAliasMatch \
"(?x)^/git/(.*/(HEAD | \
info/refs | \
objects/(info/[^/]+ | \
[0-9a-f]{2}/[0-9a-f]{38} | \
pack/pack-[0-9a-f]{40}\.(pack|idx)) | \
git-(upload|receive)-pack))$" \
/usr/lib/git-core/git-http-backend/$1
ScriptAlias /git /usr/share/gitweb/index.cgi

<LocationMatch "^/git/.*/git-receive-pack$">
AuthType Basic
AuthName "Git repository"
AuthUserFile /srv/git/users
Require valid-user
</LocationMatch>

Create a link to gitweb.js

This step is required so that the proper javascript library is available for GitWeb:
sudo ln -s /usr/share/gitweb/gitweb.js /var/www

Create users file

sudo htpasswd -c /srv/git/users john
and type the password twice

Create script to create repositories

Create a file /srv/git/create.sh with the following content:
#!/bin/sh
git init --bare $1.git
cd $1.git
git config http.receivepack true
git config gitweb.owner "John Doe"
cd ..
chown www-data:www-data -R $1.git

Use the create.sh script to create a repository

cd /srv/git
sudo sh create.sh example

Update path to repos for gitweb

In /etc/gitweb.conf update the $projectroot to:
$projectroot = "/srv/git"

Restart apache

sudo invoke-rc.d apache2 restart

That's it! you should now be able to clone and browse your repository using the smart HTTP transport!

The outcome


Remember that when you use this setup you'll have a Git repository that than be cloned by everyone but only users specified in /srv/git/users can push to this repo! This means that you'll have to provide username in the URL like this:
http://john@myserver/git/example.git

If you don't do that you'll see the following error while trying to push:
Counting objects: 3, done.
Delta compression using up to 2 threads.
Compressing objects: 100% (2/2), done.
Writing objects: 100% (3/3), 1.05 KiB, done.
Total 3 (delta 0), reused 0 (delta 0)
error: RPC failed; result=22, HTTP code = 401
fatal: The remote end hung up unexpectedly
fatal: The remote end hung up unexpectedly

Hope this will save someone some time :)

Saturday, April 23, 2011

I'm finally a Git convert

Well, yes... It happened. I don't know how or when but it just did. I'm now officially a Git convert. Period.

For those of you who know me you might also know that I was a huge Subversion advocate. This was also seen in the role of Subversion trainer that I inherited after a friend of mine in my current company. I was teaching and preaching SVN for the better part of this millennium. So why?

Well, there are a couple of things that distinct SVN from Git and the distributed/centralized part of it ain't the most important one. There are some key features that come out of the fact how Git works but they could work in Subversion OK if this damn thing wouldn't be so eager to use the fricken network... In this case the distributed part of Git is not so much about giving commit access to nobody besides me. It's also not about the "I can commit when I'm on the plane". I mean, come on, geeks! How many of regular developers do the coding at FL300 to avoid wiretaps? :D

The best part of Git is speed. I mean speed as in fricken space rocket! Like it or not in a corporate environment there's always going to be this "everybody on the team has commit access" thing and nothing is going to change that. Get over it! The best thing about Git is that it works just as good in a centralized environment as Subversion or even better, faster, lighter, jezzier, sexier and all that :D

One more thing: setting up Git server to host the one true version of the repository in a centralized environment is so damn easy! There's like 10 different ways with the one truly blessed prescription (Smart HTTP Transfer). Just go google it. It's amazing how incredibly fast it is! And it plays so nicely with Trac and Redmine!

Now that I have that out of my chest I'd like to say a few words about other counterparts: Bazaar, Mercurial, Monotone

If you're still using Bazaar - I'm so sorry you didn't see the light yet. There's definitely a guy sitting next to you that already knows what this Git thing is so you better ask him before you'll be left alone in the dark.

Hail to all the HG users! You're also great :D But not as jazzy and sexy as the Gitters :D

Monotone... Well.. letsnotbetohardonthoseguysastheyareprobablytheonesthatwrotethisthing...

Thursday, April 14, 2011

I still hate JSF - but a little less :D

If you know me you also know this for a fact: I hate JSF with a passion! There are no bad enough words that you could use to express the hatred I feel. What can I say - I'm broken this way...

Today I finally gave JSF2 a spin. This time I already knew that working with Java EE is a pain in the neck so I've decided to use my usual environment (Grails) to do the test.

JSF / JSF2 has some major drawbacks out of the box. It's heavy and it's a misery to introduce changes (again, out of the box). Sure you can use like JRebel and stuff to make your life easier but then JRebel costs money and if you're just playing with the technology with no apparent reason spending any money is just not justified at all.

So back to the topic: JSF2 on Grails. Sounds, scary, right? Yes, I've got the goosebumps too :)

What's in the box? (cited after http://grails.org/plugin/jsf2):

- Bean By convention (no need for faces-config)
- Bean access to controller parameters (session,request,params...)
- Beans dynamic methods for navigation redirect(action?,bean?,view?,uri?,url?) and - render(action?,view?,bean?),
- Automatic bean and service properties resolution
- - 'void init()' called at bean initialization if present
- 'void dispose()' called at bean destruction if present
- JSF Extended request scope ('view')
- Access to web.xml configuration via Jsf2Config.groovy
- Access to faces-config generated in web-app/faces-config.xml
- Converters for Locale, Closure, Currency, Timezone
- i18n ready, fast access with #{m['key']}
- create-bean script
- Hibernate session managed from view rendering to view response
- Execute groovy code in EL expression ( #{gtag.groov[' def i = 2; 3.times{ i++ }; i; ']} )
- Support JSF2 Components - @ManagedBean ...

And so my test went like this. I've installed the plugin the usual way, I've create a class called StatusBean (in a .groovy file!), a little bit of copy-paste from the plugin's page to figure out the signature of an event listener did the heavy lifting for me, I've checked the FAQ section to see where should I put my xhtml files and it all worked right out of the box!

Well, I'd definitely NOT go as far as saying that I actually like JSF2. Hell no! I despise it just as much as I did before. I do however recognize that there's world outside of GSPs and SiteMesh and the alternatives are good for some things.

Sunday, April 10, 2011

Quicksort - the groovy way

I must confess: I didn't write quicksort by myself ever. I always felt it's one of those things that I don't really have to do. Well, Dierk Koenig showed that it might be useful to write your own implementation of quicksort. Not for regular use but for training purposes.

You all know the Collections.sort method, right? We all know it's damn fast, well tested and all that stuff. Let's see what does it take in Groovy to implement quicksort ourselves:
def qs(list) {
if (list.size() < 2) return list
def pivot = list[0]
def items = list.groupBy { it <=> pivot }.withDefault { [] }
qs(items[-1]) + items[0] + qs(items[1])
}

WTF? 4 lines plus function definition? And it can easily be shrunk to 3 lines by inlining the pivot variable:
def qs(list) {
if (list.size() < 2) return list
def items = list.groupBy { it <=> list[0] }.withDefault { [] }
qs(items[-1]) + items[0] + qs(items[1])
}


One of my colleges told me that before he saw the implementation of quicksort in Groovy he didn't quite get the idea, what it does and all. Same here :) I never tried to dig into the details, I just accepted that it works. But with this implementation I just see what's going on! There's nothing to understand, just 3 lines to read :D
By comparison an implementation of bubble sort is around 10 lines long and is about 100 times slower :D
If you're wondering how does this implementation perform by comparison to the Collections.sort() method here are the results (sort a 100 elements list 1000 times):

def qs(list)Collections.sort()
1938ms19ms

The actual timing varies but the ratio more/less 100:1 sticks.

It's interesting to note that there's a 10 times difference in timing when invoking list.sort() and Collections.sort(list) in favor for the latter one. That's probably due to the dynamic stuff going on in between.

Saturday, April 9, 2011

33rd Degree - best place to be (EVER!!!)

Hi there folks!

I've just returned from the 33rd Degree conference and I simply need to share the positive energy I've brought home with me.

Before we start please bear in mind that the 3 days of the conference were packed with best-of-breed talks and since there's only one of me (I soooo wish this wasn't so) I was able to see only a small portion of all the great materials and performances available there. I'm sure your opinions might vary depending on what you attended :)

First of all - a fantastic surprise! I've been kind of skeptical about Dr Venkat Subramaniam which I should never ever, ever EVER have been to. This was one of the most brilliant, encouraging, humorous and inspiring talks I've ever seen on polyglot programming! Venkat, I hope you'll not forget your exercises again :) That was an absolutely brilliant metaphor to TDD. In overall it was the best source of ideas to encourage people to learn I've ever encountered! Best talk of the conference in my opinion!

Then there was the forever funny and painfully cynic Ted Neward. I just love the way he presents his ideas like a preacher in the church of St. Programmer :) He's just the one and only! Ted, great talk about the unanswerable question and believe me even if someone didn't speak Scala your talk on design patterns was still the place to be :)

There was also the best polish speaker, Sławek Sobótka with his deep-zoom like presentation about layers in CqRS architecture. Sławek: you rock! And pleeeease! Don't put the architect label on t-shirt :) Don't ever turn over to the dark side!

I must also say there was one talk that threw me completely out of balance. That was the talk by Dierk Koenig about ULC (by Canoo) framework. To give you a little bit of background here I'll tell you this: I'm usually fond of "pure" solutions. This means that mixing Flex/Flash, Silverlight or desktop Java with web development doesn't seem like a good idea to me. There's tons of stuff that you can use HTML5 for and you don't need any extras on top of the browser to make things work. That's the main reason I'm such an advocate of jQuery, its UI framework and above all the Ext JS library. Nevertheless the ULC framework by Canoo has proven itself to be a viable alternative to plain-browser design in cases where more sophisticated interoperability with client's environment is required. That includes for example interoperability with peripherals other than localStorage, sessionStorage and the other ones provided by default by HTML.
Dierk also gave a very nice and pretty advanced talk on programming in Groovy (my favorite language!). Great stuff! And very very inspiring!

Hamlet D'Arcy gave talked about ways to remove boiler plate code from your sources so that you can write more conscious code. Really good stuff, man! Thanks for the enlightenment! And thanks for bringing Groovy to the mix :) Groovy rocks!
I've also had the opportunity to exchange some thoughts with Hamlet about the applicability of the ULC toolkit. He's been extremely helpful in helping me understand the business needs this toolkit tries to address. Thanks for sharing!

If you're into the psychology kind of things then you're absolutely bound to visit Nathaniel Schutta's talk about hacking your brain. Man, that was really awesome to see so obvious and ridiculously simple ideas put into familiar context to which I could relate as a simple developer.

And last but not least: if you're into "the latest and the greatest", or in other words if you're like me striving to make your other colleagues look corny, then the talk that Jarek Pałka gave on NoSQL databases and their applicability in solving certain challenges was definitely the one to be at. Jarek is known for his specific humor and to-the-point observations he makes. This time was no different and quite frankly I've expected nothing less from this guy. Great appearance, man!

Overall this was a time very well spent. I encourage you to visit this conference next year - you'll be absolutely amazed!

I'd also like to congratulate Grzegorz Duda, the mastermind behind all of this on putting together by far the best conference ever!

Friday, April 1, 2011

Grails gotcha - controllers with same name in different packages

Well... it's tough, isn't it? You get a controller with the plugin you use and this damn controller has the same damn name as your controller. And this name is just perfect for what your controller does...

I've just found myself in this kind of situation. I asked on the Grails users group and found out only what I already knew - those damn classes have to have different names. Period.

But I'm the wild one. I need to bend software to my will. I just have to do it :D After a couple of hours of reading Grails sources and experimenting with Grails console (fricken best thing EVER!!!) I came up with this:
class BootStrap {

def grailsApplication

def init = { servletContext ->
grailsApplication.getArtefactInfo("Controller").grailsClasses.each {
it.uri2closureMap.put('/' + it.fullName, 'index')
it.uri2closureMap.put('/' + it.fullName + '/', "index")
it.uri2closureMap.put('/' + it.fullName + '/index', "index")
it.uri2closureMap.put('/' + it.fullName + '/index/**', "index")
it.configureURIsForCurrentState()
}
}

def destroy = {
}
}
With this I can use fully qualified class names in my UrlMappings.groovy!

And as usual life is good again :D