Saturday 3 December 2011

Test::WWW::Selenium::Conversion::IDE

At $work we have a LIMS system running as a web app. Nothing unusual there. However, we had a user experience a bug which had only be seen once before, and seemed impossible to recreate.

It seemed to come from asynchronous Ajax updates to one field on the user session.

My first thought, was how to recreate this bug which only comes up rarely. On my development version, I couldn't get it to happen. So, I decided to have a play with Selenium. After downloading the Firefox plugin, I recorded the actions that our user did, and ran through as fast as it would replay.

Success, the bug reappeared. If run at slow speed, the test ran through happily, but fast caused the issue with the Ajax.

Working on a solution then gave me a test case to work against, and I can happily report that the bug has gone away.

Now, as a reader of this blog, you know I am a Perl programmer, and, yes, this app is just that. A Clearpress app.

We have a good test suite exercising the model, view and api, but we don't have anything UX tests. So, can I run the Selenium IDE file (Selenese HTML) in the Perl test suite. CPAN has two modules providing drivers for the Selenium Server, but no converter from Selenese to Perl Test. That seemed to go some time ago.

So, time to actually do something about it. I chose to use the Test:: WWW::Selenium module over Selenium::Remote::Driver, as I preferred the API.

Now, I had two strategies here.

1) Fully convert the Selenese HTML file to a Perl Test file,
2) On the fly, convert and run the Selenese HTML file

I opted for 2, as I coul just hard code in a wrapper test a Selenese suite file, and then every time we record another user story, it will just get added to the suite, and run. Also, keeping the code DRY, as it will b handy to keep the Selenese HTML around to run individually in the IDE.

So, I started developing Test::WWW::Selenium::Conversion::IDE, to do just that. I released it yesterday to CPAN.

It should most definitely be considered ALPHA code. I am unlikely to change the function names, as $work will rely on it, but it is by no means feature complete. I welcome comments and patches if you need more features.

The way it works:

1) In a wrapper test file, create a Test::WWW::Selenium object with creds for your Selenium Server
2) Pass to the suite runner function this object and the filename of your suite file. You can also pass the location of the file, but it defaults to t/selenium_tests.
3) Rather than give a plan, use done_testing() at the end of your file, so the TAP plan can be accounted.

See POD for more options.

So, I push it out for the communities use.

Bye for now.

Friday 2 September 2011

Deep Magic - recover a file

We have hopefully managed to recover a file (or two) today from an existing process in which the files live in /tmp/, but if the process goes on too long, get deleted by the system
Find relevant Process ID
  >ps aux or top
  >pstree -p 

Work out files which have handles but are deleted
  >lsof -p 
  bwa     22039 srpipe    4r   REG      104,7  424718660  67171651 /tmp/iFCyWKyDjR/1.sai (deleted)
  bwa     22039 srpipe    5r   REG      104,7  401682372  67171652 /tmp/iFCyWKyDjR/2.sai (deleted)

Rebuild files
  >mkdir /tmp/iFCyWKyDjR
  >cat /proc/22039/fd/4 > /tmp/iFCyWKyDjR/1.sai
  >cat /proc/22039/fd/5 > /tmp/iFCyWKyDjR/2.sai

Check
  >ls -lh /tmp/iFCyWKyDjR
  total 789M
  -rw-rw-r-- 1 srpipe solexa 406M 2011-09-02 09:30 1.sai
  -rw-rw-r-- 1 srpipe solexa 384M 2011-09-02 09:30 2.sai

Tuesday 14 June 2011

To remember

my $last_base_index = ( length $fields[$SEQUENCE_INDEX] ) - 1;

The parenthesis are needed!

Friday 3 June 2011

Bingo!

Last year, my dad, as the Chairman of the local community association says that what might be a good fund raiser is a bingo evening.

Initially, my thought was, who are they going to get to run that then?

But he continued, and came up to the question of sourcing a bingo machine. This is were I came in and said,

'Oh, that's easy, I could write one in a couple of weekends on the computer, we jsut hook my laptop up to a big screen and that's that.'

Can you see where I'm going with this?

So, time passes, I had a quick stab last November, but stopped as Christmas was coming up, and I was writing a perl course for work...

Until March, when Dad turns round and says

'Are you going to be able to write the bingo machine in time for Annual fundraising week? What day of the week is best for you to run it?'

Eeep.

Still, never one to back down from a request to do something, I set to work. Went back to github, and decided to scrap most of what was there, start a new Catalyst project, and a couple of weekends later, I have a bingo caller, with big ball images, and a pretty simple interface.

It could still do with a pretty looking interface, but it does the job, and should run nicely next week - assuming I can sort out Moose

https://github.com/setitesuk/Bingo-Caller

Wednesday 16 March 2011

Interesting bug

I have just discovered an interesting bug, which took a lot of staring at to fathom out exactly what is wrong here:

if ( $self->is_paired_read() ) {
my $args = {
dir => $arg_refs->{dir},
position => $position,
read => $self->general_values_conf()->{sanger_read_two},
job_dependencies => $arg_refs->{job_dependencies},
control => $is_control,
is_spiked_phix => $is_spiked_phix,
};

if ( $self->is_indexed() ) {
$args->{read} = $self->general_values_conf()->{illumina_read_two};
}

$bsub_command = $self->_calibration_table_bsub_command( {
dir => $arg_refs->{dir},
position => $position,
read => $self->general_values_conf()->{sanger_read_two},
job_dependencies => $arg_refs->{job_dependencies},
control => $is_control,
is_spiked_phix => $is_spiked_phix,
} );

if ( $self->verbose() ) {
$self->log( $bsub_command );
}

push @{ $job_ids }, $self->submit_bsub_command($bsub_command);
}


Some of you may have spotted it straight away, but others may not.

The problem comes from a bit of

1) copy and paste programming (there is a read 1 as well)
2) not paying attention

Had I not had the if ( $self->is_indexed ) block, then Perl::Critic would actually have saved me here, with a unused variable error, but because $args (lexically scoped) , is used in the block, we skip that.

Simply, when you go to the trouble of defining your args outside of the call to the method, then use the args, don't rewrite. (Bangs head against wall to try to remember the fact).

The bug in production is that we always get a calibration table name with read 'sanger_read_two', when it should be read 'illumina_read_two' on an indexed run.
(These are config variables, which actually equate to 2 and 3 respectively)

So a change to:


$bsub_command = $self->_calibration_table_bsub_command( { $args } );


and all is fixed.

Monday 7 February 2011

Perl Course help!

I need some help as to whether or not to do include something in a beginners perl course I am writing to run at work.

Courses I went on and textbooks I have read (including the excellent Modern Perl) mention the idiom '0 but true', to have a true 0.

Everyone in my office when I asked either went 'what?', 'why?' or 'just something not needed and is confusing'.

Personally, I agree with the 'why?' and 'confusing', so I'm inclined to leave it out. However, what do the community at large think? One of my colleagues has been programming Perl for 15+years, and has never seen it. Is this generally the case?

Thanks to any responses in advance that support either side of the argument, particularly with good reasoning.

Just to confirm my 4 reasons for leaving it out:

1) Never seen it used
2) Too confusing to explain to people experienced in Perl, let alone Newbies
3) Too confusing to read in code
4) Won't be automatically assigned to a variable when answer is 0 (4-4), so better to use defined

Andy