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