Francois Gouget : winetest/build-patterns: Identify commits indirectly related to a test unit.

Alexandre Julliard julliard at winehq.org
Tue May 11 16:32:48 CDT 2021


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

Author: Francois Gouget <fgouget at codeweavers.com>
Date:   Tue May 11 18:07:43 2021 +0200

winetest/build-patterns: Identify commits indirectly related to a test unit.

Some test units depend on files other than the main C source file such
as resource file, JavaScript source, etc. Patches modifying these files
could also impact the test results.
Also tests may fail in Wine because of modifications to the Wine module
rather than to the test.
So report patches to any of these components, but hide the more indirect
and numerous ones.

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

---

 winetest/build-patterns | 144 +++++++++++++++++++++++++++++++++++++++---------
 winetest/report.css     |   9 +++
 2 files changed, 127 insertions(+), 26 deletions(-)

diff --git a/winetest/build-patterns b/winetest/build-patterns
index eb152c8..10cc021 100755
--- a/winetest/build-patterns
+++ b/winetest/build-patterns
@@ -312,6 +312,9 @@ my %reports;
 #     by commit id.
 my %tests;
 
+# A set containing the test units source files.
+my %testsources;
+
 foreach my $build (@sortedbuilds)
 {
     my $filename = "data/$build->{name}/testresults.txt";
@@ -360,6 +363,7 @@ foreach my $build (@sortedbuilds)
                 name => $testname,
                 source => $source,
             };
+            $testsources{$source} = 1;
         }
 
         foreach my $statreps (@items)
@@ -679,7 +683,34 @@ if (open(my $fh, "-|", $cmd))
             foreach my $filename ($path1, $path2)
             {
                 next if (!$filename);
-                $path2commits{$filename}->{$commit->{id}} = $commit;
+
+                if ($filename =~ m~((?:dlls|programs)/([^/]+))/tests/([^/]+)\.c$~)
+                {
+                    my ($moddir, $module, $unit) = ($1, $2, $3);
+                    if ($tests{"$module:$unit"})
+                    {
+                        $path2commits{$filename}->{$commit->{id}} = $commit;
+                    }
+                    else
+                    {
+                        # This C file is not the source for a test unit
+                        # so it could impact any test in that directory
+                        $path2commits{"$moddir/tests"}->{$commit->{id}} = $commit;
+                    }
+                }
+                elsif ($filename =~ m~((?:dlls|programs)/[^/]+)/tests/~)
+                {
+                    my $moddir = $1;
+                    # This is not not a C file so it could impact any test in
+                    # that directory
+                    $path2commits{"$moddir/tests"}->{$commit->{id}} = $commit;
+                }
+                elsif ($filename =~ m~((?:dlls|programs)/[^/]+)/~)
+                {
+                    my $moddir = $1;
+                    $path2commits{$moddir}->{$commit->{id}} = $commit;
+                }
+                # ignore changes to other files
             }
         }
         else
@@ -924,44 +955,85 @@ sub index2symbol($)
     return $symbols[$index % 62];
 }
 
+my %scope_descs = (
+    U => "Modifies this test",
+    t => "Modifies a test resource (maybe for another test)",
+    m => "Modifies the module",
+);
+
 sub write_commits($$)
 {
     my ($html, $test) = @_;
 
     print $html "<div class='pattern'>";
     my $i = 0;
-    my @symbuilds;
+    my (@udescs, @tmdescs);
     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
+        my $buildcommits = $test->{commits}->{$build->{name}};
+        if (!$buildcommits)
         {
             print $html " ";
+            next;
         }
-    }
-    print $html "</div> <i>← potentially related commits</i>\n";
 
