diff options
Diffstat (limited to 'examples/redis-unstable/tests/unit/moduleapi/propagate.tcl')
| -rw-r--r-- | examples/redis-unstable/tests/unit/moduleapi/propagate.tcl | 806 |
1 files changed, 0 insertions, 806 deletions
diff --git a/examples/redis-unstable/tests/unit/moduleapi/propagate.tcl b/examples/redis-unstable/tests/unit/moduleapi/propagate.tcl deleted file mode 100644 index d3d08d9..0000000 --- a/examples/redis-unstable/tests/unit/moduleapi/propagate.tcl +++ /dev/null @@ -1,806 +0,0 @@ -set testmodule [file normalize tests/modules/propagate.so] -set miscmodule [file normalize tests/modules/misc.so] -set keyspace_events [file normalize tests/modules/keyspace_events.so] - -tags "modules external:skip" { - test {Modules can propagate in async and threaded contexts} { - start_server [list overrides [list loadmodule "$testmodule"]] { - set replica [srv 0 client] - set replica_host [srv 0 host] - set replica_port [srv 0 port] - $replica module load $keyspace_events - start_server [list overrides [list loadmodule "$testmodule"]] { - set master [srv 0 client] - set master_host [srv 0 host] - set master_port [srv 0 port] - $master module load $keyspace_events - - # Start the replication process... - $replica replicaof $master_host $master_port - wait_for_sync $replica - after 1000 - - test {module propagates from timer} { - set repl [attach_to_replication_stream] - - $master propagate-test.timer - - wait_for_condition 500 10 { - [$replica get timer] eq "3" - } else { - fail "The two counters don't match the expected value." - } - - assert_replication_stream $repl { - {select *} - {incr timer} - {incr timer} - {incr timer} - } - close_replication_stream $repl - } - - test {module propagation with notifications} { - set repl [attach_to_replication_stream] - - $master set x y - - assert_replication_stream $repl { - {multi} - {select *} - {incr notifications} - {set x y} - {exec} - } - close_replication_stream $repl - } - - test {module propagation with notifications with multi} { - set repl [attach_to_replication_stream] - - $master multi - $master set x1 y1 - $master set x2 y2 - $master exec - - assert_replication_stream $repl { - {multi} - {select *} - {incr notifications} - {set x1 y1} - {incr notifications} - {set x2 y2} - {exec} - } - close_replication_stream $repl - } - - test {module propagation with notifications with active-expire} { - $master debug set-active-expire 1 - set repl [attach_to_replication_stream] - - $master set asdf1 1 PX 300 - $master set asdf2 2 PX 300 - $master set asdf3 3 PX 300 - - wait_for_condition 500 10 { - [$replica keys asdf*] eq {} - } else { - fail "Not all keys have expired" - } - - # Note whenever there's double notification: SET with PX issues two separate - # notifications: one for "set" and one for "expire" - assert_replication_stream $repl { - {multi} - {select *} - {incr notifications} - {incr notifications} - {set asdf1 1 PXAT *} - {exec} - {multi} - {incr notifications} - {incr notifications} - {set asdf2 2 PXAT *} - {exec} - {multi} - {incr notifications} - {incr notifications} - {set asdf3 3 PXAT *} - {exec} - {multi} - {incr notifications} - {incr notifications} - {incr testkeyspace:expired} - {del asdf*} - {exec} - {multi} - {incr notifications} - {incr notifications} - {incr testkeyspace:expired} - {del asdf*} - {exec} - {multi} - {incr notifications} - {incr notifications} - {incr testkeyspace:expired} - {del asdf*} - {exec} - } - close_replication_stream $repl - - $master debug set-active-expire 0 - } - - test {module propagation with notifications with eviction case 1} { - $master flushall - $master set asdf1 1 - $master set asdf2 2 - $master set asdf3 3 - - $master config set maxmemory-policy allkeys-random - $master config set maxmemory 1 - - # Please note the following loop: - # We evict a key and send a notification, which does INCR on the "notifications" key, so - # that every time we evict any key, "notifications" key exist (it happens inside the - # performEvictions loop). So even evicting "notifications" causes INCR on "notifications". - # If maxmemory_eviction_tenacity would have been set to 100 this would be an endless loop, but - # since the default is 10, at some point the performEvictions loop would end. - # Bottom line: "notifications" always exists and we can't really determine the order of evictions - # This test is here only for sanity - - # The replica will get the notification with multi exec and we have a generic notification handler - # that performs `RedisModule_Call(ctx, "INCR", "c", "multi");` if the notification is inside multi exec. - # so we will have 2 keys, "notifications" and "multi". - wait_for_condition 500 10 { - [$replica dbsize] eq 2 - } else { - fail "Not all keys have been evicted" - } - - $master config set maxmemory 0 - $master config set maxmemory-policy noeviction - } - - test {module propagation with notifications with eviction case 2} { - $master flushall - set repl [attach_to_replication_stream] - - $master set asdf1 1 EX 300 - $master set asdf2 2 EX 300 - $master set asdf3 3 EX 300 - - # Please note we use volatile eviction to prevent the loop described in the test above. - # "notifications" is not volatile so it always remains - $master config resetstat - $master config set maxmemory-policy volatile-ttl - $master config set maxmemory 1 - - wait_for_condition 500 10 { - [s evicted_keys] eq 3 - } else { - fail "Not all keys have been evicted" - } - - $master config set maxmemory 0 - $master config set maxmemory-policy noeviction - - $master set asdf4 4 - - # Note whenever there's double notification: SET with EX issues two separate - # notifications: one for "set" and one for "expire" - # Note that although CONFIG SET maxmemory is called in this flow (see issue #10014), - # eviction will happen and will not induce propagation of the CONFIG command (see #10019). - assert_replication_stream $repl { - {multi} - {select *} - {incr notifications} - {incr notifications} - {set asdf1 1 PXAT *} - {exec} - {multi} - {incr notifications} - {incr notifications} - {set asdf2 2 PXAT *} - {exec} - {multi} - {incr notifications} - {incr notifications} - {set asdf3 3 PXAT *} - {exec} - {multi} - {incr notifications} - {del asdf*} - {exec} - {multi} - {incr notifications} - {del asdf*} - {exec} - {multi} - {incr notifications} - {del asdf*} - {exec} - {multi} - {incr notifications} - {set asdf4 4} - {exec} - } - close_replication_stream $repl - } - - test {module propagation with timer and CONFIG SET maxmemory} { - set repl [attach_to_replication_stream] - - $master config resetstat - $master config set maxmemory-policy volatile-random - - $master propagate-test.timer-maxmemory - - # Wait until the volatile keys are evicted - wait_for_condition 500 10 { - [s evicted_keys] eq 2 - } else { - fail "Not all keys have been evicted" - } - - assert_replication_stream $repl { - {multi} - {select *} - {incr notifications} - {incr notifications} - {set timer-maxmemory-volatile-start 1 PXAT *} - {incr timer-maxmemory-middle} - {incr notifications} - {incr notifications} - {set timer-maxmemory-volatile-end 1 PXAT *} - {exec} - {multi} - {incr notifications} - {del timer-maxmemory-volatile-*} - {exec} - {multi} - {incr notifications} - {del timer-maxmemory-volatile-*} - {exec} - } - close_replication_stream $repl - - $master config set maxmemory 0 - $master config set maxmemory-policy noeviction - } - - test {module propagation with timer and EVAL} { - set repl [attach_to_replication_stream] - - $master propagate-test.timer-eval - - assert_replication_stream $repl { - {multi} - {select *} - {incr notifications} - {incrby timer-eval-start 1} - {incr notifications} - {set foo bar} - {incr timer-eval-middle} - {incr notifications} - {incrby timer-eval-end 1} - {exec} - } - close_replication_stream $repl - } - - test {module propagates nested ctx case1} { - set repl [attach_to_replication_stream] - - $master propagate-test.timer-nested - - wait_for_condition 500 10 { - [$replica get timer-nested-end] eq "1" - } else { - fail "The two counters don't match the expected value." - } - - assert_replication_stream $repl { - {multi} - {select *} - {incrby timer-nested-start 1} - {incrby timer-nested-end 1} - {exec} - } - close_replication_stream $repl - - # Note propagate-test.timer-nested just propagates INCRBY, causing an - # inconsistency, so we flush - $master flushall - } - - test {module propagates nested ctx case2} { - set repl [attach_to_replication_stream] - - $master propagate-test.timer-nested-repl - - wait_for_condition 500 10 { - [$replica get timer-nested-end] eq "1" - } else { - fail "The two counters don't match the expected value." - } - - assert_replication_stream $repl { - {multi} - {select *} - {incrby timer-nested-start 1} - {incr notifications} - {incr using-call} - {incr counter-1} - {incr counter-2} - {incr counter-3} - {incr counter-4} - {incr notifications} - {incr after-call} - {incr notifications} - {incr before-call-2} - {incr notifications} - {incr asdf} - {incr notifications} - {del asdf} - {incr notifications} - {incr after-call-2} - {incr notifications} - {incr timer-nested-middle} - {incrby timer-nested-end 1} - {exec} - } - close_replication_stream $repl - - # Note propagate-test.timer-nested-repl just propagates INCRBY, causing an - # inconsistency, so we flush - $master flushall - } - - test {module propagates from thread} { - set repl [attach_to_replication_stream] - - $master propagate-test.thread - - wait_for_condition 500 10 { - [$replica get a-from-thread] eq "3" - } else { - fail "The two counters don't match the expected value." - } - - assert_replication_stream $repl { - {multi} - {select *} - {incr a-from-thread} - {incr notifications} - {incr thread-call} - {incr b-from-thread} - {exec} - {multi} - {incr a-from-thread} - {incr notifications} - {incr thread-call} - {incr b-from-thread} - {exec} - {multi} - {incr a-from-thread} - {incr notifications} - {incr thread-call} - {incr b-from-thread} - {exec} - } - close_replication_stream $repl - } - - test {module propagates from thread with detached ctx} { - set repl [attach_to_replication_stream] - - $master propagate-test.detached-thread - - wait_for_condition 500 10 { - [$replica get thread-detached-after] eq "1" - } else { - fail "The key doesn't match the expected value." - } - - assert_replication_stream $repl { - {multi} - {select *} - {incr thread-detached-before} - {incr notifications} - {incr thread-detached-1} - {incr notifications} - {incr thread-detached-2} - {incr thread-detached-after} - {exec} - } - close_replication_stream $repl - } - - test {module propagates from command} { - set repl [attach_to_replication_stream] - - $master propagate-test.simple - $master propagate-test.mixed - - assert_replication_stream $repl { - {multi} - {select *} - {incr counter-1} - {incr counter-2} - {exec} - {multi} - {incr notifications} - {incr using-call} - {incr counter-1} - {incr counter-2} - {incr notifications} - {incr after-call} - {exec} - } - close_replication_stream $repl - } - - test {module propagates from EVAL} { - set repl [attach_to_replication_stream] - - assert_equal [ $master eval { \ - redis.call("propagate-test.simple"); \ - redis.call("set", "x", "y"); \ - redis.call("propagate-test.mixed"); return "OK" } 0 ] {OK} - - assert_replication_stream $repl { - {multi} - {select *} - {incr counter-1} - {incr counter-2} - {incr notifications} - {set x y} - {incr notifications} - {incr using-call} - {incr counter-1} - {incr counter-2} - {incr notifications} - {incr after-call} - {exec} - } - close_replication_stream $repl - } - - test {module propagates from command after good EVAL} { - set repl [attach_to_replication_stream] - - assert_equal [ $master eval { return "hello" } 0 ] {hello} - $master propagate-test.simple - $master propagate-test.mixed - - assert_replication_stream $repl { - {multi} - {select *} - {incr counter-1} - {incr counter-2} - {exec} - {multi} - {incr notifications} - {incr using-call} - {incr counter-1} - {incr counter-2} - {incr notifications} - {incr after-call} - {exec} - } - close_replication_stream $repl - } - - test {module propagates from command after bad EVAL} { - set repl [attach_to_replication_stream] - - catch { $master eval { return "hello" } -12 } e - assert_equal $e {ERR Number of keys can't be negative} - $master propagate-test.simple - $master propagate-test.mixed - - assert_replication_stream $repl { - {multi} - {select *} - {incr counter-1} - {incr counter-2} - {exec} - {multi} - {incr notifications} - {incr using-call} - {incr counter-1} - {incr counter-2} - {incr notifications} - {incr after-call} - {exec} - } - close_replication_stream $repl - } - - test {module propagates from multi-exec} { - set repl [attach_to_replication_stream] - - $master multi - $master propagate-test.simple - $master propagate-test.mixed - $master propagate-test.timer-nested-repl - $master exec - - wait_for_condition 500 10 { - [$replica get timer-nested-end] eq "1" - } else { - fail "The two counters don't match the expected value." - } - - assert_replication_stream $repl { - {multi} - {select *} - {incr counter-1} - {incr counter-2} - {incr notifications} - {incr using-call} - {incr counter-1} - {incr counter-2} - {incr notifications} - {incr after-call} - {exec} - {multi} - {incrby timer-nested-start 1} - {incr notifications} - {incr using-call} - {incr counter-1} - {incr counter-2} - {incr counter-3} - {incr counter-4} - {incr notifications} - {incr after-call} - {incr notifications} - {incr before-call-2} - {incr notifications} - {incr asdf} - {incr notifications} - {del asdf} - {incr notifications} - {incr after-call-2} - {incr notifications} - {incr timer-nested-middle} - {incrby timer-nested-end 1} - {exec} - } - close_replication_stream $repl - - # Note propagate-test.timer-nested just propagates INCRBY, causing an - # inconsistency, so we flush - $master flushall - } - - test {module RM_Call of expired key propagation} { - $master debug set-active-expire 0 - - $master set k1 900 px 100 - after 110 - - set repl [attach_to_replication_stream] - $master propagate-test.incr k1 - - assert_replication_stream $repl { - {multi} - {select *} - {del k1} - {propagate-test.incr k1} - {exec} - } - close_replication_stream $repl - - assert_equal [$master get k1] 1 - assert_equal [$master ttl k1] -1 - - wait_for_condition 50 100 { - [$replica get k1] eq 1 && - [$replica ttl k1] eq -1 - } else { - fail "failed RM_Call of expired key propagation" - } - } - - test {module notification on set} { - set repl [attach_to_replication_stream] - - $master SADD s foo - - wait_for_condition 500 10 { - [$replica SCARD s] eq "1" - } else { - fail "Failed to wait for set to be replicated" - } - - $master SPOP s 1 - - wait_for_condition 500 10 { - [$replica SCARD s] eq "0" - } else { - fail "Failed to wait for set to be replicated" - } - - # Currently the `del` command comes after the notification. - # When we fix spop to fire notification at the end (like all other commands), - # the `del` will come first. - assert_replication_stream $repl { - {multi} - {select *} - {incr notifications} - {sadd s foo} - {exec} - {multi} - {incr notifications} - {incr notifications} - {del s} - {exec} - } - close_replication_stream $repl - } - - test {module key miss notification do not cause read command to be replicated} { - set repl [attach_to_replication_stream] - - $master flushall - - $master get unexisting_key - - wait_for_condition 500 10 { - [$replica get missed] eq "1" - } else { - fail "Failed to wait for set to be replicated" - } - - # Test is checking a wrong!!! behavior that causes a read command to be replicated to replica/aof. - # We keep the test to verify that such a wrong behavior does not cause any crashes. - assert_replication_stream $repl { - {select *} - {flushall} - {multi} - {incr notifications} - {incr missed} - {get unexisting_key} - {exec} - } - - close_replication_stream $repl - } - - test "Unload the module - propagate-test/testkeyspace" { - assert_equal {OK} [r module unload propagate-test] - assert_equal {OK} [r module unload testkeyspace] - } - - assert_equal [s -1 unexpected_error_replies] 0 - } - } - } -} - - -tags "modules aof external:skip" { - foreach aofload_type {debug_cmd startup} { - test "Modules RM_Replicate replicates MULTI/EXEC correctly: AOF-load type $aofload_type" { - start_server [list overrides [list loadmodule "$testmodule"]] { - # Enable the AOF - r config set appendonly yes - r config set auto-aof-rewrite-percentage 0 ; # Disable auto-rewrite. - waitForBgrewriteaof r - - r propagate-test.simple - r propagate-test.mixed - r multi - r propagate-test.simple - r propagate-test.mixed - r exec - - assert_equal [r get counter-1] {} - assert_equal [r get counter-2] {} - assert_equal [r get using-call] 2 - assert_equal [r get after-call] 2 - assert_equal [r get notifications] 4 - - # Load the AOF - if {$aofload_type == "debug_cmd"} { - r debug loadaof - } else { - r config rewrite - restart_server 0 true false - wait_done_loading r - } - - # This module behaves bad on purpose, it only calls - # RM_Replicate for counter-1 and counter-2 so values - # after AOF-load are different - assert_equal [r get counter-1] 4 - assert_equal [r get counter-2] 4 - assert_equal [r get using-call] 2 - assert_equal [r get after-call] 2 - # 4+4+2+2 commands from AOF (just above) + 4 "INCR notifications" from AOF + 4 notifications for these INCRs - assert_equal [r get notifications] 20 - - assert_equal {OK} [r module unload propagate-test] - assert_equal [s 0 unexpected_error_replies] 0 - } - } - test "Modules RM_Call does not update stats during aof load: AOF-load type $aofload_type" { - start_server [list overrides [list loadmodule "$miscmodule"]] { - # Enable the AOF - r config set appendonly yes - r config set auto-aof-rewrite-percentage 0 ; # Disable auto-rewrite. - waitForBgrewriteaof r - - r config resetstat - r set foo bar - r EVAL {return redis.call('SET', KEYS[1], ARGV[1])} 1 foo bar2 - r test.rm_call_replicate set foo bar3 - r EVAL {return redis.call('test.rm_call_replicate',ARGV[1],KEYS[1],ARGV[2])} 1 foo set bar4 - - r multi - r set foo bar5 - r EVAL {return redis.call('SET', KEYS[1], ARGV[1])} 1 foo bar6 - r test.rm_call_replicate set foo bar7 - r EVAL {return redis.call('test.rm_call_replicate',ARGV[1],KEYS[1],ARGV[2])} 1 foo set bar8 - r exec - - assert_match {*calls=8,*,rejected_calls=0,failed_calls=0} [cmdrstat set r] - - - # Load the AOF - if {$aofload_type == "debug_cmd"} { - r config resetstat - r debug loadaof - } else { - r config rewrite - restart_server 0 true false - wait_done_loading r - } - - assert_no_match {*calls=*} [cmdrstat set r] - - } - } - } -} - -# This test does not really test module functionality, but rather uses a module -# command to test Redis replication mechanisms. -test {Replicas that was marked as CLIENT_CLOSE_ASAP should not keep the replication backlog from been trimmed} { - start_server [list overrides [list loadmodule "$testmodule"] tags {"external:skip"}] { - set replica [srv 0 client] - start_server [list overrides [list loadmodule "$testmodule"] tags {"external:skip"}] { - set master [srv 0 client] - set master_host [srv 0 host] - set master_port [srv 0 port] - $master config set client-output-buffer-limit "replica 10mb 5mb 0" - - # Start the replication process... - $replica replicaof $master_host $master_port - wait_for_sync $replica - - test {module propagates from timer} { - # Replicate large commands to make the replica disconnected. - $master write [format_command propagate-test.verbatim 100000 [string repeat "a" 1000]] ;# almost 100mb - # Execute this command together with module commands within the same - # event loop to prevent periodic cleanup of replication backlog. - $master write [format_command info memory] - $master flush - $master read ;# propagate-test.verbatim - set res [$master read] ;# info memory - - # Wait for the replica to be disconnected. - wait_for_log_messages 0 {"*flags=S*scheduled to be closed ASAP for overcoming of output buffer limits*"} 0 1500 10 - # Due to the replica reaching the soft limit (5MB), memory peaks should not significantly - # exceed the replica soft limit. Furthermore, as the replica release its reference to - # replication backlog, it should be properly trimmed, the memory usage of replication - # backlog should not significantly exceed repl-backlog-size (default 1MB). */ - assert_lessthan [getInfoProperty $res used_memory_peak] 20000000;# less than 20mb - assert_lessthan [getInfoProperty $res mem_replication_backlog] 2000000;# less than 2mb - } - } - } -} |
