mirror of
https://github.com/valitydev/yandex-tank.git
synced 2024-11-06 10:25:17 +00:00
1448 lines
39 KiB
Perl
Executable File
1448 lines
39 KiB
Perl
Executable File
#!/usr/bin/perl
|
|
|
|
use warnings;
|
|
use strict;
|
|
|
|
use Getopt::Long qw(:config bundling);
|
|
use Pod::Usage;
|
|
use Data::Dumper;
|
|
use LWP::Simple;
|
|
use LWP::UserAgent;
|
|
use Lunapark;
|
|
use File::Spec;
|
|
use Time::Local;
|
|
use Time::HiRes;
|
|
use Socket;
|
|
use Term::ANSIColor;
|
|
use Cwd 'abs_path';
|
|
use Net::IP;
|
|
use JSON qw/to_json from_json/;
|
|
use Encode;
|
|
use File::Which qw(which);
|
|
use File::Copy;
|
|
|
|
$| = 1;
|
|
|
|
our $MAXDISK = 90;
|
|
our $MAXCPU = 90;
|
|
|
|
### db connect params
|
|
my $db_conf = getconfig("/etc/lunapark/db.conf");
|
|
|
|
### Default params
|
|
our %default = (
|
|
debug => 0,
|
|
loop => 1,
|
|
skip_step => 0,
|
|
tank_type => 1,
|
|
writelog => 0,
|
|
timeout_prec => 1,
|
|
target_port => 80,
|
|
timeout => '10s',
|
|
instances => 1000,
|
|
time_periods =>
|
|
'1 2 3 4 5 6 7 8 9 10 20 30 40 50 60 70 80 90 100 150 200 250 300 350 400 450 500 600 650 700 750 800 850 900 950 1s 1500 2s 2500 3s 3500 4s 4500 5s 5500 6s 6500 7s 7500 8s 8500 9s 9500 10s 11s',
|
|
usedb => 1,
|
|
write2db => 1,
|
|
gatling => 0,
|
|
manual_start => 0,
|
|
timer => 0,
|
|
clearall => 0,
|
|
clear => 0,
|
|
savelog_ini => 0,
|
|
regress => 0,
|
|
script => 0,
|
|
user_phantom_log => "",
|
|
user_threads_log => "",
|
|
make_phantom_conf => 0,
|
|
saveammo => 1,
|
|
component => 0,
|
|
step_only => 0,
|
|
autocases => 1,
|
|
ammo => "",
|
|
detailed_time => "interval_real",
|
|
ssl => 0,
|
|
monitoring_config => '',
|
|
inform => '',
|
|
);
|
|
|
|
our %load = ( config => 'load.conf', );
|
|
|
|
my %known_params = (
|
|
header => 1,
|
|
instances => 1,
|
|
instances_schedule => 1,
|
|
loop => 1,
|
|
address => 1,
|
|
time_periods => 1,
|
|
task => 1,
|
|
job_name => 1,
|
|
job_dsc => 1,
|
|
tank_type => 1,
|
|
tag => 1,
|
|
ver => 1,
|
|
load => 1,
|
|
writelog => 1,
|
|
savelog => 1,
|
|
saveammo => 1,
|
|
autostop => 1,
|
|
gatling_ip => 1,
|
|
timeout_prec => 1,
|
|
debug => 1,
|
|
phantom_http_line => 1,
|
|
phantom_http_field_num => 1,
|
|
phantom_http_field => 1,
|
|
phantom_http_entity => 1,
|
|
regress => 1,
|
|
ammofile => 1,
|
|
inform => 1,
|
|
loads => 1,
|
|
manual_start => 1,
|
|
chosen_cases => 1,
|
|
component => 1,
|
|
header_http => 1,
|
|
header_connection => 1,
|
|
header_host => 1,
|
|
uri => 1,
|
|
ammo_uri => 1,
|
|
autocases => 1,
|
|
loads_str => 1,
|
|
timer => 1,
|
|
monitoring_config => 1,
|
|
detailed_time => 1,
|
|
ssl => 1
|
|
);
|
|
our $signal_caught = 0;
|
|
|
|
sub exit_kill() {
|
|
my $rc = 1;
|
|
my ($signal) = @_;
|
|
|
|
if ( !$signal_caught ) {
|
|
lp_log("Exit because of signal: $signal");
|
|
print "Exiting because of signal: $signal\n";
|
|
$signal_caught = 1;
|
|
exit_hand($rc);
|
|
}
|
|
else {
|
|
lp_log("Signal again, forcing quit: $signal");
|
|
print "Signal again, forcing quit: $signal\n";
|
|
}
|
|
print "\n";
|
|
exit $rc;
|
|
}
|
|
|
|
sub get_phantom_ver() {
|
|
my $v = `dpkg -l | grep phantom`;
|
|
my @v = split( /\s+/, $v );
|
|
return $v[2] ? $v[2] : "N/A";
|
|
}
|
|
|
|
sub makePhantomConf($) {
|
|
my $ver = get_phantom_ver();
|
|
my $l = shift;
|
|
my $out = "setup_t module_setup = setup_module_t {\n";
|
|
$out .= "\tdir = \"/usr/lib/phantom\"\n\tlist = {\n";
|
|
if ( $l->{ssl} ) {
|
|
$out .= "\t\tssl\n";
|
|
}
|
|
$out .= "\t\tio_benchmark\n";
|
|
$out .= "\t\tio_benchmark_method_stream\n";
|
|
if ( Net::IP::ip_is_ipv6( $l->{target_ip} ) ) {
|
|
$out .= "\t\tio_benchmark_method_stream_ipv6\n";
|
|
}
|
|
else {
|
|
$out .= "\t\tio_benchmark_method_stream_ipv4\n";
|
|
}
|
|
if ( $l->{ssl} ) {
|
|
$out .= "\t\tio_benchmark_method_stream_transport_ssl\n";
|
|
}
|
|
$out .= "\t\tio_benchmark_method_stream_source_log\n";
|
|
$out .= "\t\tio_benchmark_method_stream_proto_http\n"
|
|
if ( $l->{tank_type} == 1 );
|
|
$out .= "\t\tio_benchmark_method_stream_proto_none\n"
|
|
if ( $l->{tank_type} == 2 );
|
|
$out .= "\t}\n}\n";
|
|
$out .= "scheduler_t main_scheduler = scheduler_simple_t {\n";
|
|
$out .=
|
|
"\tthreads = 12\n\tevent_buf_size = 20\n\ttimeout_prec = $l->{timeout_prec}\n}\n";
|
|
$out .= "io_t benchmark_io = io_benchmark_t {\n";
|
|
|
|
if ( Net::IP::ip_is_ipv6( $l->{target_ip} ) ) {
|
|
$out .= "\tmethod_t stream_method = method_stream_ipv6_t {\n";
|
|
}
|
|
else {
|
|
$out .= "\tmethod_t stream_method = method_stream_ipv4_t {\n";
|
|
}
|
|
|
|
if ( $l->{writelog} ) {
|
|
my $level = "all";
|
|
if ( $l->{writelog} ne "1" ) { $level = $l->{writelog}; }
|
|
$out .= "\t\tlogger_t bencmark_logger = logger_default_t {\n";
|
|
$out .= "\t\t\tfilename = \"$l->{answ_log_name}\"\n";
|
|
$out .= "\t\t\tlevel = $level\n";
|
|
$out .= "\t\t\tscheduler = main_scheduler\n\t\t}\n";
|
|
}
|
|
$out .= "\t\tlogger_t brief_logger = logger_brief_t {\n";
|
|
$out .= "\t\t\tfilename = \"$l->{phantom_log_name}\"\n";
|
|
$out .=
|
|
"\t\t\ttime_format = unix\n\t\t\tscheduler = main_scheduler\n\t\t}\n";
|
|
$out .= "\t\tloggers = { brief_logger ";
|
|
$out .= "bencmark_logger " if ( $l->{writelog} );
|
|
$out .= "}\n";
|
|
$out .= "\t\tsource_t source_log = source_log_t {\n";
|
|
$out .= "\t\t\tfilename = \"ammo.stpd\"\n\t\t}\n";
|
|
|
|
if ( $l->{ssl} ) {
|
|
$out .= "\n\t\ttransport_t ssl_transport = transport_ssl_t {\n";
|
|
$out .= "\t\t\ttimeout = 1s\n\t\t}\n";
|
|
$out .= "\t\ttransport = ssl_transport\n\n";
|
|
}
|
|
if ( $l->{tank_type} == 1 ) {
|
|
my $tune = "";
|
|
for (
|
|
'phantom_http_line', 'phantom_http_field_num',
|
|
'phantom_http_field', 'phantom_http_entity'
|
|
)
|
|
{
|
|
my $key = $_;
|
|
if ( $l->{$_} ) {
|
|
$key =~ s/phantom_http_//;
|
|
$tune .= "\t\t\t\t$key = " . $l->{$_} . "\n";
|
|
}
|
|
}
|
|
if ($tune) {
|
|
$out .= "\t\tproto_t http_proto = proto_http_t {\n";
|
|
$out .= "\t\t\treply_limits = {\n";
|
|
$out .= $tune;
|
|
$out .= "\t\t\t}\n";
|
|
$out .= "\t\t}\n";
|
|
}
|
|
else {
|
|
$out .= "\t\tproto_t http_proto = proto_http_t { }\n";
|
|
}
|
|
$out .= "\t\tproto = http_proto\n";
|
|
}
|
|
elsif ( $l->{tank_type} == 2 ) {
|
|
$out .= "\t\tproto_t none_proto = proto_none_t { }\n";
|
|
$out .= "\t\tproto = none_proto\n";
|
|
}
|
|
unless ( $ver =~ /^0\.13/ ) {
|
|
$out .= "\t\taddress = $l->{target_ip}\n";
|
|
$out .= "\t\tport = $l->{target_port}\n";
|
|
}
|
|
else {
|
|
$out .= "\t\taddress = $l->{target_ip}:$l->{target_port}\n";
|
|
}
|
|
$out .= "\t\tbind = { $l->{aliaces} }\n" if $l->{gatling};
|
|
$out .= "\t\ttimeout = $l->{timeout}\n";
|
|
$out .= "\t\tsource = source_log\n\t}\n";
|
|
$out .= "\n\ttimes_t simple_times = times_simple_t {\n";
|
|
$out .= "\t\tmax = 1s\n\t\tmin = 10\n\t\tsteps = 20\n\t}\n";
|
|
$out .= "\ttimes_t list_times = times_list_t {\n";
|
|
$out .= "\t\tvalues = {$l->{time_periods}}\n";
|
|
$out .= "\t}\n\n";
|
|
$out .=
|
|
"\tinstances = $l->{instances}\n\tmethod = stream_method\n\ttimes = list_times\n";
|
|
$out .=
|
|
"\thuman_readable_report = false\n\tscheduler = main_scheduler\n}\n\n";
|
|
|
|
$out .= "stat = {
|
|
clear = true
|
|
period = 1s
|
|
time_format = full
|
|
list = { benchmark_io }
|
|
filename = \"phantom_stat.log\"
|
|
}";
|
|
|
|
open( my $P, ">phantom.conf" );
|
|
print $P $out;
|
|
close($P);
|
|
}
|
|
|
|
sub clearFiles() {
|
|
for ( "lunapark.log", "phantom.conf", "preproc.conf" ) {
|
|
unlink($_) if -r $_;
|
|
}
|
|
}
|
|
|
|
sub clearAllFiles() {
|
|
`rm lp.conf` if -r "lp.conf";
|
|
`rm ammo.stpd` if -r "ammo.stpd";
|
|
`rm -rf logs`;
|
|
clearFiles();
|
|
}
|
|
|
|
sub exit_hand($) {
|
|
my $code = shift;
|
|
|
|
lp_log("Initiated exit with code $code");
|
|
$signal_caught = 1;
|
|
print color "reset";
|
|
|
|
my $kill = curLPproc($$);
|
|
foreach my $pid (@$kill) {
|
|
lp_log("Killing $pid with signal 15");
|
|
lp_log( "Killed: " . ( kill 15, $pid ) );
|
|
}
|
|
|
|
remove_lock( $load{jobno} );
|
|
|
|
close_job( $load{jobno}, $code );
|
|
print_web_link();
|
|
sleep(1); # some time for killed processes to finalize
|
|
move_logs( \%load );
|
|
clearFiles();
|
|
}
|
|
|
|
sub detect_host($) {
|
|
my $ip = shift;
|
|
my $host = gethostbyaddr( inet_aton($ip), AF_INET );
|
|
if ( defined $host ) {
|
|
return $host;
|
|
}
|
|
else {
|
|
return $ip;
|
|
}
|
|
}
|
|
|
|
sub preprocess_phout($) {
|
|
my $phout = shift;
|
|
print "Analizing input log file (timeout and cases) ... ";
|
|
open( my $F, "<$phout" );
|
|
my $max = 0;
|
|
my %cases;
|
|
while (<$F>) {
|
|
my @v = split( "\t", $_ );
|
|
$max = $v[2] if $v[2] > $max;
|
|
$cases{ $v[1] } = 1 if $v[1];
|
|
}
|
|
close($F);
|
|
print "done.\n";
|
|
return ( ( int( $max / 1000000 ) + 1 ) * 1000, \%cases );
|
|
}
|
|
|
|
sub check_task_status($) {
|
|
my $task = shift;
|
|
if ( !$db_conf->{http_base} ) {
|
|
lp_log("No API host setting: http_base, skipped task check");
|
|
return;
|
|
}
|
|
|
|
unless (defined $task) {$task=''};
|
|
|
|
print "Checking JIRA task status: $task\n";
|
|
lp_log("Getting task info for $task...");
|
|
my $url = $db_conf->{http_base} . "api/task/" . $task . "/summary.json";
|
|
lp_log("Sending request to $url");
|
|
|
|
my $ua = new LWP::UserAgent( timeout => 60 );
|
|
my $request = HTTP::Request->new( 'GET', $url );
|
|
|
|
# query the server
|
|
my $response = $ua->request($request);
|
|
lp_log( "Server response: " . $response->as_string );
|
|
|
|
if ( $response->is_success ) {
|
|
my $result =
|
|
from_json( Encode::decode_utf8( $response->decoded_content() ) )
|
|
|| [ {} ];
|
|
|
|
if ( $result->[0]->{closed} ) {
|
|
print "ERROR: Task is closed: "
|
|
. $result->[0]->{closed}
|
|
. ", cannot proceed.\n";
|
|
exit 3;
|
|
}
|
|
}
|
|
else {
|
|
if ( $response->code == 404 ) {
|
|
print "ERROR: Task not found: " . $task . ", cannot proceed.\n";
|
|
}
|
|
else {
|
|
print
|
|
"Some server error has occured. Please, ask developers to investigate server logs.\n";
|
|
}
|
|
exit 3;
|
|
}
|
|
}
|
|
|
|
sub is_job_online($) {
|
|
my $job = shift;
|
|
my $job_info = get_job_info($job);
|
|
return $job_info->{status} eq 'online';
|
|
}
|
|
|
|
sub get_job_info($) {
|
|
my $job = shift;
|
|
|
|
lp_log("Getting job for $job...");
|
|
if ( !$db_conf->{http_base} ) {
|
|
lp_log("No API host setting: http_base, skipped check");
|
|
return;
|
|
}
|
|
|
|
my $url = $db_conf->{http_base} . "api/job/" . $job . "/summary.json";
|
|
lp_log("Sending request to $url");
|
|
|
|
my $ua = new LWP::UserAgent( timeout => 60 );
|
|
my $request = HTTP::Request->new( 'GET', $url );
|
|
|
|
# query the server
|
|
my $response = $ua->request($request);
|
|
lp_log( "Server response: " . $response->as_string );
|
|
|
|
if ( $response->is_success ) {
|
|
my $result =
|
|
from_json( Encode::decode_utf8( $response->decoded_content() ) )
|
|
|| [ {} ];
|
|
|
|
return $result->[0];
|
|
}
|
|
else {
|
|
if ( $response->code == 404 ) {
|
|
lp_log("Got 404 for job, seems it was deleted. Return fake data.");
|
|
|
|
# seems the job was deleted, faking it
|
|
return { 'status' => 'deleted' };
|
|
}
|
|
else {
|
|
print
|
|
"Some server error has occured. Please, ask developers to investigate server logs.\n";
|
|
}
|
|
exit 3;
|
|
}
|
|
}
|
|
|
|
sub close_job($$) {
|
|
my $job = shift;
|
|
if ( !$job ) {
|
|
lp_log("No jobno, skip API call");
|
|
return 0;
|
|
}
|
|
|
|
my $rc = shift;
|
|
lp_log("Finishing $job...");
|
|
if ( !$db_conf->{http_base} ) {
|
|
lp_log("No API host setting: http_base, skipped");
|
|
return;
|
|
}
|
|
print "Finishing job: $job\n";
|
|
my $url =
|
|
$db_conf->{http_base} . "api/job/" . $job . "/close.json?exitcode=" . $rc;
|
|
lp_log("Sending request to $url");
|
|
|
|
my $ua = new LWP::UserAgent( timeout => 60 );
|
|
my $request = HTTP::Request->new( 'GET', $url );
|
|
|
|
# query the server
|
|
my $response = $ua->request($request);
|
|
lp_log( "Server response: " . $response->as_string );
|
|
|
|
if ( $response->is_success ) {
|
|
my $result =
|
|
from_json( Encode::decode_utf8( $response->decoded_content() ) )
|
|
|| [ {} ];
|
|
|
|
if ( !$result->[0]->{success} ) {
|
|
lp_log("Job is already closed!");
|
|
print "WARNING: Task is already closed: " . $job . "\n";
|
|
return 17;
|
|
}
|
|
}
|
|
else {
|
|
if ( $response->code == 404 ) {
|
|
print "WARNING: Job not found: " . $job . ".\n";
|
|
lp_log("Job not found");
|
|
}
|
|
else {
|
|
print
|
|
"Some server error has occured. Please, ask developers to investigate server logs.\n";
|
|
}
|
|
return 18;
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
sub get_target_host($) {
|
|
my $ip = shift;
|
|
my $host = $ip;
|
|
lp_log("Getting info for host $ip...");
|
|
if ( !$db_conf->{http_base} ) {
|
|
lp_log("No API host setting: http_base, skipped");
|
|
return $host;
|
|
}
|
|
|
|
my $url = $db_conf->{http_base} . "api/server/virtual_host.json?ip=" . $ip;
|
|
lp_log("Sending request to $url");
|
|
|
|
my $ua = new LWP::UserAgent( timeout => 60 );
|
|
my $request = HTTP::Request->new( 'GET', $url );
|
|
|
|
# query the server
|
|
my $response = $ua->request($request);
|
|
lp_log( "Server response: " . $response->as_string );
|
|
|
|
if ( $response->is_success ) {
|
|
my $result =
|
|
from_json( Encode::decode_utf8( $response->decoded_content() ) )
|
|
|| [ {} ];
|
|
|
|
if ( $result->[0]->{is_virtual} ) {
|
|
$host = $result->[0]->{vm_host_ip};
|
|
lp_log( "Known virtual host at host-machine: " . $host );
|
|
}
|
|
else {
|
|
lp_log("Known non-virtual host");
|
|
}
|
|
}
|
|
else {
|
|
if ( $response->code == 404 ) {
|
|
lp_log( "Host not found: " . $response->status_line );
|
|
}
|
|
else {
|
|
print
|
|
"Some server error has occured. Please, ask developers to investigate server logs.\n";
|
|
exit_hand(15);
|
|
exit 15;
|
|
}
|
|
|
|
}
|
|
return $host;
|
|
}
|
|
|
|
sub new_job($$$$$$$$$) {
|
|
print "Asking KSHM for a new job number...\n";
|
|
if ( !$db_conf->{http_base} ) {
|
|
lp_log("No API host setting: http_base, skipped");
|
|
return time();
|
|
}
|
|
|
|
my (
|
|
$task, $person, $tankname,
|
|
$target_host, $target_port, $detailed_time,
|
|
$load_scheme, $load_expanded, $notify_list
|
|
) = @_;
|
|
|
|
my $data = {
|
|
task => $task,
|
|
person => $person,
|
|
tank => $tankname,
|
|
host => $target_host,
|
|
port => $target_port,
|
|
loadscheme => $load_scheme,
|
|
loadscheme_expanded => $load_expanded,
|
|
detailed_time => $detailed_time,
|
|
notify => $notify_list
|
|
};
|
|
my $json_data = to_json($data);
|
|
my $url = $db_conf->{http_base} . "api/job/create.json";
|
|
lp_log("Sending JSON request to $url: $json_data");
|
|
|
|
my $ua = new LWP::UserAgent( timeout => 60 );
|
|
my $request = HTTP::Request->new( 'POST', $url, undef, $json_data );
|
|
|
|
# query the server
|
|
my $response = $ua->request($request);
|
|
lp_log( "Server response: " . $response->as_string );
|
|
|
|
if ( $response->is_success ) {
|
|
my $result =
|
|
from_json( Encode::decode_utf8( $response->decoded_content() ) )
|
|
|| [ {} ];
|
|
|
|
if ( defined $result->[0]->{job} ) {
|
|
return $result->[0]->{job};
|
|
}
|
|
else {
|
|
print "Server returned no new job: " . Dumper($result);
|
|
exit 11;
|
|
}
|
|
}
|
|
else {
|
|
print "Failed to get new job: " . $response->status_line . "\n";
|
|
if ( $response->code == 403 ) {
|
|
print
|
|
"Server rejected your test. Please, request access from server administrator.\n";
|
|
}
|
|
elsif ( $response->code == 400 ) {
|
|
print
|
|
"JIRA task not found, either it is closed, or doesn't exists in database. Please, consult with server administrator.\n";
|
|
}
|
|
else {
|
|
print
|
|
"Some server error has occured. Please, ask developers to investigate server logs.\n";
|
|
}
|
|
exit 11;
|
|
}
|
|
}
|
|
|
|
sub set_job_info($$$$$$$$$$$) {
|
|
print "Updating job info...\n";
|
|
if ( !$db_conf->{http_base} ) {
|
|
lp_log("No API host setting: http_base, skipped");
|
|
return;
|
|
}
|
|
my (
|
|
$jobno,
|
|
$job_name, #
|
|
$job_dsc, #
|
|
$instances,
|
|
$ammo_path,
|
|
$loop_count,
|
|
$ver,
|
|
$regress,
|
|
$component,
|
|
$tank_type,
|
|
$command_line
|
|
) = @_;
|
|
|
|
$job_name ||= "[none]";
|
|
|
|
my $data = {
|
|
name => decode( 'utf-8', $job_name ),
|
|
description => decode( 'utf-8', $job_dsc ),
|
|
instances => $instances,
|
|
ammo => $ammo_path,
|
|
loop => $loop_count,
|
|
version => $ver,
|
|
regression => $regress,
|
|
component => $component,
|
|
tank_type => $tank_type,
|
|
command_line => $command_line,
|
|
starred => 0
|
|
};
|
|
|
|
my $json = JSON->new->utf8;
|
|
my $json_data = $json->encode($data);
|
|
my $url = $db_conf->{http_base} . "api/job/" . $jobno . "/edit.json";
|
|
lp_log("Sending JSON request to $url: $json_data");
|
|
|
|
my $ua = new LWP::UserAgent( timeout => 60 );
|
|
my $request = HTTP::Request->new( 'POST', $url, undef, $json_data );
|
|
|
|
# query the server
|
|
my $response = $ua->request($request);
|
|
lp_log( "Server response: " . $response->as_string );
|
|
|
|
if ( $response->is_success ) {
|
|
my $result =
|
|
from_json( Encode::decode_utf8( $response->decoded_content() ) )
|
|
|| [ {} ];
|
|
|
|
if ( !( defined $result->[0]->{success} ) ) {
|
|
print "Server failed to set job info: " . Dumper($result);
|
|
exit 13;
|
|
}
|
|
}
|
|
else {
|
|
print "Failed to set job info: " . $response->status_line . "\n";
|
|
print
|
|
"Some server error has occured. Please, ask developers to investigate server logs.\n";
|
|
exit_hand(13);
|
|
exit 13;
|
|
}
|
|
}
|
|
|
|
sub get_tank_operator() {
|
|
my (
|
|
$login, $passwd, $uid, $gid, $quota,
|
|
$comment, $gcos, $dir, $shell, $expire
|
|
) = getpwuid($<);
|
|
return $login;
|
|
}
|
|
|
|
sub start_monitoring() {
|
|
my $mon_path = which('load-monitor');
|
|
|
|
if ( !$mon_path
|
|
|| $load{monitoring_config} eq 'none'
|
|
|| !$db_conf->{http_base} )
|
|
{
|
|
lp_log("Monitoring disabled");
|
|
return 0;
|
|
}
|
|
|
|
my $filename = $load{monitoring_config};
|
|
my $monitoring_host = $load{target_ip};
|
|
|
|
unless ( $load{monitoring_config} ) {
|
|
my $out = "";
|
|
$monitoring_host = get_target_host( $load{target_ip} );
|
|
if ( !$monitoring_host ) {
|
|
$monitoring_host = $load{target_ip};
|
|
}
|
|
|
|
$out = "<Monitoring><Host address='$monitoring_host'/></Monitoring>";
|
|
|
|
$filename = $load{monitoring_tmp};
|
|
open( my $TMP, ">" . $filename );
|
|
print $TMP $out;
|
|
close($TMP);
|
|
}
|
|
|
|
print "Starting target resource monitoring with config: $filename\n";
|
|
my $cmd =
|
|
"load-monitor -c $filename -o monitoring_$load{jobno}.data -j $load{jobno} -t $monitoring_host 2>&1 |";
|
|
lp_log("Starting monitoring: $cmd");
|
|
my $pid = open( PP, $cmd );
|
|
lp_log( "Child pipe open status: " . $! );
|
|
|
|
my $success = 0;
|
|
while (<PP>) {
|
|
lp_log( "Monitoring out: " . $_ );
|
|
if ( $_ =~ /agents installed OK/ ) {
|
|
print "\tAgents installed OK\n";
|
|
}
|
|
|
|
if ( $_ =~ /Sent first data OK/ ) {
|
|
print "\tFirst data sent OK\n";
|
|
$success = 1;
|
|
last;
|
|
}
|
|
|
|
if ( $_ =~ /\[ERROR\]/ ) {
|
|
print $_;
|
|
}
|
|
}
|
|
|
|
if ( !$success ) {
|
|
if ( $load{monitoring_config} ) {
|
|
print
|
|
"ERROR: Failed to start monitoring, see monitoring.log for details\n";
|
|
unless ($load{script}) {
|
|
exit_hand(14);
|
|
exit 14;
|
|
}
|
|
}
|
|
else {
|
|
print
|
|
"WARNING: Failed to start monitoring, see monitoring.log for details\n";
|
|
sleep(5); # for user to see the error
|
|
}
|
|
}
|
|
else {
|
|
lp_log("Monitoring pid: $pid");
|
|
}
|
|
return $pid;
|
|
}
|
|
|
|
sub print_web_link() {
|
|
if ( $db_conf->{http_base} && $load{jobno} ) {
|
|
print "Web Link: " . $db_conf->{http_base} . $load{jobno} . "\n";
|
|
}
|
|
}
|
|
|
|
sub check_lock($) {
|
|
my ($ignore_locks) = @_;
|
|
my $interval = 5;
|
|
|
|
while (1) {
|
|
lp_log("Checking lock files... ");
|
|
my ( $end_time, $task ) = ( 0, 0 );
|
|
my $locks = getlocks();
|
|
my $need_exit = 0;
|
|
if ( scalar( @{$locks} ) ) {
|
|
for my $lock (@$locks) {
|
|
lp_log("Lock file detected: $lock");
|
|
my $l = getconfig($lock);
|
|
if ( is_job_online( $l->{jobno} ) ) {
|
|
if ($ignore_locks) {
|
|
lp_log("Lock ignored [$ignore_locks]: $lock");
|
|
}
|
|
else {
|
|
lp_log("User: $l->{user}\tJob#: $l->{jobno}");
|
|
print
|
|
"WARNING: Tank is busy. User: $l->{user}\tJob: $db_conf->{http_base}$l->{jobno}\n";
|
|
$need_exit = 1;
|
|
}
|
|
}
|
|
else {
|
|
remove_lock( $l->{jobno} );
|
|
}
|
|
}
|
|
}
|
|
|
|
if ($need_exit) {
|
|
print "Waiting " . $interval . "s for lock file to be cleared...\n";
|
|
sleep($interval);
|
|
}
|
|
else {
|
|
last;
|
|
}
|
|
}
|
|
}
|
|
|
|
sub remove_lock($) {
|
|
my ($jobno) = @_;
|
|
unlink("/var/lock/lunapark_$jobno.lock") if $jobno;
|
|
}
|
|
|
|
sub acquire_lock($$$$) {
|
|
lp_log("Obtaining lock");
|
|
my ( $jobno, $person, $ignore_locks, $endtime ) = @_;
|
|
|
|
check_lock($ignore_locks);
|
|
|
|
### Create lock file with jobno and
|
|
open LOCK, ">/var/lock/lunapark_$jobno.lock";
|
|
print LOCK "jobno=$load{jobno}\nuser=$person\nend=$endtime\n";
|
|
close LOCK;
|
|
}
|
|
|
|
#== START WORK
|
|
$SIG{INT} = \&exit_kill;
|
|
$SIG{QUIT} = \&exit_kill;
|
|
$SIG{TERM} = \&exit_kill;
|
|
|
|
my ( $pu0, $pu1, $pu2 );
|
|
|
|
### Command line arguments
|
|
$load{command_line} = "$0 " . join( " ", @ARGV );
|
|
|
|
my $help;
|
|
|
|
GetOptions(
|
|
"debug|d!" => \$load{debug},
|
|
"config|c:s" => \$load{config},
|
|
"ammo|a=s" => \$load{ammo},
|
|
"skip-step|s" => \$load{skip_step},
|
|
"step-only|o" => \$load{step_only},
|
|
"instances|i=i" => \$load{instances},
|
|
"address=s" => \$load{address},
|
|
"manual-start|m" => \$load{manual_start},
|
|
"timer|t=s" => \$load{timer},
|
|
"gatling|g" => \$load{gatling},
|
|
"clearall" => \$load{clearall},
|
|
"clear" => \$load{clear},
|
|
"script" => \$load{script},
|
|
"autocases" => \$load{autocases},
|
|
"phantomlog|p=s" => \$load{user_phantom_log},
|
|
"threadlog|r=s" => \$load{user_threads_log},
|
|
"make_phantom_conf" => \$load{make_phantom_conf},
|
|
"help|h" => \$help,
|
|
) or pod2usage(2);
|
|
pod2usage(1) if $help;
|
|
$load{ammo} = shift @ARGV if @ARGV;
|
|
|
|
print "==== Welcome to Lunapark ====\n";
|
|
|
|
if ( $load{clearall} ) {
|
|
clearAllFiles();
|
|
exit 0;
|
|
}
|
|
|
|
if ( $load{clear} ) {
|
|
clearFiles();
|
|
exit 0;
|
|
}
|
|
|
|
unless( $load{config} ) {
|
|
if (-r "load.conf") {
|
|
die ("Can't create load.conf: file exists");
|
|
} else {
|
|
copy ("/etc/lunapark/load.conf.example", "load.conf");
|
|
print "Created default load.conf\n";
|
|
exit 0;
|
|
}
|
|
}
|
|
|
|
### Reading local and updating global config
|
|
my $tmp;
|
|
if ( -s "lp.conf" ) {
|
|
$tmp = read_conf("lp.conf");
|
|
}
|
|
|
|
if ( $load{skip_step} ) {
|
|
$load{config} = $tmp->{config};
|
|
}
|
|
my $conf = getconfig( $load{config} );
|
|
|
|
if ( $conf->{ammofile} && !$load{ammo} ) { $load{ammo} = $conf->{ammofile}; }
|
|
|
|
if ( $conf->{uri} ) {
|
|
my $ammo_tmp = "ammo_" . formatFn(time) . ".txt";
|
|
open( my $F, ">" . $ammo_tmp );
|
|
if ( ref( $conf->{uri} ) eq 'ARRAY' ) {
|
|
print $F $_ . "\n" for ( @{ $conf->{uri} } );
|
|
}
|
|
else {
|
|
print $F $conf->{uri};
|
|
}
|
|
close($F);
|
|
$load{ammo} = $ammo_tmp;
|
|
}
|
|
|
|
if ( $load{user_phantom_log} ) {
|
|
unless ( -s $load{user_phantom_log} ) {
|
|
print "Cannot detect '$load{user_phantom_log}'\n";
|
|
exit 4;
|
|
}
|
|
}
|
|
|
|
unless ( $load{skip_step}
|
|
|| $load{make_phantom_conf}
|
|
|| $load{user_phantom_log} )
|
|
{
|
|
unless ( !( $load{clearall} ) && !( $load{clear} ) && $load{ammo} ) {
|
|
pod2usage(2);
|
|
exit 4;
|
|
}
|
|
}
|
|
|
|
### Command line arguments preprocessing
|
|
if ( !defined $load{address} && defined $conf->{address} ) {
|
|
$load{address} = $conf->{address};
|
|
}
|
|
|
|
for ( keys %{$conf} ) {
|
|
next if /^header_/;
|
|
unless ( $known_params{$_} ) {
|
|
print "Unknown param '$_' in $load{config}\n";
|
|
exit 7;
|
|
}
|
|
}
|
|
|
|
update_conf( \%load, $conf );
|
|
|
|
check_lock( $load{script} );
|
|
|
|
#print Dumper(\%load);
|
|
### Config arguments preprocessing
|
|
if ( $load{address} =~ /(\d+\.\d+\.\d+\.\d+):?(\d*)/ ) {
|
|
( $load{target_ip}, $load{target_port} ) =
|
|
( $1, $2 ? $2 : $default{target_port} )
|
|
unless defined $load{target_ip};
|
|
}
|
|
else {
|
|
if ( $load{address} =~ /(.+):(\d+)$/ ) {
|
|
( $load{target_ip}, $load{target_port} ) =
|
|
( $1, $2 ? $2 : $default{target_port} )
|
|
unless defined $load{target_ip};
|
|
}
|
|
else { die( "Can't parse address: " . $load{address} ); }
|
|
}
|
|
|
|
if ( defined $conf->{time_periods}
|
|
&& $conf->{time_periods} =~ /.+\s(\d+)(s)?\s*$/ )
|
|
{
|
|
if ($2) {
|
|
$load{time_periods} =
|
|
$conf->{time_periods} . " " . int( $1 * 1.1 * 1000 );
|
|
$load{timeout} = $1 . $2;
|
|
}
|
|
else {
|
|
$load{time_periods} = $conf->{time_periods} . " " . int( $1 * 1.1 );
|
|
$load{timeout} = $1;
|
|
}
|
|
}
|
|
if ( defined $load{job_name} ) {
|
|
if ( $load{job_name} ) {
|
|
$load{job_name} = $load{job_name};
|
|
}
|
|
else {
|
|
if ( $load{script} ) {
|
|
$load{job_name} = "";
|
|
}
|
|
else {
|
|
$load{job_name} = UserDialog("Please, enter the job name: ");
|
|
}
|
|
}
|
|
}
|
|
if ( defined $load{job_dsc} ) {
|
|
if ( $load{job_dsc} ) {
|
|
$load{job_dsc} = $load{job_dsc};
|
|
}
|
|
else {
|
|
if ( $load{script} ) {
|
|
$load{job_dsc} = "";
|
|
}
|
|
else {
|
|
$load{job_dsc} = UserDialog("Please, enter the job description: ");
|
|
}
|
|
}
|
|
}
|
|
|
|
# handling task=dir
|
|
if ( defined $load{task} ) {
|
|
if ( $load{task} eq 'dir' ) {
|
|
my $found = 0;
|
|
my @dirs = reverse split( /\//, `pwd` );
|
|
for my $dir (@dirs) {
|
|
if ( $dir =~ /^(\w+)-(\d+)/ ) {
|
|
$load{task} = uc($1) . "-" . $2;
|
|
$found = 1;
|
|
last;
|
|
}
|
|
}
|
|
die 'Cannot detect folder, matching with JIRA task' unless $found;
|
|
}
|
|
else {
|
|
die "Wrong task name '$load{task}'"
|
|
unless ( $load{task} =~ /(\w+\-\d+)/ );
|
|
}
|
|
}
|
|
|
|
if ( defined $load{manual_start} ) {
|
|
my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday, $isdst ) =
|
|
localtime;
|
|
if ( $load{manual_start} =~
|
|
/(\d{4})-(\d{2})-(\d{2}) (\d{2}):(\d{2}):(\d{2})/ )
|
|
{
|
|
$load{start_ts} = formatTS( $load{manual_start} );
|
|
}
|
|
elsif ( $load{manual_start} =~ /(\d{2}):(\d{2}):(\d{2})/ ) {
|
|
( $sec, $min, $hour ) = ( $3, $2, $1 );
|
|
$load{start_ts} = timelocal( $sec, $min, $hour, $mday, $mon, $year );
|
|
}
|
|
}
|
|
if ( defined $load{timer} ) {
|
|
print $load{timer} . "\n";
|
|
if ( $load{timer} =~ /(\d{2}):(\d{2}):(\d{2})/ ) {
|
|
$load{time_to_start} += $1 * 3600 + $2 * 60 + $3;
|
|
}
|
|
}
|
|
|
|
unless ( $load{target_ip} ) {
|
|
print "You should set address in config file: 'address=ip:port'\n";
|
|
print
|
|
"or use command line argument: 'lunapark AMMO-FILE [--address=ip:port]'\n";
|
|
exit 5;
|
|
}
|
|
|
|
### Time params and filenames
|
|
my $ts = time;
|
|
( $load{fn}, $load{fd} ) = ( formatFn($ts), formatDate($ts) );
|
|
if ( $load{user_phantom_log} ) {
|
|
$load{phantom_log_name} = $load{user_phantom_log};
|
|
my $cmd = `wc -l $load{user_phantom_log}`;
|
|
if ( $cmd =~ /^(\d+)/ ) {
|
|
$load{ammo_count} = $1;
|
|
}
|
|
open( my $H, ">phantom.log" );
|
|
print $H "2011-03-28 14:21:59.601 +0400 [info] phantom Exit\n";
|
|
close($H);
|
|
}
|
|
else {
|
|
$load{phantom_log_name} = "phout_$load{fn}.txt";
|
|
}
|
|
$load{preproc_log_name} = "prepr_$load{fn}.txt";
|
|
$load{answ_log_name} = "answ_$load{fn}.txt";
|
|
|
|
update_conf( \%load, \%default );
|
|
|
|
if ( $load{user_phantom_log} ) {
|
|
my ( $timeout, $cases ) = preprocess_phout( $load{user_phantom_log} );
|
|
|
|
$load{time_periods} .= ' ' . $timeout;
|
|
my $case_str = '';
|
|
for my $c ( keys %{$cases} ) {
|
|
$case_str .= "'$c' ";
|
|
}
|
|
$load{cases} = $case_str;
|
|
$load{header_http} = 1.0;
|
|
$load{tank_type} = 1;
|
|
$load{autocases} = 1;
|
|
$load{loadscheme} = '';
|
|
$load{steps} = '(1;1)';
|
|
}
|
|
|
|
$load{monitoring_tmp} = "monitoring_tmp_" . time;
|
|
|
|
if ( -r "lp.conf" ) {
|
|
save_conf( update_value_conf( read_conf("lp.conf"), \%load ) );
|
|
}
|
|
else {
|
|
save_conf( \%load );
|
|
}
|
|
|
|
if ( $load{make_phantom_conf} ) {
|
|
makePhantomConf( \%load );
|
|
exit 0;
|
|
}
|
|
|
|
### Cheking tank version amd user
|
|
lp_log("Detecting versions of phantom, tank and user...\n");
|
|
$_ = `dpkg -l phantom | grep phantom`;
|
|
if (/(\d+\.\d+\.\d+)/) {
|
|
$load{phantom} = $1;
|
|
}
|
|
else {
|
|
print "WARNING: Unable to detect phantom version\n";
|
|
$load{phantom} = "N/A";
|
|
}
|
|
|
|
$_ = `dpkg -l | grep yandex-load-tank`;
|
|
if (/yandex-load-tank\s+((\d+).(\d+)-(\d+))\s+(.+)/) {
|
|
$load{tank_version} = $1;
|
|
}
|
|
else {
|
|
$load{tank_version} = "N/A";
|
|
}
|
|
|
|
$load{person} = get_tank_operator();
|
|
|
|
$_ = `hostname -f`;
|
|
chomp;
|
|
$load{tank} = $_;
|
|
lp_log("Detecting versions of phantom, tank and user... Done");
|
|
###
|
|
|
|
print
|
|
"$load{tank} ($load{person})\nphantom=$load{phantom}\nyandex-load-tank=$load{tank_version}\n";
|
|
|
|
## Checking task status
|
|
check_task_status( $load{task} );
|
|
|
|
### Cheking Tank Usage
|
|
my $cmd = `df -hl -x fuse`;
|
|
while ( $cmd =~ /(\d+)%\s(.*)/g ) {
|
|
if ( $1 > $MAXDISK && $load{script} == 0 ) {
|
|
print "\nWarning!\n";
|
|
print "Disk $2 (Usage: $1%)\n";
|
|
exit 6;
|
|
}
|
|
}
|
|
|
|
$cmd = `ps -A -o %c%u%C`;
|
|
while ( $cmd =~ /([\w\/\-]*)\s*(\w+)\s*(\d+)\.(\d+)\s*/g ) {
|
|
if ( $3 > $MAXCPU && $load{script} == 0 ) {
|
|
print "\nWarning!\n";
|
|
print "Process: $2 ($1 $3% CPU) \n";
|
|
exit 6;
|
|
}
|
|
}
|
|
###
|
|
|
|
### Check gatling mode
|
|
if ( $load{gatling} ) {
|
|
my $al = getTankAliaces();
|
|
$load{aliaces} = join( " ", keys %{$al} );
|
|
if ( $load{gatling_ip} ) {
|
|
$load{aliaces} = $load{gatling_ip};
|
|
print "gatling enabled: $load{aliaces}\n";
|
|
}
|
|
elsif ( scalar( keys %{$al} ) > 1 ) {
|
|
print "gatling enabled: $load{aliaces}\n";
|
|
}
|
|
else {
|
|
print "gatling disabled. Not enough aliaces: $load{aliaces}\n ";
|
|
sleep(1);
|
|
$load{gatling} = 0;
|
|
}
|
|
}
|
|
###
|
|
|
|
if ( $load{skip_step} ) {
|
|
$load{ammo_count} = $tmp->{ammo_count};
|
|
$load{cases} = $tmp->{cases};
|
|
$load{steps} = $tmp->{steps};
|
|
$load{loadscheme} = $tmp->{loadscheme};
|
|
$load{ammo} = $tmp->{ammo};
|
|
$load{ammo_path} = $tmp->{ammo_path};
|
|
$load{loop_count} = $tmp->{loop_count};
|
|
}
|
|
else {
|
|
$load{ammo_path} = File::Spec->rel2abs("$load{ammo}");
|
|
}
|
|
|
|
print "ammo=" . $load{ammo_path} . "\n";
|
|
|
|
save_conf( \%load );
|
|
|
|
my $loadscheme = "";
|
|
|
|
### Generating ammo-file or use last generated ammo-file
|
|
if ( !$load{skip_step} ) {
|
|
$loadscheme = `stepper.py -c $load{config} -l`;
|
|
$loadscheme =~ s/==== Stepper ====\n//;
|
|
$load{loadscheme} = $loadscheme;
|
|
$load{loadscheme} =~ s/\n=== Stepper ====\n//g;
|
|
$load{loadscheme} =~ s/\n/;/g;
|
|
}
|
|
else {
|
|
$loadscheme = $load{loadscheme};
|
|
$loadscheme =~ s/;/\n/g;
|
|
print "lunapark: skip stepping ammo, using ammo.stpd.\n";
|
|
}
|
|
|
|
unless ( $load{user_phantom_log} ) {
|
|
if ( !$load{skip_step} ) {
|
|
system("stepper.py -a $load{ammo} -c $load{config}");
|
|
if ($?) {
|
|
print "\n";
|
|
die "Error while stepping ammo";
|
|
}
|
|
}
|
|
}
|
|
|
|
if ( $load{step_only} ) {
|
|
exit 0;
|
|
}
|
|
|
|
my $load = update_value_conf( read_conf("lp.conf"), \%load );
|
|
%load = %{$load};
|
|
|
|
$load{target_host} = detect_host( $load{target_ip} );
|
|
|
|
my @inform_list = split( / /, $load{inform} ? $load{inform} : '' );
|
|
my @load_list = split( /;/, $load{loads_str} ? $load{loads_str} : '' );
|
|
my @load_expanded_list =
|
|
split( /;/, $load{loadscheme} ? $load{loadscheme} : '' );
|
|
$load{jobno} = new_job(
|
|
$load{task}, $load{person}, $load{tank},
|
|
$load{target_host}, $load{target_port}, $load{detailed_time},
|
|
\@load_list, \@load_expanded_list, \@inform_list
|
|
);
|
|
acquire_lock( $load{jobno}, $load{person}, $load{script}, 'N/A' );
|
|
set_job_info(
|
|
$load{jobno}, $load{job_name}, $load{job_dsc},
|
|
$load{instances}, $load{ammo_path}, $load{loop_count},
|
|
$load{ver}, $load{regress}, $load{component},
|
|
$load{tank_type}, $load{command_line}
|
|
);
|
|
|
|
print_web_link();
|
|
|
|
# save lp.conf
|
|
if ( -r "lp.conf" ) {
|
|
save_conf( update_value_conf( read_conf("lp.conf"), \%load ) );
|
|
}
|
|
|
|
### Auto start: by time and manual
|
|
if ( $load{start_ts} ) {
|
|
print "==== Lunapark ====\n" if time <= $load{start_ts};
|
|
print "Start time:\t" . formatDate( $load{start_ts} ) . "\n"
|
|
if time <= $load{start_ts};
|
|
while ( time <= $load{start_ts} ) {
|
|
print "Current time:\t" . formatDate(time) . ". ";
|
|
print "Remaining "
|
|
. MinSec( 1000 * ( $load{start_ts} - time ), 0, 1 )
|
|
. " \r";
|
|
sleep(1);
|
|
}
|
|
print "\n";
|
|
}
|
|
elsif ( $load{timer} ) {
|
|
my $time_to_start = $load{time_to_start};
|
|
while ( $time_to_start >= 0 ) {
|
|
my $h = int( $time_to_start / 3600 );
|
|
my $m = int( ( $time_to_start - $h * 3600 ) / 60 );
|
|
my $s = $time_to_start % 60;
|
|
my $str = sprintf( "%02d:%02d:%02d", $h, $m, $s );
|
|
print "time to start: $str\r";
|
|
$time_to_start--;
|
|
sleep(1);
|
|
}
|
|
print " " x 30;
|
|
print "\n";
|
|
}
|
|
elsif ( $load{manual_start} ) {
|
|
print "==== Lunapark ====\n";
|
|
while ( $load{manual_start} ) {
|
|
print "Continue? (y) ";
|
|
chomp( $_ = <STDIN> );
|
|
last if (/^\s*y\s*$/);
|
|
}
|
|
}
|
|
|
|
makePhantomConf( \%load );
|
|
|
|
my $phantom_start_time = 0;
|
|
|
|
### Pure task: using phantom as load generator
|
|
unless ( $load{user_phantom_log} ) {
|
|
my $MONITORING = start_monitoring();
|
|
|
|
lp_log("Start phantom");
|
|
|
|
# Start phantom
|
|
if ( !open( my $PH, "phantom run phantom.conf 1>phantom.log 2>&1 |" ) ) {
|
|
exit_hand(12);
|
|
exit 12;
|
|
}
|
|
lp_log("Phantom started OK");
|
|
$phantom_start_time = time;
|
|
|
|
# Wait for log from phantom
|
|
my $retry_count = 0;
|
|
while ( !( -r $load{phantom_log_name} ) && $retry_count < 30 ) {
|
|
sleep(1);
|
|
$retry_count++;
|
|
}
|
|
|
|
# Start preproc (phantom log aggregator)
|
|
lp_log("Start preproc");
|
|
my $preproc_cmd =
|
|
"(prd.pl $load{phantom_log_name} phantom_stat.log | preproc.pl) 2>&1 |";
|
|
print "lunapark: starting preproc... ";
|
|
my $PREPR;
|
|
if ( !open( $PREPR, $preproc_cmd ) ) {
|
|
exit_hand(12);
|
|
exit 12;
|
|
}
|
|
print " Done\n";
|
|
|
|
# Wait for aggregated data from preproc
|
|
while ( !( -r $load{preproc_log_name} ) ) {
|
|
sleep(1);
|
|
}
|
|
|
|
# Start fantom (console output)
|
|
system(
|
|
"fantom.py $load{preproc_log_name} --phantom-start=$phantom_start_time --config=$load{config}"
|
|
);
|
|
|
|
# Handling fantom exit code (2x - autostop)
|
|
my $code = $?;
|
|
|
|
lp_log( "fantom.py exit code:" . $code . "\n" );
|
|
if ($code) {
|
|
my $c = "";
|
|
my %excode = ( "time" => 21, http => 22, net => 23 );
|
|
if ( $code == 2 * 256 ) {
|
|
$c = "time";
|
|
}
|
|
elsif ( $code == 3 * 256 ) {
|
|
$c = "http";
|
|
}
|
|
elsif ( $code == 4 * 256 ) {
|
|
$c = "net";
|
|
}
|
|
else {
|
|
lp_log("Exiting with code $code");
|
|
print "code: $code\n";
|
|
exit_hand($code);
|
|
close($PREPR);
|
|
kill 15, $MONITORING if $MONITORING;
|
|
exit $code;
|
|
}
|
|
|
|
lp_log("fantom exit (code $code)");
|
|
print "lunapark: fantom exit (code $code)\n";
|
|
exit_hand( $excode{$c} );
|
|
close($PREPR);
|
|
kill 15, $MONITORING if $MONITORING;
|
|
exit $excode{$c};
|
|
}
|
|
|
|
lp_log("Killing monitoring process: $MONITORING");
|
|
my $killed = kill 15, $MONITORING if $MONITORING;
|
|
lp_log("Killed: $killed") if $killed;
|
|
}
|
|
else {
|
|
### Use only phantom-like log (from any other load-generator)
|
|
save_conf( update_value_conf( read_conf("lp.conf"), \%load ) );
|
|
my $PHAN;
|
|
my $preproc_file_ok = 0;
|
|
while ( $preproc_file_ok == 0 ) {
|
|
if ( -r "$load{phantom_log_name}" ) {
|
|
if ( $load{user_phantom_log} ) {
|
|
print "Preprocess data...\n";
|
|
|
|
`prd.pl $load{phantom_log_name} $load{user_threads_log} | preproc.pl`;
|
|
$preproc_file_ok = 1;
|
|
}
|
|
else {
|
|
print "lunapark: starting preproc... ";
|
|
my $preproc_cmd =
|
|
"(prd.pl $load{phantom_log_name} $load{user_threads_log} | preproc.pl) 2>&1 |";
|
|
if ( !open( my $PREPR, $preproc_cmd ) ) {
|
|
exit_hand(12);
|
|
exit 12;
|
|
}
|
|
print " Done\n";
|
|
}
|
|
$preproc_file_ok = 1;
|
|
|
|
my $phout_file_ok = 0;
|
|
while ( $phout_file_ok == 0 ) {
|
|
if ( -r "$load{preproc_log_name}" ) {
|
|
print "lunapark: starting fantom... ";
|
|
system(
|
|
"fantom.py $load{preproc_log_name} --phantom-start=$phantom_start_time --config=$load{config}"
|
|
);
|
|
print " Done\n";
|
|
$phout_file_ok = 1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
lp_log("Happy End");
|
|
exit_hand(0);
|
|
exit 0;
|
|
|
|
__END__
|
|
|
|
=head1 NAME
|
|
|
|
sample - Using Getopt::Long and Pod::Usage
|
|
|
|
=head1 SYNOPSIS
|
|
|
|
lunapark AMMO-FILE [OPTIONS]
|
|
|
|
Try `lunapark --help' for more information.
|
|
|
|
=head1 OPTIONS
|
|
|
|
=over 23
|
|
|
|
=item B<-a, --ammo=FILE>
|
|
|
|
use custom ammo-file (file with requests)
|
|
|
|
=item B<-c, --config=FILE>
|
|
|
|
use custom config file (default: load.conf)
|
|
|
|
=item B<-s, --skip-step>
|
|
|
|
start without ammo-generating (using generated ammo from last task)
|
|
|
|
=item B<-o, --step-only>
|
|
|
|
only ammo-generating, without start. useful for starting next task without ammo-generating
|
|
|
|
=item B<-g, --gatling>
|
|
|
|
use gatling mode
|
|
|
|
=item B<--script>
|
|
|
|
start without checking tank lock, CPU and disk usage
|
|
|
|
=item B<--clear>
|
|
|
|
delete files from previous task, created by lunapark (excl. logs) in current directory
|
|
|
|
=item B<--clearall>
|
|
|
|
delete all files from previous tasks, created by lunapark (incl. logs) in current directory
|
|
|
|
=item B<-p, --phantomlog=FILE>
|
|
|
|
loading custom data at lunapark base. data format have to be equal to phantom output format
|
|
|
|
=item B<-d, --debug>
|
|
|
|
debug output
|
|
|
|
=item B<-i, --instances=NUM>
|
|
|
|
set number of used instances (default: 1000). blocker to load.conf
|
|
|
|
=item B<--address=IP:PORT>
|
|
|
|
use custom address for queries. blocker to load.conf
|
|
|
|
=item B<--manual-start>
|
|
|
|
manual start after ammo generating. useful for synchronous tasks. blocker to load.conf
|
|
|
|
=back
|
|
|
|
=cut
|