You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
238 lines
9.4 KiB
238 lines
9.4 KiB
package NGCP::TestFramework;
|
|
|
|
use strict;
|
|
use warnings;
|
|
use Cpanel::JSON::XS;
|
|
use Data::Walk;
|
|
use DateTime qw();
|
|
use DateTime::Format::Strptime qw();
|
|
use DateTime::Format::ISO8601 qw();
|
|
use Digest::MD5 qw/md5_hex/;
|
|
use Log::Log4perl qw(:easy);
|
|
use Moose;
|
|
use Net::Domain qw(hostfqdn);
|
|
use Test::More;
|
|
use URI;
|
|
use YAML::XS qw(LoadFile);
|
|
use Data::Dumper;
|
|
|
|
use NGCP::TestFramework::RequestBuilder;
|
|
use NGCP::TestFramework::Client;
|
|
use NGCP::TestFramework::TestExecutor;
|
|
|
|
has 'file_path' => (
|
|
isa => 'Str',
|
|
is => 'ro'
|
|
);
|
|
|
|
sub run {
|
|
my ( $self ) = @_;
|
|
|
|
my $test_case_name = $self->file_path;
|
|
$test_case_name =~ s/.+\/(\w+).yaml/$1/;
|
|
chomp $test_case_name;
|
|
Log::Log4perl->easy_init( { level => $DEBUG,
|
|
file => ">>/var/log/ngcp/test-framework/$test_case_name.log",
|
|
category => "TestFramework::Client",
|
|
layout => '%d - %F{1} line %L - %M: %m%n' },
|
|
{ level => $DEBUG,
|
|
file => ">>/var/log/ngcp/test-framework/$test_case_name.log",
|
|
category => "TestFramework::RequestBuilder",
|
|
layout => '%d - %F{1} line %L - %M: %m%n' },
|
|
{ level => $DEBUG,
|
|
file => ">>/var/log/ngcp/test-framework/$test_case_name.log",
|
|
category => "TestFramework::TestExecutor",
|
|
layout => '%d - %F{1} line %L - %M: %m%n' },
|
|
{ level => $DEBUG,
|
|
file => ">/var/log/ngcp/test-framework/$test_case_name.log",
|
|
layout => '%d - %F{1} line %L - %M: %m%n' }
|
|
);
|
|
|
|
INFO( "Started running the Test TestFramework!" );
|
|
unless ( $self->file_path ) {
|
|
return;
|
|
}
|
|
$YAML::XS::DumpCode = 1;
|
|
$YAML::XS::LoadCode = 1;
|
|
$YAML::XS::UseCode = 1;
|
|
$YAML::XS::LoadBlessed = 1;
|
|
|
|
INFO( "Loading YAML file." );
|
|
my $testing_data = LoadFile($self->file_path);
|
|
|
|
INFO( "Setting up the base URI." );
|
|
my $base_uri = $ENV{CATALYST_SERVER} || ('https://'.hostfqdn.':4443');
|
|
INFO( "Setting up the RequestBuilder." );
|
|
my $request_builder = NGCP::TestFramework::RequestBuilder->new({ base_uri => $base_uri });
|
|
INFO( "Setting up the Client." );
|
|
my $client = NGCP::TestFramework::Client->new( { uri => $base_uri } );
|
|
INFO( "Setting up the Test Executor." );
|
|
my $test_executor = NGCP::TestFramework::TestExecutor->new();
|
|
|
|
# initializing time to add to fields which need to be unique
|
|
my $retained = { unique_id => int(rand(100000)) };
|
|
|
|
my $test_case_result = { success => 1, error_count => 0 };
|
|
|
|
foreach my $test ( @$testing_data ) {
|
|
DEBUG( "In test '".$test->{name}."'" );
|
|
next if ( $test->{skip} );
|
|
|
|
# build request
|
|
my $request = $request_builder->build({
|
|
method => $test->{method},
|
|
path => $test->{path},
|
|
header => $test->{header} || undef,
|
|
content => $test->{content} || undef,
|
|
retain => $retained
|
|
});
|
|
DEBUG ( "Request: ".Dumper $request );
|
|
|
|
# handle separate types
|
|
if ( $test->{type} eq 'item' ) {
|
|
INFO( "Performing request." );
|
|
my $result = $client->perform_request($request);
|
|
DEBUG ( "Result: ".Dumper $result );
|
|
if ( $test->{retain} ) {
|
|
INFO( "Storing retained variables." );
|
|
$self->_get_retained_elements( $test->{retain}, $retained, $result );
|
|
}
|
|
if ( $test->{perl_code} ){
|
|
INFO( "Executing perl code." );
|
|
my $sub = $test->{perl_code};
|
|
$sub->( $retained );
|
|
}
|
|
if ( $test->{conditions} ) {
|
|
INFO( "Running tests." );
|
|
my $tests_result = $test_executor->run_tests( $test->{conditions}, $result, $retained, $test->{name} );
|
|
if ( !$tests_result->{success} ) {
|
|
map { print $_." in test case '$test_case_name'\n" } @{$tests_result->{errors}};
|
|
$test_case_result->{success} = 0;
|
|
$test_case_result->{error_count} += scalar @{$tests_result->{errors}};
|
|
}
|
|
}
|
|
}
|
|
elsif ( $test->{type} eq 'batch' ) {
|
|
foreach my $iteration ( 1..$test->{iterations} ) {
|
|
INFO( "Performing request for iteration $iteration." );
|
|
my $result = $client->perform_request($request);
|
|
DEBUG ( "Result: ".Dumper $result );
|
|
if ( $test->{retain} ) {
|
|
INFO( "Storing retained variables." );
|
|
$self->_get_retained_elements( $test->{retain}, $retained, $result );
|
|
}
|
|
if ( $test->{conditions} ) {
|
|
INFO( "Running tests." );
|
|
my $tests_result = $test_executor->run_tests( $test->{conditions}, $result, $retained, $test->{name} );
|
|
if ( !$tests_result->{success} ) {
|
|
map { print $_." in test case '$test_case_name'\n" } @{$tests_result->{errors}};
|
|
$test_case_result->{success} = 0;
|
|
$test_case_result->{error_count} += scalar @{$tests_result->{errors}};
|
|
}
|
|
}
|
|
$retained->{unique_id}=int(rand(100000));
|
|
}
|
|
}
|
|
elsif ( $test->{type} eq 'pagination' ) {
|
|
my $nexturi = $test->{path};
|
|
do {
|
|
INFO( "Performing request for pagination." );
|
|
$request->uri( $base_uri.$nexturi );
|
|
my $result = $client->perform_request($request);
|
|
DEBUG ( "Result: ".Dumper $result );
|
|
if ( $test->{retain} ) {
|
|
INFO( "Storing retained variables." );
|
|
$self->_get_retained_elements( $test->{retain}, $retained, $result );
|
|
}
|
|
my $body = decode_json( $result->decoded_content() );
|
|
|
|
#build default conditions for pagination
|
|
$test->{conditions}->{is}->{$nexturi} = $body->{_links}->{self}->{href};
|
|
|
|
my $colluri = URI->new($base_uri.$body->{_links}->{self}->{href});
|
|
my %q = $colluri->query_form;
|
|
$test->{conditions}->{ok}->{$q{page}} = 'defined';
|
|
$test->{conditions}->{ok}->{$q{rows}} = 'defined';
|
|
my $page = int($q{page});
|
|
my $rows = int($q{rows});
|
|
if($page == 1) {
|
|
$test->{conditions}->{ok}->{'${collection}._links.prev.href'} = 'undefined';
|
|
} else {
|
|
$test->{conditions}->{ok}->{'${collection}._links.prev.href'} = 'defined';
|
|
}
|
|
if(($retained->{collection}->{total_count} / $rows) <= $page) {
|
|
$test->{conditions}->{ok}->{'${collection}._links.next.href'} = 'undefined';
|
|
} else {
|
|
$test->{conditions}->{ok}->{'${collection}._links.next.href'} = 'defined';
|
|
}
|
|
|
|
if ( $test->{conditions} ) {
|
|
INFO( "Running tests." );
|
|
my $tests_result = $test_executor->run_tests( $test->{conditions}, $result, $retained, $test->{name} );
|
|
if ( !$tests_result->{success} ) {
|
|
map { print $_." in test case '$test_case_name'\n" } @{$tests_result->{errors}};
|
|
$test_case_result->{success} = 0;
|
|
$test_case_result->{error_count} += scalar @{$tests_result->{errors}};
|
|
}
|
|
}
|
|
|
|
if( $body->{_links}->{next}->{href} ) {
|
|
$nexturi = $body->{_links}->{next}->{href};
|
|
} else {
|
|
$nexturi = undef;
|
|
}
|
|
} while ( $nexturi )
|
|
}
|
|
}
|
|
return $test_case_result;
|
|
}
|
|
|
|
sub _get_retained_elements {
|
|
my ( $self, $retain, $retained, $result ) = @_;
|
|
|
|
while ( my ( $retain_elem, $retain_value ) = each %{$retain} ) {
|
|
if ( $retain_value =~ /.+\..+/ ) {
|
|
my @splitted_values = split (/\./, $retain_value);
|
|
$retained->{$retain_elem} = $self->_retrieve_from_composed_key( $result, \@splitted_values, $retain_elem );
|
|
}
|
|
elsif ( $retain_value eq 'body' ) {
|
|
$retained->{$retain_elem} = decode_json( $result->decoded_content() );
|
|
}
|
|
else {
|
|
return {
|
|
success => 0,
|
|
message => 'Wrong retain instructions!'
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
sub _retrieve_from_composed_key {
|
|
my ( $self, $result, $splitted_values, $retain_elem ) = @_;
|
|
|
|
if ( $splitted_values->[0] eq 'header' ) {
|
|
my $value = $result->header(ucfirst $splitted_values->[1]);
|
|
if ( $retain_elem =~ /^.+_id$/ ) {
|
|
$value =~ /^.+\/(\d+)$/;
|
|
$value = $1;
|
|
}
|
|
return $value;
|
|
}
|
|
}
|
|
|
|
sub _variables_available {
|
|
my( $self, $retained, $test ) = @_;
|
|
|
|
return 0 if ( $test->{path} =~ /\$\{(.*)\}/ && !$retained->{$1} );
|
|
|
|
# substitute variables in content
|
|
if ( $test->{content} && ref $test->{content} eq 'HASH' ) {
|
|
foreach my $content_key (keys %{$test->{content}}) {
|
|
return 0 if ( $test->{content}->{$content_key} =~ /\$\{(.*)\}/ && !$retained->{$1} );
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
1;
|