[tools 2/2] winetest: Provide more detailed status information on index pages.

Francois Gouget fgouget at codeweavers.com
Wed Apr 21 09:26:43 CDT 2021


This requires dissect to store more detailed status information in the
summary.txt file. Then gather can convert these into more specific cell
labels and descriptions.

Signed-off-by: Francois Gouget <fgouget at codeweavers.com>
---
One side effect is that the tests skipped due to a missing entry point 
are not hidden from the index pages. I think it's better that way 
but that could be changed if desired.

The new gather script is compatible with the summary.txt files generated 
by the old dissect script. So it's ok to simply update the scripts and 
wait for the old pages to expire.

But it's also possible to regenerate all the pages to accelerate the 
process and benefit from the extra details right now. The detailed 
information will also be used to build the pattern pages so it would 
also help with that.

First to test things out one can run the new scripts on a single report 
as so:

  cd winetest/data
  dissect --update `pwd`/788fd4ee44fc9877b01888fdd3cd72b9ac88228e/report
  gather --update `pwd`/788fd4ee44fc9877b01888fdd3cd72b9ac88228e

  xdg-open https://test.winehq.org/data/788fd4ee44fc9877b01888fdd3cd72b9ac88228e/index_Win1507+.html


If that's satisfactory refreshing everything is just a matter of 
industrialising the process:
  
  cd winetest/data
  find `pwd`/ -name report -print | \
      nice xargs -P8 -n 1 dissect --update

  find `pwd`/ -name total.txt -print | \
      while read p;do dirname $p;done | \
      nice xargs -P8 -n 1 gather --update

Don't forget to adjust the path to dissect and gather. Ajust -P8 for the 
desired level of parallelism. Here refreshing my test.winehq.org mirror 
takes under 5 minutes.
---
 winetest/dissect | 43 +++++++++++++++++++----
 winetest/gather  | 91 ++++++++++++++++++++++++++++++++----------------
 2 files changed, 98 insertions(+), 36 deletions(-)

diff --git a/winetest/dissect b/winetest/dissect
index ce3329ea6..0ae7251f5 100755
--- a/winetest/dissect
+++ b/winetest/dissect
@@ -44,7 +44,7 @@ $name0 =~ s+^.*/++;
 # We support reports version 4 and up
 my $minimum_report_version=4;
 # And we generate summary files version 4
-my $summary_version=4;
+my $summary_version=5;
 
 
 #
@@ -248,6 +248,8 @@ open IN, "<:raw", $report or mydie "could not open '$report' for reading: $!";
 # summary.txt file format:
 # Version <version>
 # - <dll> - missing - - - -
+# - <dll> - missing(dll|entrypoint|ordinal|sxs) - - - -
+# - <dll> - (loaderror<code>|native|stub) - - - -
 # - <dll> - skipped - - - -
 # - <dll> <unit> skipped - - - <source>
 # - <dll> <unit> failed (258|crash) - - <source>
@@ -351,7 +353,7 @@ if (!defined $plid or !defined $major or !defined $minor or !defined $product) {
 my @idmatch = (
     # Describes how to match a platform's version information
     # with a dissect platform id:
-    # dissect id  plid  major  minor  build  product  prediluvian
+    # dissect_id  plid  major  minor  build  product prediluvian
     [ "95",          1,     4,     0, undef, undef,  1 ],
     [ "98",          1,     4,    10, undef, undef,  1 ],
     [ "me",          1,     4,    90, undef, undef,  1 ],
@@ -447,10 +449,37 @@ while ($line = <IN> || "")
     last if ($line !~ /^\s+([^ =]+)=(.*?)\r?$/);
     my ($dll, $info) = ($1, $2);
     $dllinfo{$dll} = { version => $info };
-    if ($info =~ /^dll is (?:missing|native|a stub)/ or
-        $info =~ /^(?:(?:load|version) error \d+|version not (?:found|present))/ or
-        # For compatibility with old WineTest versions
-        $info =~ /^(?:failed|unknown|version not available)$/)
+    if ($info =~ /^dll is missing an ordinal/)
+    {
+        print SUM "- $dll - missingordinal - - - -\n";
+    }
+    elsif ($info =~ /^dll is missing an entrypoint/)
+    {
+        print SUM "- $dll - missingentrypoint - - - -\n";
+    }
+    elsif ($info =~ /^dll is missing the requested side-by-side version/)
+    {
+        print SUM "- $dll - missingsxs - - - -\n";
+    }
+    elsif ($info =~ /^dll is missing/)
+    {
+        print SUM "- $dll - missingdll - - - -\n";
+    }
+    elsif ($info =~ /^dll is native/)
+    {
+        print SUM "- $dll - native - - - -\n";
+    }
+    elsif ($info =~ /^dll is a stub/)
+    {
+        print SUM "- $dll - stub - - - -\n";
+    }
+    elsif ($info =~ /^load error \d+$/)
+    {
+        $info =~ s/ //g;
+        print SUM "- $dll - $info - - - -\n";
+    }
+    elsif (# For compatibility with old WineTest versions
+           $info =~ /^(?:failed|unknown|version not available)$/)
     {
         print SUM "- $dll - missing - - - -\n";
     }
@@ -459,6 +488,8 @@ while ($line = <IN> || "")
         print SUM "- $dll - skipped - - - -\n";
         mydie "too many dlls skipped by user request (>$maxuserskips at $dll)" if ++$skipped_units > $maxuserskips;
     }
+    # The version errors don't prevent the test from running so do not report
+    # them.
 }
 
 
