Francois Gouget : winetest/build-patterns: Add links to the test commits.

Alexandre Julliard julliard at winehq.org
Thu May 6 14:55:12 CDT 2021


Module: tools
Branch: master
Commit: ebbd6ac838bd3ef7bd9261959983eb49f933ad33
URL:    https://source.winehq.org/git/tools.git/?a=commit;h=ebbd6ac838bd3ef7bd9261959983eb49f933ad33

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Thu May  6 14:23:00 2021 +0200

winetest/build-patterns: Add links to the test commits.

This provides a link to the most likely culprit when a test starts
failing.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 winetest/build-patterns | 149 +++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 146 insertions(+), 3 deletions(-)

diff --git a/winetest/build-patterns b/winetest/build-patterns
index d16050d..eb152c8 100755
--- a/winetest/build-patterns
+++ b/winetest/build-patterns
@@ -31,7 +31,7 @@ sub BEGIN
     }
     unshift @INC, $1 if ($0 =~ m=^(/.*)/[^/]+$=);
 }
-use vars qw/$workdir $gitdir $patternbuilds $fixed_threshold/;
+use vars qw/$workdir $gitdir $gitweb $patternbuilds $fixed_threshold/;
 require "winetest.conf";
 
 my $name0=$0;
@@ -249,6 +249,9 @@ my %reports;
 # - name
 #   The uniquely identifying test name in the form 'module:unit'.
 #
+# - source
+#   The source file for that test unit.
+#
 # - colors
 #   A hashtable of colors indexed by failure count.
 #
@@ -303,6 +306,10 @@ my %reports;
 #
 #   - status
 #     A hashtable of test results indexed by the build name.
+#
+#   - commits
+#     A hashtable of the commit objects, indexed first buy build name and then
+#     by commit id.
 my %tests;
 
 foreach my $build (@sortedbuilds)
@@ -339,7 +346,7 @@ foreach my $build (@sortedbuilds)
     while (my $line = <$fh>)
     {
         chomp $line;
-        my ($testname, $_source, @items) = split / /, $line;
+        my ($testname, $source, @items) = split / /, $line;
         if ($testname !~ /:/)
         {
             error("found an invalid test unit name ($testname) in '$filename'\n");
@@ -347,7 +354,13 @@ foreach my $build (@sortedbuilds)
         }
         $build->{hastest}->{$testname} = 1;
         my $test = $tests{$testname};
-        $tests{$testname} = $test = { name => $testname } if (!$test);
+        if (!$test)
+        {
+            $tests{$testname} = $test = {
+                name => $testname,
+                source => $source,
+            };
+        }
 
         foreach my $statreps (@items)
         {
@@ -604,6 +617,80 @@ foreach my $testname (keys %tests)
 }
 
 
+#
+# Collect the related commits
+#
+
+# A hashtable of commit objects indexed by their Git commit id.
+# Each object has the following fields:
+#
+# - index
+#   An integer recording the commit order, with 0 for the newest commit and
+#   negative numbers for the others.
+#
+# - id
+#   The Git commit id.
+#
+# - build
+#   The Git commit id of the first build after this commit.
+#
+# - summary
+#   The commit summary.
+my %commits;
+
+# A hashtable mapping filenames to a set of matching commit objects indexed by
+# Git commit id.
+my %path2commits;
+
+my $cmd = "git log --pretty=oneline --name-status $sortedbuilds[0]->{name}^..$sortedbuilds[-1]->{name}";
+if (open(my $fh, "-|", $cmd))
+{
+    my $index = 0;
+    my ($commit, $build);
+    foreach my $line (<$fh>)
+    {
+        chomp $line;
+        if ($line =~ /^([0-9a-f]{40}) (.*)$/)
+        {
+            my ($commitid, $summary) = ($1, $2);
+            # The commits are returned in reverse chronological order. So the
+            # build commit comes first, then the commits that got into it.
+            $build = $builds{$commitid} if ($builds{$commitid});
+            if (!$build)
+            {
+                error("$commit does not belong to any build\n");
+                next;
+            }
+            $commits{$commitid} = $commit = {
+                index => $index--,
+                id => $commitid,
+                build => $build,
+                summary => $summary,
+            };
+        }
+        elsif ($line =~ /^R[0-9]+\t(\S+)\t(\S+)$/ or $line =~ /^.\t(\S+)$/)
+        {
+            my ($path1, $path2) = ($1, $2);
+            if (!$commit)
+            {
+                error("did not find a commit before: $line\n");
+                next;
+            }
+            foreach my $filename ($path1, $path2)
+            {
+                next if (!$filename);
+                $path2commits{$filename}->{$commit->{id}} = $commit;
+            }
+        }
+        else
+        {
+            error("found an unsupported line type in '$cmd' output: $line\n");
+        }
+    }
+    close($fh);
+}
+
+
 #
 # Compute color gradients
 #
@@ -830,6 +917,54 @@ sub write_pattern_line($$$)
     print $html "</div> $label\n";
 }
 
+sub index2symbol($)
+{
+    my ($index) = @_;
+    my @symbols = ("0".."9", "a".."z", "A".."Z");
+    return $symbols[$index % 62];
+}
+
+sub write_commits($$)
+{
+    my ($html, $test) = @_;
+
+    print $html "<div class='pattern'>";
+    my $i = 0;
+    my @symbuilds;
+    foreach my $build (@sortedbuilds)
+    {
+        if ($test->{commits}->{$build->{name}})
+        {
+            my $symbol = index2symbol($i++);
+            push @symbuilds, [$symbol, $build];
+            printf $html "<a title='%s'>%s</a>",
+                         short_date($build->{date}), $symbol;
+        }
+        else
+        {
+            print $html " ";
+        }
+    }
+    print $html "</div> <i>← potentially related commits</i>\n";
+
+    if (@symbuilds)
+    {
+        print $html "\n";
+        foreach my $symbuild (@symbuilds)
+        {
+            my $first = 1;
+            my ($symbol, $build) = @$symbuild;
+            my $buildcommits = $test->{commits}->{$build->{name}};
+            foreach my $commit (sort { $a->{index} <=> $b->{index} } values %$buildcommits)
+            {
+                print $html $first ? "$symbol." : "  ";
+                $first = undef;
+                printf $html " <a href='%s/commitdiff/%s' title='%s'>%s</a>\n", $gitweb, $commit->{id}, short_date($build->{date}), $commit->{summary};
+            }
+        }
+    }
+}
+
 sub write_pattern($$$)
 {
     my ($html, $test, $pagereports) = @_;
@@ -843,6 +978,7 @@ sub write_pattern($$$)
         next if (!$test->{testreports}->{$reportdir}->{failed});
         write_pattern_line($html, $test, $reportdir);
     }
+    write_commits($html, $test) if (%{$test->{commits}});
 }
 
 sub write_patterns_list($$$$)
@@ -917,6 +1053,7 @@ EOF
     {
         my $test = $tests{$testname};
         $test->{colors} = {};
+        $test->{commits} = {};
 
         my $first = @sortedbuilds;
         my $last = -1;
@@ -965,6 +1102,12 @@ EOF
                      %{$test->{newmodes}} ? "newmode" :
                      "regular";
         push @{$lists{$listid}->{testnames}}, $testname;
+
+        foreach my $commit (values %{$path2commits{$test->{source}}})
+        {
+            my $buildname = $commit->{build}->{name};
+            $test->{commits}->{$buildname}->{$commit->{id}} = $commit;
+        }
     }
 
     # Generate the lists index (and up test unit links)




More information about the wine-cvs mailing list