test.tcl 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. set ::num_tests 0
  2. set ::num_passed 0
  3. set ::num_failed 0
  4. set ::num_skipped 0
  5. set ::num_aborted 0
  6. set ::tests_failed {}
  7. proc fail {msg} {
  8. error "assertion:$msg"
  9. }
  10. proc assert {condition} {
  11. if {![uplevel 1 [list expr $condition]]} {
  12. error "assertion:Expected condition '$condition' to be true ([uplevel 1 [list subst -nocommands $condition]])"
  13. }
  14. }
  15. proc assert_match {pattern value} {
  16. if {![string match $pattern $value]} {
  17. error "assertion:Expected '$value' to match '$pattern'"
  18. }
  19. }
  20. proc assert_equal {expected value {detail ""}} {
  21. if {$expected ne $value} {
  22. if {$detail ne ""} {
  23. set detail " (detail: $detail)"
  24. }
  25. error "assertion:Expected '$value' to be equal to '$expected'$detail"
  26. }
  27. }
  28. proc assert_error {pattern code} {
  29. if {[catch {uplevel 1 $code} error]} {
  30. assert_match $pattern $error
  31. } else {
  32. error "assertion:Expected an error but nothing was caught"
  33. }
  34. }
  35. proc assert_encoding {enc key} {
  36. set dbg [r debug object $key]
  37. assert_match "* encoding:$enc *" $dbg
  38. }
  39. proc assert_type {type key} {
  40. assert_equal $type [r type $key]
  41. }
  42. # Wait for the specified condition to be true, with the specified number of
  43. # max retries and delay between retries. Otherwise the 'elsescript' is
  44. # executed.
  45. proc wait_for_condition {maxtries delay e _else_ elsescript} {
  46. while {[incr maxtries -1] >= 0} {
  47. set errcode [catch {uplevel 1 [list expr $e]} result]
  48. if {$errcode == 0} {
  49. if {$result} break
  50. } else {
  51. return -code $errcode $result
  52. }
  53. after $delay
  54. }
  55. if {$maxtries == -1} {
  56. set errcode [catch [uplevel 1 $elsescript] result]
  57. return -code $errcode $result
  58. }
  59. }
  60. proc test {name code {okpattern undefined}} {
  61. # abort if tagged with a tag to deny
  62. foreach tag $::denytags {
  63. if {[lsearch $::tags $tag] >= 0} {
  64. incr ::num_aborted
  65. send_data_packet $::test_server_fd ignore $name
  66. return
  67. }
  68. }
  69. # abort if test name in skiptests
  70. if {[lsearch $::skiptests $name] >= 0} {
  71. incr ::num_skipped
  72. send_data_packet $::test_server_fd skip $name
  73. return
  74. }
  75. # abort if test name in skiptests
  76. if {[llength $::only_tests] > 0 && [lsearch $::only_tests $name] < 0} {
  77. incr ::num_skipped
  78. send_data_packet $::test_server_fd skip $name
  79. return
  80. }
  81. # check if tagged with at least 1 tag to allow when there *is* a list
  82. # of tags to allow, because default policy is to run everything
  83. if {[llength $::allowtags] > 0} {
  84. set matched 0
  85. foreach tag $::allowtags {
  86. if {[lsearch $::tags $tag] >= 0} {
  87. incr matched
  88. }
  89. }
  90. if {$matched < 1} {
  91. incr ::num_aborted
  92. send_data_packet $::test_server_fd ignore $name
  93. return
  94. }
  95. }
  96. incr ::num_tests
  97. set details {}
  98. lappend details "$name in $::curfile"
  99. send_data_packet $::test_server_fd testing $name
  100. if {[catch {set retval [uplevel 1 $code]} error]} {
  101. if {[string match "assertion:*" $error]} {
  102. set msg [string range $error 10 end]
  103. lappend details $msg
  104. lappend ::tests_failed $details
  105. incr ::num_failed
  106. send_data_packet $::test_server_fd err [join $details "\n"]
  107. } else {
  108. # Re-raise, let handler up the stack take care of this.
  109. error $error $::errorInfo
  110. }
  111. } else {
  112. if {$okpattern eq "undefined" || $okpattern eq $retval || [string match $okpattern $retval]} {
  113. incr ::num_passed
  114. send_data_packet $::test_server_fd ok $name
  115. } else {
  116. set msg "Expected '$okpattern' to equal or match '$retval'"
  117. lappend details $msg
  118. lappend ::tests_failed $details
  119. incr ::num_failed
  120. send_data_packet $::test_server_fd err [join $details "\n"]
  121. }
  122. }
  123. if {$::traceleaks} {
  124. set output [exec leaks redis-server]
  125. if {![string match {*0 leaks*} $output]} {
  126. send_data_packet $::test_server_fd err "Detected a memory leak in test '$name': $output"
  127. }
  128. }
  129. }