summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorViktor Söderqvist <viktor.soderqvist@est.tech>2022-02-22 11:09:46 +0100
committerGitHub <noreply@github.com>2022-02-22 12:09:46 +0200
commite9ae03787e0a2e0484914737f82bfe216f8e9d52 (patch)
tree3294c22330518bf2b5681411b36ae042ad32bdcf /tests
parent47c51d0c7858dc8ce7747b78b73cf8cec2e59ff3 (diff)
downloadredis-e9ae03787e0a2e0484914737f82bfe216f8e9d52.tar.gz
Delete key doesn't dirty client who watched stale key (#10256)
When WATCH is called on a key that's already logically expired, avoid discarding the transaction when the keys is actually deleted. When WATCH is called, a flag is stored if the key is already expired at the time of watch. The expired key is not deleted, only checked. When a key is "touched", if it is deleted and it was already expired when a client watched it, the client is not marked as dirty. Co-authored-by: Oran Agra <oran@redislabs.com> Co-authored-by: zhaozhao.zz <zhaozhao.zz@alibaba-inc.com>
Diffstat (limited to 'tests')
-rw-r--r--tests/unit/multi.tcl85
1 files changed, 85 insertions, 0 deletions
diff --git a/tests/unit/multi.tcl b/tests/unit/multi.tcl
index 8a0b731d5..70e33b74b 100644
--- a/tests/unit/multi.tcl
+++ b/tests/unit/multi.tcl
@@ -147,6 +147,45 @@ start_server {tags {"multi"}} {
r debug set-active-expire 1
} {OK} {needs:debug}
+ test {WATCH stale keys should not fail EXEC} {
+ r del x
+ r debug set-active-expire 0
+ r set x foo px 1
+ after 2
+ r watch x
+ r multi
+ r ping
+ assert_equal {PONG} [r exec]
+ r debug set-active-expire 1
+ } {OK} {needs:debug}
+
+ test {Delete WATCHed stale keys should not fail EXEC} {
+ r del x
+ r debug set-active-expire 0
+ r set x foo px 1
+ after 2
+ r watch x
+ # EXISTS triggers lazy expiry/deletion
+ assert_equal 0 [r exists x]
+ r multi
+ r ping
+ assert_equal {PONG} [r exec]
+ r debug set-active-expire 1
+ } {OK} {needs:debug}
+
+ test {FLUSHDB while watching stale keys should not fail EXEC} {
+ r del x
+ r debug set-active-expire 0
+ r set x foo px 1
+ after 2
+ r watch x
+ r flushdb
+ r multi
+ r ping
+ assert_equal {PONG} [r exec]
+ r debug set-active-expire 1
+ } {OK} {needs:debug}
+
test {After successful EXEC key is no longer watched} {
r set x 30
r watch x
@@ -245,6 +284,52 @@ start_server {tags {"multi"}} {
r exec
} {} {singledb:skip}
+ test {SWAPDB does not touch watched stale keys} {
+ r flushall
+ r select 1
+ r debug set-active-expire 0
+ r set x foo px 1
+ after 2
+ r watch x
+ r swapdb 0 1 ; # expired key replaced with no key => no change
+ r multi
+ r ping
+ assert_equal {PONG} [r exec]
+ r debug set-active-expire 1
+ } {OK} {singledb:skip needs:debug}
+
+ test {SWAPDB does not touch non-existing key replaced with stale key} {
+ r flushall
+ r select 0
+ r debug set-active-expire 0
+ r set x foo px 1
+ after 2
+ r select 1
+ r watch x
+ r swapdb 0 1 ; # no key replaced with expired key => no change
+ r multi
+ r ping
+ assert_equal {PONG} [r exec]
+ r debug set-active-expire 1
+ } {OK} {singledb:skip needs:debug}
+
+ test {SWAPDB does not touch stale key replaced with another stale key} {
+ r flushall
+ r debug set-active-expire 0
+ r select 1
+ r set x foo px 1
+ r select 0
+ r set x bar px 1
+ after 2
+ r select 1
+ r watch x
+ r swapdb 0 1 ; # no key replaced with expired key => no change
+ r multi
+ r ping
+ assert_equal {PONG} [r exec]
+ r debug set-active-expire 1
+ } {OK} {singledb:skip needs:debug}
+
test {WATCH is able to remember the DB a key belongs to} {
r select 5
r set x 30