schobes blog

Test2 is nearing Stable Release

Written by schobes on
Permalink

Chad 'Exodist' Granum is nearing a stable release of Test2 and a replacement for Test::Builder! This is exciting news indeed. I have been using Test2's predesessor for some time @work and it is has been extremely helpful in speeding up our test environment.

Test::Stream, successfully allowed us to use fork() within our tests with predictable result outputs. This allowed us to create tools for taking long running tests and run them in parallel.

use Test::More;   # 1.301001082
use Test::Stream; # 1.301001082
use POSIX qw(WNOHANG);

my $stream  = Test::Stream->shared;
$stream->set_subtest_tap_instant(1);
$stream->use_fork();

my @test_groups = (
    [qw( 1 1 1 1 )],
    [qw( 1 1 1 1 0 0 1)],
);

my $code = sub {
    my $tests = shift;
    foreach my $test (@$tests) {
        ok($test, 'this test passed');
    }
    return;
};

my @pids;
foreach my $group (@test_groups) {
    my $pid = fork();
    die "Unable to fork!" unless defined $pid;
    if ($pid) {
        push(@pids, $pid);
    }
    else {
        $code->($group);
    }
}

do {
    sleep(1);
    Test::Stream->cull();
    foreach my $pid (@pids) {
        my $kid_done = waitpid($pid, WNOHANG);
        if ($kid_done) {
            @pids = grep { $_ != $kid_done } @pids;
        }
    }
} while @pids;

The above code probably doesn't work for the most recent version of Test::Stream (which is no deprecated in favor of Test2 and Test2::Suite).

I believe this is how the new code should work.

use Test2::IPC;
use Test2::Bundle::Extended;
use POSIX qw(WNOHANG);

my @test_groups = (
    [qw( 1 1 1 1 )],
    [qw( 1 1 1 1 0 0 1)],
);

my $code = sub {
    my $tests = shift;
    foreach my $test (@$tests) {
        ok($test, 'this test passed');
    }
    return;
};

my @pids;
foreach my $group (@test_groups) {
    my $pid = fork();
    die "Unable to fork!" unless defined $pid;
    if ($pid) {
        push(@pids, $pid);
    }
    else {
        $code->($group);
    }
}

do {
    sleep(1);
    Test2::IPC->cull();
    foreach my $pid (@pids) {
        my $kid_done = waitpid($pid, WNOHANG);
        if ($kid_done) {
            @pids = grep { $_ != $kid_done } @pids;
        }
    }
} while @pids;

I will follow-up later with the improvements we made and some benchmarks compared to the previous Test::Stream solution.


Comments

No Comments Yet!