How to use SOAP::Transport::HTTP::Plack

I needed to port a little cgi-script that implements a simple SOAP-server to Plack. After a little searching, I came across SOAP::Transport::HTTP::Plack.

Unfortunately, the documentation of this module is ... not really helpful.

Here's my (slightly modified) cgi-script:

#!/usr/bin/perl

use SOAP::Transport::HTTP;

SOAP::Transport::HTTP::CGI
    ->dispatch_to(
        '/some/directory', 
        'Some::SOAP::Module1', 
        'Some::SOAP::Module2',
    )->handle;

Simple enough.

After some help of the awesome hobbs on IRC, here's part of my Plack psgi file:

use Plack::Builder;
use Plack::Request;
use SOAP::Transport::HTTP::Plack;

my $soap = SOAP::Transport::HTTP::Plack->new;

my $soap_app = sub {
    my $env = shift;

    return $soap
            ->dispatch_to(
                '/some/directory', 
                'Some::SOAP::Module1', 
                'Some::SOAP::Module2',
            )->handler( Plack::Request->new( $env ) );
};

return builder {
    mount 
        '/soap_test' => $soap_app;
}

And low and behold, it works!

LCLOC of the month

Here's the Least Comprehensible Line Of Code I came across this month. Took me a while to make sure it really did what I thought it did.

my @array;
# ...
@array = map {$_;} (@array, keys %{$this->{'someobject'}->get_some_hash_ref()});

Bonus points for using $this instead of $self.

What Moose is doing to my nose

It's only been a couple of months since I've been using Moose, but it is already changing the way I read code. Of course, it changed the way I write code in a very short time, but I was surprised when I realized that it also changes the way I smell code.

Things that seemed normal last year, now are a code smell to me. Whenever I see an object being constructed inside a method whose name doesn't start with '_build_', I wonder if something bad is going on. Even method calls with parameters are now becoming a code smell. Whenever I smell that smell, I ask myself "should this be an attribute?".

And that's a pretty good thing. I never found testing my code easier. "Dependency injection" is harder to spell out than it is to just do it. And I find myself being able to understand my own code a couple of weeks later.

So, to sum it all up: Thank you, Moose Cabal!

Perl testing with Jenkins/Hudson: avoiding some pitfalls

Having continuous integration is incredibly helpful and setting up a Jenkins server is surprisingly easy. However, configuring Jenkins to run your Perl unit tests is a wee bit harder, although it may seem easy at first. Here are a couple of issues I ran into and some things I learned:

We all know that Perl unit tests, aided by Test::More and prove produce results in TAP format. But since Jenkins is Java and someone once dictated that Java shall only read XML and only write XML, Jenkins expects test results to conform to the JUnit XML format. Well, OK, if they want XML, let's give them XML. So you turn to your favorite search engine and ask it how to transform TAP to JUnit. You will, of course, find something. And since that something was actually written by Justin Mason of SpamAssassin fame, you stop searching at that point and download that conversion script.

Well, the first mistake was to use Google. It's always better to search CPAN first in a case like that. A quick look at those CPAN search results goes a long way. It turns out that you don't have to transform TAP to JUnit, you can simply tell prove to use a different formatter for its output:

prove --formatter=TAP::Formatter::JUnit -l t > test_results.xml

It's really that simple. Now go ahead and look at the documentation for prove. It's full of goodness! For example, you might want to add --timer to the line above, and you will not only see which tests failed or didn't, but also how long each test took.

prove --timer --formatter=TAP::Formatter::JUnit -l t > test_results.xml

There is really no need to save temporary TAP output and then transform it into JUnit later.

Moving along, you will find that some people out there are actually trying to tell you that you should run a find to gather your test files and then loop over the results to pass them to prove. Of course that's possible, but it's also quite clumsy, completely unnecessary and it will run your tests in no particular order. So don't do this:

for t in $(find t -name '*.t') ; do prove ....; done

prove will find you test files if you tell it to, simply use -r for that.

prove -r --timer --formatter=TAP::Formatter::JUnit -l t > test_results.xml

Still relying on Google, you might come up with some clever Unix sexyness:

prove -r --timer --formatter=TAP::Formatter::JUnit -l t | tee test_results.xml

I guess people use the tee because that lets them see the test output when looking at the console output of their build jobs, but tee has a nasty side effect: It will hide prove's exit value from Jenkins. Your builds will not fail when you tee their output. At worst, they will be marked as unstable. So if you want your build to fail when some of your tests fail, stay away from tee! Use it for the initial configuration of your jobs to make sure you don't miss any error messages in the console output, but then get rid of it.

Perl is elegant. Or can be. For me, what I learned about prove when working with Jenkins, confirmed this once again.

This is what I started with:

for t in $(find t -name '*.t') ; do prove -l $t 2>&1 | tee -a $OUTPUT/test-$BUILD_NUMBER.tap; done
tap-to-junit-xml --input=$OUTPUT/test-$BUILD_NUMBER.tap --output=test_results.xml

And this is what I ended up with:

prove -r --timer --formatter=TAP::Formatter::JUnit -l t > test_results.xml

Not only is this easier to read, it also does what I want.

Can we afford bad code on blogs.perl.org?

If you have a regular look on blogs.perl.org, you will have noticed a certain newcomer around here who keeps posting uncommented Perl scripts. I don't mind a noob asking stupid questions. Heck, I don't even think that noobs can ask stupid questions. But can the Perl community afford to have really bad code on a domain named 'perl.org'?

Just asking.