diff options
Diffstat (limited to 'examples/redis-unstable/tests/unit/tracking.tcl')
| -rw-r--r-- | examples/redis-unstable/tests/unit/tracking.tcl | 902 |
1 files changed, 0 insertions, 902 deletions
diff --git a/examples/redis-unstable/tests/unit/tracking.tcl b/examples/redis-unstable/tests/unit/tracking.tcl deleted file mode 100644 index 666b593..0000000 --- a/examples/redis-unstable/tests/unit/tracking.tcl +++ /dev/null @@ -1,902 +0,0 @@ -# logreqres:skip because it seems many of these tests rely heavily on RESP2 -start_server {tags {"tracking network logreqres:skip"}} { - # Create a deferred client we'll use to redirect invalidation - # messages to. - set rd_redirection [redis_deferring_client] - $rd_redirection client id - set redir_id [$rd_redirection read] - $rd_redirection subscribe __redis__:invalidate - $rd_redirection read ; # Consume the SUBSCRIBE reply. - - # Create another client that's not used as a redirection client - # We should always keep this client's buffer clean - set rd [redis_deferring_client] - - # Client to be used for SET and GET commands - # We don't read this client's buffer - set rd_sg [redis_client] - - proc clean_all {} { - uplevel { - # We should make r TRACKING off first. If r is in RESP3, - # r FLUSH ALL will send us tracking-redir-broken or other - # info which will not be consumed. - r CLIENT TRACKING off - $rd QUIT - $rd_redirection QUIT - set rd [redis_deferring_client] - set rd_redirection [redis_deferring_client] - $rd_redirection client id - set redir_id [$rd_redirection read] - $rd_redirection subscribe __redis__:invalidate - $rd_redirection read ; # Consume the SUBSCRIBE reply. - r FLUSHALL - r HELLO 2 - r config set tracking-table-max-keys 1000000 - } - } - - test {Clients are able to enable tracking and redirect it} { - r CLIENT TRACKING on REDIRECT $redir_id - } {*OK} - - test {The other connection is able to get invalidations} { - r SET a{t} 1 - r SET b{t} 1 - r GET a{t} - r INCR b{t} ; # This key should not be notified, since it wasn't fetched. - r INCR a{t} - set keys [lindex [$rd_redirection read] 2] - assert {[llength $keys] == 1} - assert {[lindex $keys 0] eq {a{t}}} - } - - test {The client is now able to disable tracking} { - # Make sure to add a few more keys in the tracking list - # so that we can check for leaks, as a side effect. - r MGET a{t} b{t} c{t} d{t} e{t} f{t} g{t} - r CLIENT TRACKING off - } {*OK} - - test {Clients can enable the BCAST mode with the empty prefix} { - r CLIENT TRACKING on BCAST REDIRECT $redir_id - } {*OK*} - - test {The connection gets invalidation messages about all the keys} { - r MSET a{t} 1 b{t} 2 c{t} 3 - set keys [lsort [lindex [$rd_redirection read] 2]] - assert {$keys eq {a{t} b{t} c{t}}} - } - - test {Clients can enable the BCAST mode with prefixes} { - r CLIENT TRACKING off - r CLIENT TRACKING on BCAST REDIRECT $redir_id PREFIX a: PREFIX b: - r MULTI - r INCR a:1{t} - r INCR a:2{t} - r INCR b:1{t} - r INCR b:2{t} - # we should not get this key - r INCR c:1{t} - r EXEC - # Because of the internals, we know we are going to receive - # two separated notifications for the two different prefixes. - set keys1 [lsort [lindex [$rd_redirection read] 2]] - set keys2 [lsort [lindex [$rd_redirection read] 2]] - set keys [lsort [list {*}$keys1 {*}$keys2]] - assert {$keys eq {a:1{t} a:2{t} b:1{t} b:2{t}}} - } - - test {Adding prefixes to BCAST mode works} { - r CLIENT TRACKING on BCAST REDIRECT $redir_id PREFIX c: - r INCR c:1234 - set keys [lsort [lindex [$rd_redirection read] 2]] - assert {$keys eq {c:1234}} - } - - test {Tracking NOLOOP mode in standard mode works} { - r CLIENT TRACKING off - r CLIENT TRACKING on REDIRECT $redir_id NOLOOP - r MGET otherkey1{t} loopkey{t} otherkey2{t} - $rd_sg SET otherkey1{t} 1; # We should get this - r SET loopkey{t} 1 ; # We should not get this - $rd_sg SET otherkey2{t} 1; # We should get this - # Because of the internals, we know we are going to receive - # two separated notifications for the two different keys. - set keys1 [lsort [lindex [$rd_redirection read] 2]] - set keys2 [lsort [lindex [$rd_redirection read] 2]] - set keys [lsort [list {*}$keys1 {*}$keys2]] - assert {$keys eq {otherkey1{t} otherkey2{t}}} - } - - test {Tracking NOLOOP mode in BCAST mode works} { - r CLIENT TRACKING off - r CLIENT TRACKING on BCAST REDIRECT $redir_id NOLOOP - $rd_sg SET otherkey1 1; # We should get this - r SET loopkey 1 ; # We should not get this - $rd_sg SET otherkey2 1; # We should get this - # Because $rd_sg send command synchronously, we know we are - # going to receive two separated notifications. - set keys1 [lsort [lindex [$rd_redirection read] 2]] - set keys2 [lsort [lindex [$rd_redirection read] 2]] - set keys [lsort [list {*}$keys1 {*}$keys2]] - assert {$keys eq {otherkey1 otherkey2}} - } - - test {Tracking gets notification of expired keys} { - r CLIENT TRACKING off - r CLIENT TRACKING on BCAST REDIRECT $redir_id NOLOOP - r SET mykey myval px 1 - r SET mykeyotherkey myval ; # We should not get it - after 1000 - set keys [lsort [lindex [$rd_redirection read] 2]] - assert {$keys eq {mykey}} - } - - test {Tracking gets notification of lazy expired keys} { - r CLIENT TRACKING off - r CLIENT TRACKING on BCAST REDIRECT $redir_id NOLOOP - # Use multi-exec to expose a race where the key gets an two invalidations - # in the same event loop, once by the client so filtered by NOLOOP, and - # the second one by the lazy expire - r MULTI - r SET mykey{t} myval px 1 - r SET mykeyotherkey{t} myval ; # We should not get it - r DEBUG SLEEP 0.1 - r GET mykey{t} - r EXEC - set keys [lsort [lindex [$rd_redirection read] 2]] - assert {$keys eq {mykey{t}}} - } {} {needs:debug} - - test {HELLO 3 reply is correct} { - set reply [r HELLO 3] - assert_equal [dict get $reply proto] 3 - } - - test {HELLO without protover} { - set reply [r HELLO 3] - assert_equal [dict get $reply proto] 3 - - set reply [r HELLO] - assert_equal [dict get $reply proto] 3 - - set reply [r HELLO 2] - assert_equal [dict get $reply proto] 2 - - set reply [r HELLO] - assert_equal [dict get $reply proto] 2 - - # restore RESP3 for next test - r HELLO 3 - } - - test {RESP3 based basic invalidation} { - r CLIENT TRACKING off - r CLIENT TRACKING on - $rd_sg SET key1 1 - r GET key1 - $rd_sg SET key1 2 - r read - } {invalidate key1} - - test {RESP3 tracking redirection} { - r CLIENT TRACKING off - r CLIENT TRACKING on REDIRECT $redir_id - $rd_sg SET key1 1 - r GET key1 - $rd_sg SET key1 2 - set res [lindex [$rd_redirection read] 2] - assert {$res eq {key1}} - } - - test {Invalidations of previous keys can be redirected after switching to RESP3} { - r HELLO 2 - $rd_sg SET key1 1 - r GET key1 - r HELLO 3 - $rd_sg SET key1 2 - set res [lindex [$rd_redirection read] 2] - assert {$res eq {key1}} - } - - test {Invalidations of new keys can be redirected after switching to RESP3} { - r HELLO 3 - $rd_sg SET key1 1 - r GET key1 - $rd_sg SET key1 2 - set res [lindex [$rd_redirection read] 2] - assert {$res eq {key1}} - } - - test {Invalid keys should not be tracked for scripts in NOLOOP mode} { - $rd_sg CLIENT TRACKING off - $rd_sg CLIENT TRACKING on NOLOOP - $rd_sg HELLO 3 - $rd_sg SET key1 1 - assert_equal "1" [$rd_sg GET key1] - - # For write command in script, invalid key should not be tracked with NOLOOP flag - $rd_sg eval "return redis.call('set', 'key1', '2')" 1 key1 - assert_equal "2" [$rd_sg GET key1] - $rd_sg CLIENT TRACKING off - } - - test {Tracking only occurs for scripts when a command calls a read-only command} { - r CLIENT TRACKING off - r CLIENT TRACKING on - $rd_sg MSET key2{t} 1 key2{t} 1 - - # If a script doesn't call any read command, don't track any keys - r EVAL "redis.call('set', 'key3{t}', 'bar')" 2 key1{t} key2{t} - $rd_sg MSET key2{t} 2 key1{t} 2 - assert_equal "PONG" [r ping] - - # If a script calls a read command, just the read keys - r EVAL "redis.call('get', 'key2{t}')" 2 key1{t} key2{t} - $rd_sg MSET key2{t} 2 key3{t} 2 - assert_equal {invalidate key2{t}} [r read] - assert_equal "PONG" [r ping] - - # RO variants work like the normal variants - - # If a RO script doesn't call any read command, don't track any keys - r EVAL_RO "redis.call('ping')" 2 key1{t} key2{t} - $rd_sg MSET key2{t} 2 key1{t} 2 - assert_equal "PONG" [r ping] - - # If a RO script calls a read command, just the read keys - r EVAL_RO "redis.call('get', 'key2{t}')" 2 key1{t} key2{t} - $rd_sg MSET key2{t} 2 key3{t} 2 - assert_equal {invalidate key2{t}} [r read] - assert_equal "PONG" [r ping] - } - - test {RESP3 Client gets tracking-redir-broken push message after cached key changed when rediretion client is terminated} { - r CLIENT TRACKING on REDIRECT $redir_id - $rd_sg SET key1 1 - r GET key1 - $rd_redirection QUIT - assert_equal OK [$rd_redirection read] - $rd_sg SET key1 2 - set MAX_TRIES 100 - set res -1 - for {set i 0} {$i <= $MAX_TRIES && $res < 0} {incr i} { - set res [lsearch -exact [r PING] "tracking-redir-broken"] - } - assert {$res >= 0} - # Consume PING reply - assert_equal PONG [r read] - - # Reinstantiating after QUIT - set rd_redirection [redis_deferring_client] - $rd_redirection CLIENT ID - set redir_id [$rd_redirection read] - $rd_redirection SUBSCRIBE __redis__:invalidate - $rd_redirection read ; # Consume the SUBSCRIBE reply - } - - test {Different clients can redirect to the same connection} { - r CLIENT TRACKING on REDIRECT $redir_id - $rd CLIENT TRACKING on REDIRECT $redir_id - assert_equal OK [$rd read] ; # Consume the TRACKING reply - $rd_sg MSET key1{t} 1 key2{t} 1 - r GET key1{t} - $rd GET key2{t} - assert_equal 1 [$rd read] ; # Consume the GET reply - $rd_sg INCR key1{t} - $rd_sg INCR key2{t} - set res1 [lindex [$rd_redirection read] 2] - set res2 [lindex [$rd_redirection read] 2] - assert {$res1 eq {key1{t}}} - assert {$res2 eq {key2{t}}} - } - - test {Different clients using different protocols can track the same key} { - $rd HELLO 3 - set reply [$rd read] ; # Consume the HELLO reply - assert_equal 3 [dict get $reply proto] - $rd CLIENT TRACKING on - assert_equal OK [$rd read] ; # Consume the TRACKING reply - $rd_sg set key1 1 - r GET key1 - $rd GET key1 - assert_equal 1 [$rd read] ; # Consume the GET reply - $rd_sg INCR key1 - set res1 [lindex [$rd_redirection read] 2] - $rd PING ; # Non redirecting client has to talk to the server in order to get invalidation message - set res2 [lindex [split [$rd read] " "] 1] - assert_equal PONG [$rd read] ; # Consume the PING reply, which comes together with the invalidation message - assert {$res1 eq {key1}} - assert {$res2 eq {key1}} - } - - test {No invalidation message when using OPTIN option} { - r CLIENT TRACKING on OPTIN REDIRECT $redir_id - $rd_sg SET key1 1 - r GET key1 ; # This key should not be notified, since OPTIN is on and CLIENT CACHING yes wasn't called - $rd_sg SET key1 2 - # Preparing some message to consume on $rd_redirection so we don't get blocked - r CLIENT TRACKING off - r CLIENT TRACKING on REDIRECT $redir_id - $rd_sg SET key2 1 - r GET key2 ; # This key should be notified - $rd_sg SET key2 2 - set res [lindex [$rd_redirection read] 2] - assert {$res eq {key2}} - } - - test {Invalidation message sent when using OPTIN option with CLIENT CACHING yes} { - r CLIENT TRACKING on OPTIN REDIRECT $redir_id - $rd_sg SET key1 3 - r CLIENT CACHING yes - r GET key1 - $rd_sg SET key1 4 - set res [lindex [$rd_redirection read] 2] - assert {$res eq {key1}} - } - - test {Invalidation message sent when using OPTOUT option} { - r CLIENT TRACKING off - r CLIENT TRACKING on OPTOUT REDIRECT $redir_id - $rd_sg SET key1 1 - r GET key1 - $rd_sg SET key1 2 - set res [lindex [$rd_redirection read] 2] - assert {$res eq {key1}} - } - - test {No invalidation message when using OPTOUT option with CLIENT CACHING no} { - $rd_sg SET key1 1 - r CLIENT CACHING no - r GET key1 ; # This key should not be notified, since OPTOUT is on and CLIENT CACHING no was called - $rd_sg SET key1 2 - # Preparing some message to consume on $rd_redirection so we don't get blocked - $rd_sg SET key2 1 - r GET key2 ; # This key should be notified - $rd_sg SET key2 2 - set res [lindex [$rd_redirection read] 2] - assert {$res eq {key2}} - } - - test {Able to redirect to a RESP3 client} { - $rd_redirection UNSUBSCRIBE __redis__:invalidate ; # Need to unsub first before we can do HELLO 3 - set res [$rd_redirection read] ; # Consume the UNSUBSCRIBE reply - assert_equal {__redis__:invalidate} [lindex $res 1] - $rd_redirection HELLO 3 - set res [$rd_redirection read] ; # Consume the HELLO reply - assert_equal [dict get $reply proto] 3 - $rd_redirection SUBSCRIBE __redis__:invalidate - set res [$rd_redirection read] ; # Consume the SUBSCRIBE reply - assert_equal {__redis__:invalidate} [lindex $res 1] - r CLIENT TRACKING on REDIRECT $redir_id - $rd_sg SET key1 1 - r GET key1 - $rd_sg INCR key1 - set res [lindex [$rd_redirection read] 1] - assert {$res eq {key1}} - $rd_redirection HELLO 2 - set res [$rd_redirection read] ; # Consume the HELLO reply - assert_equal [dict get $res proto] 2 - } - - test {After switching from normal tracking to BCAST mode, no invalidation message is produced for pre-BCAST keys} { - r CLIENT TRACKING off - r HELLO 3 - r CLIENT TRACKING on - $rd_sg SET key1 1 - r GET key1 - r CLIENT TRACKING off - r CLIENT TRACKING on BCAST - $rd_sg INCR key1 - set inv_msg [r PING] - set ping_reply [r read] - assert {$inv_msg eq {invalidate key1}} - assert {$ping_reply eq {PONG}} - } - - test {BCAST with prefix collisions throw errors} { - set r [redis_client] - catch {$r CLIENT TRACKING ON BCAST PREFIX FOOBAR PREFIX FOO} output - assert_match {ERR Prefix 'FOOBAR'*'FOO'*} $output - - catch {$r CLIENT TRACKING ON BCAST PREFIX FOO PREFIX FOOBAR} output - assert_match {ERR Prefix 'FOO'*'FOOBAR'*} $output - - $r CLIENT TRACKING ON BCAST PREFIX FOO PREFIX BAR - catch {$r CLIENT TRACKING ON BCAST PREFIX FO} output - assert_match {ERR Prefix 'FO'*'FOO'*} $output - - catch {$r CLIENT TRACKING ON BCAST PREFIX BARB} output - assert_match {ERR Prefix 'BARB'*'BAR'*} $output - - $r CLIENT TRACKING OFF - } - - test {hdel deliver invalidate message after response in the same connection} { - r CLIENT TRACKING off - r HELLO 3 - r CLIENT TRACKING on - r HSET myhash f 1 - r HGET myhash f - set res [r HDEL myhash f] - assert_equal $res 1 - set res [r read] - assert_equal $res {invalidate myhash} - } - - test {Tracking invalidation message is not interleaved with multiple keys response} { - r CLIENT TRACKING off - r HELLO 3 - r CLIENT TRACKING on - # We need disable active expire, so we can trigger lazy expire - r DEBUG SET-ACTIVE-EXPIRE 0 - r MULTI - r MSET x{t} 1 y{t} 2 - r PEXPIRE y{t} 100 - r GET y{t} - r EXEC - after 110 - # Read expired key y{t}, generate invalidate message about this key - set res [r MGET x{t} y{t}] - assert_equal $res {1 {}} - # Consume the invalidate message which is after command response - set res [r read] - assert_equal $res {invalidate y{t}} - r DEBUG SET-ACTIVE-EXPIRE 1 - } {OK} {needs:debug} - - test {Tracking invalidation message is not interleaved with transaction response} { - r CLIENT TRACKING off - r HELLO 3 - r CLIENT TRACKING on - r MSET a{t} 1 b{t} 2 - r GET a{t} - # Start a transaction, make a{t} generate an invalidate message - r MULTI - r INCR a{t} - r GET b{t} - set res [r EXEC] - assert_equal $res {2 2} - set res [r read] - # Consume the invalidate message which is after command response - assert_equal $res {invalidate a{t}} - } - - test {Tracking invalidation message of eviction keys should be before response} { - # Get the current memory limit and calculate a new limit. - r CLIENT TRACKING off - r HELLO 3 - r CLIENT TRACKING on - - # make the previous test is really done before sampling used_memory - wait_lazyfree_done r - - set used [expr {[s used_memory] - [s mem_not_counted_for_evict]}] - set limit [expr {$used+100*1024}] - set old_policy [lindex [r config get maxmemory-policy] 1] - r config set maxmemory $limit - # We set policy volatile-random, so only keys with ttl will be evicted - r config set maxmemory-policy volatile-random - # Add a volatile key and tracking it. - r setex volatile-key 10000 x - r get volatile-key - # We use SETBIT here, so we can set a big key and get the used_memory - # bigger than maxmemory. Next command will evict volatile keys. We - # can't use SET, as SET uses big input buffer, so it will fail. - r setbit big-key 1600000 0 ;# this will consume 200kb - # volatile-key is evicted before response. - set res [r getbit big-key 0] - assert_equal $res {invalidate volatile-key} - set res [r read] - assert_equal $res 0 - r config set maxmemory-policy $old_policy - r config set maxmemory 0 - } - - test {Unblocked BLMOVE gets notification after response} { - r RPUSH list2{t} a - $rd HELLO 3 - $rd read - $rd CLIENT TRACKING on - $rd read - # Tracking key list2{t} - $rd LRANGE list2{t} 0 -1 - $rd read - # We block on list1{t} - $rd BLMOVE list1{t} list2{t} left left 0 - wait_for_blocked_clients_count 1 - # unblock $rd, list2{t} gets element and generate invalidation message - r rpush list1{t} foo - assert_equal [$rd read] {foo} - assert_equal [$rd read] {invalidate list2{t}} - } - - test {Tracking gets notification on tracking table key eviction} { - r CLIENT TRACKING off - r CLIENT TRACKING on REDIRECT $redir_id NOLOOP - r MSET key1{t} 1 key2{t} 2 - # Let the server track the two keys for us - r MGET key1{t} key2{t} - # Force the eviction of all the keys but one: - r config set tracking-table-max-keys 1 - # Note that we may have other keys in the table for this client, - # since we disabled/enabled tracking multiple time with the same - # ID, and tracking does not do ID cleanups for performance reasons. - # So we check that eventually we'll receive one or the other key, - # otherwise the test will die for timeout. - while 1 { - set keys [lindex [$rd_redirection read] 2] - if {$keys eq {key1{t}} || $keys eq {key2{t}}} break - } - # We should receive an expire notification for one of - # the two keys (only one must remain) - assert {$keys eq {key1{t}} || $keys eq {key2{t}}} - } - - test {Invalidation message received for flushall} { - clean_all - r CLIENT TRACKING on REDIRECT $redir_id - $rd_sg SET key1 1 - r GET key1 - $rd_sg FLUSHALL - set msg [$rd_redirection read] - assert {[lindex msg 2] eq {} } - } - - test {Invalidation message received for flushdb} { - clean_all - r CLIENT TRACKING on REDIRECT $redir_id - $rd_sg SET key1 1 - r GET key1 - $rd_sg FLUSHDB - set msg [$rd_redirection read] - assert {[lindex msg 2] eq {} } - } - - test {Test ASYNC flushall} { - clean_all - r CLIENT TRACKING on REDIRECT $redir_id - r GET key1 - r GET key2 - assert_equal [s 0 tracking_total_keys] 2 - $rd_sg FLUSHALL ASYNC - assert_equal [s 0 tracking_total_keys] 0 - assert_equal [lindex [$rd_redirection read] 2] {} - } - - test {flushdb tracking invalidation message is not interleaved with transaction response} { - clean_all - r HELLO 3 - r CLIENT TRACKING on - r SET a{t} 1 - r GET a{t} - r MULTI - r FLUSHDB - set res [r EXEC] - assert_equal $res {OK} - # Consume the invalidate message which is after command response - r read - } {invalidate {}} - - # Keys are defined to be evicted 100 at a time by default. - # If after eviction the number of keys still surpasses the limit - # defined in tracking-table-max-keys, we increases eviction - # effort to 200, and then 300, etc. - # This test tests this effort incrementation. - test {Server is able to evacuate enough keys when num of keys surpasses limit by more than defined initial effort} { - clean_all - set NUM_OF_KEYS_TO_TEST 250 - set TRACKING_TABLE_MAX_KEYS 1 - r CLIENT TRACKING on REDIRECT $redir_id - for {set i 0} {$i < $NUM_OF_KEYS_TO_TEST} {incr i} { - $rd_sg SET key$i $i - r GET key$i - } - r config set tracking-table-max-keys $TRACKING_TABLE_MAX_KEYS - # If not enough keys are evicted, we won't get enough invalidation - # messages, and "$rd_redirection read" will block. - # If too many keys are evicted, we will get too many invalidation - # messages, and the assert will fail. - for {set i 0} {$i < $NUM_OF_KEYS_TO_TEST - $TRACKING_TABLE_MAX_KEYS} {incr i} { - $rd_redirection read - } - $rd_redirection PING - assert {[$rd_redirection read] eq {pong {}}} - } - - test {Tracking info is correct} { - clean_all - r CLIENT TRACKING on REDIRECT $redir_id - $rd_sg SET key1 1 - $rd_sg SET key2 2 - r GET key1 - r GET key2 - $rd CLIENT TRACKING on BCAST PREFIX prefix: - assert [string match *OK* [$rd read]] - $rd_sg SET prefix:key1 1 - $rd_sg SET prefix:key2 2 - set info [r info] - regexp "\r\ntracking_total_items:(.*?)\r\n" $info _ total_items - regexp "\r\ntracking_total_keys:(.*?)\r\n" $info _ total_keys - regexp "\r\ntracking_total_prefixes:(.*?)\r\n" $info _ total_prefixes - regexp "\r\ntracking_clients:(.*?)\r\n" $info _ tracking_clients - assert {$total_items == 2} - assert {$total_keys == 2} - assert {$total_prefixes == 1} - assert {$tracking_clients == 2} - } - - test {CLIENT GETREDIR provides correct client id} { - set res [r CLIENT GETREDIR] - assert_equal $redir_id $res - r CLIENT TRACKING off - set res [r CLIENT GETREDIR] - assert_equal -1 $res - r CLIENT TRACKING on - set res [r CLIENT GETREDIR] - assert_equal 0 $res - } - - test {CLIENT TRACKINGINFO provides reasonable results when tracking off} { - r CLIENT TRACKING off - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {off} $flags - set redirect [dict get $res redirect] - assert_equal {-1} $redirect - set prefixes [dict get $res prefixes] - assert_equal {} $prefixes - } - - test {CLIENT TRACKINGINFO provides reasonable results when tracking on} { - r CLIENT TRACKING on - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {on} $flags - set redirect [dict get $res redirect] - assert_equal {0} $redirect - set prefixes [dict get $res prefixes] - assert_equal {} $prefixes - } - - test {CLIENT TRACKINGINFO provides reasonable results when tracking on with options} { - r CLIENT TRACKING on REDIRECT $redir_id noloop - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {on noloop} $flags - set redirect [dict get $res redirect] - assert_equal $redir_id $redirect - set prefixes [dict get $res prefixes] - assert_equal {} $prefixes - } - - test {CLIENT TRACKINGINFO provides reasonable results when tracking optin} { - r CLIENT TRACKING off - r CLIENT TRACKING on optin - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {on optin} $flags - set redirect [dict get $res redirect] - assert_equal {0} $redirect - set prefixes [dict get $res prefixes] - assert_equal {} $prefixes - - r CLIENT CACHING yes - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {on optin caching-yes} $flags - } - - test {CLIENT TRACKINGINFO provides reasonable results when tracking optout} { - r CLIENT TRACKING off - r CLIENT TRACKING on optout - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {on optout} $flags - set redirect [dict get $res redirect] - assert_equal {0} $redirect - set prefixes [dict get $res prefixes] - assert_equal {} $prefixes - - r CLIENT CACHING no - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {on optout caching-no} $flags - } - - test {CLIENT TRACKINGINFO provides reasonable results when tracking bcast mode} { - r CLIENT TRACKING off - r CLIENT TRACKING on BCAST PREFIX foo PREFIX bar - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {on bcast} $flags - set redirect [dict get $res redirect] - assert_equal {0} $redirect - set prefixes [lsort [dict get $res prefixes]] - assert_equal {bar foo} $prefixes - - r CLIENT TRACKING off - r CLIENT TRACKING on BCAST - set res [r client trackinginfo] - set prefixes [dict get $res prefixes] - assert_equal {{}} $prefixes - } - - test {CLIENT TRACKINGINFO provides reasonable results when tracking redir broken} { - clean_all - r HELLO 3 - r CLIENT TRACKING on REDIRECT $redir_id - $rd_sg SET key1 1 - r GET key1 - $rd_redirection QUIT - assert_equal OK [$rd_redirection read] - $rd_sg SET key1 2 - set res [lsearch -exact [r read] "tracking-redir-broken"] - assert {$res >= 0} - set res [r client trackinginfo] - set flags [dict get $res flags] - assert_equal {on broken_redirect} $flags - set redirect [dict get $res redirect] - assert_equal $redir_id $redirect - set prefixes [dict get $res prefixes] - assert_equal {} $prefixes - } - - test {Regression test for #11715} { - # This issue manifests when a client invalidates keys through the max key - # limit, which invalidates keys to get Redis below the limit, but no command is - # then executed. This can occur in several ways but the simplest is through - # multi-exec which queues commands. - clean_all - r config set tracking-table-max-keys 2 - - # The cron will invalidate keys if we're above the limit, so disable it. - r debug pause-cron 1 - - # Set up a client that has listened to 2 keys and start a multi, this - # sets up the crash for later. - $rd HELLO 3 - $rd read - $rd CLIENT TRACKING on - assert_match "OK" [$rd read] - $rd mget "1{tag}" "2{tag}" - assert_match "{} {}" [$rd read] - $rd multi - assert_match "OK" [$rd read] - - # Reduce the tracking table keys to 1, this doesn't immediately take affect, but - # instead will apply on the next command. - r config set tracking-table-max-keys 1 - - # This command will get queued, so make sure this command doesn't crash. - $rd ping - $rd exec - - # Validate we got some invalidation message and then the command was queued. - assert_match "invalidate *{tag}" [$rd read] - assert_match "QUEUED" [$rd read] - assert_match "PONG" [$rd read] - - r debug pause-cron 0 - } {OK} {needs:debug} - - foreach resp {3 2} { - test "RESP$resp based basic invalidation with client reply off" { - # This entire test is mostly irrelevant for RESP2, but we run it anyway just for some extra coverage. - clean_all - - $rd hello $resp - $rd read - $rd client tracking on - $rd read - - $rd_sg set foo bar - $rd get foo - $rd read - - $rd client reply off - - $rd_sg set foo bar2 - - if {$resp == 3} { - assert_equal {invalidate foo} [$rd read] - } elseif {$resp == 2} { } ;# Just coverage - - # Verify things didn't get messed up and no unexpected reply was pushed to the client. - $rd client reply on - assert_equal {OK} [$rd read] - $rd ping - assert_equal {PONG} [$rd read] - } - } - - test {RESP3 based basic redirect invalidation with client reply off} { - clean_all - - set rd_redir [redis_deferring_client] - $rd_redir hello 3 - $rd_redir read - - $rd_redir client id - set rd_redir_id [$rd_redir read] - - $rd client tracking on redirect $rd_redir_id - $rd read - - $rd_sg set foo bar - $rd get foo - $rd read - - $rd_redir client reply off - - $rd_sg set foo bar2 - assert_equal {invalidate foo} [$rd_redir read] - - # Verify things didn't get messed up and no unexpected reply was pushed to the client. - $rd_redir client reply on - assert_equal {OK} [$rd_redir read] - $rd_redir ping - assert_equal {PONG} [$rd_redir read] - - $rd_redir close - } - - test {RESP3 based basic tracking-redir-broken with client reply off} { - clean_all - - $rd hello 3 - $rd read - $rd client tracking on redirect $redir_id - $rd read - - $rd_sg set foo bar - $rd get foo - $rd read - - $rd client reply off - - $rd_redirection quit - $rd_redirection read - - $rd_sg set foo bar2 - - set res [lsearch -exact [$rd read] "tracking-redir-broken"] - assert_morethan_equal $res 0 - - # Verify things didn't get messed up and no unexpected reply was pushed to the client. - $rd client reply on - assert_equal {OK} [$rd read] - $rd ping - assert_equal {PONG} [$rd read] - } - - $rd_redirection close - $rd_sg close - $rd close -} - -# Just some extra coverage for --log-req-res, because we do not -# run the full tracking unit in that mode -start_server {tags {"tracking network"}} { - test {Coverage: Basic CLIENT CACHING} { - set rd_redirection [redis_deferring_client] - $rd_redirection client id - set redir_id [$rd_redirection read] - assert_equal {OK} [r CLIENT TRACKING on OPTIN REDIRECT $redir_id] - assert_equal {OK} [r CLIENT CACHING yes] - r CLIENT TRACKING off - } {OK} - - test {Coverage: Basic CLIENT REPLY} { - r CLIENT REPLY on - } {OK} - - test {Coverage: Basic CLIENT TRACKINGINFO} { - r CLIENT TRACKINGINFO - } {flags off redirect -1 prefixes {}} - - test {Coverage: Basic CLIENT GETREDIR} { - r CLIENT GETREDIR - } {-1} -} |
