Testing Mason autohandlers

phillup on 2004-11-13T00:56:30

In my last installment I found out that destruction of objects durning global garbage collection happens in a somewhat random order.

So, I need to make sure that all of my code undefines the $session instead of letting Perl do it for me. This way I know that the objects I'm referring haven't been destroyed yet and I can clean up properly.

Since this code runs in a Mason environment, the natural thing to do was insert a cleanup section in my autohandlers. But, I wasn't sure I had got them all.

And, I wanted to make sure that if I created an autohandler in the future that I remembered to clean my session.

Since I'm working on tests for the application, this seemed like a natural fit. So, I wrote a test to check all of my autohandlers for the correct code.

Now, if I create another autohandler it will get caught by the test script. At the very worst I'll have to update the plan. But, I won't forget to clean my session!

--- the code ---

#!/usr/bin/perl

# check all of the autohandlers and dhandlers and make sure that they have a cleanup section # that undefines the $session variable if they do not inherit from another file

use strict; use warnings;

use Test::More tests => 20;

# start in this directory my $app_dir = '/home/Mason/comp/Gradebook/';

use File::Find::Rule;

my $rule = File::Find::Rule->new; $rule->or( $rule->new->directory->name('CVS')->prune->discard, $rule->new->directory->name('Admin')->prune->discard, $rule->new->file->name('autohandler'), $rule->new->file->name('dhandler') ); my @files = $rule->in($app_dir);

foreach my $handler (@files) { # open our file and read it in open I, $handler or print 'Bail out!'; local $/; my $code = ; close I;

# first we need to check and see if this autohandler inherits from another if ($code =~ m|^<%flags>\ninherit=>'undef'\n|sm){ # if it doesn't then it should have a cleanup section # let's grab the contents $code =~ m|^<%cleanup>(.*)|sm; my $cleanup = $1 || ''; # so we don't trigger a warning with undefined scalar # and check to see that we are triggering the DESTROY method of our session ok( $cleanup =~ m|undef \$session;$|sm , "$handler cleans the session" ); } # if inherits } # foreach handler


Not a good idea

autarch on 2004-11-13T17:41:05

If you call $m->abort, or just die, then the cleanup sections never get run. It'd be better to write a custom handler, wrap the call to Mason in an eval block, and do cleanup after that.

Re:Not a good idea

phillup on 2004-11-13T19:09:23

Yeah, this was one of those 80% solutions.

I started with the custom handler but it wasn't playing nicely with some of my internal redirects. So, this was kind of a "quick hack" 'till I could study the problem a bit more.

The flip side of the coin is that I never had a problem in the Mason environment with the session and just letting it get destroyed during global destruction. I did, however, notice the problem when I needed to make a change to the database and decided to use the session module to do most of the work... because it already had methods in it to do what I needed.

It was while writing a script to run from the command line that I noticed the problem with the session.