Merge branch 'cc/codespeed'

"perf" test output can be sent to codespeed server.

* cc/codespeed:
  perf/run: read GIT_PERF_REPO_NAME from perf.repoName
  perf/run: learn to send output to codespeed server
  perf/run: learn about perf.codespeedOutput
  perf/run: add conf_opts argument to get_var_from_env_or_config()
  perf/aggregate: implement codespeed JSON output
  perf/aggregate: refactor printing results
  perf/aggregate: fix checking ENV{GIT_PERF_SUBSECTION}
maint
Junio C Hamano 2018-01-23 13:16:38 -08:00
commit 86d7fcc40a
2 changed files with 140 additions and 57 deletions

View File

@ -3,6 +3,7 @@
use lib '../../perl/blib/lib'; use lib '../../perl/blib/lib';
use strict; use strict;
use warnings; use warnings;
use JSON;
use Git; use Git;


sub get_times { sub get_times {
@ -35,10 +36,15 @@ sub format_times {
return $out; return $out;
} }


my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests); my (@dirs, %dirnames, %dirabbrevs, %prefixes, @tests, $codespeed);
while (scalar @ARGV) { while (scalar @ARGV) {
my $arg = $ARGV[0]; my $arg = $ARGV[0];
my $dir; my $dir;
if ($arg eq "--codespeed") {
$codespeed = 1;
shift @ARGV;
next;
}
last if -f $arg or $arg eq "--"; last if -f $arg or $arg eq "--";
if (! -d $arg) { if (! -d $arg) {
my $rev = Git::command_oneline(qw(rev-parse --verify), $arg); my $rev = Git::command_oneline(qw(rev-parse --verify), $arg);
@ -70,8 +76,10 @@ if (not @tests) {
} }


my $resultsdir = "test-results"; my $resultsdir = "test-results";
if ($ENV{GIT_PERF_SUBSECTION} ne "") { my $results_section = "";
if (exists $ENV{GIT_PERF_SUBSECTION} and $ENV{GIT_PERF_SUBSECTION} ne "") {
$resultsdir .= "/" . $ENV{GIT_PERF_SUBSECTION}; $resultsdir .= "/" . $ENV{GIT_PERF_SUBSECTION};
$results_section = $ENV{GIT_PERF_SUBSECTION};
} }


my @subtests; my @subtests;
@ -100,13 +108,6 @@ sub read_descr {
return $line; return $line;
} }


my %descrs;
my $descrlen = 4; # "Test"
for my $t (@subtests) {
$descrs{$t} = $shorttests{$t}.": ".read_descr("$resultsdir/$t.descr");
$descrlen = length $descrs{$t} if length $descrs{$t}>$descrlen;
}

sub have_duplicate { sub have_duplicate {
my %seen; my %seen;
for (@_) { for (@_) {
@ -122,54 +123,117 @@ sub have_slash {
return 0; return 0;
} }


my %newdirabbrevs = %dirabbrevs; sub print_default_results {
while (!have_duplicate(values %newdirabbrevs)) { my %descrs;
%dirabbrevs = %newdirabbrevs; my $descrlen = 4; # "Test"
last if !have_slash(values %dirabbrevs); for my $t (@subtests) {
%newdirabbrevs = %dirabbrevs; $descrs{$t} = $shorttests{$t}.": ".read_descr("$resultsdir/$t.descr");
for (values %newdirabbrevs) { $descrlen = length $descrs{$t} if length $descrs{$t}>$descrlen;
s{^[^/]*/}{}; }

my %newdirabbrevs = %dirabbrevs;
while (!have_duplicate(values %newdirabbrevs)) {
%dirabbrevs = %newdirabbrevs;
last if !have_slash(values %dirabbrevs);
%newdirabbrevs = %dirabbrevs;
for (values %newdirabbrevs) {
s{^[^/]*/}{};
}
}

my %times;
my @colwidth = ((0)x@dirs);
for my $i (0..$#dirs) {
my $d = $dirs[$i];
my $w = length (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
$colwidth[$i] = $w if $w > $colwidth[$i];
}
for my $t (@subtests) {
my $firstr;
for my $i (0..$#dirs) {
my $d = $dirs[$i];
$times{$prefixes{$d}.$t} = [get_times("$resultsdir/$prefixes{$d}$t.times")];
my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
my $w = length format_times($r,$u,$s,$firstr);
$colwidth[$i] = $w if $w > $colwidth[$i];
$firstr = $r unless defined $firstr;
}
}
my $totalwidth = 3*@dirs+$descrlen;
$totalwidth += $_ for (@colwidth);

printf "%-${descrlen}s", "Test";
for my $i (0..$#dirs) {
my $d = $dirs[$i];
printf " %-$colwidth[$i]s", (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
}
print "\n";
print "-"x$totalwidth, "\n";
for my $t (@subtests) {
printf "%-${descrlen}s", $descrs{$t};
my $firstr;
for my $i (0..$#dirs) {
my $d = $dirs[$i];
my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
printf " %-$colwidth[$i]s", format_times($r,$u,$s,$firstr);
$firstr = $r unless defined $firstr;
}
print "\n";
} }
} }


my %times; sub print_codespeed_results {
my @colwidth = ((0)x@dirs); my ($results_section) = @_;
for my $i (0..$#dirs) {
my $d = $dirs[$i]; my $project = "Git";
my $w = length (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d});
$colwidth[$i] = $w if $w > $colwidth[$i]; my $executable = `uname -s -m`;
} chomp $executable;
for my $t (@subtests) {
my $firstr; if ($results_section ne "") {
for my $i (0..$#dirs) { $executable .= ", " . $results_section;
my $d = $dirs[$i];
$times{$prefixes{$d}.$t} = [get_times("$resultsdir/$prefixes{$d}$t.times")];
my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
my $w = length format_times($r,$u,$s,$firstr);
$colwidth[$i] = $w if $w > $colwidth[$i];
$firstr = $r unless defined $firstr;
} }

my $environment;
if (exists $ENV{GIT_PERF_REPO_NAME} and $ENV{GIT_PERF_REPO_NAME} ne "") {
$environment = $ENV{GIT_PERF_REPO_NAME};
} elsif (exists $ENV{GIT_TEST_INSTALLED} and $ENV{GIT_TEST_INSTALLED} ne "") {
$environment = $ENV{GIT_TEST_INSTALLED};
$environment =~ s|/bin-wrappers$||;
} else {
$environment = `uname -r`;
chomp $environment;
}

my @data;

for my $t (@subtests) {
for my $d (@dirs) {
my $commitid = $prefixes{$d};
$commitid =~ s/^build_//;
$commitid =~ s/\.$//;
my ($result_value, $u, $s) = get_times("$resultsdir/$prefixes{$d}$t.times");

my %vals = (
"commitid" => $commitid,
"project" => $project,
"branch" => $dirnames{$d},
"executable" => $executable,
"benchmark" => $shorttests{$t} . " " . read_descr("$resultsdir/$t.descr"),
"environment" => $environment,
"result_value" => $result_value,
);
push @data, \%vals;
}
}

print to_json(\@data, {utf8 => 1, pretty => 1}), "\n";
} }
my $totalwidth = 3*@dirs+$descrlen;
$totalwidth += $_ for (@colwidth);


binmode STDOUT, ":utf8" or die "PANIC on binmode: $!"; binmode STDOUT, ":utf8" or die "PANIC on binmode: $!";


printf "%-${descrlen}s", "Test"; if ($codespeed) {
for my $i (0..$#dirs) { print_codespeed_results($results_section);
my $d = $dirs[$i]; } else {
printf " %-$colwidth[$i]s", (exists $dirabbrevs{$d} ? $dirabbrevs{$d} : $dirnames{$d}); print_default_results();
}
print "\n";
print "-"x$totalwidth, "\n";
for my $t (@subtests) {
printf "%-${descrlen}s", $descrs{$t};
my $firstr;
for my $i (0..$#dirs) {
my $d = $dirs[$i];
my ($r,$u,$s) = @{$times{$prefixes{$d}.$t}};
printf " %-$colwidth[$i]s", format_times($r,$u,$s,$firstr);
$firstr = $r unless defined $firstr;
}
print "\n";
} }

View File

@ -105,7 +105,8 @@ get_var_from_env_or_config () {
env_var="$1" env_var="$1"
conf_sec="$2" conf_sec="$2"
conf_var="$3" conf_var="$3"
# $4 can be set to a default value conf_opts="$4" # optional
# $5 can be set to a default value


# Do nothing if the env variable is already set # Do nothing if the env variable is already set
eval "test -z \"\${$env_var+x}\"" || return eval "test -z \"\${$env_var+x}\"" || return
@ -116,18 +117,18 @@ get_var_from_env_or_config () {
if test -n "$GIT_PERF_SUBSECTION" if test -n "$GIT_PERF_SUBSECTION"
then then
var="$conf_sec.$GIT_PERF_SUBSECTION.$conf_var" var="$conf_sec.$GIT_PERF_SUBSECTION.$conf_var"
conf_value=$(git config -f "$GIT_PERF_CONFIG_FILE" "$var") && conf_value=$(git config $conf_opts -f "$GIT_PERF_CONFIG_FILE" "$var") &&
eval "$env_var=\"$conf_value\"" && return eval "$env_var=\"$conf_value\"" && return
fi fi
var="$conf_sec.$conf_var" var="$conf_sec.$conf_var"
conf_value=$(git config -f "$GIT_PERF_CONFIG_FILE" "$var") && conf_value=$(git config $conf_opts -f "$GIT_PERF_CONFIG_FILE" "$var") &&
eval "$env_var=\"$conf_value\"" && return eval "$env_var=\"$conf_value\"" && return


test -n "${4+x}" && eval "$env_var=\"$4\"" test -n "${5+x}" && eval "$env_var=\"$5\""
} }


run_subsection () { run_subsection () {
get_var_from_env_or_config "GIT_PERF_REPEAT_COUNT" "perf" "repeatCount" 3 get_var_from_env_or_config "GIT_PERF_REPEAT_COUNT" "perf" "repeatCount" "--int" 3
export GIT_PERF_REPEAT_COUNT export GIT_PERF_REPEAT_COUNT


get_var_from_env_or_config "GIT_PERF_DIRS_OR_REVS" "perf" "dirsOrRevs" get_var_from_env_or_config "GIT_PERF_DIRS_OR_REVS" "perf" "dirsOrRevs"
@ -136,6 +137,9 @@ run_subsection () {
get_var_from_env_or_config "GIT_PERF_MAKE_COMMAND" "perf" "makeCommand" get_var_from_env_or_config "GIT_PERF_MAKE_COMMAND" "perf" "makeCommand"
get_var_from_env_or_config "GIT_PERF_MAKE_OPTS" "perf" "makeOpts" get_var_from_env_or_config "GIT_PERF_MAKE_OPTS" "perf" "makeOpts"


get_var_from_env_or_config "GIT_PERF_REPO_NAME" "perf" "repoName"
export GIT_PERF_REPO_NAME

GIT_PERF_AGGREGATING_LATER=t GIT_PERF_AGGREGATING_LATER=t
export GIT_PERF_AGGREGATING_LATER export GIT_PERF_AGGREGATING_LATER


@ -143,10 +147,25 @@ run_subsection () {
set -- . "$@" set -- . "$@"
fi fi


codespeed_opt=
test "$GIT_PERF_CODESPEED_OUTPUT" = "true" && codespeed_opt="--codespeed"

run_dirs "$@" run_dirs "$@"
./aggregate.perl "$@"
if test -z "$GIT_PERF_SEND_TO_CODESPEED"
then
./aggregate.perl $codespeed_opt "$@"
else
json_res_file="test-results/$GIT_PERF_SUBSECTION/aggregate.json"
./aggregate.perl --codespeed "$@" | tee "$json_res_file"
send_data_url="$GIT_PERF_SEND_TO_CODESPEED/result/add/json/"
curl -v --request POST --data-urlencode "json=$(cat "$json_res_file")" "$send_data_url"
fi
} }


get_var_from_env_or_config "GIT_PERF_CODESPEED_OUTPUT" "perf" "codespeedOutput" "--bool"
get_var_from_env_or_config "GIT_PERF_SEND_TO_CODESPEED" "perf" "sendToCodespeed"

cd "$(dirname $0)" cd "$(dirname $0)"
. ../../GIT-BUILD-OPTIONS . ../../GIT-BUILD-OPTIONS