dg-cmp-results.sh 5.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213
  1. #!/bin/bash
  2. # Copyright (C) 2006, 2008 Free Software Foundation
  3. #
  4. # Analyze changes in GCC DejaGNU test logs for binutils, gcc, gdb, etc.
  5. # Original version written in 2005 by James Lemke <jwlemke@wasabisystems.com>.
  6. #
  7. # See usage() below.
  8. usage () {
  9. cat <<EOF >&2
  10. Usage:
  11. dg-cmp-results.sh [-v] [-v] [-v] <variant-name> <old-file> <new-file>
  12. <variant-name> names the desired variant, "/" must be written as "\/".
  13. Use the empty string ("") for the first variant in each file.
  14. Output is to stdout.
  15. Non-verbose output is degradation info like PASS->FAIL.
  16. -v adds improvement info like FAIL->PASS.
  17. -v -v adds info like tests that are no longer run.
  18. -v -v -v adds info for tests that have not changed status.
  19. -v -v -v -v is used for debugging.
  20. EOF
  21. }
  22. verbose=0
  23. while test "$1" = "-v"; do
  24. verbose=`expr $verbose + 1`
  25. shift
  26. done
  27. if test $# -ne 3 ; then
  28. usage
  29. exit 1
  30. fi
  31. if test ! -f "$2"; then
  32. echo "unable to open $2" >&2
  33. exit 1
  34. fi
  35. if test ! -f "$3"; then
  36. echo "unable to open $3" >&2
  37. exit 1
  38. fi
  39. # Command differences for various platforms.
  40. case `uname -s` in
  41. Darwin|NetBSD)
  42. E=-E # sed
  43. ;;
  44. *)
  45. E=-r # sed
  46. ;;
  47. esac
  48. # sections are identified by separator lines beginning with '\t\t==='.
  49. # section 0 identifies run date, target, and host.
  50. # section 1 and subsequent contain test data for a target variant.
  51. # -skip to /^Running target/ and use that line to identify the variant.
  52. # -subsequent lines contain the result data. They begin with:
  53. # '(PASS|FAIL|XFAIL|XPASS|UNTESTED|UNSUPPORTED|UNRESOLVED):'
  54. VARIANT="$1"
  55. OFILE="$2"
  56. OBASE=`basename "$2"`
  57. NFILE="$3"
  58. NBASE=`basename "$3"`
  59. TMPDIR=${TMPDIR:-/tmp}
  60. echo "dg-cmp-results.sh: Verbosity is ${verbose}, Variant is \"${VARIANT}\""
  61. echo
  62. header="^Running target $VARIANT"
  63. temp=`grep "$header" $OFILE`
  64. if test -z "$temp"; then
  65. echo "Error: variant \"$VARIANT\" not found in $OFILE."
  66. exit 1
  67. fi
  68. temp=`grep "$header" $NFILE`
  69. if test -z "$temp"; then
  70. echo "Error: variant \"$VARIANT\" not found in $NFILE."
  71. exit 1
  72. fi
  73. unset temp
  74. # Copy out the old file's section 0.
  75. echo "Older log file: $OFILE"
  76. sed $E -e '/^[[:space:]]+===/,$d' $OFILE
  77. # Copy out the new file's section 0.
  78. echo "Newer log file: $NFILE"
  79. sed $E -e '/^[[:space:]]+===/,$d' $NFILE
  80. # Create a temporary file from the old file's interesting section.
  81. sed $E -e "/$header/,/^[[:space:]]+===.*Summary ===/!d" \
  82. -e '/^[A-Z]+:/!d' \
  83. -e '/^(WARNING|ERROR):/d' \
  84. -e 's/\r$//' \
  85. -e 's/^/O:/' \
  86. $OFILE |
  87. sort -s -t : -k 3b - \
  88. >$TMPDIR/o$$-$OBASE
  89. # Create a temporary file from the new file's interesting section.
  90. sed $E -e "/$header/,/^[[:space:]]+===.*Summary ===/!d" \
  91. -e '/^[A-Z]+:/!d' \
  92. -e '/^(WARNING|ERROR):/d' \
  93. -e 's/\r$//' \
  94. -e 's/^/N:/' \
  95. $NFILE |
  96. sort -s -t : -k 3b - \
  97. >$TMPDIR/n$$-$NBASE
  98. # Merge the two files, then compare adjacent lines.
  99. # Comparison is complicated by tests that may be run multiple times.
  100. # If that case, we assume that the order is the same in both files.
  101. cat <<EOF >compare-$$.awk
  102. BEGIN {
  103. FS = ":"
  104. queue1 = 1; queueN = 0; status[queue1] = ""; name[queue1] = ""
  105. verbose = verbose + 0 # Make sure it's defined.
  106. }
  107. # FIFO circular queue
  108. function push(st, nm) {
  109. queueN += 1; status[queueN] = st; name[queueN] = nm
  110. }
  111. function peek() {
  112. result = 0
  113. if (queueN >= queue1) result = queue1
  114. return result
  115. }
  116. function drop() {
  117. queue1 += 1
  118. if (queue1 > queueN) { queue1 = 1; queueN = 0; }
  119. }
  120. function compare(st, nm) {
  121. old = peek()
  122. if (old == 0) {
  123. # This new test wasn't run last time.
  124. if(st == "FAIL" || st == "UNRESOLVED" || verbose >= 2) {
  125. # New test fails or we want all changes
  126. printf("NA->%s:%s\n", st, nm)
  127. }
  128. }
  129. else {
  130. # Compare this new test to the first queued old one.
  131. if (verbose >= 4) {
  132. printf("Comparing two lines:\n O:%s:%s\n N:%s:%s\n",
  133. status[old], name[old], st, nm)
  134. }
  135. if (name[old] != nm) {
  136. # The old test wasn't run this time and
  137. # the new test wasn't run last time.
  138. if (verbose >= 2) {
  139. printf("%s->NA:%s\n", status[old], name[old])
  140. if (nm != "") printf("NA->%s:%s\n", st, nm)
  141. }
  142. drop()
  143. }
  144. else {
  145. notable = 0
  146. if (status[old] == st) {
  147. # Status of this test has not changed.
  148. if (verbose >= 3) printf("%s:%s\n", st, nm)
  149. }
  150. else if(status[old] == "PASS" && st == "XFAIL") {
  151. if (verbose >= 1) notable = 1
  152. }
  153. else if(status[old] == "PASS" || st == "FAIL") {
  154. # Test did pass but doesn't now
  155. # or didn't fail but does now.
  156. notable = 1
  157. }
  158. else if(st == "PASS") {
  159. # Test didn't pass but does now.
  160. if (verbose >= 1) notable = 1
  161. }
  162. else if(verbose >= 2) {
  163. # Miscellaneous status change.
  164. notable = 1
  165. }
  166. if (notable > 0) printf("%s->%s:%s\n", status[old], st, nm)
  167. drop()
  168. }
  169. }
  170. }
  171. /^O:/ {
  172. while (old = peek()) {
  173. if (name[old] == \$3) break;
  174. # The queued test is no longer run.
  175. compare("", "");
  176. }
  177. # Save this test for later comparison.
  178. push(\$2, \$3)
  179. }
  180. /^N:/ {
  181. compare(\$2, \$3)
  182. }
  183. END {
  184. while (old = peek()) compare("", "")
  185. }
  186. EOF
  187. sort -m -s -t : -k 3b $TMPDIR/o$$-$OBASE $TMPDIR/n$$-$NBASE |
  188. awk -v verbose=$verbose -f compare-$$.awk /dev/stdin
  189. # Delete the temporary files.
  190. rm -f compare-$$.awk $TMPDIR/o$$-$OBASE $TMPDIR/n$$-$NBASE
  191. exit 0