Algorithm-Classifier-IsolationForest
view release on metacpan or search on metacpan
t/90-cli-commands.t view on Meta::CPAN
};
subtest 'stream resumes a saved model' => sub {
my $out = `$^X -Ilib $bin stream -i $stream_csv -m $omodel 2>&1`;
is( $?, 0, 'stream (resume) exits 0' );
my @lines = split /\n/, $out;
is( scalar @lines, 121, 'one output row per input row on resume' );
};
subtest 'stream --score-only does not advance the model' => sub {
my $before = do { local ( @ARGV, $/ ) = ($omodel); <> };
my $out = `$^X -Ilib $bin stream --score-only -i $stream_csv -m $omodel -o $oscores 2>&1`;
is( $?, 0, 'stream --score-only exits 0' );
ok( -s $oscores, 'score output file written' );
my $after = do { local ( @ARGV, $/ ) = ($omodel); <> };
is( $after, $before, 'model file unchanged by --score-only' );
};
subtest 'stream --learn-only emits nothing but updates the model' => sub {
my $before = do { local ( @ARGV, $/ ) = ($omodel); <> };
my $out = `$^X -Ilib $bin stream --learn-only -i $stream_csv -m $omodel 2>&1`;
is( $?, 0, 'stream --learn-only exits 0' );
is( $out, '', 'no score output' );
my $after = do { local ( @ARGV, $/ ) = ($omodel); <> };
isnt( $after, $before, 'model file advanced by --learn-only' );
};
subtest 'info recognises an online model' => sub {
my $out = `$^X -Ilib $bin info -m $omodel 2>&1`;
is( $?, 0, 'info exits 0 on an online model' );
like( $out, qr/type\s+online/, 'info reports type=online' );
like( $out, qr/window_size\s+64/, 'info reports window_size' );
like( $out, qr/max_leaf_samples\s+16/, 'info reports max_leaf_samples' );
like( $out, qr/tree_total_nodes\s+\d+/, 'info reports tree stats' );
t/90-cli-commands.t view on Meta::CPAN
close $fh;
}
subtest 'fit --mungers accepts raw CSV and saves the spec' => sub {
my $out
= `$^X -Ilib $bin fit -i $raw_csv -o $mmodel -n 30 -m 32 -s 42 -t method -t path_len -t bytes --mungers $munger_json 2>&1`;
is( $?, 0, 'fit --mungers exits 0' ) or diag $out;
ok( -s $mmodel, 'model written' );
like(
scalar(
do { local ( @ARGV, $/ ) = ($mmodel); <> }
),
qr/"mungers"/,
'model JSON carries the munger spec'
);
}; ## end 'fit --mungers accepts raw CSV and saves the spec' => sub
subtest 'fit --mungers without -t is refused' => sub {
my $out = `$^X -Ilib $bin fit -i $raw_csv -o $tmp/nope.json -w --mungers $munger_json 2>&1`;
isnt( $?, 0, 'exits non-zero' );
like( $out, qr/requires feature tags/, 'error explains -t is needed' );
t/91-streamd.t view on Meta::CPAN
END {
for my $pid (@ALL_PIDS) {
kill( 'TERM', $pid ) if kill( 0, $pid );
}
}
subtest 'startup artefacts' => sub {
ok( -S $sock, 'socket exists' ) or diag( scalar `cat $logf` );
ok( -f $pidf, 'pid file exists' );
my $recorded = do { local ( @ARGV, $/ ) = ($pidf); <> };
chomp $recorded;
is( $recorded, $daemon, 'pid file records the daemon pid (foreground: the child)' );
};
my $c = connect_client();
subtest 'ping and client-tag echo' => sub {
is_deeply( rt( $c, { cmd => 'ping' } ), { ok => 'pong' }, 'ping pongs, no tag when none sent' );
is_deeply(
rt( $c, { cmd => 'ping', tag => 'req-1' } ),
t/92-streamc.t view on Meta::CPAN
# --batch 2 over 5 rows exercises partial-batch flush and ordering.
my $batched = `$sc -i $q_csv --mode score --batch 2 2>&1`;
my $whole = `$sc -i $q_csv --mode score 2>&1`;
is( $batched, $whole, 'batch size does not change the output' );
# -o writes the same thing to a file.
my $out_csv = "$tmp/scores.csv";
`$sc -i $q_csv --mode score -o $out_csv 2>&1`;
is(
scalar(
do { local ( @ARGV, $/ ) = ($out_csv); <> }
),
$whole,
'-o file matches stdout output'
);
}; ## end 'CSV stream mode: learn, prequential, score, -d' => sub
subtest 'jsonl stream mode: tagged rows, verbatim replies' => sub {
my $jsonl = "$tmp/rows.jsonl";
{
open my $fh, '>', $jsonl or die $!;
( run in 1.110 second using v1.01-cache-2.11-cpan-a9496e3eb41 )