Elegance Fail

xsawyerx on 2010-01-19T22:22:02

this was originally posted on my new blogs.perl.org journal, which can be found here.

Elegance might seem like a lost trait in programming these days, but it is live and vibrant in Perl. A rather large part of the Test namespace is devoted to providing an elegant way to write "run this code, get the result, compare it with this one".

Today I found myself at a loss of an elegant solution to a problem.

I want to run a set of tests. Theoretically I can write each subset of tests as a Role in a test object (there are at least three testing frameworks that allow this nicely) and then run the tests in the object. I can even use MooseX::POE (or regular POE, AnyEvent, Test::Aggregate and the list goes on) to run them asynchronously in order to save the time.

Two things bug me:

  • The majority of the tests count on file content, grep, cat, readlink and such. So basically I'm trying to run simple shell functions inside Perl. I could probably use Test::File for this and expand it to add what's missing.
  • I'm testing a remote server, not my own box.

I can:

  • Write the tests as if they're being run locally. Copy them over, run them and then delete them: I don't like this method. It's unclean.
  • Wrap everything in Net::OpenSSH (or POE::Component::OpenSSH): I don't like this method since it involves a lot of calls just to get the content. Even if I configure my OpenSSH to use a shared socket, it's just wasted ops, ya know?
  • Use an RPC server: that means running an RPC server (open iptables for this, of course), rewrite the commands in a long HEREDOC or q{} which is ugly and not very readable.

What else is there to do?

Right now the first option (writing the tests, copying them over and running them) seems like the best method because that way I get to write the tests the way I want to and could use Test::File and stuff like that to check what I want. However, I wish there was a more elegant way to solve this. GRID::Machine seems interesting. I could write test subroutines and send their references to the GRID machine.Of course I lose a matter of scoping and would definitely be tricky to manage the inheritance and roles connection I want to use. Frustrating.