test.tcl 5.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. set ::num_tests 0
  2. set ::num_passed 0
  3. set ::num_failed 0
  4. set ::tests_failed {}
  5. proc assert {condition} {
  6. if {![uplevel 1 expr $condition]} {
  7. error "assertion:Expected '$value' to be true"
  8. }
  9. }
  10. proc assert_match {pattern value} {
  11. if {![string match $pattern $value]} {
  12. error "assertion:Expected '$value' to match '$pattern'"
  13. }
  14. }
  15. proc assert_equal {expected value} {
  16. if {$expected ne $value} {
  17. error "assertion:Expected '$value' to be equal to '$expected'"
  18. }
  19. }
  20. proc assert_error {pattern code} {
  21. if {[catch {uplevel 1 $code} error]} {
  22. assert_match $pattern $error
  23. } else {
  24. error "assertion:Expected an error but nothing was catched"
  25. }
  26. }
  27. proc assert_encoding {enc key} {
  28. # Swapped out values don't have an encoding, so make sure that
  29. # the value is swapped in before checking the encoding.
  30. set dbg [r debug object $key]
  31. while {[string match "* swapped at:*" $dbg]} {
  32. r debug swapin $key
  33. set dbg [r debug object $key]
  34. }
  35. assert_match "* encoding:$enc *" $dbg
  36. }
  37. proc assert_type {type key} {
  38. assert_equal $type [r type $key]
  39. }
  40. # Test if TERM looks like to support colors
  41. proc color_term {} {
  42. expr {[info exists ::env(TERM)] && [string match *xterm* $::env(TERM)]}
  43. }
  44. # This is called before starting the test
  45. proc announce_test {s} {
  46. if {[color_term]} {
  47. puts -nonewline "$s\033\[0K"
  48. flush stdout
  49. set ::backward_count [string length $s]
  50. }
  51. }
  52. # This is called after the test finished
  53. proc colored_dot {tags passed} {
  54. if {[color_term]} {
  55. # Go backward and delete what announc_test function printed.
  56. puts -nonewline "\033\[${::backward_count}D\033\[0K\033\[J"
  57. # Print a coloured char, accordingly to test outcome and tags.
  58. if {[lsearch $tags list] != -1} {
  59. set colorcode {31}
  60. set ch L
  61. } elseif {[lsearch $tags hash] != -1} {
  62. set colorcode {32}
  63. set ch H
  64. } elseif {[lsearch $tags set] != -1} {
  65. set colorcode {33}
  66. set ch S
  67. } elseif {[lsearch $tags zset] != -1} {
  68. set colorcode {34}
  69. set ch Z
  70. } elseif {[lsearch $tags basic] != -1} {
  71. set colorcode {35}
  72. set ch B
  73. } else {
  74. set colorcode {37}
  75. set ch .
  76. }
  77. if {$colorcode ne {}} {
  78. if {$passed} {
  79. puts -nonewline "\033\[0;${colorcode};40m"
  80. } else {
  81. puts -nonewline "\033\[7;${colorcode};40m"
  82. }
  83. puts -nonewline $ch
  84. puts -nonewline "\033\[0m"
  85. flush stdout
  86. }
  87. } else {
  88. if {$passed} {
  89. puts -nonewline .
  90. } else {
  91. puts -nonewline F
  92. }
  93. }
  94. }
  95. proc test {name code {okpattern undefined}} {
  96. # abort if tagged with a tag to deny
  97. foreach tag $::denytags {
  98. if {[lsearch $::tags $tag] >= 0} {
  99. return
  100. }
  101. }
  102. # check if tagged with at least 1 tag to allow when there *is* a list
  103. # of tags to allow, because default policy is to run everything
  104. if {[llength $::allowtags] > 0} {
  105. set matched 0
  106. foreach tag $::allowtags {
  107. if {[lsearch $::tags $tag] >= 0} {
  108. incr matched
  109. }
  110. }
  111. if {$matched < 1} {
  112. return
  113. }
  114. }
  115. incr ::num_tests
  116. set details {}
  117. lappend details $::curfile
  118. lappend details $::tags
  119. lappend details $name
  120. if {$::verbose} {
  121. puts -nonewline [format "#%03d %-68s " $::num_tests $name]
  122. flush stdout
  123. } else {
  124. announce_test $name
  125. }
  126. if {[catch {set retval [uplevel 1 $code]} error]} {
  127. if {[string match "assertion:*" $error]} {
  128. set msg [string range $error 10 end]
  129. lappend details $msg
  130. lappend ::tests_failed $details
  131. incr ::num_failed
  132. if {$::verbose} {
  133. puts "FAILED"
  134. puts "$msg\n"
  135. } else {
  136. colored_dot $::tags 0
  137. }
  138. } else {
  139. # Re-raise, let handler up the stack take care of this.
  140. error $error $::errorInfo
  141. }
  142. } else {
  143. if {$okpattern eq "undefined" || $okpattern eq $retval || [string match $okpattern $retval]} {
  144. incr ::num_passed
  145. if {$::verbose} {
  146. puts "PASSED"
  147. } else {
  148. colored_dot $::tags 1
  149. }
  150. } else {
  151. set msg "Expected '$okpattern' to equal or match '$retval'"
  152. lappend details $msg
  153. lappend ::tests_failed $details
  154. incr ::num_failed
  155. if {$::verbose} {
  156. puts "FAILED"
  157. puts "$msg\n"
  158. } else {
  159. colored_dot $::tags 0
  160. }
  161. }
  162. }
  163. flush stdout
  164. if {$::traceleaks} {
  165. set output [exec leaks redis-server]
  166. if {![string match {*0 leaks*} $output]} {
  167. puts "--- Test \"$name\" leaked! ---"
  168. puts $output
  169. exit 1
  170. }
  171. }
  172. }