APP-REST-RestTestSuite
view release on metacpan or search on metacpan
lib/APP/REST/RestTestSuite.pm view on Meta::CPAN
#specification; validate that before trying to execute them.
my $err = $self->validate_test_cases(@_);
die "ERROR: $err\n" if ($err);
my %test_cases = @_;
my $ua = LWP::UserAgent->new;
$ua->agent("RTAT/$VERSION");
$ua->timeout(90); # in seconds
$ua->default_header('Accept' => '*/*'); # to get cross platform support
my ( $config, $total, $total_response_time, $skip, $pass, $fail ) = (0) x 6;
my ( $uri, $method, $req_content_type, $req_body, $status ) = (undef) x 5;
my ( $request, $response ) = (undef) x 2;
my ( $username, $password ) = (undef) x 2;
$username = $self->{username};
$password = $self->{password};
my $fh = $self->get_log_file_handle();
my $err_fh = $self->get_err_log_file_handle();
if ( $self->{html_log_required}
&& ( $self->{html_log_required} =~ /yes/i ) )
{
print $fh
qq|<HTML> <HEAD> <TITLE>LOG for $self->{endpoint}</TITLE> </HEAD>|
. qq|<BODY><textarea rows="999999" cols="120" style="border:none;">|;
print $err_fh
qq|<HTML> <HEAD> <TITLE>ERROR LOG for $self->{endpoint}</TITLE> </HEAD>|
. qq|<BODY><textarea rows="999999" cols="120" style="border:none;">|;
}
print STDERR "\nTest Suite executed on $self->{endpoint}\n";
print $fh "\nTest Suite executed on $self->{endpoint}\n";
print $err_fh "\nTest Suite executed on $self->{endpoint}\n";
foreach my $count ( sort { $a <=> $b } keys(%test_cases) ) {
my $tc = $test_cases{$count};
$config++;
print $fh "\n", LINE, "\n";
if ( $tc->{execute} && ( $tc->{execute} =~ /no/i ) ) {
print $fh "\nSkipping Test case $count => $tc->{test_case} \n";
$skip++;
next;
}
$uri = qq|$self->{rest_uri_base}| . qq|$tc->{uri}|;
$method = uc( $tc->{request_method} );
$req_content_type = $tc->{request_content_type};
$req_body = $tc->{request_body} || 0;
$status = $tc->{response_status};
if ( $tc->{request_method} =~ /get/i ) {
$request = HTTP::Request->new( $method, $uri );
$request->authorization_basic( $username, $password )
if ( $username && $password );
} else {
$request =
HTTP::Request->new( $method, $uri, new HTTP::Headers, $req_body );
$request->authorization_basic( $username, $password )
if ( $username && $password );
$request->content_type($req_content_type);
$request->content_length( length($req_body) );
}
print STDERR "Executing Test case $count => $tc->{test_case}";
print $fh "Executing Test case $count => $tc->{test_case}";
my $start_time = time;
$response = $ua->request($request);
$total++;
my $exec_time = $self->delta_time( start_time => $start_time );
$total_response_time += $exec_time;
$exec_time = sprintf( "%.2f", $exec_time );
print STDERR " [Completed in $exec_time ms]\n";
print $fh " [Completed in $exec_time ms]\n";
$self->_print_logs(
fh => $fh,
uri => $uri,
method => $method,
req_body => $req_body,
);
$self->_print_logs(
fh => $fh,
res => $response,
exec_time => $exec_time,
);
#Level-1 check => check for response status code
#Level-2 check => check for expected response content_type
my $resp_code = $response->code;
if ( $status =~ m/$resp_code/ ) {
my $failed = 0;
if ( defined $tc->{response_content_type} ) {
my $expected_response_content_type =
$tc->{response_content_type};
#my $respose_content_type = $response->{_headers}->content_type;
my $respose_content_type = $response->header('Content-Type');
unless ( defined $respose_content_type ) {
$failed = 1;
} elsif ( $expected_response_content_type !~
m/$respose_content_type/ )
{
$failed = 1;
print $err_fh "\n", LINE, "\n";
print $err_fh
"Executing Test case $count => $tc->{test_case}";
print $err_fh
"\n*********ATTENTION CONTENT TYPE ERROR ******";
print $err_fh
"\n\nExpected content_type is $expected_response_content_type\n";
print $err_fh
"content_type recieved in response is $respose_content_type\n";
print $err_fh
"\n*********ATTENTION CONTENT TYPE ERROR ******";
$self->_print_logs(
fh => $err_fh,
lib/APP/REST/RestTestSuite.pm view on Meta::CPAN
die "ERROR: $err\n" if ($err);
my %test_cases = @_;
# use my customized user agent for parallel invokes
my $pua = APP::REST::ParallelMyUA->new();
$pua->agent("RTAT/$VERSION");
$pua->in_order(1); # handle requests in order of registration
$pua->duplicates(0); # ignore duplicates
$pua->timeout(60); # in seconds
$pua->redirect(1); # follow redirects
$pua->default_header('Accept' => '*/*'); # to get cross platform support
my ( $config, $total, $total_response_time, $skip, $pass, $fail ) = (0) x 6;
my ( $uri, $method, $req_content_type, $req_body, $status ) = (undef) x 5;
my ( $request, $response ) = (undef) x 2;
my ( $username, $password ) = (undef) x 2;
$username = $self->{username};
$password = $self->{password};
my $fh = $self->get_log_file_handle();
if ( $self->{html_log_required}
&& ( $self->{html_log_required} =~ /yes/i ) )
{
print $fh
qq|<HTML> <HEAD> <TITLE>LOG for $self->{endpoint}</TITLE> </HEAD>|
. qq|<BODY><textarea rows="999999" cols="120" style="border:none;">|;
}
print STDERR "\nTest Suite executed on $self->{endpoint}\n";
print $fh "\nTest Suite executed on $self->{endpoint}\n";
my @reqs;
foreach my $count ( sort { $a <=> $b } keys(%test_cases) ) {
my $tc = $test_cases{$count};
$config++;
if ( $tc->{execute} =~ /no/i ) {
print $fh "\nSkipping Test case $count => $tc->{test_case} \n";
$skip++;
next;
}
$uri = qq|$self->{rest_uri_base}| . qq|$tc->{uri}|;
#Support only GET methods at present
if ( $tc->{request_method} =~ /get/i ) {
# Create HTTP request pool for later execution by parallel useragent
$method = uc( $tc->{request_method} );
$req_content_type = $tc->{request_content_type};
$req_body = $tc->{request_body} || 0;
$status = $tc->{response_status};
my $request = HTTP::Request->new( $method, $uri );
$request->authorization_basic( $username, $password )
if ( $username && $password );
push( @reqs, $request );
}
$total++;
}
print STDERR "\nRequesting [$total] web services together.\n";
foreach my $req (@reqs) {
# register all requests and wait for them to finish
if ( my $res = $pua->register($req) ) {
print STDERR $res->error_as_HTML;
}
}
print STDERR "Receiving response from web services. Please wait..!\n";
# will return once all forked web services are either completed or timeout
my $entries = $pua->wait();
print STDERR "\n\n";
foreach ( keys %$entries ) {
my $response = $entries->{$_}->response;
my $tick = $entries->{$_}->{tick};
my $exec_time = ( $tick->{end} - $tick->{start} ) * 1000 ;
$total_response_time += $exec_time;
$exec_time = sprintf( "%.2f", $exec_time );
print STDERR "\n", $response->request->url,
"\n ! Response Status [", $response->code,
"]\tResponse Time [$exec_time ms]";
$self->_print_logs(
fh => $fh,
uri => $response->request->url,
method => $response->request->method,
req_body => ''
);
$self->_print_logs(
fh => $fh,
res => $response,
exec_time => $exec_time,
);
}
#convert milli seconds to seconds for total_exec_time
$total_response_time = sprintf( "%.2f", $total_response_time / 1000 );
my $avg_response_time =
sprintf( "%.2f", ( $total_response_time * 1000 ) / $total );
print STDERR
"\n\n\nComplete test case report is in $self->{file}->{log_file}";
print STDERR
"\n\nResponse time of $total web service calls => [$total_response_time seconds]\n";
print STDERR
"Average response time of a web service => [$avg_response_time milli seconds]\n\n";
lib/APP/REST/RestTestSuite.pm view on Meta::CPAN
=cut
1; # End of APP::REST::RestTestSuite
__DATA__
# RestTestSuite supports config file of below format.
# All values in LHS of ':' are case sensitive.
# Every test case should be within the '#START_TEST_CASE' and '#END_TEST_CASE' block.
# Create application specific config file in below format and pass the
# full path of file as an argument to the constructor
# for POST and PUT methods you need to supply the request body within
# [START] and [END] tags
# request_body :
# [START]
# xml or json or form based
# [END]
################
#Set below values to configure the base URL for all test cases
####################
#START_COMMON_CONFIG
################################################################################
endpoint : www.thomas-bayer.com
port :
base_uri : /sqlrest
html_log_required : no
username :
################################################################################
#END_COMMON_CONFIG
##################
#####################
#START_TEST_CASE
#####################
test_case : get_product
uri : /PRODUCT/49
request_content_type : application/xml
request_method : GET
request_body :
response_status : 200
execute : yes
response_content_type : application/xml
#####################
#END_TEST_CASE
#####################
###########################
#START_HTTP_CODE_DEF
############################
200 : operation successful.
201 : Successful creation of a resource.
202 : The request was received.
204 : The request was processed successfully, but no response body is needed.
301 : Resource has moved.
303 : Redirection.
304 : Resource has not been modified.
400 : Malformed syntax or a bad query.
401 : Action requires user authentication.
403 : Authentication failure or invalid Application ID.
404 : Resource not found.
405 : Method not allowed on resource.
406 : Requested representation not available for the resource.
408 : Request has timed out.
409 : State of the resource doesn't permit request.
410 : The URI used to refer to a resource.
411 : The server needs to know the size of the entity body and it should be specified in the Content Length header.
412 : Operation not completed because preconditions were not met.
413 : The representation was too large for the server to handle.
414 : The URI has more than 2k characters.
415 : Representation not supported for the resource.
416 : Requested range not satisfiable.
500 : Internal server error.
501 : Requested HTTP operation not supported.
502 : Backend service failure (data store failure).
505 : HTTP version not supported.
############################
#END_HTTP_CODE_DEF
############################
####################
#END_OF_CONFIG_FILE
####################
( run in 0.912 second using v1.01-cache-2.11-cpan-5c0b1e786e0 )