package tests::functional::LrCronTest;
use strict;
use base qw/Lire::Test::FunctionalTestCase
tests::functional::TestSchemaFixture
tests::ChartTypesFixture
tests::OutputFormatsFixture /;
use Lire::Config;
use Lire::DlfStore;
use Lire::Utils qw/create_file/;
use File::Copy qw/copy/;
use POSIX qw/strftime/;
use File::Basename qw/basename/;
{
# See LrMailTest.pm for rationale
use utf8;
use MIME::Parser;
}
use Time::Local;
#our @TESTS = qw//;
sub new {
my $self = shift->SUPER::new(@_);
$self->tests::functional::TestSchemaFixture::init(@_);
$self->{'log_file'} = $self->tests_datadir() . "/test.dlf";
return $self;
}
sub set_up {
my $self = $_[0];
$self->SUPER::set_up();
$self->set_up_test_schemas();
$self->set_up_test_specs();
$self->set_up_TestDlfConverter();
$self->set_up_test_analysers();
$self->set_up_test_another_analyser();
Lire::Config->init();
$self->{'store_path'} = $self->homedir() . "/store";
return;
}
sub tear_down {
my $self = $_[0];
$self->SUPER::tear_down();
$self->tests::functional::TestSchemaFixture::tear_down();
return;
}
sub test_usage_period {
my $self = $_[0];
my $result = $self->lire_run( "lr_cron" );
$self->annotate( $result->stderr() );
$self->assert_not_equals( 0, $result->status() );
$self->assert( !$result->stdout(), "stdout should be empty" );
$self->assert_str_equals( "Missing 'period' argument.\nUsage: lr_cron <period> <store>\n",
$result->stderr() );
}
sub test_usage_store {
my $self = $_[0];
my $result = $self->lire_run( "lr_cron daily" );
$self->annotate( $result->stderr() );
$self->assert_not_equals( 0, $result->status() );
$self->assert( !$result->stdout(), "stdout should be empty" );
$self->assert_str_equals( "Missing 'store' argument.\nUsage: lr_cron <period> <store>\n",
$result->stderr() );
}
sub test_usage_bad_period {
my $self = $_[0];
my $result = $self->lire_run( "lr_cron bad" );
$self->annotate( $result->stderr() );
$self->assert_not_equals( 0, $result->status() );
$self->assert( !$result->stdout(), "stdout should be empty" );
$self->assert_str_equals( "Invalid period 'bad'. Should be one of hourly, daily, weekly, monthly or yearly.\nUsage: lr_cron <period> <store>\n",
$result->stderr() );
}
sub set_up_import_jobs {
my $self = $_[0];
my $store = Lire::DlfStore->open( $self->{'store_path'}, 1 );
my $cfg = $store->config();
my $jobs = $cfg->get( 'import_jobs' );
my $hourly_job = $jobs->spec()->get( 'import_job' )->instance();
$hourly_job->get( 'name' )->set( 'hourly' );
$hourly_job->get( 'period' )->set( 'hourly' );
$hourly_job->get( 'service' )->set_plugin( 'test_newapi' );
$hourly_job->get( 'log_file' )->set( $self->{'log_file'} );
$hourly_job->get( 'log_encoding' )->set( '' );
$hourly_job->get( 'filter' )->set( '' );
my $daily_job = $jobs->spec()->get( 'import_job' )->instance();
$daily_job->get( 'name' )->set( 'daily' );
$daily_job->get( 'period' )->set( 'daily' );
$daily_job->get( 'service' )->set_plugin( 'test_newapi' );
$daily_job->get( 'log_file' )->set( $self->{'log_file'} );
$daily_job->get( 'log_encoding' )->set( '' );
$daily_job->get( 'filter' )->set( 'grep " flacoste "' );
$jobs->append( $hourly_job );
$jobs->append( $daily_job );
$store->get_stream_config( 'test-derived' )->get( 'test-extended' )->set_plugin( 'none' );
$store->close();
}
sub test_import_daily_job {
my $self = $_[0];
$self->set_up_import_jobs();
my $jan26_2003 = timelocal( 0, 0, 1, 26, 0, 2003 );
my $result = $self->lire_run( "lr_cron daily $self->{'store_path'} $jan26_2003" );
$self->annotate( $result->stderr() );
$self->assert_num_equals( 0, $result->status() );
$self->assert( !$result->stdout(), "stdout should be empty" );
$self->assert( !$result->stderr(), "stderr should be empty" );
my $store = Lire::DlfStore->open( $self->{'store_path'} );
my $stream = $store->open_dlf_stream( 'lire_import_stats', 'r' );
my $stats = $stream->read_dlf();
$self->assert_str_equals( 'daily', $stats->{'job_name'} );
$self->assert_num_equals( 0, $stats->{'line_count'} );
$self->assert_num_equals( 2, $stats->{'dlf_count'} );
$self->assert_num_equals( 0, $stats->{'ignored_count'} );
$self->assert_num_equals( 0, $stats->{'saved_count'} );
$self->assert_num_equals( 0, $stats->{'error_count'} );
$stats = $stream->read_dlf();
$self->assert_str_equals( 'derived', $stats->{'job_name'} );
$self->assert_num_equals( 2, $stats->{'dlf_count'} );
$self->assert_num_equals( 0, $stats->{'error_count'} );
$stats = $stream->read_dlf();
$self->assert_str_equals( 'extended', $stats->{'job_name'} );
$self->assert_num_equals( 2, $stats->{'dlf_count'} );
$self->assert_num_equals( 0, $stats->{'error_count'} );
$self->assert_null( $stream->read_dlf() );
$stream->close();
$stream = $store->open_dlf_stream( 'test', 'r' );
$self->assert_num_equals( 2, $stream->nrecords() );
$self->assert_num_equals( 1043514300, $stream->start_time() );
$self->assert_num_equals( 1043515075, $stream->end_time() );
$stream->close();
$stream = $store->open_dlf_stream( 'test-extended', 'r' );
$self->assert_num_equals( 2, $stream->nrecords() );
$stream->close();
$stream = $store->open_dlf_stream( 'test-derived', 'r' );
$self->assert_num_equals( 2, $stream->nrecords() );
$stream->close();
$store->close();
}
sub set_up_store_config {
my $self = $_[0];
my $cfg_file = $self->create_test_cfg_file( 'lr_week_numbering' );
$cfg_file->get( 'lr_week_numbering' )->set( 'ISO' );
$cfg_file->save();
my $store = Lire::DlfStore->open( $self->rundir() . "/store", 1 );
$self->{'store_path'} = $store->path();
$store->close();
copy( $self->tests_datadir() . "/jobs-config.xml",
"$self->{'store_path'}/config.xml" );
}
# We will run a daily job from 21 to 27
# that is the jobs for the week Jan 20th to 26th 2003
#
# The configuration should be identifcal to the one
# tested in Lire::Test::test_configure_jobs(). These
# two tests making a central Lire use-case
sub test_lr_cron_one_week {
my $self = $_[0];
$self->set_up_chart_types();
$self->set_up_output_formats();
my $jan21_2003 = timelocal( 0, 0, 1, 21, 0, 2003 );
$self->set_up_store_config();
for ( my $i=0; $i < 7; $i++ ) {
my $time = $jan21_2003 + $i*86400;
if ( $i == 5 ) {
# 25th
copy( $self->tests_datadir() . "/test.dlf",
$self->rundir() . "/test.dlf" );
} else {
create_file( $self->rundir() . "/test.dlf", '' );
}
$self->annotate( strftime( "==> lr_cron daily %Y-%m-%d %H:%M\n\n",
localtime $time ) );
my $result = $self->lire_run( "lr_cron daily $self->{'store_path'} $time" );
$self->annotate( $result->stderr() );
$self->assert_num_equals( 0, $result->status() );
$self->assert( ! $result->stdout(), "stdout should be empty" );
$self->assert_does_not_match( qr/ (crit|err|warning) /,
$result->stderr(),
"There were warnings or error messages." );
if ( $i == 5 ) {
# 25th we have DLF data
$self->check_daily_report( $time, $result->sent_mail() );
} else {
$self->check_nodata_report( $time, $result->sent_mail() );
}
}
my $time = $jan21_2003 + 6 * 86400;
$self->annotate( strftime( "==> lr_cron weekly %Y-%m-%d %H:%M\n\n",
localtime( $time ) ) );
my $result = $self->lire_run( "lr_cron weekly $self->{'store_path'} $time" );
$self->annotate( $result->stderr() );
$self->assert_num_equals( 0, $result->status() );
$self->assert( ! $result->stdout(), "stdout should be empty" );
$self->assert_does_not_match( qr/ (crit|err|warning) /,
$result->stderr(),
"There were warnings or error messages." );
$self->check_weekly_report( $time, $result->sent_mail() );
# We run lr_cron daily another time to check for streams cleaning
# since on the 2003/01/27 01:00 - 1d (cron offset) - 1d (keep_days) =
# delete records < 2003/01/25 01:00
$time = $jan21_2003 + 7 * 86400;
$self->annotate( strftime( "==> lr_cron daily %Y-%m-%d %H:%M\n\n",
localtime( $time ) ) );
$result = $self->lire_run( "lr_cron daily $self->{'store_path'} $time" );
$self->annotate( $result->stderr() );
$self->assert_num_equals( 0, $result->status() );
$self->assert( ! $result->stdout(), "stdout should be empty" );
$self->assert_does_not_match( qr/ (crit|err|warning) /,
$result->stderr(),
"There were warnings or error messages." );
$self->check_streams_cleaning();
}
sub check_streams_cleaning {
my $self = $_[0];
my $store = Lire::DlfStore->open( $self->{'store_path'} );
foreach my $name ( qw/ test test-derived test-extended / ) {
my $stream = $store->open_dlf_stream( $name, 'r' );
$self->assert_num_equals( 0, $stream->nrecords(),
"$name wasn't cleaned" );
$stream->close();
}
$store->close();
}
sub check_nodata_report {
my ( $self, $time, $mails ) = @_;
# Since reports are generated for the previous period
my $day = (localtime( $time ))[3] - 1;
my $xml_report = "$self->{'store_path'}/daily_reports/Test_Report/200301/$day.xml";
$self->assert( ! -s $xml_report, "File '$xml_report' exists" );
$self->assert_num_equals( 0, scalar @$mails );
}
sub check_daily_report {
my ( $self, $time, $mails ) = @_;
# Since reports are generated for the previous period
my $day = (localtime( $time ))[3] - 1;
my $xml_report = "$self->{'store_path'}/daily_reports/Test_Report/200301/$day.xml";
$self->assert( -s $xml_report, "File '$xml_report' is missing" );
$self->check_xml_report( $self->tests_datadir() . "/TestReport_daily_jan25_2003.xml",
$xml_report );
$self->assert_num_equals( 1, scalar @$mails );
$self->assert_deep_equals( [ 'flacoste@logreport.org' ],
$mails->[0]{'recipients'} );
my $parser = new MIME::Parser();
$parser->output_under( $self->rundir() );
my $msg = $parser->parse_data( $mails->[0]{'message'} );
$self->assert_str_equals( "PDF Report\n", $msg->head()->get( 'Subject' ) );
$self->assert_str_equals( 'application/pdf', $msg->mime_type() );
$self->assert( length( $msg->bodyhandle()->as_string() ) > 0,
"PDF report is empty" );
return;
}
sub check_weekly_report {
my ( $self, $time, $mails ) = @_;
my $xml_report = "$self->{'store_path'}/weekly_reports/Test_Report/2003/04.xml";
$self->assert( -s $xml_report, "File '$xml_report' is missing" );
$self->check_xml_report( $self->tests_datadir() . "/TestReport_weekly_w04_2003.xml",
$xml_report );
$self->assert( -d $self->rundir() . "/report 2003-W04",
"HTML report 'report 2003-W04' is missing" );
$self->assert( -s $self->rundir() . "/report 2003-W04/index.html",
"File 'report 2003-W04/index.html' is missing" );
$self->assert_num_equals( 1, scalar @$mails );
$self->assert_deep_equals( [ 'wolfgang@logreport.org' ],
$mails->[0]{'recipients'} );
my $parser = new MIME::Parser();
$parser->output_under( $self->rundir() );
my $msg = $parser->parse_data( $mails->[0]{'message'} );
$self->assert_str_equals( "Text Report\n", $msg->head()->get( 'Subject' ));
$self->assert_str_equals( 'text/plain', $msg->mime_type() );
$self->assert_matches( qr/movies\/001145\.mpg/,
$msg->bodyhandle()->as_string() );
}
1;
syntax highlighted by Code2HTML, v. 0.9.1