gdb/testsuite: Detect and warn about duplicate test names
authorAndrew Burgess <andrew.burgess@embecosm.com>
Thu, 23 Apr 2020 14:19:15 +0000 (15:19 +0100)
committerAndrew Burgess <andrew.burgess@embecosm.com>
Mon, 11 May 2020 21:27:04 +0000 (22:27 +0100)
Building on the previous commit, this patch detects when two tests
have the same test name and causes Dejagnu to print a new result type
'# of duplicate test names' in the result summary.  A line starting
with 'DUPLICATE: ' is also added to the gdb.sum and gdb.log files.

The DUPLICATE markers will be printed the second time a duplicate test
name is seen, and every time after that.  So you might see:

  PASS: gdb.base/sometest.exp: foo
  PASS: gdb.base/sometest.exp: bar
  PASS: gdb.base/sometest.exp: foo
  DUPLICATE: gdb.base/sometest.exp: foo
  PASS: gdb.base/sometest.exp: baz
  PASS: gdb.base/sometest.exp: foo
  DUPLICATE: gdb.base/sometest.exp: foo

However, the results will report a duplicate count of 1, indicating
that just one test name (foo) was duplicated.

Currently if the tests are run in parallel mode the new result type is
not merged into the combined summary file so users will need to run in
non-parallel mode to check this result.  Similarly, the 'DUPLICATE: '
markers will not be merged into the final gdb.sum file.  A later
commit will fix this.

gdb/testsuite/ChangeLog:

* lib/check-test-names.exp (all_test_names): New module variable.
(counts): Add 'duplicates' field.
(_check_duplicates): New procedure.
(check): Also check for duplicates.
(do_log_summary): Print duplicates count.
(do_reset_vars): Reset counter for duplicate test names, and
discard all know test names.

gdb/testsuite/ChangeLog
gdb/testsuite/lib/check-test-names.exp

index 0806b62d7ff34996bbf497bd68d1c1801235aed6..29b6636b7ce5c5cb77a403c52d1f5875cf051c42 100644 (file)
@@ -1,3 +1,13 @@
+2020-05-11  Andrew Burgess  <andrew.burgess@embecosm.com>
+
+       * lib/check-test-names.exp (all_test_names): New module variable.
+       (counts): Add 'duplicates' field.
+       (_check_duplicates): New procedure.
+       (check): Also check for duplicates.
+       (do_log_summary): Print duplicates count.
+       (do_reset_vars): Reset counter for duplicate test names, and
+       discard all know test names.
+
 2020-05-11  Andrew Burgess  <andrew.burgess@embecosm.com>
 
        * lib/gdb.exp: Include check-test-names.exp library.
index addce4b8242073e33a3ac8556aca00990954a63b..4c0fde6e4ea92a05b386719d0ff065129ec17ce6 100644 (file)
 # to compare results between two runs of GDB from different trees.
 
 namespace eval ::CheckTestNames {
-    # An associative array of counts of tests that include a path in their
-    # test name.  There are two counts, 'count', which counts occurrences
-    # within a single variant run, and 'total', which counts across all
-    # variants.
+    # An associative array of all test names to the number of times each
+    # name is seen.  Used to detect duplicate test names.
+    variable all_test_names
+    array set all_test_names {}
+
+    # An associative array of counts of tests that either include a path in
+    # their test name, or have a duplicate test name.  There are two counts
+    # for each issue, 'count', which counts occurrences within a single
+    # variant run, and 'total', which counts across all variants.
     variable counts
     array set counts {}
-    foreach nm {paths} {
+    foreach nm {paths duplicates} {
        set counts($nm,count) 0
        set counts($nm,total) 0
     }
@@ -54,6 +59,25 @@ namespace eval ::CheckTestNames {
        return false
     }
 
+    # Check if MESSAGE is a duplicate, if it is then increment the
+    # duplicates counter and return true, otherwise, return false.
+    proc _check_duplicates { message } {
+       variable all_test_names
+
+       # Initialise a count, or increment the count for this test name.
+       if {![info exists all_test_names($message)]} {
+           set all_test_names($message) 0
+       } else {
+           if {$all_test_names($message) == 0} {
+               inc_count duplicates
+           }
+           incr all_test_names($message)
+           return true
+       }
+
+       return false
+    }
+
     # Remove the leading Dejagnu status marker from MESSAGE, and
     # return the remainder of MESSAGE.  A status marker is something
     # like 'PASS: '.  It is assumed that MESSAGE does contain such a
@@ -82,6 +106,10 @@ namespace eval ::CheckTestNames {
        if [ _check_paths $message ] {
            clone_output "PATH: $message"
        }
+
+       if [ _check_duplicates $message ] {
+           clone_output "DUPLICATE: $message"
+       }
     }
 
     # If COUNT is greater than zero, disply PREFIX followed by COUNT.
@@ -109,17 +137,21 @@ namespace eval ::CheckTestNames {
 
        maybe_show_count "# of paths in test names\t" \
            $counts(paths,$which)
+       maybe_show_count "# of duplicate test names\t" \
+           $counts(duplicates,$which)
     }
 
     # Rename Dejagnu's reset_vars procedure, and create do_reset_vars to
     # replace it.  We arrange to have do_reset_vars called later.
     rename ::reset_vars reset_vars
     proc do_reset_vars {} {
+       variable all_test_names
        variable counts
 
        CheckTestNames::reset_vars
 
-       foreach nm {paths} {
+       unset all_test_names
+       foreach nm {paths duplicates} {
            set counts($nm,count) 0
        }
     }