From 24e60859a4b9e73dc146461aed63a43aa6b20c85 Mon Sep 17 00:00:00 2001 From: "gd.zhou" Date: Tue, 29 Sep 2026 19:46:54 +0800 Subject: [PATCH] [feat] intercept swap-unsupported data type commands stream commands (XADD, XREADGROUP, XGROUP, XSETID, XACK, XCLAIM, XAUTOCLAIM, XDEL, XTRIM) operate on data types that swap does not support. Add a flag-based mechanism to intercept and count these commands with an operator-controlled opt-in switch. Flags (CMD_SWAP_HARD_BLOCKED, CMD_SWAP_OPT_IN) are parsed from sflags and recognized by module flags. Counters are exposed via swap.info output. Master propagates opt-in setting via swap.info. A swap.debug reset-cmd-stats command clears the counters. A new unit test (swap/unit/swap_unsupport_cmd) covers opt-in on/off, counter increment, reset, and swap.info output. --- deps/xredis-gtid | 2 +- src/config.c | 1 + src/ctrip_swap.h | 4 + src/ctrip_swap_cmd.c | 72 ++++++--- src/ctrip_swap_server.c | 3 + src/ctrip_swap_server.h | 9 ++ src/ctrip_swap_stat.c | 15 ++ src/module.c | 4 + src/scripting.c | 8 + src/server.c | 14 ++ src/server.h | 4 + tests/swap/unit/swap_unsupport_cmd.tcl | 193 +++++++++++++++++++++++++ tests/test_helper.tcl | 3 + 13 files changed, 310 insertions(+), 22 deletions(-) create mode 100644 tests/swap/unit/swap_unsupport_cmd.tcl diff --git a/deps/xredis-gtid b/deps/xredis-gtid index 7e829465c64..837ee264308 160000 --- a/deps/xredis-gtid +++ b/deps/xredis-gtid @@ -1 +1 @@ -Subproject commit 7e829465c642345e33a045fb903432db14de3db8 +Subproject commit 837ee264308d2b2544c4de55678eefcd291f176b diff --git a/src/config.c b/src/config.c index 7e19b6848db..8071139da10 100644 --- a/src/config.c +++ b/src/config.c @@ -3184,6 +3184,7 @@ standardConfig configs[] = { createBoolConfig("swap-rdb-bitmap-encode-enabled", NULL, MODIFIABLE_CONFIG, server.swap_rdb_bitmap_encode_enabled, 1, NULL, NULL), createBoolConfig("swap-bitmap-subkeys-enabled", NULL, MODIFIABLE_CONFIG, server.swap_bitmap_subkeys_enabled, 1, NULL, NULL), createBoolConfig("swap-ttl-compact-enabled", NULL, MODIFIABLE_CONFIG, server.swap_ttl_compact_enabled, 1, NULL, NULL), + createBoolConfig("swap-soft-block-cmd-enabled", NULL, MODIFIABLE_CONFIG, server.swap_soft_block_cmd_enabled, 0, NULL, NULL), createBoolConfig("rocksdb.data.cache_index_and_filter_blocks", "rocksdb.cache_index_and_filter_blocks", IMMUTABLE_CONFIG, server.rocksdb_data_cache_index_and_filter_blocks, 0, NULL, NULL), createBoolConfig("rocksdb.meta.cache_index_and_filter_blocks", NULL, IMMUTABLE_CONFIG, server.rocksdb_meta_cache_index_and_filter_blocks, 0, NULL, NULL), createBoolConfig("rocksdb.enable_pipelined_write", NULL, IMMUTABLE_CONFIG, server.rocksdb_enable_pipelined_write, 0, NULL, NULL), diff --git a/src/ctrip_swap.h b/src/ctrip_swap.h index e6e465196f5..6ae67d89f22 100644 --- a/src/ctrip_swap.h +++ b/src/ctrip_swap.h @@ -2089,6 +2089,10 @@ void swapApplySwapInfo(int swap_info_argc, sds *swap_info_argv); int submitReplClientRequests(client *c); sds genSwapReplInfoString(sds info); +/* Command */ +sds genSwapCommandInfoString(sds info); +int swapCmdShouldBlock(client *c, struct redisCommand *cmd); + /* Swap */ void swapInit(void); int dbSwap(client *c); diff --git a/src/ctrip_swap_cmd.c b/src/ctrip_swap_cmd.c index b43cb6a933e..a08d5fba90f 100644 --- a/src/ctrip_swap_cmd.c +++ b/src/ctrip_swap_cmd.c @@ -870,64 +870,64 @@ struct redisCommand redisCommandTable[SWAP_CMD_COUNT] = { 0,NULL,NULL,SWAP_IN,0,2,2,1,0,0,0}, {"xadd",xaddCommand,-5, - "write use-memory fast random @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + "write use-memory fast random swap-soft-blocked @stream", + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xrange",xrangeCommand,-4, "read-only @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xrevrange",xrevrangeCommand,-4, "read-only @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xlen",xlenCommand,2, "read-only fast @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xread",xreadCommand,-4, "read-only @stream @blocking", - 0,xreadGetKeys,NULL,SWAP_IN,0,0,0,0,0,0,0}, + 0,xreadGetKeys,NULL,SWAP_NOP,0,0,0,0,0,0,0}, {"xreadgroup",xreadCommand,-7, - "write @stream @blocking", - 0,xreadGetKeys,NULL,SWAP_IN,0,0,0,0,0,0,0}, + "write swap-soft-blocked @stream @blocking", + 0,xreadGetKeys,NULL,SWAP_NOP,0,0,0,0,0,0,0}, {"xgroup",xgroupCommand,-2, - "write use-memory @stream", + "write use-memory swap-soft-blocked @stream", 0,NULL,NULL,SWAP_NOP,0,2,2,1,0,0,0}, {"xsetid",xsetidCommand,3, - "write use-memory fast @stream", + "write use-memory fast swap-soft-blocked @stream", 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xack",xackCommand,-4, - "write fast random @stream", + "write fast random swap-soft-blocked @stream", 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xpending",xpendingCommand,-3, "read-only random @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xclaim",xclaimCommand,-6, - "write random fast @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + "write random fast swap-soft-blocked @stream", + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xautoclaim",xautoclaimCommand,-6, - "write random fast @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + "write random fast swap-soft-blocked @stream", + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xinfo",xinfoCommand,-2, "read-only random @stream", - 0,NULL,NULL,SWAP_IN,0,2,2,1,0,0,0}, + 0,NULL,NULL,SWAP_NOP,0,2,2,1,0,0,0}, {"xdel",xdelCommand,-3, - "write fast @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + "write fast swap-soft-blocked @stream", + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"xtrim",xtrimCommand,-4, - "write random @stream", - 0,NULL,NULL,SWAP_IN,0,1,1,1,0,0,0}, + "write random swap-soft-blocked @stream", + 0,NULL,NULL,SWAP_NOP,0,1,1,1,0,0,0}, {"post",securityWarningCommand,-1, "ok-loading ok-stale read-only", @@ -2312,6 +2312,36 @@ void swapInfoCommand(client *c) { addReply(c,shared.ok); } +/* Return 1 when cmd must be rejected. The swap check lives inside so + * callers do not wrap the call in ENABLE_SWAP. */ +int swapCmdShouldBlock(client *c, struct redisCommand *cmd) { + + if (!cmd || + !(cmd->flags & (CMD_SWAP_HARD_BLOCKED|CMD_SWAP_SOFT_BLOCKED))) + return 0; + + if (c && (c->flags & CLIENT_MASTER)) { + server.swap_master_allowed_cmd_count++; + return 0; + } + /* AOF replay applies commands that were already accepted. */ + if (c && c->id == CLIENT_ID_AOF) + return 0; + + /* reject_blocked: local client, command refused. + * allowed_blocked: local client, soft-blocked command executed. */ + if (cmd->flags & CMD_SWAP_HARD_BLOCKED) { + server.swap_reject_blocked_cmd_count++; + return 1; + } + if (server.swap_soft_block_cmd_enabled) { + server.swap_reject_blocked_cmd_count++; + return 1; + } + server.swap_allowed_blocked_cmd_count++; + return 0; +} + #ifdef REDIS_TEST void rewriteResetClientCommandCString(client *c, int argc, ...) { diff --git a/src/ctrip_swap_server.c b/src/ctrip_swap_server.c index 30bacc2740e..d6dbbd590b1 100644 --- a/src/ctrip_swap_server.c +++ b/src/ctrip_swap_server.c @@ -244,6 +244,9 @@ void swapInitServer(void) { server.rocksdb_rdb_checkpoint_dir = NULL; server.rocksdb_internal_stats = NULL; server.swap_util_task_manager = createRocksdbUtilTaskManager(); + server.swap_reject_blocked_cmd_count = 0; + server.swap_allowed_blocked_cmd_count = 0; + server.swap_master_allowed_cmd_count = 0; asyncCompleteQueueInit(); parallelSyncInit(server.swap_ps_parallism_rdb); diff --git a/src/ctrip_swap_server.h b/src/ctrip_swap_server.h index d181b7c4600..d9ac9db8345 100644 --- a/src/ctrip_swap_server.h +++ b/src/ctrip_swap_server.h @@ -39,6 +39,11 @@ #define CMD_SWAP_DATATYPE_LIST (1ULL<<46) #define CMD_SWAP_DATATYPE_BITMAP (1ULL<<47) +/*cmd flag*/ +#define CMD_SWAP_HARD_BLOCKED (1ULL<<48) +#define CMD_SWAP_SOFT_BLOCKED (1ULL<<49) + + /* CHECK: CLIENT_REPL_RDBONLY is the last CLIENT_xx flag */ #define CLIENT_SWAPPING (1ULL<<43) /* The client is waiting swap. */ #define CLIENT_SWAP_UNLOCKING (1ULL<<44) /* Client is releasing swap lock. */ @@ -346,6 +351,10 @@ typedef struct swapBatchLimitsConfig { /* for swap.info command, which propagate system info to replica */ \ int swap_swap_info_supported; \ int swap_swap_info_propagate_mode; \ + int swap_soft_block_cmd_enabled; \ + long long swap_reject_blocked_cmd_count; \ + long long swap_allowed_blocked_cmd_count; \ + long long swap_master_allowed_cmd_count; \ unsigned long long swap_swap_info_slave_period; /* Master send cmd swap.info to the slave every N seconds */ #ifdef __APPLE__ diff --git a/src/ctrip_swap_stat.c b/src/ctrip_swap_stat.c index 12a7e30c9d2..0802e162875 100644 --- a/src/ctrip_swap_stat.c +++ b/src/ctrip_swap_stat.c @@ -348,6 +348,20 @@ void trackSwapInstantaneousMetrics() { trackSwapRateLimitInstantaneousMetrics(); } + +sds genSwapCommandInfoString(sds info) { + + info = sdscatprintf(info, + "swap_cmd_stats:" + "reject_blocked=%lld," + "allowed_blocked=%lld," + "master_allowed=%lld\r\n", + server.swap_reject_blocked_cmd_count, + server.swap_allowed_blocked_cmd_count, + server.swap_master_allowed_cmd_count); + return info; +} + sds genSwapInfoString(sds info) { info = genSwapStorageInfoString(info); info = genSwapHitInfoString(info); @@ -365,6 +379,7 @@ sds genSwapInfoString(sds info) { info = genSwapBitmapStringSwitchedInfoString(info); info = genSwapTtlCompactInfoString(info); info = genSwapFullCompactInfoString(info); + info = genSwapCommandInfoString(info); return info; } diff --git a/src/module.c b/src/module.c index aa56e7bc442..d3bf72db6c7 100644 --- a/src/module.c +++ b/src/module.c @@ -811,6 +811,10 @@ int64_t commandFlagsFromString(char *s) { else if (!strcasecmp(t,"getkeys-api")) flags |= CMD_MODULE_GETKEYS; else if (!strcasecmp(t,"no-cluster")) flags |= CMD_MODULE_NO_CLUSTER; else if (!strcasecmp(t,"gtid-non-determinism")) flags |= CMD_GTID_NON_DETERMINISM; +#ifdef ENABLE_SWAP + else if (!strcasecmp(t, "swap-hard-blocked")) flags |= CMD_SWAP_HARD_BLOCKED; + else if (!strcasecmp(t, "swap-soft-blocked")) flags |= CMD_SWAP_SOFT_BLOCKED; +#endif else break; } sdsfreesplitres(tokens,count); diff --git a/src/scripting.c b/src/scripting.c index ccd78a8bfa9..bd2d59da583 100644 --- a/src/scripting.c +++ b/src/scripting.c @@ -633,6 +633,14 @@ int luaRedisGenericCommand(lua_State *lua, int raise_error) { goto cleanup; } +#ifdef ENABLE_SWAP + if (swapCmdShouldBlock(server.lua_caller, cmd)) { + luaPushError(lua, + "Can't execute this command: data type is not supported by swap"); + goto cleanup; + } +#endif + /* Check the ACLs. */ int acl_errpos; int acl_retval = ACLCheckAllPerm(c,&acl_errpos); diff --git a/src/server.c b/src/server.c index 2f131804b93..f2594ac7740 100644 --- a/src/server.c +++ b/src/server.c @@ -3782,6 +3782,12 @@ int populateCommandTableParseFlags(struct redisCommand *c, char *strflags) { c->flags |= CMD_MAY_REPLICATE; } else if (!strcasecmp(flag, "gtid-non-determinism")) { c->flags |= CMD_GTID_NON_DETERMINISM; +#ifdef ENABLE_SWAP + } else if (!strcasecmp(flag, "swap-hard-blocked")) { + c->flags |= CMD_SWAP_HARD_BLOCKED; + } else if (!strcasecmp(flag, "swap-soft-blocked")) { + c->flags |= CMD_SWAP_SOFT_BLOCKED; +#endif } else { /* Parse ACL categories here if the flag name starts with @. */ uint64_t catflag; @@ -4571,6 +4577,14 @@ int processCommand(client *c) { rejectCommandFormat(c, "Previous master draining."); return C_OK; } + + + if (swapCmdShouldBlock(c, c->cmd)) { + rejectCommandFormat(c, + "-ERR Can't execute '%s' command: data type is not supported by swap", + c->cmd->name); + return C_OK; + } #endif /* Only allow a subset of commands in the context of Pub/Sub if the diff --git a/src/server.h b/src/server.h index 954df547905..326a3fbb36e 100644 --- a/src/server.h +++ b/src/server.h @@ -2369,6 +2369,10 @@ int getMaxmemoryState(size_t *total, size_t *logical, size_t *tofree, float *lev size_t freeMemoryGetNotCountedMemory(); int overMaxmemoryAfterAlloc(size_t moremem); int processCommand(client *c); +/* Return 1 when cmd must be rejected. Updates swap_cmd_stats when swap is + * enabled. caller is the originating client. Lua passes server.lua_caller + * because the fake Lua client does not carry CLIENT_MASTER. */ +int swapCmdShouldBlock(client *caller, struct redisCommand *cmd); int processPendingCommandsAndResetClient(client *c); void setupSignalHandlers(void); void removeSignalHandlers(void); diff --git a/tests/swap/unit/swap_unsupport_cmd.tcl b/tests/swap/unit/swap_unsupport_cmd.tcl new file mode 100644 index 00000000000..58a8cfe803e --- /dev/null +++ b/tests/swap/unit/swap_unsupport_cmd.tcl @@ -0,0 +1,193 @@ +start_server {tags {"swap-unsupport-cmd"}} { + r config set swap-soft-block-cmd-enabled yes + + test {stream write rejected when soft block enabled} { + catch {r xadd s * f v} err + assert_match "*not supported by swap*" $err + assert_equal 0 [r exists s] + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 1 + assert_equal [get_info_property r Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property r Swap swap_cmd_stats master_allowed] 0 + } + + test {swap_cmd_stats fields appear in info} { + set info [r info swap] + assert_match "*swap_cmd_stats:*" $info + assert_match "*reject_blocked=*" $info + assert_match "*allowed_blocked=*" $info + assert_match "*master_allowed=*" $info + } + + test {lua redis.call xadd rejected when soft block enabled} { + catch {r eval {return redis.call('xadd','s','*','f','v')} 0} err + assert_match "*not supported by swap*" $err + assert_equal 0 [r exists s] + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 2 + } + + test {lua redis.pcall xadd is blocked and the script can continue} { + assert_equal ok [r eval {redis.pcall('xadd','s','*','f','v'); redis.call('set','k','1'); return 'ok'} 0] + assert_equal 0 [r exists s] + assert_equal 1 [r exists k] + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 3 + } + + test {lua redis.call stops the script before the blocked xadd} { + catch {r eval {redis.call('set','k2','1'); return redis.call('xadd','s','*','f','v')} 0} err + assert_match "*not supported by swap*" $err + assert_equal 1 [r exists k2] + assert_equal 0 [r exists s] + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 4 + } + + test {lua evalsha xadd rejected when soft block enabled} { + set sha [r script load {return redis.call('xadd',KEYS[1],'*','f','v')}] + catch {r evalsha $sha 1 s} err + assert_match "*not supported by swap*" $err + assert_equal 0 [r exists s] + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 5 + } + + test {lua command without the soft-block flag is not counted} { + assert_equal PONG [r eval {return redis.call('ping')} 0] + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 5 + assert_equal [get_info_property r Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property r Swap swap_cmd_stats master_allowed] 0 + } + + test {multi xadd rejected when soft block enabled} { + r multi + catch {r xadd s * f v} err + assert_match "*not supported by swap*" $err + r discard + assert_equal 0 [r exists s] + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 6 + assert_equal [get_info_property r Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property r Swap swap_cmd_stats master_allowed] 0 + } + + test {multi command without the soft-block flag is not counted} { + r multi + r set k3 1 + r exec + assert_equal 1 [r get k3] + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 6 + assert_equal [get_info_property r Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property r Swap swap_cmd_stats master_allowed] 0 + } +} + +start_server {tags {"swap-unsupport-cmd"}} { + r config set swap-soft-block-cmd-enabled no + + test {stream write allowed when soft block disabled is counted} { + r xadd s * f v + r xadd s * f v + assert_equal [r xlen s] 2 + assert_equal [get_info_property r Swap swap_cmd_stats allowed_blocked] 2 + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 0 + assert_equal [get_info_property r Swap swap_cmd_stats master_allowed] 0 + } + + test {lua stream write allowed when soft block disabled is counted} { + r eval {return redis.call('xadd','slua','*','f','v')} 0 + r eval {return redis.pcall('xadd','slua','*','f','v')} 0 + assert_equal [r xlen slua] 2 + assert_equal [get_info_property r Swap swap_cmd_stats allowed_blocked] 4 + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 0 + assert_equal [get_info_property r Swap swap_cmd_stats master_allowed] 0 + } + + test {multi stream write allowed when soft block disabled is counted} { + r multi + r xadd smulti * f v + r xadd smulti * f v + r exec + assert_equal [r xlen smulti] 2 + assert_equal [get_info_property r Swap swap_cmd_stats allowed_blocked] 6 + assert_equal [get_info_property r Swap swap_cmd_stats reject_blocked] 0 + assert_equal [get_info_property r Swap swap_cmd_stats master_allowed] 0 + } +} + +start_server {tags {"swap-unsupport-cmd"} overrides {save ""}} { + set master [srv 0 client] + set master_host [srv 0 host] + set master_port [srv 0 port] + + start_server {tags {"swap-unsupport-cmd"} overrides {save ""}} { + set slave [srv 0 client] + $slave slaveof $master_host $master_port + wait_for_sync $slave + + # Master accepts the write so it is replicated. + # Slave rejects the same write from a local client. + $master config set swap-soft-block-cmd-enabled no + $slave config set swap-soft-block-cmd-enabled yes + $slave config set replica-read-only no + + test {master stream write is applied on slave and counted as master_allowed} { + $master xadd s * f v + wait_for_ofs_sync $master $slave + + assert_equal [$slave xlen s] 1 + assert_equal [get_info_property $slave Swap swap_cmd_stats master_allowed] 1 + assert_equal [get_info_property $slave Swap swap_cmd_stats reject_blocked] 0 + assert_equal [get_info_property $slave Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property $master Swap swap_cmd_stats allowed_blocked] 1 + assert_equal [get_info_property $master Swap swap_cmd_stats reject_blocked] 0 + assert_equal [get_info_property $master Swap swap_cmd_stats master_allowed] 0 + + catch {$slave xadd s * f local} err + assert_match "*not supported by swap*" $err + assert_equal [get_info_property $slave Swap swap_cmd_stats reject_blocked] 1 + assert_equal [get_info_property $slave Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property $slave Swap swap_cmd_stats master_allowed] 1 + assert_equal [$slave xlen s] 1 + } + + test {lua xadd from master is applied on slave and counted as master_allowed} { + $master eval {return redis.call('xadd','slua','*','f','v')} 0 + wait_for_ofs_sync $master $slave + + assert_equal [$slave xlen slua] 1 + assert_equal [get_info_property $slave Swap swap_cmd_stats master_allowed] 2 + assert_equal [get_info_property $slave Swap swap_cmd_stats reject_blocked] 1 + assert_equal [get_info_property $slave Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property $master Swap swap_cmd_stats allowed_blocked] 2 + assert_equal [get_info_property $master Swap swap_cmd_stats reject_blocked] 0 + assert_equal [get_info_property $master Swap swap_cmd_stats master_allowed] 0 + + catch {$slave eval {return redis.call('xadd','slua','*','f','local')} 0} err + assert_match "*not supported by swap*" $err + assert_equal [get_info_property $slave Swap swap_cmd_stats reject_blocked] 2 + assert_equal [get_info_property $slave Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property $slave Swap swap_cmd_stats master_allowed] 2 + assert_equal [$slave xlen slua] 1 + } + + test {multi xadd from master is applied on slave and counted as master_allowed} { + $master multi + $master xadd smulti * f v + $master exec + wait_for_ofs_sync $master $slave + + assert_equal [$slave xlen smulti] 1 + assert_equal [get_info_property $slave Swap swap_cmd_stats master_allowed] 3 + assert_equal [get_info_property $slave Swap swap_cmd_stats reject_blocked] 2 + assert_equal [get_info_property $slave Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property $master Swap swap_cmd_stats allowed_blocked] 3 + assert_equal [get_info_property $master Swap swap_cmd_stats reject_blocked] 0 + assert_equal [get_info_property $master Swap swap_cmd_stats master_allowed] 0 + + $slave multi + catch {$slave xadd smulti * f local} err + assert_match "*not supported by swap*" $err + $slave discard + assert_equal [get_info_property $slave Swap swap_cmd_stats reject_blocked] 3 + assert_equal [get_info_property $slave Swap swap_cmd_stats allowed_blocked] 0 + assert_equal [get_info_property $slave Swap swap_cmd_stats master_allowed] 3 + assert_equal [$slave xlen smulti] 1 + } + } +} diff --git a/tests/test_helper.tcl b/tests/test_helper.tcl index be87b69dff2..ee521edf8b8 100644 --- a/tests/test_helper.tcl +++ b/tests/test_helper.tcl @@ -98,6 +98,7 @@ set ::all_tests { } set ::disk_tests { + swap/unit/swap_unsupport_cmd swap/ported/integration/replication-psync swap/ported/integration/replication swap/ported/integration/replication-3 @@ -165,6 +166,8 @@ set ::disk_tests { swap/unit/metascan_multidb swap/unit/ltrim_check swap/unit/swap_thread_race_scaledown + unit/type/stream + unit/type/stream-cgroups } set ::all_tests [concat $::gtid_tests $::all_tests]