#!perl -T use 5.006; use strict; use warnings; use Test::More; use Test::Exception; use diagnostics; use Security::Monitoring::Detection::Markov; use Security::Monitoring::Utils; BEGIN { plan tests => 25; use_ok( 'Security::Monitoring::Detection::Markov' ) || print "Bail out!\n"; } our $dict_file; my $class='Security::Monitoring::Detection::Markov'; #setup and test function existence diag( "Testing Markov module $Security::Monitoring::Detection::Markov::VERSION, Perl $], $^X" ); ok(defined(Security::Monitoring::Detection::Markov->new(10)),"automata generator working"); my $automaton = Security::Monitoring::Detection::Markov->new(10); ok(ref $automaton,"generator correctly returned a ref to the new automaton"); my $learnstring = "test_dict"; open my $fh, '>',$learnstring; print $fh "dd\nff"; close $fh; dies_ok(sub {my $new = $class->new(undef)},"new dies with undef alert_level"); dies_ok(sub {my $new = $class->new('trololol')},"new dies with non int alert_level"); #tests learning dies_ok(sub {$automaton->learn('trololol');},"learn dies with incorrect filename"); dies_ok(sub {$automaton->learn(undef);},"learn dies with undef filename"); dies_ok(sub{$automaton->learn(undef,1)},"learn dies with undef string"); dies_ok(sub {$automaton->learn('',1)},"learn dies with empty string"); #undefines all env variables to prevent taint warning flush_env; `/usr/bin/touch emptyfile`; dies_ok(sub{$automaton->learn('emptyfile')},"learn dies with empty file"); is($automaton->learn($learnstring),2,"automaton learnt 2 words from file"); unlink $learnstring; is($automaton->_transitions,4,"automaton has 4 transitions"); is($automaton->get_score("mama"),4,"automaton scored 4 on a four new letters word"); is($automaton->get_score("dd"),0.5,"automaton scored 0.5 on one of the two learnt words"); is($automaton->learn("tata\ntutu",1),2,"automaton learnt two words from string"); my $emptymaton = Security::Monitoring::Detection::Markov->new(10); $ENV{PATH} = '/usr/bin'; my $dict_words_number = `wc -l /usr/share/dict/words`; chomp $dict_words_number; $dict_words_number =~ s/[\D]//g; dies_ok(sub{$class->sys_learn;},"sys learn dies when called as class method"); my $tmp = $Security::Monitoring::Detection::Markov::dict_file; dies_ok(sub{ $Security::Monitoring::Detection::Markov::dict_file = 'trololol'; my $auto = $class->new; $auto->sys_learn; },"sys learn dies with dummy dict file name"); dies_ok(sub{ $Security::Monitoring::Detection::Markov::dict_file = 'emptyfile'; my $auto = $class->new; $auto->sys_learn; },"sys learn dies with empty dict file "); unlink 'emptyfile'; $Security::Monitoring::Detection::Markov::dict_file= $tmp; is($emptymaton->sys_learn,$dict_words_number,"sys_learn works correctly"); is($emptymaton->{word_count},$dict_words_number,"automaton correctly reports number of words learnt"); #tests save and load ok(($automaton->save("automaton.at") =~ /automaton\.at/) && (-e "automaton.at"),"automaton correctly saved to disk"); my $newtomaton = $class->load("automaton.at"); ok(defined($newtomaton),"automaton reloaded"); unlink "automaton.at"; $newtomaton->{empty}->{a}+=1; my $autsub = $class->new(10); my $autsub2 = $class->new(10); my $hash1 = {a=>1}; my $hash2 = {b=>2}; $autsub->{t_table}->{x} = $hash1; $autsub2->{t_table}->{x} = $hash2; #tests false positive handling my $word = 'xxxxxxxmmmmmnnnxyxyxyxynmnmnmn'; ok($newtomaton->flag_as_false_positive($word),"false positive flagging works"); is(${$newtomaton->get_false_positives}[0],$word,"get_false_positive works"); is($newtomaton->get_score($word),$newtomaton->{mean_score},"false positive evaluation returns correct value");