Add and test start_services() for Service.run_once_on_start.

This commit is contained in:
Daniel Nichter
2013-03-25 14:27:53 -06:00
parent 2eff2692fe
commit bdc3487919
4 changed files with 176 additions and 8 deletions

View File

@@ -4647,6 +4647,7 @@ use Time::HiRes qw(sleep time);
use JSON qw(decode_json);
use File::Temp qw(tempfile);
use File::Path;
use FindBin;
use Percona::Toolkit;
use Percona::WebAPI::Client;
@@ -5089,8 +5090,8 @@ sub run_agent {
lib_dir => $lib_dir,
config => $config,
services => $services,
json => $args{json}, # optional, for testing
json => $args{json}, # optional, for testing
bin_dir => $args{bin_dir}, # optional, for testing
);
}
@@ -5214,6 +5215,14 @@ sub get_services {
schedule_services(
services => $new_services,
lib_dir => $lib_dir,
bin_dir => $args{bin_dir}, # optional, for testing
);
# TODO: this probably can't/won't fail, but if it does, is it
# worth setting success=0?
start_services(
services => $new_services,
bin_dir => $args{bin_dir}, # optional, for testing
);
$services = $new_services;
@@ -5268,8 +5277,9 @@ sub write_config {
return;
}
# Check and init the --lib dir. This dir is used to save the Agent resource (/agent),
# Service resources (/services/), and crontab for services (/conrtab, /crontab.err).
# Check and init the --lib dir. This dir is used to save the Agent resource
# (/agent), Service resources (/services/), and crontab for services(/conrtab,
# /crontab.err).
sub init_lib_dir {
my (%args) = @_;
@@ -5442,6 +5452,8 @@ sub make_new_crontab {
# Optional args
my $crontab_list = defined $args{crontab_list} ? $args{crontab_list}
: `crontab -l 2>/dev/null`;
my $bin_dir = defined $args{bin_dir} ? $args{bin_dir}
: "$FindBin::Bin/";
my @other_lines
= grep { $_ !~ m/pt-agent (?:--run-service|--send-data)/ }
@@ -5452,12 +5464,12 @@ sub make_new_crontab {
foreach my $service ( @$services ) {
push @pt_agent_lines,
$service->run_schedule
. " pt-agent --run-service "
. " ${bin_dir}pt-agent --run-service "
. $service->name;
if ( $service->spool_schedule ) {
push @pt_agent_lines,
$service->spool_schedule
. " pt-agent --send-data "
. " ${bin_dir}pt-agent --send-data "
. $service->name;
}
}
@@ -5468,10 +5480,39 @@ sub make_new_crontab {
return $new_crontab;
}
# Start all services that have the run_once_on_start flag enabled. This is
# used for "setup services" so the user doesn't have to wait until the next
# the service is actually scheduled to run.
sub start_services {
my (%args) = @_;
have_required_args(\%args, qw(
services
)) or die;
my $services = $args{services};
# Optional args
my $bin_dir = defined $args{bin_dir} ? $args{bin_dir}
: "$FindBin::Bin/";
foreach my $service ( @$services ) {
next unless $service->run_once_on_start;
my $cmd = "${bin_dir}pt-agent --run-service " . $service->name;
_info('Starting ' . $service->name . ' service: ' . $cmd);
# TODO: need service-specific log files, else where is this output
# supposed to go?
system("$cmd </dev/null >/dev/null 2>&1 &");
}
return;
}
# ########################## #
# --run-service process subs #
# ########################## #
# TODO: need service-specific PID files so two "--run-service enable-slow-log"
# can't run at the same time.
sub run_service {
my (%args) = @_;
@@ -5560,7 +5601,7 @@ sub run_service {
# special vars like __RUN_N_OUTPUT__, __TMPDIR__, etc.
my $cmd = join(' ',
$task->program,
$task->options,
($task->options || ''),
'>',
$output_file,
);

View File

@@ -34,6 +34,7 @@ sub test_make_new_crontab {
my $new_crontab = pt_agent::make_new_crontab(
services => $services,
crontab_list => $crontab_list,
bin_dir => '',
);
ok(
@@ -122,6 +123,7 @@ SKIP: {
my $new_crontab = pt_agent::make_new_crontab(
services => [ $svc0 ],
bin_dir => '',
);
is(

View File

@@ -141,7 +141,7 @@ is(
"init_config_file()"
);
my $tmpdir = tempdir("/tmp/pt-agent.$PID.XXXXXX", CLEANUP => 1);
my $tmpdir = tempdir("/tmp/pt-agent.$PID.XXXXXX", CLEANUP => 0);
mkdir "$tmpdir/services" or die "Error making $tmpdir/services: $OS_ERROR";
my @ok_code = (); # callbacks
@@ -308,6 +308,121 @@ is(
"Crontab is the same"
);
# #############################################################################
# Test a run_once_on_start service
# #############################################################################
diag(`rm -f $tmpdir/* >/dev/null 2>&1`);
diag(`rm -rf $tmpdir/services/*`);
mkdir "$tmpdir/spool" or die $OS_ERROR;
$config_file = pt_agent::get_config_file();
unlink $config_file if -f $config_file;
pt_agent::init_config_file(file => $config_file, api_key => '123');
$config = Percona::WebAPI::Resource::Config->new(
ts => 1363720060,
name => 'Test run_once_on_start',
options => {
'check-interval' => "60",
'lib' => $tmpdir,
'spool' => "$tmpdir/spool",
'pid' => "$tmpdir/pid",
'log' => "$tmpdir/log"
},
links => {
self => '/agents/123/config',
services => '/agents/123/services',
},
);
$run0 = Percona::WebAPI::Resource::Task->new(
name => 'run-at-start',
number => '0',
program => 'date',
output => 'spool',
);
$svc0 = Percona::WebAPI::Resource::Service->new(
name => 'test-run-at-start',
run_schedule => '0 0 1 1 *',
spool_schedule => '0 0 1 1 *',
run_once_on_start => 1, # here's the magic
tasks => [ $run0 ],
links => {
self => '/query-history',
data => '/query-history/data',
},
);
$ua->{responses}->{get} = [
{
headers => { 'X-Percona-Resource-Type' => 'Config' },
content => as_hashref($config, with_links => 1),
},
{
headers => { 'X-Percona-Resource-Type' => 'Service' },
content => [ as_hashref($svc0, with_links => 1) ],
},
{
headers => { 'X-Percona-Resource-Type' => 'Config' },
content => as_hashref($config, with_links => 1),
},
{
headers => { 'X-Percona-Resource-Type' => 'Service' },
content => [ as_hashref($svc0, with_links => 1) ],
},
];
@ok_code = (); # callbacks
@oktorun = (1, 1, 0);
@wait = ();
$output = output(
sub {
pt_agent::run_agent(
agent => $agent,
client => $client,
interval => $interval,
config_file => $config_file,
lib_dir => $tmpdir,
oktorun => $oktorun, # optional, for testing
json => $json, # optional, for testing
bin_dir => "$trunk/bin/", # optional, for testing
);
},
stderr => 1,
);
Percona::Test::wait_for_files("$tmpdir/spool/test-run-at-start");
like(
$output,
qr/Starting test-run-at-start service/,
"Ran service on start"
);
my @runs = $output =~ m/Starting test-run-at-start service/g;
is(
scalar @runs,
1,
"... only ran it once"
);
chomp($output = `cat $tmpdir/spool/test-run-at-start 2>/dev/null`);
ok(
$output,
"... service ran at start"
) or diag($output);
chomp($output = `crontab -l`);
like(
$output,
qr/--run-service test-run-at-start/,
"... service was scheduled"
);
# #############################################################################
# Done.
# #############################################################################
@@ -320,4 +435,5 @@ if ( -f $config_file ) {
unlink $config_file
or warn "Error removing $config_file: $OS_ERROR";
}
done_testing;

View File

@@ -81,6 +81,15 @@ is(
) or diag($output);
$crontab = `crontab -l 2>/dev/null`;
# pt-agent uses $FindBin::Bin/pt-agent for the path to pt-agent,
# which in testing will be $trunk/t/pt-agent/ because that's where
# this file is located. However, if $FindBin::Bin resovles sym
# links where as $trunk does not, so to make things simple we just
# cut out the full path.
if ( $crontab ) {
$crontab =~ s! /.+?/pt-agent --! pt-agent --!g;
}
is(
$crontab,
"* 0 * * * date > /dev/null