-    if (@symbuilds)
-    {
-        print $html "\n";
-        foreach my $symbuild (@symbuilds)
+        my $symbol = index2symbol($i++);
+        my ($ucount, $tcount, $tmcount) = (0, 0, 0);
+        foreach my $commit (sort { $a->{index} <=> $b->{index} } values %$buildcommits)
         {
-            my $first = 1;
-            my ($symbol, $build) = @$symbuild;
-            my $buildcommits = $test->{commits}->{$build->{name}};
-            foreach my $commit (sort { $a->{index} <=> $b->{index} } values %$buildcommits)
+            my $scope = "m";
+            if ($path2commits{$test->{source}}->{$commit->{id}})
             {
-                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};
+                $scope = "U";
+            }
+            else
+            {
+                my $testdir = $test->{source};
+                $testdir =~ s~/[^/]+$~~;
+                if ($path2commits{$testdir}->{$commit->{id}})
+                {
+                    $scope = "t";
+                    $tcount++;
+                }
+            }
+
+            my $desc = sprintf(" <a class='commit%s' title='%s'>%s</a> <a href='%s/commitdiff/%s' title='%s'>%s</a>",
+                               $scope, $scope_descs{$scope}, $scope,
+                               $gitweb, $commit->{id},
+                               short_date($build->{date}),
+                               $commit->{summary});
+            if ($scope eq "U")
+            {
+                push @udescs, ($ucount ? "\n  " : "\n$symbol."), $desc;
+                $ucount++;
+            }
+            else
+            {
+                push @tmdescs, ($tmcount ? "  " : "$symbol."), $desc, "\n";
+                $tmcount++;
             }
         }
+        push @udescs, " <i>[+$tmcount in details]</i>" if ($ucount and $tmcount);
+
+        my @impacts;
+        push @impacts, "this test" if ($ucount);
+        push @impacts, "test resources" if ($tcount);
+        push @impacts, "the module" if ($tmcount > $tcount);
+        my $scope = $ucount ? "U" : $tcount ? "t" : "m";
+        my $count = $ucount + $tmcount;
+        printf $html "<a class='commit%s' title='%s : %s commit%s to %s'>%s</a>",
+                     $scope, short_date($build->{date}),
+                     $count, $count > 1 ? "s" : "",
+                     join(", ", @impacts), $symbol;
+    }
+    print $html "</div> <i>← potentially related commits</i>\n";
+
+    print $html @udescs if (@udescs);
+    if (@tmdescs)
+    {
+        print $html "<details><summary>Test and module patch details</summary>";
+        print $html @tmdescs;
+        print $html "</details>";
     }
 }
 
@@ -1012,6 +1084,18 @@ sub write_patterns_list($$$$)
     }
 }
 
+sub add_path_commits($$)
+{
+    my ($commits, $path) = @_;
+
+    return if (!$path2commits{$path});
+    foreach my $commit (values %{$path2commits{$path}})
+    {
+        my $buildname = $commit->{build}->{name};
+        $commits->{$buildname}->{$commit->{id}} = $commit;
+    }
+}
+
 sub write_patterns_page($$$)
 {
     my ($pagereports, $subpage, $title) = (@_);
@@ -1055,6 +1139,7 @@ EOF
         $test->{colors} = {};
         $test->{commits} = {};
 
+        my $has_wine_failures;
         my $first = @sortedbuilds;
         my $last = -1;
         my $fixed = 1;
@@ -1073,6 +1158,8 @@ EOF
                           $testreport->{first};
             $last = $replast if ($replast > $last);
 
+            $has_wine_failures ||= $reports{$reportdir}->{is_wine};
+
             for my $i (0.. at sortedbuilds-1)
             {
                 my $build = $sortedbuilds[$i];
@@ -1103,10 +1190,15 @@ EOF
                      "regular";
         push @{$lists{$listid}->{testnames}}, $testname;
 
-        foreach my $commit (values %{$path2commits{$test->{source}}})
+        add_path_commits($test->{commits}, $test->{source});
+        # Also take into account commits to test resources
+        my $moddir = $test->{source};
+        $moddir =~ s~/tests/[^/]+$~~;
+        add_path_commits($test->{commits}, "$moddir/tests");
+        if ($has_wine_failures)
         {
-            my $buildname = $commit->{build}->{name};
-            $test->{commits}->{$buildname}->{$commit->{id}} = $commit;
+            # In Wine any patch to the module could have caused the failures
+            add_path_commits($test->{commits}, $moddir);
         }
     }
 
diff --git a/winetest/report.css b/winetest/report.css
index 2cc4663..4c91972 100644
--- a/winetest/report.css
+++ b/winetest/report.css
@@ -111,3 +111,12 @@ div.pattern :hover   { color: black; text-decoration: underline; }
 .patL { /* error while getting the test list */
     background-color: #80aaff;
 }
+
+.commitU {
+    font-weight: bold;
+}
+.committ {
+}
+.commitm {
+    font-style: italic;
+}




More information about the wine-cvs mailing list