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