diff options
| author | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-01-21 22:40:55 +0100 |
|---|---|---|
| committer | Mitja Felicijan <mitja.felicijan@gmail.com> | 2026-01-21 22:40:55 +0100 |
| commit | 5d8dfe892a2ea89f706ee140c3bdcfd89fe03fda (patch) | |
| tree | 1acdfa5220cd13b7be43a2a01368e80d306473ca /examples/redis-unstable/tests/unit/lazyfree.tcl | |
| parent | c7ab12bba64d9c20ccd79b132dac475f7bc3923e (diff) | |
| download | crep-5d8dfe892a2ea89f706ee140c3bdcfd89fe03fda.tar.gz | |
Add Redis source code for testing
Diffstat (limited to 'examples/redis-unstable/tests/unit/lazyfree.tcl')
| -rw-r--r-- | examples/redis-unstable/tests/unit/lazyfree.tcl | 200 |
1 files changed, 200 insertions, 0 deletions
diff --git a/examples/redis-unstable/tests/unit/lazyfree.tcl b/examples/redis-unstable/tests/unit/lazyfree.tcl new file mode 100644 index 0000000..2e60355 --- /dev/null +++ b/examples/redis-unstable/tests/unit/lazyfree.tcl @@ -0,0 +1,200 @@ +start_server {tags {"lazyfree"}} { + test "UNLINK can reclaim memory in background" { + set orig_mem [s used_memory] + set args {} + for {set i 0} {$i < 100000} {incr i} { + lappend args $i + } + r sadd myset {*}$args + assert {[r scard myset] == 100000} + set peak_mem [s used_memory] + assert {[r unlink myset] == 1} + assert {$peak_mem > $orig_mem+1000000} + wait_for_condition 50 100 { + [s used_memory] < $peak_mem && + [s used_memory] < $orig_mem*2 + } else { + fail "Memory is not reclaimed by UNLINK" + } + } + + test "FLUSHDB ASYNC can reclaim memory in background" { + # make the previous test is really done before sampling used_memory + wait_lazyfree_done r + + set orig_mem [s used_memory] + set args {} + for {set i 0} {$i < 100000} {incr i} { + lappend args $i + } + r sadd myset {*}$args + assert {[r scard myset] == 100000} + set peak_mem [s used_memory] + r flushdb async + assert {$peak_mem > $orig_mem+1000000} + wait_for_condition 50 100 { + [s used_memory] < $peak_mem && + [s used_memory] < $orig_mem*2 + } else { + fail "Memory is not reclaimed by FLUSHDB ASYNC" + } + } + + test "lazy free a stream with all types of metadata" { + # make the previous test is really done before doing RESETSTAT + wait_for_condition 50 100 { + [s lazyfree_pending_objects] == 0 + } else { + fail "lazyfree isn't done" + } + + r config resetstat + r config set stream-node-max-entries 5 + for {set j 0} {$j < 1000} {incr j} { + if {rand() < 0.9} { + r xadd stream * foo $j + } else { + r xadd stream * bar $j + } + } + r xgroup create stream mygroup 0 + set records [r xreadgroup GROUP mygroup Alice COUNT 2 STREAMS stream >] + r xdel stream [lindex [lindex [lindex [lindex $records 0] 1] 1] 0] + r xack stream mygroup [lindex [lindex [lindex [lindex $records 0] 1] 0] 0] + r unlink stream + + # make sure it was lazy freed + wait_for_condition 50 100 { + [s lazyfree_pending_objects] == 0 + } else { + fail "lazyfree isn't done" + } + assert_equal [s lazyfreed_objects] 1 + } {} {needs:config-resetstat} + + test "lazy free a stream with deleted cgroup" { + r config resetstat + r xadd s * a b + r xgroup create s bla $ + r xgroup destroy s bla + r unlink s + + # make sure it was not lazy freed + wait_for_condition 50 100 { + [s lazyfree_pending_objects] == 0 + } else { + fail "lazyfree isn't done" + } + assert_equal [s lazyfreed_objects] 0 + } {} {needs:config-resetstat} + + test "FLUSHALL SYNC optimized to run in bg as blocking FLUSHALL ASYNC" { + set num_keys 1000 + r config resetstat + + # Verify at start there are no lazyfree pending objects + assert_equal [s lazyfree_pending_objects] 0 + + # Fillup DB with items + populate $num_keys + + # Run FLUSHALL SYNC command, optimized as blocking ASYNC + r flushall + + # Verify all keys counted as lazyfreed + assert_equal [s lazyfreed_objects] $num_keys + } + + test "Run consecutive blocking FLUSHALL ASYNC successfully" { + r config resetstat + set rd [redis_deferring_client] + + # Fillup DB with items + r set x 1 + r set y 2 + + $rd write "FLUSHALL\r\nFLUSHALL\r\nFLUSHDB\r\n" + $rd flush + assert_equal [$rd read] {OK} + assert_equal [$rd read] {OK} + assert_equal [$rd read] {OK} + assert_equal [s lazyfreed_objects] 2 + $rd close + } + + test "FLUSHALL SYNC in MULTI not optimized to run as blocking FLUSHALL ASYNC" { + r config resetstat + + # Fillup DB with items + r set x 11 + r set y 22 + + # FLUSHALL SYNC in multi + r multi + r flushall + r exec + + # Verify flushall not run as lazyfree + assert_equal [s lazyfree_pending_objects] 0 + assert_equal [s lazyfreed_objects] 0 + } + + test "Client closed in the middle of blocking FLUSHALL ASYNC" { + set num_keys 100000 + r config resetstat + + # Fillup DB with items + populate $num_keys + + # close client in the middle of ongoing Blocking FLUSHALL ASYNC + set rd [redis_deferring_client] + $rd flushall + $rd close + + # Wait to verify all keys counted as lazyfreed + wait_for_condition 50 100 { + [s lazyfreed_objects] == $num_keys + } else { + fail "Unexpected number of lazyfreed_objects: [s lazyfreed_objects]" + } + } + + test "Pending commands in querybuf processed once unblocking FLUSHALL ASYNC" { + r config resetstat + set rd [redis_deferring_client] + + # Fillup DB with items + r set x 1 + r set y 2 + + $rd write "FLUSHALL\r\nPING\r\n" + $rd flush + assert_equal [$rd read] {OK} + assert_equal [$rd read] {PONG} + assert_equal [s lazyfreed_objects] 2 + $rd close + } + + test "Unblocks client blocked on lazyfree via REPLICAOF command" { + r config resetstat + set rd [redis_deferring_client] + + populate 50000 ;# Just to make flushdb async slower + $rd flushdb + + # Verify flushdb run as lazyfree + wait_for_condition 50 100 { + [s lazyfree_pending_objects] > 0 || + [s lazyfreed_objects] > 0 + } else { + fail "FLUSHDB didn't run as lazyfree" + } + + # Test that slaveof command unblocks clients without assertion failure + r slaveof 127.0.0.1 0 + assert_equal [$rd read] {OK} + $rd close + r ping + r slaveof no one + } {OK} {external:skip} +} |
