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" ); } };