summaryrefslogtreecommitdiff
path: root/tests/support/redis.tcl
diff options
context:
space:
mode:
Diffstat (limited to 'tests/support/redis.tcl')
-rw-r--r--tests/support/redis.tcl58
1 files changed, 53 insertions, 5 deletions
diff --git a/tests/support/redis.tcl b/tests/support/redis.tcl
index 861e8bc27..53fa9fe91 100644
--- a/tests/support/redis.tcl
+++ b/tests/support/redis.tcl
@@ -28,6 +28,8 @@
package require Tcl 8.5
package provide redis 0.1
+source [file join [file dirname [info script]] "response_transformers.tcl"]
+
namespace eval redis {}
set ::redis::id 0
array set ::redis::fd {}
@@ -41,6 +43,11 @@ array set ::redis::tls {}
array set ::redis::callback {}
array set ::redis::state {} ;# State in non-blocking reply reading
array set ::redis::statestack {} ;# Stack of states, for nested mbulks
+array set ::redis::curr_argv {} ;# Remember the current argv, to be used in response_transformers.tcl
+array set ::redis::testing_resp3 {} ;# Indicating if the current client is using RESP3 (only if the test is trying to test RESP3 specific behavior. It won't be on in case of force_resp3)
+
+set ::force_resp3 0
+set ::log_req_res 0
proc redis {{server 127.0.0.1} {port 6379} {defer 0} {tls 0} {tlsoptions {}} {readraw 0}} {
if {$tls} {
@@ -62,6 +69,8 @@ proc redis {{server 127.0.0.1} {port 6379} {defer 0} {tls 0} {tlsoptions {}} {re
set ::redis::deferred($id) $defer
set ::redis::readraw($id) $readraw
set ::redis::reconnect($id) 0
+ set ::redis::curr_argv($id) 0
+ set ::redis::testing_resp3($id) 0
set ::redis::tls($id) $tls
::redis::redis_reset_state $id
interp alias {} ::redis::redisHandle$id {} ::redis::__dispatch__ $id
@@ -123,6 +132,20 @@ proc ::redis::__dispatch__raw__ {id method argv} {
set fd $::redis::fd($id)
}
+ # Transform HELLO 2 to HELLO 3 if force_resp3
+ # All set the connection var testing_resp3 in case of HELLO 3
+ if {[llength $argv] > 0 && [string compare -nocase $method "HELLO"] == 0} {
+ if {[lindex $argv 0] == 3} {
+ set ::redis::testing_resp3($id) 1
+ } else {
+ set ::redis::testing_resp3($id) 0
+ if {$::force_resp3} {
+ # If we are in force_resp3 we run HELLO 3 instead of HELLO 2
+ lset argv 0 3
+ }
+ }
+ }
+
set blocking $::redis::blocking($id)
set deferred $::redis::deferred($id)
if {$blocking == 0} {
@@ -146,6 +169,7 @@ proc ::redis::__dispatch__raw__ {id method argv} {
return -code error "I/O error reading reply"
}
+ set ::redis::curr_argv($id) [concat $method $argv]
if {!$deferred} {
if {$blocking} {
::redis::redis_read_reply $id $fd
@@ -200,6 +224,8 @@ proc ::redis::__method__close {id fd} {
catch {unset ::redis::state($id)}
catch {unset ::redis::statestack($id)}
catch {unset ::redis::callback($id)}
+ catch {unset ::redis::curr_argv($id)}
+ catch {unset ::redis::testing_resp3($id)}
catch {interp alias {} ::redis::redisHandle$id {}}
}
@@ -253,7 +279,7 @@ proc ::redis::redis_multi_bulk_read {id fd} {
set err {}
for {set i 0} {$i < $count} {incr i} {
if {[catch {
- lappend l [redis_read_reply $id $fd]
+ lappend l [redis_read_reply_logic $id $fd]
} e] && $err eq {}} {
set err $e
}
@@ -269,8 +295,8 @@ proc ::redis::redis_read_map {id fd} {
set err {}
for {set i 0} {$i < $count} {incr i} {
if {[catch {
- set k [redis_read_reply $id $fd] ; # key
- set v [redis_read_reply $id $fd] ; # value
+ set k [redis_read_reply_logic $id $fd] ; # key
+ set v [redis_read_reply_logic $id $fd] ; # value
dict set d $k $v
} e] && $err eq {}} {
set err $e
@@ -296,13 +322,25 @@ proc ::redis::redis_read_bool fd {
return -code error "Bad protocol, '$v' as bool type"
}
+proc ::redis::redis_read_double {id fd} {
+ set v [redis_read_line $fd]
+ # unlike many other DTs, there is a textual difference between double and a string with the same value,
+ # so we need to transform to double if we are testing RESP3 (i.e. some tests check that a
+ # double reply is "1.0" and not "1")
+ if {[should_transform_to_resp2 $id]} {
+ return $v
+ } else {
+ return [expr {double($v)}]
+ }
+}
+
proc ::redis::redis_read_verbatim_str fd {
set v [redis_bulk_read $fd]
# strip the first 4 chars ("txt:")
return [string range $v 4 end]
}
-proc ::redis::redis_read_reply {id fd} {
+proc ::redis::redis_read_reply_logic {id fd} {
if {$::redis::readraw($id)} {
return [redis_read_line $fd]
}
@@ -314,7 +352,7 @@ proc ::redis::redis_read_reply {id fd} {
: -
( -
+ {return [redis_read_line $fd]}
- , {return [expr {double([redis_read_line $fd])}]}
+ , {return [redis_read_double $id $fd]}
# {return [redis_read_bool $fd]}
= {return [redis_read_verbatim_str $fd]}
- {return -code error [redis_read_line $fd]}
@@ -340,6 +378,11 @@ proc ::redis::redis_read_reply {id fd} {
}
}
+proc ::redis::redis_read_reply {id fd} {
+ set response [redis_read_reply_logic $id $fd]
+ ::response_transformers::transform_response_if_needed $id $::redis::curr_argv($id) $response
+}
+
proc ::redis::redis_reset_state id {
set ::redis::state($id) [dict create buf {} mbulk -1 bulk -1 reply {}]
set ::redis::statestack($id) {}
@@ -416,3 +459,8 @@ proc ::redis::redis_readable {fd id} {
}
}
}
+
+# when forcing resp3 some tests that rely on resp2 can fail, so we have to translate the resp3 response to resp2
+proc ::redis::should_transform_to_resp2 {id} {
+ return [expr {$::force_resp3 && !$::redis::testing_resp3($id)}]
+}