mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-09-01 18:25:59 +00:00
186 lines
5.6 KiB
Perl
186 lines
5.6 KiB
Perl
#!/usr/bin/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";
|
|
$ENV{PTTEST_PRETTY_JSON} = 0;
|
|
|
|
};
|
|
|
|
use strict;
|
|
use warnings FATAL => 'all';
|
|
use English qw(-no_match_vars);
|
|
use Test::More;
|
|
use JSON;
|
|
use File::Slurp;
|
|
|
|
use Data::Dumper;
|
|
$Data::Dumper::Indent = 1;
|
|
$Data::Dumper::Sortkeys = 1;
|
|
$Data::Dumper::Quotekeys = 0;
|
|
|
|
use JSONReportFormatter;
|
|
use OptionParser;
|
|
use DSNParser;
|
|
use EventAggregator;
|
|
use QueryRewriter;
|
|
use QueryParser;
|
|
use Quoter;
|
|
use PerconaTest;
|
|
|
|
my ($result, $events, $expected);
|
|
|
|
my $o = new OptionParser(description=>'JSONReportFormatter');
|
|
my $q = new Quoter();
|
|
my $qp = new QueryParser();
|
|
my $qr = new QueryRewriter(QueryParser=>$qp);
|
|
|
|
$o->get_specs("$trunk/bin/pt-query-digest");
|
|
|
|
my $j = new JSONReportFormatter(
|
|
OptionParser => $o,
|
|
QueryRewriter => $qr,
|
|
QueryParser => $qp,
|
|
Quoter => $q,
|
|
);
|
|
|
|
my $ea = new EventAggregator(
|
|
groupby => 'fingerprint',
|
|
worst => 'Query_time',
|
|
attributes => {
|
|
Query_time => [qw(Query_time)],
|
|
Lock_time => [qw(Lock_time)],
|
|
user => [qw(user)],
|
|
ts => [qw(ts)],
|
|
Rows_sent => [qw(Rows_sent)],
|
|
Rows_examined => [qw(Rows_examined)],
|
|
db => [qw(db)],
|
|
},
|
|
);
|
|
|
|
isa_ok(
|
|
$j,
|
|
'JSONReportFormatter'
|
|
) or die "Cannot create a JSONReportFormatter";
|
|
|
|
$events = [
|
|
{ ts => '071015 21:43:52',
|
|
cmd => 'Query',
|
|
user => 'root',
|
|
host => 'localhost',
|
|
ip => '',
|
|
arg => "SELECT id FROM users WHERE name='foo'",
|
|
Query_time => '8.000652',
|
|
Lock_time => '0.000109',
|
|
Rows_sent => 1,
|
|
Rows_examined => 1,
|
|
pos_in_log => 1,
|
|
db => 'test3',
|
|
},
|
|
{ ts => '071015 21:43:52',
|
|
cmd => 'Query',
|
|
user => 'root',
|
|
host => 'localhost',
|
|
ip => '',
|
|
arg =>
|
|
"INSERT IGNORE INTO articles (id, body,)VALUES(3558268,'sample text')",
|
|
Query_time => '1.001943',
|
|
Lock_time => '0.000145',
|
|
Rows_sent => 0,
|
|
Rows_examined => 0,
|
|
pos_in_log => 2,
|
|
db => 'test1',
|
|
},
|
|
{ ts => '071015 21:43:53',
|
|
cmd => 'Query',
|
|
user => 'bob',
|
|
host => 'localhost',
|
|
ip => '',
|
|
arg => "SELECT id FROM users WHERE name='bar'",
|
|
Query_time => '1.000682',
|
|
Lock_time => '0.000201',
|
|
Rows_sent => 1,
|
|
Rows_examined => 2,
|
|
pos_in_log => 5,
|
|
db => 'test1',
|
|
}
|
|
];
|
|
|
|
# Here's the breakdown of values for those three events:
|
|
#
|
|
# ATTRIBUTE VALUE BUCKET VALUE RANGE
|
|
# Query_time => 8.000652 326 7.700558026 range [7.700558026, 8.085585927)
|
|
# Query_time => 1.001943 284 0.992136979 range [0.992136979, 1.041743827)
|
|
# Query_time => 1.000682 284 0.992136979 range [0.992136979, 1.041743827)
|
|
# -------- -----------
|
|
# 10.003277 9.684831984
|
|
#
|
|
# Lock_time => 0.000109 97 0.000108186 range [0.000108186, 0.000113596)
|
|
# Lock_time => 0.000145 103 0.000144980 range [0.000144980, 0.000152229)
|
|
# Lock_time => 0.000201 109 0.000194287 range [0.000194287, 0.000204002)
|
|
# -------- -----------
|
|
# 0.000455 0.000447453
|
|
#
|
|
# Rows_sent => 1 284 0.992136979 range [0.992136979, 1.041743827)
|
|
# Rows_sent => 0 0 0
|
|
# Rows_sent => 1 284 0.992136979 range [0.992136979, 1.041743827)
|
|
# -------- -----------
|
|
# 2 1.984273958
|
|
#
|
|
# Rows_exam => 1 284 0.992136979 range [0.992136979, 1.041743827)
|
|
# Rows_exam => 0 0 0
|
|
# Rows_exam => 2 298 1.964363355, range [1.964363355, 2.062581523)
|
|
# -------- -----------
|
|
# 3 2.956500334
|
|
|
|
# I hand-checked these values with my TI-83 calculator.
|
|
# They are, without a doubt, correct.
|
|
|
|
foreach my $event (@$events) {
|
|
$event->{fingerprint} = $qr->fingerprint( $event->{arg} );
|
|
$ea->aggregate($event);
|
|
}
|
|
$ea->calculate_statistical_metrics(apdex_t=>1);
|
|
my %top_spec = (
|
|
attrib => 'Query_time',
|
|
orderby => 'sum',
|
|
total => 100,
|
|
count => undef,
|
|
);
|
|
@top_spec{qw(ol_attrib ol_limit ol_freq)} = split(/:/, "Query_time:1:10");
|
|
my ($worst, $other) = $ea->top_events(%top_spec);
|
|
$result = $j->query_report(
|
|
ea => $ea,
|
|
worst => $worst,
|
|
orderby => 'Query_time',
|
|
groupby => 'fingerprint',
|
|
);
|
|
|
|
my $sample_file = "t/lib/samples/JSONReportFormatter/report001.json";
|
|
my $want_text = read_file($sample_file);
|
|
my $want = decode_json $want_text;
|
|
my $got = decode_json $result;
|
|
|
|
|
|
# I've change the original test because it was comparing JSONs as strings
|
|
# but it is hard (or impossible) to ensure in all environments the output
|
|
# will have a particular order.
|
|
# I prefer to decode_json($result) and compare it against the struct I am
|
|
# expecting as a result for 2 reasons:
|
|
# 1) using decode_json ensures that the json syntax is valid, but comparing
|
|
# strings cannot ensure that since the sample json may contain syntax errors.
|
|
# 2) Using structs (hashes) and is_deeply makes this test to work regarding
|
|
# of the sort order during the encoding process.
|
|
|
|
is_deeply(
|
|
$got,
|
|
$want,
|
|
'Basic output',
|
|
);
|
|
|
|
# #############################################################################
|
|
# Done.
|
|
# #############################################################################
|
|
done_testing;
|