diff --git a/winetest/gather b/winetest/gather
index 456fa0b5d..2a23f0a59 100755
--- a/winetest/gather
+++ b/winetest/gather
@@ -39,7 +39,7 @@ my $name0=$0;
 $name0 =~ s+^.*/++;
 
 # We support summary files version 4 and up
-my $summary_version=4;
+my $summary_version="[45]";
 
 
 #
@@ -106,7 +106,8 @@ sub short_date($)
 #  tag           The report's tag.
 #  dir           The directory containing the report data (log files, etc).
 #  group         A reference to the group the report belongs to.
-#  dllmissing    A hash of the missing dlls for that system.
+#  missing       A hash of the reason why some test results are missing,
+#                  indexed by the test unit name.
 #  filelimit     The name of the last test that was run before the report file
 #                  size limit was reached.
 #  <testname>    Maps the test names to a structure containing the individual
@@ -357,8 +358,9 @@ foreach my $file (glob "$builddir/*/summary.txt") {
         error("could not open '$file' for reading: $!\n");
         next;
     }
-    if (($_ = <TEST>) ne "Version $summary_version\n") {
-        error("wrong header in '$file': $_\n");
+    my $version = <TEST>;
+    if ($version !~ /^Version $summary_version\n$/) {
+        error("wrong header in '$file': $version\n");
         close TEST;
         next;
     }
@@ -371,12 +373,18 @@ foreach my $file (glob "$builddir/*/summary.txt") {
 
         if ($count eq "missing")
         {
-            $report->{dllmissing}->{$dll} = "dll missing";
+            # For compatibility with old summary.txt versions
+            $report->{missing}->{$dll} = "missingdll";
+            next;
+        }
+        if ($count =~ /^(?:missing|loaderror|native|stub)/)
+        {
+            $report->{missing}->{$dll} = $count;
             next;
         }
         if ($unit eq "-" and $count eq "skipped")
         {
-            $report->{dllmissing}->{$dll} = "skipped";
+            $report->{missing}->{$dll} = "skipped";
             next;
         }
 
@@ -444,11 +452,11 @@ sub merge_status($$)
         $group_result->{status} = $result->{status};
     } elsif ($result->{status} eq "skipped") {
         ; # Nothing to do
-    } elsif ($group_result->{status} eq "dll missing" and
+    } elsif ($group_result->{status} =~ /^missing/ and
              $result->{status} eq "run") {
         $group_result->{status} = "run";
     } elsif ($group_result->{status} eq "run" and
-             $result->{status} eq "dll missing") {
+             $result->{status} =~ /^missing/) {
         ; # Nothing to do
     } elsif ($group_result->{status} ne $result->{status}) {
         $group_result->{status} = "mixed";
@@ -474,17 +482,18 @@ foreach my $group (@groups) {
             if (!exists $report->{$testname}) {
                 my ($dll, $unit) = split(/:/, $testname);
                 my $filelimit = $report->{filelimit};
-                if (exists $report->{dllmissing}->{$dll}) {
-                    # Mark this test as missing because of a missing dll
-                    $report->{$testname} = { status => $report->{dllmissing}->{$dll},
+                if (exists $report->{missing}->{$dll}) {
+                    # Record the reason why this test is missing
+                    $report->{$testname} = { status => $report->{missing}->{$dll},
                                              count  => [ 1, 1 ],
                                              skips  => [ 1, 1 ]
                                            };
                 } elsif (defined $filelimit && $testname gt $filelimit) {
                     # Mark this test as missing because of a partial report file
-                    $report->{$testname}->{status} = "filelimit";
+                    $report->{$testname}->{status} = "truncated";
                 } else {
-                    # Mark this test as missing for an unknown reason
+                    # Mark this test as missing for an unknown reason (typically
+                    # the start & done lines where unrecognizable)
                     $report->{$testname}->{status} = "missing";
                 }
             }
@@ -496,8 +505,7 @@ foreach my $group (@groups) {
             merge_status( $test_results{$testname}->{$group->{name}}, $report->{$testname} );
         }
         $group->{$testname} = $group_result;
-        if ($group_result->{status} eq "dll missing" or
-            $group_result->{status} eq "skipped" or
+        if ($group_result->{status} =~ /^(?:missing(?:dll|sxs)|skipped|stub)$/ or
             ($group_result->{status} eq "run" and
              $group_result->{errors}->[1] == 0 and
              $group_result->{todos}->[1] == 0 and
@@ -521,7 +529,8 @@ foreach my $group (@groups) {
         $report->{runs} = 0;
         foreach my $testname (sort keys %alltests) {
             my $result = $report->{$testname};
-            if ($result->{status} !~ /^(?:dll missing|run|skipped)$/ or
+            # Treat missing APIs, --list errors and native dlls as failures
+            if ($result->{status} !~ /^(?:run|missing(?:dll|sxs)?|skipped|stub)$/ or
                 ($result->{status} eq "run" and
                  $result->{errors}->[1] != 0))
             {
@@ -532,7 +541,7 @@ foreach my $group (@groups) {
             {
                 $report->{todos}++;
             }
-            if ($result->{status} !~ /^(?:dll missing|skipped)$/)
+            if ($result->{status} !~ /^(?:loaderror|missing|native|skipped|stub)/)
             {
                 $report->{runs}++;
             }
@@ -652,7 +661,7 @@ sub get_result_class($)
         $class .= " also-skip" if ($result->{skips}->[1]);
         return "result $class";
     }
-    if ($result->{status} eq "dll missing" or $result->{status} eq "skipped")
+    if ($result->{status} =~ /^(?:missing(?:dll|sxs)|skipped|stub)$/)
     {
         return "result pass also-skip";
     }
@@ -681,18 +690,31 @@ sub get_result_title($$)
         $title .= ", $mm_skips skips" if ($mm_skips);
         return $title;
     }
-    if ($result->{status} eq "dll missing")
-    {
-        my ($dll, $unit) = split(/:/, $testname);
-        $dll.=".dll" if ($dll !~ /\./);
-        return "No tests run as $dll is not present on this system";
-    }
-    if ($result->{status} eq "skipped") { return "Test skipped by user request"; }
-    if ($result->{status} eq "filelimit") { return "Test is missing because of a partial report file"; }
-    if ($result->{status} eq "missing") { return "Test did not run for an unknown reason"; }
     if ($result->{status} eq "mixed") { return "Mixed results"; }
     if ($result->{status} eq "crash") { return "Test crashed"; }
     if ($result->{status} eq "258") { return "Test timed out"; }
+    if ($result->{status} eq "skipped") { return "Skipped by user request"; }
+    if ($result->{status} eq "truncated") { return "The report was truncated"; }
+
+    my ($dll, $unit) = split(/:/, $testname);
+    $dll.=".dll" if ($dll !~ /\....?$/);
+    if ($result->{status} =~ /^missing(.*)$/)
+    {
+        my $reason = $1;
+        return ($reason eq "dll") ? "Not run because $dll is missing" :
+            ($reason eq "entrypoint") ? "Not run because a dependency ($dll?) is missing an entry point" :
+            ($reason eq "ordinal") ? "Not run because a dependency ($dll?) is missing an ordinal" :
+            ($reason eq "sxs") ? "Not run because a dependency ($dll?) is missing the requested side-by-side version" :
+            "Not run for an unknown reason";
+    }
+    if ($result->{status} =~ /^loaderror(.*)$/)
+    {
+        my $code = $1;
+        return "Not run because getting the test list ".
+                ($code eq "258" ? "timed out" : "failed with error $code");
+    }
+    if ($result->{status} eq "native") { return "Not run because $dll is a native Windows dll (not allowed for Wine tests)"; }
+    if ($result->{status} eq "stub") { return "Not run because $dll is a stub Windows dll"; }
     return "";
 }
 
@@ -735,18 +757,27 @@ sub singletest($$$) {
              !$result->{errors}->[1] ? $result->{todos}->[1] :
              "$result->{errors}->[1]+$result->{todos}->[1]";
     }
+    elsif ($status =~ /^loaderror/)
+    {
+        $msg = "no list";
+    }
     else
     {
         my %status2label = (
             missing           => "not run",
-            "dll missing"     => "n/a",
+            missingdll        => "n/a",
+            missingsxs        => "version",
+            missingentrypoint => "api",
+            missingordinal    => "ordinal",
+            stub              => "stub",
             skipped           => "skipped",
+            native            => "native",
             crash             => "crashed",
             258               => "timeout",
             mixed             => "mixed",
-            filelimit         => "truncated",
+            truncated         => "truncated",
         );
-        $msg = $status2label{$status} || "failed";
+        $msg = $status2label{$status} || "unknown";
     }
     $title = join(" | ", $prefix, $title);
     printf OUT "      <td class=\"%s\"><a %s %s>%s</a></td>\n",
-- 
2.20.1



More information about the wine-devel mailing list