use strict;
use constant NUM_ROUNDS => 2;
use Test::More tests => 5 + (6*NUM_ROUNDS);
BEGIN {
use_ok('Win32::EventLog');
}
TODO: {
local $TODO = "Win32::EventLog::GetMessageText misbehaviour";
is($Win32::EventLog::GetMessageText, 1, "Set Win32::EventLog::GetMessageText");
}
my $hnd;
sub open_log {
$hnd = new Win32::EventLog("Win32EventLog Log4perl Test", Win32::NodeName);
}
END {
if ($hnd) {
$hnd->Close;
$hnd = undef;
}
}
sub get_number {
my $cnt = -1;
$hnd->GetNumber($cnt);
return 0+$cnt;
}
sub get_last_event {
my $event = { };
if ($hnd->Read(
EVENTLOG_BACKWARDS_READ() |
EVENTLOG_SEQUENTIAL_READ(), 0, $event)) {
return $event;
} else {
diag( "WARNING: Unable to read event log" );
return;
}
}
eval {
require Log::Log4perl;
import Log::Log4perl;
};
my $has_it = ($@) ? 0 : 1;
SKIP: {
skip "Log::Log4perl not found", 3+(6*NUM_ROUNDS)
unless ($has_it);
open_log();
my $config = qq{
log4j.category.cat1 = INFO, myAppender
log4j.appender.myAppender=org.apache.log4j.NTEventLogAppender
log4j.appender.myAppender.source=Win32EventLog Log4j Test
log4j.appender.myAppender.layout=org.apache.log4j.SimpleLayout
};
Log::Log4perl::init( \$config );
my $log = Log::Log4perl->get_logger('cat1');
ok( defined $log, "get_logger" );
my %Events = ( ); # track events that we logged
my $time = sub {sprintf '%04d%02d%02d%02d%02d%02d',
$_[5]+1900, $_[4]+1, reverse(@_[0..3])}->(localtime);
# We run multiple rounds because we want to avoid checking passing the
# tests based on previous run of this script. That, combined with
# using the time to differentiate runs, should make sure that we test
# for each session.
foreach my $tag (1..NUM_ROUNDS) {
my $cnt1 = get_number();
$log->error("error,$tag,$time");
$Events{"error,$tag,$time"} = 1;
my $cnt2 = get_number();
cmp_ok( $cnt2, '>=', $cnt1, "round $tag get 1" );
$log->warn("warning,$tag,$time");
$Events{"warning,$tag,$time"} = 1;
$cnt1 = get_number();
cmp_ok( $cnt2, '<=', $cnt1, "round $tag get 2" );
$log->info("info,$tag,$time");
$Events{"info,$tag,$time"} = 1;
$cnt2 = get_number();
cmp_ok( $cnt2, '>=', $cnt1, "round $tag get 3" );
}
{
is( (keys %Events), (3*NUM_ROUNDS), "all events logged" );
while ((keys %Events) && (my $event = get_last_event())) {
my $string = $event->{Strings};
if ( ($string =~ /(\w+)\,(\d+),(\d+)/) &&
($event->{Source} eq 'Win32EventLog Log4j Test') ) {
if ( $3 == $time) {
my $key = "$1,$2,$3";
ok(delete $Events{$key}, "removed event $key");
}
}
}
is( (keys %Events), 0, "all events accounted for" );
}
};