package tests::AggregatorTest; use strict; use base qw/ Lire::Test::TestCase tests::TestStoreFixture /; use Lire::ReportSpec; use Lire::Report::Subreport; use Lire::Report::TableInfo; use Lire::Test::Mock; use tests::MockAggregate; use tests::MockAggregator; sub new { my $self = shift()->SUPER::new( @_ ); $self->init(); return $self; } sub set_up { my $self = $_[0]; $self->SUPER::set_up(); $self->set_up_test_store(); my $spec = $self->{'spec'} = new Lire::ReportSpec(); $spec->superservice( 'test' ); $spec->joined_schemas( [ 'test-extended' ] ); $self->{'aggregator'} = new tests::MockAggregator( 'report_spec' => $spec ); $spec->calc_spec( $self->{'aggregator'} ); my $nested1 = new tests::MockAggregator( 'name' => 'nested1', 'report_spec' => $spec, 'parent' => $self->{'aggregator'} ); my $nested2 = new tests::MockAggregator( 'name' => 'nested2', 'report_spec' => $spec, 'parent' => $self->{'aggregator'} ); $self->{'aggregator'}->ops( [ $nested1, $nested2 ] ); $nested1->ops( [ new tests::MockAggregate( 'name' => 'mock1', 'parent' => $nested1, 'report_spec' => $spec ) ] ); $nested2->ops( [ new tests::MockAggregate( 'name' => 'mock2', 'parent' => $nested2, 'report_spec' => $spec ) ] ); return; } sub set_up_mock_query_spec { my $self = $_[0]; my $top = new_proxy Lire::Test::Mock( 'tests::MockAggregator', 'report_spec' => $self->{'spec'} ); $top->set_result( 'create_entry' => sub { my ($self, $group, $row ) = @_; return undef if ($self->{'count'} || 0) > 3; my $e = $group->create_entry(); $e->add_name( $row->{'client_host'} ); $e->add_name( $row->{'user'} ); $self->{'count'}++; return $e; } ); my $nested1 = new_proxy Lire::Test::Mock( 'tests::MockAggregator', 'report_spec' => $self->{'spec'}, 'parent' => $top, 'name' => 'nested1' ); $nested1->set_result( 'create_entry' => sub { my ($self, $group, $row ) = @_; my $e = $group->create_entry(); $e->add_name( $row->{'connection_id'} ); return $e; } ); $top->ops( [ $nested1 ] ); $nested1->ops( [ new tests::MockAggregate( 'name' => 'mock', 'parent' => $nested1, 'report_spec' => $self->{'spec'} ) ] ); $self->{'spec'}->calc_spec( $top ); $self->{'mock_query_spec'} = $top; return; } sub set_up_mock_query { my $self = $_[0]; $self->{'mock_query_info'} = new Lire::Report::TableInfo(); $self->{'mock_query_info'}->create_column_info( 'client_host', 'categorical', 'string' ); $self->{'mock_query_info'}->create_column_info( 'user', 'categorical', 'string' ); my $n1_info = $self->{'mock_query_info'}->create_group_info( 'nested1' ); $n1_info->create_column_info( 'connection_id', 'categorical', 'string' ); $n1_info->create_column_info( 'mock', 'numerical', 'int' ); $self->{'mock_query'} = new Lire::DlfQuery( 'test' ); $self->{'mock_query'}->add_group_field( 'client_host' ); $self->{'mock_query'}->add_group_field( 'user' ); $self->{'mock_query'}->set_sort_spec( 'client_host user' ); my $nested1 = $self->{'mock_query'}->create_nested_query(); $nested1->add_group_field( 'connection_id' ); $nested1->set_sort_spec( 'connection_id' ); $nested1->add_aggr_field( '_lr_nrecords', 'count()' ); $nested1->add_aggr_field( 'mock', 'count()' ); return; } sub set_up_mock_query_report { my $self = $_[0]; my $stream = $self->{'store'}->open_dlf_stream( 'test', 'r' ); my $subreport = new Lire::Report::Subreport( 'mock', 'mock-subreport' ); $subreport->table_info( $self->{'mock_query_info'} ); $subreport->nrecords( 24 ); $subreport->set_summary_value( 'mock', 'content' => 24 ); my %group_cache = (); foreach my $c ( [ '127.0.0.1', 'francis', '13', '13' ], [ '192.168.250.1', 'flacoste', '2', '2' ], [ '192.168.250.2', 'joostvb', '5', '5' ], [ '192.168.250.3', 'wdankers', '3', '3' ], ) { my $entry = $subreport->create_entry(); $entry->add_name( $c->[0] ); $entry->add_name( $c->[1] ); my $group = $entry->create_group(); $group->nrecords( $c->[2] ); $group->set_summary_value( 'mock', 'content' => $c->[3] ); $group_cache{$c->[0] . $c->[1]} = $group; } my %n_group_cache = (); foreach my $c ( [ '127.0.0.1', 'francis', 'AABBCCDD', '13', '13' ], [ '192.168.250.1', 'flacoste', 'AABBCCDE', '1', '1' ], [ '192.168.250.1', 'flacoste', 'AABBCCDF', '1', '1' ], [ '192.168.250.2', 'joostvb', 'AABBCCDG', '5', '5' ], [ '192.168.250.3', 'wdankers', 'AABBCCDD', '3', '3' ], ) { my $group = $group_cache{ $c->[0] . $c->[1]}; my $entry = $group->create_entry(); $entry->add_name( $c->[2] ); $entry->add_value( 'content' => $c->[4] ); } $self->{'mock_query_subreport'} = $subreport; return; } sub tear_down { my $self = $_[0]; $self->SUPER::tear_down(); $self->tear_down_test_store(); return; } sub test_create_entries { my $self = $_[0]; $self->set_up_mock_query(); $self->set_up_mock_query_report(); my $aggr = new_proxy Lire::Test::Mock( 'tests::MockAggregator', 'report_spec' => $self->{'spec'} ); $aggr->set_result( 'build_table' => '' ); my $filter = new Lire::Test::Mock( 'Lire::FilterExpr', 'sql_expr' => 'myfilter = ?', 'sql_params' => [ 'myparam' ] ); $self->{'spec'}->filter_spec( $filter ); my $subreport = new Lire::Report::Subreport( 'mock', 'mock-subreport' ); $subreport->table_info( $self->{'mock_query_info'} ); $aggr->create_entries( $subreport ); $self->assert_equals( 0, scalar $subreport->entries() ); $aggr->{'store'} = $self->{'store'}; $aggr->create_entries( $subreport ); $self->assert_num_equals( 1, $aggr->invocation_count( 'build_table' ) ); $self->assert_num_equals( $self->{'store'}, $aggr->get_invocation( 'build_table' )->[1] ); my $query = $aggr->get_invocation( 'build_table' )->[2]; $self->assert_isa( 'Lire::DlfQuery', $query ); $self->assert_str_equals( 'test', $query->stream_name() ); $self->assert_deep_equals( [ 'test', 'test-extended' ], $query->joined_streams() ); $self->assert_str_equals( 'myfilter = ?', $query->filter_clause() ); $self->assert_deep_equals( [ 'myparam' ], $query->sql_params() ); } sub test_build_query { my $self = $_[0]; my $test_query = new Lire::DlfQuery( "test" ); my $sub1 = $test_query->create_nested_query(); $sub1->add_aggr_field( '_lr_nrecords', 'count(*)' ); $sub1->add_aggr_field( 'mock1', 'count()' ); my $sub2 = $test_query->create_nested_query(); $sub2->add_aggr_field( '_lr_nrecords', 'count(*)' ); $sub2->add_aggr_field( 'mock2', 'count()' ); my $query = new Lire::DlfQuery( "test" ); $self->{'aggregator'}->build_query( $query ); $self->assert_deep_equals( $test_query, $query ); } sub test_build_table_summary { my $self = $_[0]; my $query = new Lire::DlfQuery( "test" ); $self->{'aggregator'}->build_query( $query ); my $subreport = new Lire::Report::Subreport( 'mock', 'mock-subreport' ); $subreport->table_info( $self->{'spec'}->create_table_info() ); $self->{'aggregator'}->build_table_summary( $self->{'store'}, $query, $subreport ); $self->assert_equals( 24, $subreport->nrecords() ); $self->assert_equals( 24, $subreport->get_summary_value( 'mock1' )->{'content'} ); $self->assert_equals( 24, $subreport->get_summary_value( 'mock2' )->{'content'} ); } sub test_set_group_summary { my $self = $_[0]; my $query = new Lire::DlfQuery( "test" ); $self->{'aggregator'}->build_query( $query ); my $stream = $self->{'store'}->open_dlf_stream( 'test', 'r' ); my $subreport = new Lire::Report::Subreport( 'mock', 'mock-subreport' ); my $aggr1 = $self->{'aggregator'}->ops()->[0]->ops()->[0]; $subreport->table_info( $self->{'spec'}->create_table_info() ); $self->{'aggregator'}->set_group_summary( $subreport, { '_lr_nrecords' => 24, 'mock1' => 22, 'mock2' => 23, } ); $self->assert_equals( 24, $subreport->nrecords() ); $self->assert_equals( 22, $subreport->get_summary_value( 'mock1' )->{'content'} ); $self->assert_equals( 23, $subreport->get_summary_value( 'mock2' )->{'content'} ); $self->assert_equals( 1, scalar @{$aggr1->{'parent_groups'}}); $self->assert_str_equals( $subreport, $aggr1->{'parent_groups'}[0] ); my $nested1 = $self->{'aggregator'}->ops()->[0]; my $entry = $subreport->create_entry(); $entry->add_name(); my $group = $entry->create_group(); $nested1->set_group_summary( $group, { '_lr_nrecords' => 24, 'mock1' => 22, 'mock2' => 23, } ); $self->assert_equals( 2, scalar @{$aggr1->{'parent_groups'}}); $self->assert_str_equals( $subreport, $aggr1->{'parent_groups'}[1] ); } sub test_build_table { my $self = $_[0]; $self->set_up_mock_query_spec(); $self->set_up_mock_query(); $self->set_up_mock_query_report(); my $e_subreport = $self->{'mock_query_subreport'}; my $subreport = new Lire::Report::Subreport( 'mock', 'mock-subreport' ); $subreport->table_info( $self->{'mock_query_info'} ); $self->{'mock_query_spec'}->build_table( $self->{'store'}, $self->{'mock_query'}, $subreport ); $self->assert_deep_equals( $e_subreport, $subreport ); } sub test_is_name_defined { my $self = $_[0]; my $aggr = $self->{'aggregator'}; $aggr->{'name'} = 'topAggr'; $self->assert( $aggr->is_name_defined( 'topAggr' ), 'is_name_defined( "topAggr" ) returned false' ); $self->assert( $aggr->is_name_defined( 'nested1' ), 'is_name_defined( "nested1" ) returned false' ); $self->assert( !$aggr->is_name_defined( 'newName' ), 'is_name_defined( "newName" ) returned true' ); } 1;