Stories
Slash Boxes
Comments
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

use Perl Log In

Log In

[ Create a new account ]

xsawyerx (8978)

xsawyerx
  (email not shown publicly)

Journal of xsawyerx (8978)

Thursday December 10, 2009
08:27 AM

Please stop ignoring tickets

this was originally posted on my new blogs.perl.org journal, which can be found here which is also the RSS feed for it.

It's a lot of fun to contribute to other people's code (especially code you're using) and it's very fulfilling. Some people say it's a downer when your code isn't accepted, and I can understand that. However, the serious downer is when your code gets ignored.

When I go over a module, I go over the ticket list. When I see a ticket from over a year and it's still "new", it disappoints me and when I contribute to a project and it takes six months to get a reply, it disappoints me.

I know there are also different types of patches. Some of them complex and take time to test, check, correct and adapt. However, some patches are simple errors, common typos, data that should be added (like another entry for a hash of static data). These shouldn't be stuck so long back there. And, above all, don't ignore the contributor. Go over the tickets once a month and see if you can comment on anything. Even saying "I can't address this in the near future" means a lot to the contributor.

If you feel you don't have the time to work on a project, write about it, and suggest someone (most likely someone you already trust) be able to have co-maintainer status in order to apply some patches and release a new version.

Often times I see a project and think "well, I could fix this or that" or "seems like these only need applying and testing" but I don't want to take over the leadership of the module. I've contacted a lot of authors over the years. I've gotten only a few replies.

Sometimes I think releasing Your::Module::Patched will be the only way to get some of the patches I or other authors write included in. Obviously, that isn't a smart move. CPAN isn't Github. It doesn't look kindly on forks because it still has to maintain some authoritative version of a project for users to be able to download. Users want authoritative versions, not "his/her version".

Other than trying to contact an author, writing an email (or another one) and maintaining a personal collection of patches, I don't know what else can be done.

Please, give your RT some love, give your contributors some love.

I think I'll personally try to contact some authors for co-maintainer status just to patch things up.

Tuesday December 08, 2009
04:45 AM

Security by Obscurity, DLC style

this was originally posted on my new blogs.perl.org journal, which can be found here which is also the RSS feed for it.

<rant>

Rapidshare deletes illegal files, so instead of sharing Rapidshare links, sites nowadays apparently started sharing .dlc files (or so I've heard). DLC is an encrypted container format. It is very very stupid. I'll elaborate.

Let's break it down:

  • Only one server decrypts - single point of failure.
  • Disregarding the necessity for internet, this binds you to specific programs that have the keys hardcoded in them to be able to access the server.
  • The protocol is secret, the key is secret, the programs are closed source (at least the part that matters).
  • One program is for Windows only. The main one is written in Java. Stupid Java. I've gone over the parts of it that are open source and it's horrible (really really horrible).
  • I have not managed to get the program running on three different computers, and on Windows as well.
  • Apparently they change the key every once in a while so you always have to stay updated with the program.

However, these are all implementation issues. The problem here is that a bunch of freelance programmers (I'm assuming) think that by hardcoding and source-closing the key to their wanna-be-open-source application, it will somehow deter people who make it their job to crack it.

Since you still want the average boob (that is, the average dumbbell) to be able to operate the program and download the stuff, you need to make it accessible enough for him/her. Once it's that accessible, it's accessible to any IRAA/MPAA/<enter agency name> agent to reach as well, since they are at least as smart as the average bear, err... boob.

You're telling me a well funded agency can't open the stupid program and click the link? They can't write a program that automatically opens the other program and clicks the link? Really? Oh, this is ultra super secure now? You can write a Visual Basic program that does that in 10 minutes.
(please don't write a visual basic program)

I've emailed at least one website that does that, trying to get a decent answer for this. Still no response.

As to the JDownloader developers: Your program doesn't work, and your super ultra secure technology is closed source i-wouldn't-touch-it-with-a-ten-foot-pole icky. Yes, icky. You've secured nothing!

Fox21.at [fox21.at] release various Perl programs. One of them is called dlc2txt (oh, here's the Google Translate for it). Using this program, given the key and host, you can just crack DLC files yourself.

Of course the developers keep the key in JDownloader only. They also issues two other keys for two other programs (one of them written in Python) and threatened them not to reveal the key. The other programs and JDownloader keep the key closed source by compiling it.

So you have to use JDownloader or the other programs.
Right? Wrong!

Here is a fully detailed post on how to crack DLC completely.

I will probably write a Perl module to use this new kickass webservice that cracks DLC for you.

Meanwhile, please quit trying to convince people that your new thinga-ma-gic protects them even though it really doesn't. It only adds complexity for the user (much more than for an agent) and pisses people (like me) off.

Thank you.

</rant>

Monday November 30, 2009
03:26 AM

I'm moving on up! (... or simply away)

I'm seriously sick of use.perl.org. I liked it when I just started blogging (id est bitching), it was fine. However, soon enough I wanted to write a blog entry without writing all the HTML code myself, without writing in a really small textarea, without working really hard on writing even the smallest post... and damn, I wanted some interface that wasn't this ugly.

In the Perl world, we now work very hard on being "less ugly" because many of us are system-oriented people. We don't see pretty or ugly, but other people do, and it makes them stray away from our technology.

Blogs.Perl.Org looks the way blogging in Perl-world should look like. I'm moving there. I might cross-post here as well, I might not.

The live feed for blogs.perl.org is http://blogs.perl.org/atom.xml. Use it!

My personal blog there is under Sawyer X. I'll have Perl Sphere updated with my new blog as well.

See ya on the flip side...

Wednesday November 04, 2009
10:47 AM

Extensive POE Testing PT. 7 - Testing, Event Parameters PT.2

There is actually a limit on the length of the subject, this should actually be entitled: Extensive POE Testing PT. 7 - Testing, Unordered Event Parameters

Last post talked about Ordered Event Parameter testing which is basically setting a set of parameters that should be for each event, in the order in which they are suppose to be run.

A weak point that remains in this rather strong testing feature is the ability to make it unordered. That is, to say "I know the event next will be called with each of these parameter sets, but I don't know which one will come before the other.

A good example would be two events (one could even be an alarm) were to reach the same event, each with different parameters:

package Session;
use MooseX::POE;
sub START {
    $_[KERNEL]->alarm( 'mine_alarmz', time() + int rand 2 );
    # ... other stuff
    $_[KERNEL]->yield( 'next', 'from START' );
}

event 'mine_alarmz' => sub {
    $_[KERNEL]->yield( 'next', 'from alarmz' );
};

The race condition here manifests by having two codes (START, alarm) running the same event (next) and not knowing for sure which will reach it first.

In this case, testing for the set of parameters next will be called with (especially in a specific order) will be worthless. Taking into account that we don't really care what set of parameters is called first, setting possible sets of parameters for next will make sure that when it is called, it will not be called with anything that isn't defined as a set of parameters and will allow this race condition to exist, without causing trouble. This is actually the preferable method of testing event parameters for most people.

When using POE::Test::Helpers to do it, you merely have to override another attribute to set it. Here is a sample:

package Session;
use Test::More tests => 4;
use MooseX::POE;
with 'POE::Test::Helpers';
has '+event_params' => (
    default => sub { {
        'next' => [ [ 'hello', 'world' ], [ 'goodbye' ] ],
        'more' => [ [] ],
} } );

# this is the new attribute to override
has '+event_params_type' => ( default => 'unordered' );

my $flag = 0;
sub START           { $_[KERNEL]->yield( 'next', 'goodbye' ) }
event 'next' => sub { $_[KERNEL]->yield( 'more'            ) };
event 'more' => sub {
    $flag++ || $_[KERNEL]->yield( 'next', 'hello', 'world' );
};

package main;
use POE::Kernel;
Session->new();
POE::Kernel->run();

Next post (hopefully won't be in too long) will cover writing some tests with POE::Test::Helpers

Wednesday October 28, 2009
03:27 AM

Extensive POE Testing PT. 6 - Testing, Event Parameters PT.1

There is actually a limit on the length of the subject, this should actually be entitled: Extensive POE Testing PT. 6 - Testing, Ordered Event Parameters

We've covered the rules, ordered tests, sequence ordered tests, event counting and a mixture of event counting and sequence ordered tests. Now it's time to play with some more advanced stuff.

The last frontier I came across trying to battle testing in POE was wanting to make sure the parameters to each event were what I expected. Why?

  • I'm able to test who called what and how many times, but if the parameters change, how would I know?
  • What if there an error in a function that's hard to test and it calls incorrect parameters?
  • What if I have a race condition?

So, naturally, I wanted to know what parameters are sent to each event. This is how it can be done with my POE::Test::Helpers 0.06:

package Session;
use Test::More tests => 4; # this can also be defined in main
use MooseX::POE;
with 'POE::Test::Helpers';

has '+event_params' => ( default => sub { {
    next => [ [ 'hello', 'world' ], [ 'goodbye' ] ],
    more => [],
} } );

# a flag for making sure next runs again
my $flag = 0;

# set up the events
sub START { $_[KERNEL]->yield( 'next', qw( hello world ) ) }

event 'next' => sub { $_[KERNEL]->yield('more') };
event 'more' => sub {
    $flag++ || $_[KERNEL]->yield( 'next', 'goodbye' );
};

# set up main
package main;
use POE::Kernel;
Session->new();
POE::Kernel->run();

What happens when the Kernel is run is that:

  • START -> next (parameters: "hello", "world")
  • next -> more (no parameters)
  • more -> next (parameters: "goodbye")
  • next -> more (no parameters)
  • more does nothing and the program closes.

What we can see is that we defined with our helpers the assumed iterations of each event. next is assumed to first run with the parameters "hello" and "world", and secondly run with the parameter "goodbye". We also assume that more will be called with no parameters at all.

These are the results of the test:

1..4
ok 1 - (next) Correct params
ok 2 - (more) Correct params
ok 3 - (next) Correct params
ok 4 - (more) Correct params

This helps make sure the events run with the exact parameters we want for each run, in the order we specified. This is extremely important to understand. It checks that you called it first with the first parameter set (in an arrayref) and only then with the second one. If by some weird turn of events (or code editing), the calls would get mixed up and it will call next with "goodbye" first, the test will fail.

This is how it would look if we reverse the order of the parameters:

not ok 1 - (next) Correct params
#   Failed test '(next) Correct params'
#   at lib/POE/Test/Helpers.pm line 94.
# Comparing $data as a Bag
# Missing: 'goodbye'
# Extra: 'hello', 'world'
ok 2 - (more) Correct params
not ok 3 - (next) Correct params
#   Failed test '(next) Correct params'
#   at lib/POE/Test/Helpers.pm line 94.
# Comparing $data as a Bag
# Missing: 'hello', 'world'
# Extra: 'goodbye'
ok 4 - (more) Correct params
# Looks like you failed 2 tests of 4.

One question remains: what if I can't know the order? What if I don't care? What if either of them can run but I don't know which one would come before the other? That's left for the next post.

BTW, as promised, I will demonstrate how to test for a pretty nasty race condition using these methods, easily.

Tuesday October 20, 2009
03:39 AM

Extensive POE Testing PT. 5 - Testing, Seq-Ordered and Count

dngor corrected me on some errors in the last post. they were fixed.

This is a short post in my series. It simply shows how to combine (using POE::Test::Helpers) both sequence ordered tests and event counting tests at the same time.

# drawing from a previous example:
package Session;
use MooseX::POE;
use Test::More;
with 'POE::Test::Helpers'; # actual title

has '+seq_ordering' => ( default => sub { {
    START => 1,
    next  => 4,
    more  => 4,
    last  => { 1 => [ 'START', 'next', 'more' ] },
    STOP  => [ 'START', 'next', 'more', 'last' ],
} } );

my $count = 0;
sub START           { $_[KERNEL]->yield('next') }
event 'next' => sub { $_[KERNEL]->yield('more') };
event 'more' => sub {
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};
event 'last' => sub { 1 };

# adding the runner
package main;
use Test::More tests => 6;
use POE::Kernel;

Session->new();
POE::Kernel->run();

Here we can see how our test requirements are declared:

  • START runs only once
  • next runs four times
  • more runs four times
  • last runs once
  • last runs ONLY after START, next and more
  • STOP runs only after all the other events

That comes out to 6 tests. That's what we wrote in the Test::More plan and this is the result:

$ perl -Ilib t/articles/2.t
1..6
ok 1 - Correct sequence for last
ok 2 - Correct sequence for STOP
ok 3 - (next) Correct number of runs
ok 4 - (START) Correct number of runs
ok 5 - (last) Correct number of runs
ok 6 - (more) Correct number of runs

We can see that it only tested last and STOP for sequence ordering (or event dependency). Also, it only checked the number of correct runs on next, START, last and more.

You might notice the test output didn't come out in the same order the events ran. That's because it takes them from the attribute we set, which is a hash and hence, has no order.

What next?
While I'm working on releasing it today to Github and hopefully soon enough to CPAN as well, I still have a few things to go over. There's one more type of tests that I found the most important for me and it's pretty sweet. I intend to write another post or two on that. Then I'm going to present the framework (it should already be on CPAN by that time) and show a pretty insane race condition we found at $work and tested using this framework. Stay tuned!

Sunday October 18, 2009
06:43 AM

Extensive POE Testing PT. 4 - Testing, Event Count

update: fixed a few errors

So it took some time, but here's the next article/post on POE testing.

The last one discussed Sequence Ordered tests, which is the way I call the type of tests that do not rely on whether the event ran at the specified order by number, but by previously running events. However, all the previous posts still ignored a serious need that we have for event testing, which is how many times did each event really run?

If you use ordered tests, you cannot have the same event running more than once without some logic to test the specific iteration of the event. sequence ordered tests help reduce that but they also reduce the count.

Let us take a look at code which runs the same event more than once:

package Session;
use MooseX::POE;

my $count  = 0;

sub START           { $_[KERNEL]->yield('next')  }
event 'next' => sub { $_[KERNEL]->yield('more')  };

event 'more' => sub {
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};

event 'last' => sub { print "last!\n"; };

Now let's add tests:

package Session;
use MooseX::POE;
use Test::More tests => 4;

my %events = ();
my $count  = 0;

sub START {
    $events{'START'}++;
    $_[KERNEL]->yield('next');
}

event 'next' => sub {
    $events{'next'}++;
    $_[KERNEL]->yield('more');
};

event 'more' => sub {
    $events{'more'}++;
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};

event 'last' => sub {
    $events{'last'}++;
    print "last!\n";
};

event 'STOP' => sub {
    cmp_ok( $events{'START'}, '==', 1, 'START ran once'   );
    cmp_ok( $events{'next'},  '==', 4, 'next ran 4 times' );
    cmp_ok( $events{'more'},  '==', 4, 'last ran 4 times' );
    cmp_ok( $events{'last'},  '==', 1, 'last ran once'    );
};

This is how we could accomplish it. Here is how it's done with the current iteration of my (still yet unpublished) testing framework:

package Session;
use MooseX::POE;
use Test::More tests => 4;
with 'POE::Test::Simple'; # running title

has '+seq_ordering' => ( default => sub { {
    START => 1,
    next  => 4,
    more  => 4,
    last  => 1,
} } );

my $count = 0;

sub START {
    $_[OBJECT]->seq_order('START');
    $_[KERNEL]->yield('next');
}

event 'next' => sub {
    $_[OBJECT]->seq_order('next');
    $_[KERNEL]->yield('more');
};

event 'more' => sub {
    $_[OBJECT]->seq_order('more');
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};

event 'last' => sub {
    $_[OBJECT]->seq_order('last');
    print "last!\n";
};

event 'STOP' => sub {
    $_[OBJECT]->seq_end();
};

And this is how it would look in the (hopefully) upcoming version:

package Session;
use MooseX::POE;
use Test::More tests => 4;
with 'POE::Test::Simple'; # running title

has '+seq_ordering' => ( default => sub { {
    START => 1,
    next  => 4,
    more  => 4,
    last  => 1,
} } );

my $count = 0;

sub START           { $_[KERNEL]->yield('next') }
event 'next' => sub { $_[KERNEL]->yield('more') };

event 'more' => sub {
    $count++ < 3 ? $_[KERNEL]->yield('next') :
                   $_[KERNEL]->yield('last');
};

event 'last' => sub { print "last!\n" };

Next post is a short one in which I'll show samples of using both event counting and sequence order (event dependencies).

Sunday October 11, 2009
04:42 AM

Extensive POE Testing PT. 3 - Testing, Sequence Ordered

My last post went over the idea of ordered tests, in which we run events in a certain order. It's a simple concept, it's easy to test and it's very nifty.

However, it fails to cover some more advanced grounds, specifically the idea of multiple runtimes of a session or event, in which we can result in a race condition where two or more instances of the event will try to fire first and we aren't exactly sure which will come first. One could stumble over an if() that will take it a little bit more while the other might handle an unexpected delay because of its flow.

Still, the point to make is that usually in such situations we don't really care what was the numbered order of the events, we care about the preceeding order of the events. Meaning, the sequence of events.

Here is an example:

package MyPackage;
use MooseX::POE;

has 'num' => ( is => 'ro', isa => 'Int', default => 0 );

sub START { # in MX::POE, this is mapped to _start
    $_[KERNEL]->yield('first');
}

event 'first' => sub {
    if ( $_[OBJECT]->num == 7 ) {
        # lucky number slevin
        $_[KERNEL]->yield('long_taking_event');
    }

    $_[KERNEL]->yield('second');
};

event 'second' => sub {
    print "reached second!\n";
};

event 'long_taking_event' => sub {
    print "reached long taking event!\n";
};

package main;
MyPackage->new( num => rand(10) ) for 1 .. 5;

In this example, we aren't exactly sure if num will be 7 or not, and thus we aren't sure if long_taking_event will even be called. Besides, we're running each event more than once so the order function with the static number of running order of the events cannot even be applied here.

Interestingly enough, we can stipulate that we do know first is suppose to run only after START. This might seem a bit given, but maybe we've made an error in the code and run first directly? How about knowing that long_taking_event and second can only be run after first? That's pretty good to know. If we run the program and it will see that second ran before first, we know we've made a mistake!

That's what I call sequenced-ordered tests or event-dependency order. It's when the order isn't conclusive, but the sequence of events is. Right now my (yet unnamed and unpublished) framework supports that in a very simple form:

with 'POE::Test::Simple'; # running title

has '+seq_ordering' => ( default => sub { {
    'first'            => [ 'START'          ],
    'second'           => [ 'START', 'first' ],
    'long_taking_event => [ 'START', 'first' ],
} } );

# then each event/sub called can register itself with the framework
event 'second' => sub {
    $_[OBJECT]->seq_order('second');
};

Right now I'm working on making this implicit so it's not required to run at all in order for the testing to run. Much help on this came from mst, doy and other great people at #moose. Thanks guys!

Again, thinking about what this still misses: how many times each event ran? We have no counting of this, so the next post will cover event counting, which is exactly it. Meanwhile, if you feel like pitching ideas for the framework module name, I'd appreciate it.

Friday October 09, 2009
09:32 AM

Extensive POE Testing PT. 2 - Testing, Ordered

A special thanks goes here to Adam Kennedy for sending me on this path and giving me ideas. Adam, I wanted to thank you personally but couldn't catch you on IRC, so thanks! :)

I tried to cover in my last post the basic guidelines I have for testing in POE. Testing in POE is different since we want to test a flow and not just subroutines. This time I want to try go over the first type of tests that I find necessary. It's called ordered tests - at least that's how I call it.

This method was first hinted at me by the great Adam Kennedy who used it in his POE::Declare module. Basically it describes the following scenario: I have a POE::Session event flow and I want to make sure that every event is run at the specific order.

package MyPackage;
use MooseX::POE;
use Test::More;

# this is taken from POE::Declare's t/04-stop.t
my $order = 0;
sub order {
    my $position = shift;
    my $message  = shift;
    is( $order++, $position, "$message ($position)" );
}

# then we can do this (written in MX::POE)
event 'eg' => sub {
    order( 0, 'Started eg event' );
};

Now, each event could run this subroutine with a number indicating the order of this event in our overall flow of the session. Here, for example, with the order( 0, 'event name' ) code if any event is running at a time that wasn't meant for it, it will fail.

However, it has a few disadvantages:

  • If any of the events repeat, it creates a problem. You'll have to set up a system to check which iteration of the event it is and execute the correct order()
  • What if you're yelding the kernel for two events and you aren't sure which one will run first?
  • What if it doesn't matter which one will run first?
  • What about running two sessions of the same object? It has the exact same events, with the exact same code. It will fail for sure.

My suggestion: allow a test that checks for event dependency. Instead of saying "this runs first", you could say "this runs ONLY after that" and "this - this runs only after these two". That would allow to have an order based on a sequence of events. Each event can only come after different events.

This is what the next post will discuss.

Wednesday October 07, 2009
05:46 AM

Extensive POE Testing PT. 1 - The Rules

If you only use POE::Session for your POE code and find no need for more elaborate tests, feel free to skip these posts. I won't be offended, I promise. :)

After a lot of frustration of trying to set up proper tests for POE (using mainly MooseX::POE while at it), I've decided to write a proper testing framework. However, instead I wrote something simple, yet relatively extensive that helps write fingergrained tests for POE using Moose, specifically aimed towards MooseX::POE.

I've decided to write it in Moose (using Moose::Role) because it makes it much easier for me to do it than other frameworks/modules. I don't intend (at least at this time) to write it in bare bones Perl and I personally don't care about complete optimizations for my testing code, I don't think a lot of people would mind either.

This article will only discuss the general need, the idea and the general rules I've layed out for myself to help me test POE code. It might help you too. The following articles in this series (and I assure you, there will be!) discuss the types of tests that I feel are required and examples of code that does it. I'll also present my new (unnamed) testing framework that's already being used at $work.

Preliminary:
In POE, you have a layer of "events" which are actually just mappings of names of events that can be run to the actual subroutines that they will trigger when run. This seems pretty simple to test. You can check each subroutine separately and that's just fine. However, there are some things it doesn't cover:

  • MooseX::POE: if you're using MooseX::POE your events are mapped for you to anonymous subroutines. Instead of writing a named subroutine and then mapping it through inline_states (or whatever), you simply do event 'something' => sub {}; Problem is, you cannot test it that easily.
  • Sometimes you want to run stuff and see how it works: It is important to test every small component separately, but it's always nice (especially when it comes to complete environments) to check a bigger chunk. It's also easier to comprehend. Sure, I know that check_stuff() was run, but when the program was started, did it get run 3 or 4 times?
  • Some things are harder [and/or take longer] to test. For example, suppose a subroutine can be called several times (loop, events, alarm) with varying inputs. Perhaps there's an alarm that checks each time and only then runs another event. To test every subroutine's possible iteration is possible, but not as much fun.

Theory of tests in POE:
I found that the cleanest and easiest way to test is always accompanied by these following guidelines:

  • Always test a single POE Session at a time. Sometimes the sessions interact. You can mock sessions in order to work through that. Testing POE is difficult enough as it is without testing 10, 20 or 300 Sessions at a time. So do yourself a favor. Each time work on only one session. I separate my tests to folders according to the sessions I have. I have a folder for a Master Session, a Slave Session, a Worker session and so on.
  • Override the session you intend to test. This will allow you to change the session environment, its subroutines, events, alarms, and so on. It will keep the Kernel session-specific and make everything self-contained and a hell of a lot easier.
  • Preferably test events separately. This isn't always desired or necessary but I find it much more comfortable. I keep every event as a separate test file. The reason for this is the same as why I work on only one session at a time. I helps me test it without going insane with the multitude.
  • When testing an event, override and mock everything in its surrounding in order to test it. This is something the True Test Lords have known for a long while now. Creating a controlled environment is the best way to check something. Same goes here. You should mock and override every subroutine, attribute, event or anything else that comes in contact with the event you're testing. Think... Ebola!
  • Separate event tests with subroutine tests. All subroutines should be tested regardless of the POE Running test, in the regular way you test subroutines (or methods). Events will be tested separately in a different manner that requires running POE and seeing what happens.

Next post starts with types of tests!