Files
percona-toolkit/t/pt-agent/init_agent.t
2013-03-19 14:44:02 -06:00

281 lines
6.2 KiB
Perl

#!/usr/bin/env perl
BEGIN {
die "The PERCONA_TOOLKIT_BRANCH environment variable is not set.\n"
unless $ENV{PERCONA_TOOLKIT_BRANCH} && -d $ENV{PERCONA_TOOLKIT_BRANCH};
unshift @INC, "$ENV{PERCONA_TOOLKIT_BRANCH}/lib";
};
use strict;
use warnings FATAL => 'all';
use English qw(-no_match_vars);
use Test::More;
use JSON;
use File::Temp qw(tempdir);
use Percona::Test;
use Percona::Test::Mock::UserAgent;
require "$trunk/bin/pt-agent";
Percona::Toolkit->import(qw(Dumper));
Percona::WebAPI::Representation->import(qw(as_hashref));
my $tmpdir = tempdir("/tmp/pt-agent.$PID.XXXXXX", CLEANUP => 1);
my $ua = Percona::Test::Mock::UserAgent->new(
encode => sub { my $c = shift; return encode_json($c || {}) },
);
my $client = eval {
Percona::WebAPI::Client->new(
api_key => '123',
ua => $ua,
);
};
is(
$EVAL_ERROR,
'',
'Create Client with mock user agent'
) or die;
# #############################################################################
# Init a new agent, i.e. create it.
# #############################################################################
my $return_agent = {
uuid => '123',
hostname => `hostname`,
versions => {
'Percona::WebAPI::Client' => "$Percona::WebAPI::Client::VERSION",
'Perl' => sprintf('%vd', $PERL_VERSION),
},
links => {
self => '/agents/123',
config => '/agents/123/config',
},
};
$ua->{responses}->{post} = [
{
headers => { 'Location' => '/agents/123' },
},
];
$ua->{responses}->{get} = [
{
headers => { 'X-Percona-Resource-Type' => 'Agent' },
content => $return_agent,
},
];
# interval is a callback that subs call to sleep between failed
# client requests. We're not faking a client request failure,
# so @wait should stay empty.
my @wait;
my $interval = sub {
my $t = shift;
push @wait, $t;
};
my $agent;
my $output = output(
sub {
$agent = pt_agent::init_agent(
client => $client,
interval => $interval,
agents_link => "/agents",
lib_dir => $tmpdir,
);
},
stderr => 1,
);
is_deeply(
as_hashref($agent, with_links => 1),
$return_agent,
'Create new Agent'
) or diag($output, Dumper(as_hashref($agent, with_links => 1)));
is(
scalar @wait,
0,
"Client did not wait (new Agent)"
) or diag($output);
# The tool should immediately write the Agent to --lib/agent.
ok(
-f "$tmpdir/agent",
"Wrote Agent to --lib/agent"
) or diag($output);
# From above, we return an Agent with id=123. Check that this
# is what the tool actually wrote.
$output = `cat $tmpdir/agent 2>/dev/null`;
like(
$output,
qr/"uuid":"123"/,
"Saved new Agent"
) or diag($output);
# Repeat this test but this time fake an error, so the tool isn't
# able to create the Agent first time, so it should wait (call
# interval), and try again.
unlink "$tmpdir/agent" if -f "$tmpdir/agent";
$return_agent->{id} = '456';
$return_agent->{links} = {
self => '/agents/456',
config => '/agents/456/config',
};
$ua->{responses}->{post} = [
{ # 1, the fake error
code => 500,
},
# 2, code should call interval
{ # 3, code should try again, then receive this
code => 200,
headers => { 'Location' => '/agents/456' },
},
];
# 4, code will GET the new Agent
$ua->{responses}->{get} = [
{
headers => { 'X-Percona-Resource-Type' => 'Agent' },
content => $return_agent,
},
];
@wait = ();
$ua->{requests} = [];
$output = output(
sub {
$agent = pt_agent::init_agent(
client => $client,
interval => $interval,
agents_link => '/agents',
lib_dir => $tmpdir,
);
},
stderr => 1,
);
is_deeply(
as_hashref($agent, with_links => 1),
$return_agent,
'Create new Agent after error'
) or diag(Dumper(as_hashref($agent, with_links => 1)));
is(
scalar @wait,
1,
"Client waited"
);
is_deeply(
$ua->{requests},
[
'POST /agents', # first attempt, 500 error
'POST /agents', # second attemp, 200 OK
'GET /agents/456', # GET new Agent
],
"POST POST GET new Agent"
) or diag(Dumper($ua->{requests}));
like(
$output,
qr{WARNING Failed to POST /agents},
"POST /agents failure logged"
);
ok(
-f "$tmpdir/agent",
"Wrote Agent to --lib/agent again"
);
$output = `cat $tmpdir/agent 2>/dev/null`;
like(
$output,
qr/"id":"456"/,
"Saved new Agent again"
) or diag($output);
# Do not remove lib/agent; the next test will use it.
# #############################################################################
# Init an existing agent, i.e. update it.
# #############################################################################
# If --lib/agent exists, the tool should create an Agent obj from it
# then attempt to PUT it to the agents link. The previous tests should
# have left an Agent file with id=456.
my $hashref = decode_json(pt_agent::slurp("$tmpdir/agent"));
my $saved_agent = Percona::WebAPI::Resource::Agent->new(%$hashref);
$ua->{responses}->{put} = [
{
code => 200,
headers => {
Location => '/agents/123',
},
},
];
$ua->{responses}->{get} = [
{
code => 200,
headers => { 'X-Percona-Resource-Type' => 'Agent' },
content => $return_agent,
}
];
@wait = ();
$ua->{requests} = [];
$output = output(
sub {
$agent = pt_agent::init_agent(
client => $client,
interval => $interval,
agents_link => '/agents',
lib_dir => $tmpdir,
);
},
stderr => 1,
);
is_deeply(
as_hashref($agent),
as_hashref($saved_agent),
'Used saved Agent'
) or diag($output, Dumper(as_hashref($agent)));
like(
$output,
qr/Reading saved Agent from $tmpdir\/agent/,
"Reports reading saved Agent"
) or diag($output);
is(
scalar @wait,
0,
"Client did not wait (saved Agent)"
);
is_deeply(
$ua->{requests},
[
'PUT /agents/123',
'GET /agents/123',
],
"PUT then GET saved Agent"
) or diag(Dumper($ua->{requests}));
# #############################################################################
# Done.
# #############################################################################
done_testing;