mirror of
https://github.com/percona/percona-toolkit.git
synced 2025-10-20 01:16:14 +00:00
Fix pt-ioprofile so it works without a file. Add more tests.
This commit is contained in:
@@ -441,10 +441,44 @@ rm_tmpdir() {
|
||||
# End tmpdir package
|
||||
# ###########################################################################
|
||||
|
||||
# ###########################################################################
|
||||
# alt_cmds package
|
||||
# ###########################################################################
|
||||
|
||||
# seq N, return 1, ..., 5
|
||||
_seq() {
|
||||
local i="$1"
|
||||
awk "BEGIN { for(i=1; i<=$i; i++) print i; }"
|
||||
}
|
||||
|
||||
_pidof() {
|
||||
local cmd="$1"
|
||||
if ! pidof "$cmd" 2>/dev/null; then
|
||||
ps -eo pid,ucomm | awk -v comm="$cmd" '$2 == comm { print $1 }'
|
||||
fi
|
||||
}
|
||||
|
||||
_lsof() {
|
||||
local pid="$1"
|
||||
if ! lsof -p $pid 2>/dev/null; then
|
||||
/bin/ls -l /proc/$pid/fd 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
_which() {
|
||||
# which on CentOS is aliased to a cmd that prints extra stuff.
|
||||
# Also, if the cmd isn't found, a msg is printed to stderr.
|
||||
[ -x /usr/bin/which ] && /usr/bin/which "$1" 2>/dev/null | awk '{print $1}'
|
||||
}
|
||||
|
||||
# ###########################################################################
|
||||
# End alt_cmds package
|
||||
# ###########################################################################
|
||||
|
||||
# ###########################################################################
|
||||
# Global variables
|
||||
# ###########################################################################
|
||||
TOOL=`basename $0`
|
||||
TOOL="pt-ioprofile"
|
||||
|
||||
# ###########################################################################
|
||||
# Subroutines
|
||||
@@ -454,8 +488,6 @@ TOOL=`basename $0`
|
||||
# pid function fd_no size timing filename
|
||||
# The arguments are the files to summarize.
|
||||
tabulate_strace() {
|
||||
local file="$1"
|
||||
|
||||
cat > $TMPDIR/tabulate_strace.awk <<EOF
|
||||
BEGIN {
|
||||
# These are function names, or partial function names, that we care about.
|
||||
@@ -553,7 +585,7 @@ tabulate_strace() {
|
||||
}
|
||||
}
|
||||
EOF
|
||||
awk -f $TMPDIR/tabulate_strace.awk "$file"
|
||||
awk -f $TMPDIR/tabulate_strace.awk "$@"
|
||||
}
|
||||
|
||||
# Takes as input the output from tabulate_strace. Arguments are just a subset
|
||||
@@ -565,7 +597,7 @@ summarize_strace() {
|
||||
local group_by="$3"
|
||||
local file="$4"
|
||||
|
||||
cat > $TMPDIR/summarize_strace.awk <<EOF
|
||||
cat > "$TMPDIR/summarize_strace.awk" <<EOF
|
||||
BEGIN {
|
||||
# These are function names, or partial function names, that we care about.
|
||||
# Later we will ignore any function whose name doesn't look like these.
|
||||
@@ -687,7 +719,10 @@ EOF
|
||||
}
|
||||
|
||||
main() {
|
||||
if [ $# -eq 0 ]; then
|
||||
if [ $# -gt 0 ]; then
|
||||
# Summarize the files the user passed in.
|
||||
tabulate_strace "$@" > $TMPDIR/tabulated_samples
|
||||
else
|
||||
# There's no file to analyze, so we'll make one.
|
||||
if which strace > /dev/null 2>&1; then
|
||||
|
||||
@@ -697,13 +732,7 @@ main() {
|
||||
# gave us it explicitly with --profile-pid.
|
||||
local proc_pid="$OPT_PROFILE_PID"
|
||||
if [ -z "$proc_pid" ]; then
|
||||
proc_pid=$(pidof -s "$OPT_PROFILE_PROCESS" 2>/dev/null);
|
||||
if [ -z "$proc_pid" ]; then
|
||||
proc_pid=$(pgrep -o -x "$OPT_PROFILE_PROCESS" 2>/dev/null)
|
||||
fi
|
||||
if [ -z "$proc_pid" ]; then
|
||||
proc_pid=$(ps -eaf | grep "$OPT_PROFILE_PROCESS" | grep -v grep | awk '{print $2}' | head -n1);
|
||||
fi
|
||||
proc_pid=$(_pidof "$OPT_PROFILE_PROCESS" | awk '{print $1; exit;'})
|
||||
fi
|
||||
|
||||
date
|
||||
@@ -711,7 +740,7 @@ main() {
|
||||
if [ "$proc_pid" ]; then
|
||||
echo "Tracing process ID $proc_pid"
|
||||
|
||||
lsof -n -P -s -p "$proc_pid" > "$samples" 2>&1
|
||||
_lsof "$proc_pid" > "$samples" 2>&1
|
||||
if [ "$?" -ne "0" ]; then
|
||||
echo "Error: could not execute lsof, error code $?"
|
||||
exit 1
|
||||
@@ -756,32 +785,36 @@ main() {
|
||||
echo "strace is not in PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
else
|
||||
# Summarize the files the user passed in.
|
||||
tabulate_strace "$@" > $TMPDIR/tabulated_samples
|
||||
fi
|
||||
|
||||
summarize_strace \
|
||||
$OPT_AGGREGATE \
|
||||
$OPT_CELL \
|
||||
$OPT_GROUP_BY \
|
||||
$TMPDIR/tabulated_samples
|
||||
"$TMPDIR/tabulated_samples"
|
||||
}
|
||||
|
||||
# Execute the program if it was not included from another file.
|
||||
# This makes it possible to include without executing, and thus test.
|
||||
if [ "$(basename "$0")" = "pt-ioprofile" ] \
|
||||
|| [ "$(basename "$0")" = "bash" -a "$_" = "$0" ]; then
|
||||
if [ "${0##*/}" = "$TOOL" ] \
|
||||
|| [ "${0##*/}" = "bash" -a "$_" = "$0" ]; then
|
||||
|
||||
# Parse command line options. We must do this first so we can
|
||||
# see if --daemonize was specified.
|
||||
mk_tmpdir
|
||||
parse_options $0 "$@"
|
||||
usage_or_errors $0
|
||||
EXIT_STATUS=$?
|
||||
if [ $EXIT_STATUS -eq 0 ]; then
|
||||
# No errors parsing command line options, run the program.
|
||||
main "$EXT_ARGV"
|
||||
parse_options "$0" "$@"
|
||||
usage_or_errors "$0"
|
||||
po_status=$?
|
||||
if [ $po_status -eq 0 ]; then
|
||||
# XXX
|
||||
# TODO: This should be quoted but because the way parse_options()
|
||||
# currently works, it flattens files in $@ (i.e. given on the cmd
|
||||
# line) into the string $ARGV. So if we pass "$ARGV" then other
|
||||
# functions will see 1 file named "file1 file2" instead of "file1"
|
||||
# "file2".
|
||||
main $ARGV
|
||||
else
|
||||
[ $OPT_ERRS -gt 0 ] && EXIT_STATUS=1
|
||||
fi
|
||||
rm_tmpdir
|
||||
exit $EXIT_STATUS
|
||||
|
@@ -9,16 +9,53 @@ BEGIN {
|
||||
use strict;
|
||||
use warnings FATAL => 'all';
|
||||
use English qw(-no_match_vars);
|
||||
use Test::More;
|
||||
use Time::HiRes qw(time);
|
||||
|
||||
use PerconaTest;
|
||||
use DSNParser;
|
||||
use Sandbox;
|
||||
|
||||
my ($tool) = $PROGRAM_NAME =~ m/([\w-]+)\.t$/;
|
||||
push @ARGV, "$trunk/t/$tool/*.sh" unless @ARGV;
|
||||
my $dp = new DSNParser(opts=>$dsn_opts);
|
||||
my $sb = new Sandbox(basedir => '/tmp', DSNParser => $dp);
|
||||
my $dbh = $sb->get_dbh_for('master');
|
||||
|
||||
$ENV{BIN_DIR} = "$trunk/bin";
|
||||
$ENV{T_DIR} = "$trunk/t/$tool";
|
||||
if ( !$dbh ) {
|
||||
plan skip_all => "Cannot connect to master sandbox";
|
||||
}
|
||||
else {
|
||||
plan tests => 3;
|
||||
}
|
||||
|
||||
system("$trunk/util/test-bash-functions $trunk/t/lib/samples/bash/dummy.sh @ARGV");
|
||||
my $output = "";
|
||||
|
||||
$output = `$trunk/bin/pt-ioprofile --help 2>&1`;
|
||||
like(
|
||||
$output,
|
||||
qr/--version/,
|
||||
"--help"
|
||||
);
|
||||
|
||||
|
||||
my $t0 = time;
|
||||
$output = `$trunk/bin/pt-ioprofile --run-time 3 2>&1`;
|
||||
my $t1 = time;
|
||||
|
||||
like(
|
||||
$output,
|
||||
qr/Tracing process ID \d+/,
|
||||
"Runs without a file (bug 925778)"
|
||||
);
|
||||
|
||||
# If the system is really slow, it may take a second to process the files
|
||||
# and then clean up all the temp stuff. In any case, the default run-time
|
||||
# is 30s so it should be way less than that.
|
||||
cmp_ok(
|
||||
$t1 - $t0,
|
||||
'<',
|
||||
5,
|
||||
"Runs for --run-time"
|
||||
);
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
|
5
t/pt-ioprofile/samples/003-processed.txt
Normal file
5
t/pt-ioprofile/samples/003-processed.txt
Normal file
@@ -0,0 +1,5 @@
|
||||
total pread read open close getdents64 _llseek filename
|
||||
0.006348 0.006348 0.000000 0.000000 0.000000 0.000000 0.000000 /data/data/abd_2dia/aia_227_228.ibd
|
||||
0.000504 0.000000 0.000000 0.000096 0.000098 0.000310 0.000000 /data/data/abd_2dia/
|
||||
0.000369 0.000369 0.000000 0.000000 0.000000 0.000000 0.000000 /data/data/abd_2dia/aia_227_223.ibd
|
||||
0.000288 0.000000 0.000062 0.000054 0.000045 0.000000 0.000127 /data/data/abd_2dia/test/db.opt
|
35
t/pt-ioprofile/saved_samples.t
Normal file
35
t/pt-ioprofile/saved_samples.t
Normal file
@@ -0,0 +1,35 @@
|
||||
#!/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 tests => 1;
|
||||
|
||||
use PerconaTest;
|
||||
|
||||
my $sample = "t/pt-ioprofile/samples";
|
||||
my $output = "";
|
||||
|
||||
# Files with raw samples should be named N-samples.txt
|
||||
# in t/pt-ioprofile/samples/.
|
||||
foreach my $sampleno ( qw(003) ) {
|
||||
ok(
|
||||
no_diff(
|
||||
"$trunk/bin/pt-ioprofile $trunk/$sample/$sampleno-samples.txt",
|
||||
"$sample/$sampleno-processed.txt",
|
||||
stderr => 1,
|
||||
),
|
||||
"$sampleno-samples.txt"
|
||||
);
|
||||
}
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
exit;
|
26
t/pt-ioprofile/unit_tests.pl
Normal file
26
t/pt-ioprofile/unit_tests.pl
Normal file
@@ -0,0 +1,26 @@
|
||||
#!/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 PerconaTest;
|
||||
|
||||
my $tool = "pt-ioprofile";
|
||||
push @ARGV, "$trunk/t/$tool/*.sh" unless @ARGV;
|
||||
|
||||
$ENV{BIN_DIR} = "$trunk/bin";
|
||||
$ENV{T_DIR} = "$trunk/t/$tool";
|
||||
|
||||
system("$trunk/util/test-bash-functions $trunk/t/lib/samples/bash/dummy.sh @ARGV");
|
||||
|
||||
# #############################################################################
|
||||
# Done.
|
||||
# #############################################################################
|
||||
exit;
|
Reference in New Issue
Block a user