summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBinbin <binloveplay1314@qq.com>2023-04-27 14:32:14 +0800
committerGitHub <noreply@github.com>2023-04-27 09:32:14 +0300
commitd659c734569be4ed32a270bac2527ccf35418c43 (patch)
treeac24eb78d850a93a63adefefb5f0476d635df215
parent5ddc0af33e8d071d2883a12ceb10336fdd25f843 (diff)
downloadredis-d659c734569be4ed32a270bac2527ccf35418c43.tar.gz
Add missing reply schema and coverage tests (#12079)
The change in #12018 break the CI (fixed by #12083). There are quite a few sentinel commands that are missing both test coverage and also schema. PR added reply-schema to the following commands: - sentinel debug - sentinel info-cache - sentinel pendding-scripts - sentinel reset - sentinel simulate-failure Added some very basic tests for other sentinel commands, just so that they have some coverage. - sentinel help - sentinel masters - sentinel myid - sentinel sentinels - sentinel slaves These tests should be improved / replaced in a followup PR.
-rw-r--r--src/commands/sentinel-debug.json15
-rw-r--r--src/commands/sentinel-info-cache.json41
-rw-r--r--src/commands/sentinel-pending-scripts.json39
-rw-r--r--src/commands/sentinel-reset.json4
-rw-r--r--src/commands/sentinel-simulate-failure.json15
-rw-r--r--src/sentinel.c13
-rw-r--r--tests/sentinel/tests/00-base.tcl51
-rw-r--r--tests/sentinel/tests/05-manual.tcl25
-rwxr-xr-xutils/req-res-log-validator.py11
9 files changed, 197 insertions, 17 deletions
diff --git a/src/commands/sentinel-debug.json b/src/commands/sentinel-debug.json
index 186b1df9d..c671ec5e1 100644
--- a/src/commands/sentinel-debug.json
+++ b/src/commands/sentinel-debug.json
@@ -12,6 +12,21 @@
"SENTINEL",
"ONLY_SENTINEL"
],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The configuration update was successful.",
+ "const": "OK"
+ },
+ {
+ "description": "List of configurable time parameters and their values (milliseconds).",
+ "type": "object",
+ "additionalProperties": {
+ "type": "string"
+ }
+ }
+ ]
+ },
"arguments": [
{
"name": "data",
diff --git a/src/commands/sentinel-info-cache.json b/src/commands/sentinel-info-cache.json
index 29af975bc..af89f182e 100644
--- a/src/commands/sentinel-info-cache.json
+++ b/src/commands/sentinel-info-cache.json
@@ -12,6 +12,47 @@
"SENTINEL",
"ONLY_SENTINEL"
],
+ "reply_schema": {
+ "type": "array",
+ "description": "This is actually a map, the odd entries are a master name, and the even entries are the last cached INFO output from that master and all its replicas.",
+ "minItems": 0,
+ "maxItems": 4294967295,
+ "items": [
+ {
+ "oneOf": [
+ {
+ "type": "string",
+ "description": "The master name."
+ },
+ {
+ "type": "array",
+ "description": "This is an array of pairs, the odd entries are the INFO age, and the even entries are the cached INFO string. The first pair belong to the master and the rest are its replicas.",
+ "minItems": 2,
+ "maxItems": 2,
+ "items": [
+ {
+ "description": "The number of milliseconds since when the INFO was cached.",
+ "type": "integer"
+ },
+ {
+ "description": "The cached INFO string or null.",
+ "oneOf": [
+ {
+ "description": "The cached INFO string.",
+ "type": "string"
+ },
+ {
+ "description": "No cached INFO string.",
+ "type": "null"
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ }
+ ]
+ },
"arguments": [
{
"name": "nodename",
diff --git a/src/commands/sentinel-pending-scripts.json b/src/commands/sentinel-pending-scripts.json
index 141343149..22dae4774 100644
--- a/src/commands/sentinel-pending-scripts.json
+++ b/src/commands/sentinel-pending-scripts.json
@@ -10,6 +10,43 @@
"ADMIN",
"SENTINEL",
"ONLY_SENTINEL"
- ]
+ ],
+ "reply_schema": {
+ "type": "array",
+ "description": "List of pending scripts.",
+ "items": {
+ "type": "object",
+ "additionalProperties": false,
+ "properties": {
+ "argv": {
+ "type": "array",
+ "description": "Script arguments.",
+ "items": {
+ "type": "string"
+ }
+ },
+ "flags": {
+ "type": "string",
+ "description": "Script flags."
+ },
+ "pid": {
+ "type": "string",
+ "description": "Script pid."
+ },
+ "run-time": {
+ "type": "string",
+ "description": "Script run-time."
+ },
+ "run-delay": {
+ "type": "string",
+ "description": "Script run-delay."
+ },
+ "retry-num": {
+ "type": "string",
+ "description": "Number of times we tried to execute the script."
+ }
+ }
+ }
+ }
}
}
diff --git a/src/commands/sentinel-reset.json b/src/commands/sentinel-reset.json
index 14ccbd5a1..17b53a481 100644
--- a/src/commands/sentinel-reset.json
+++ b/src/commands/sentinel-reset.json
@@ -12,6 +12,10 @@
"SENTINEL",
"ONLY_SENTINEL"
],
+ "reply_schema": {
+ "type": "integer",
+ "description": "The number of masters that were reset."
+ },
"arguments": [
{
"name": "pattern",
diff --git a/src/commands/sentinel-simulate-failure.json b/src/commands/sentinel-simulate-failure.json
index 00aad668d..5031d44ae 100644
--- a/src/commands/sentinel-simulate-failure.json
+++ b/src/commands/sentinel-simulate-failure.json
@@ -11,6 +11,21 @@
"SENTINEL",
"ONLY_SENTINEL"
],
+ "reply_schema": {
+ "oneOf": [
+ {
+ "description": "The simulated flag was set.",
+ "const": "OK"
+ },
+ {
+ "description": "Supported simulates flags. Returned in case `HELP` was used.",
+ "type": "array",
+ "items": {
+ "type": "string"
+ }
+ }
+ ]
+ },
"arguments": [
{
"name": "mode",
diff --git a/src/sentinel.c b/src/sentinel.c
index 03482fdd2..3d5c3861c 100644
--- a/src/sentinel.c
+++ b/src/sentinel.c
@@ -4071,11 +4071,14 @@ NULL
}
/* Reply format:
- * 1.) master name
- * 2.) 1.) info from master
- * 2.) info from replica
- * ...
- * 3.) other master name
+ * 1) master name
+ * 2) 1) 1) info cached ms
+ * 2) info from master
+ * 2) 1) info cached ms
+ * 2) info from replica1
+ * ...
+ * 3) other master name
+ * ...
* ...
*/
addReplyArrayLen(c,dictSize(masters_local) * 2);
diff --git a/tests/sentinel/tests/00-base.tcl b/tests/sentinel/tests/00-base.tcl
index 1b33ca7a3..b4d65751b 100644
--- a/tests/sentinel/tests/00-base.tcl
+++ b/tests/sentinel/tests/00-base.tcl
@@ -31,6 +31,50 @@ test "Sentinel command flag infrastructure works correctly" {
}
}
+test "SENTINEL HELP output the sentinel subcommand help" {
+ assert_match "*SENTINEL <subcommand> *" [S 0 SENTINEL HELP]
+}
+
+test "SENTINEL MYID return the sentinel instance ID" {
+ assert_equal 40 [string length [S 0 SENTINEL MYID]]
+ assert_equal [S 0 SENTINEL MYID] [S 0 SENTINEL MYID]
+}
+
+test "SENTINEL INFO CACHE returns the cached info" {
+ set res [S 0 SENTINEL INFO-CACHE mymaster]
+ assert_morethan_equal [llength $res] 2
+ assert_equal "mymaster" [lindex $res 0]
+
+ set res [lindex $res 1]
+ assert_morethan_equal [llength $res] 2
+ assert_morethan [lindex $res 0] 0
+ assert_match "*# Server*" [lindex $res 1]
+}
+
+test "SENTINEL PENDING-SCRIPTS returns the information about pending scripts" {
+ # may or may not have a value, so assert greater than or equal to 0.
+ assert_morethan_equal [llength [S 0 SENTINEL PENDING-SCRIPTS]] 0
+}
+
+test "SENTINEL MASTERS returns a list of monitored masters" {
+ assert_match "*mymaster*" [S 0 SENTINEL MASTERS]
+ assert_morethan_equal [llength [S 0 SENTINEL MASTERS]] 1
+}
+
+test "SENTINEL SENTINELS returns a list of sentinel instances" {
+ assert_morethan_equal [llength [S 0 SENTINEL SENTINELS mymaster]] 1
+}
+
+test "SENTINEL SLAVES returns a list of the monitored replicas" {
+ assert_morethan_equal [llength [S 0 SENTINEL SLAVES mymaster]] 1
+}
+
+test "SENTINEL SIMULATE-FAILURE HELP list supported flags" {
+ set res [S 0 SENTINEL SIMULATE-FAILURE HELP]
+ assert_morethan_equal [llength $res] 2
+ assert_equal {crash-after-election crash-after-promotion} $res
+}
+
test "Basic failover works if the master is down" {
set old_port [RPort $master_id]
set addr [S 0 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster]
@@ -149,3 +193,10 @@ test "Failover works if we configure for absolute agreement" {
test "New master [join $addr {:}] role matches" {
assert {[RI $master_id role] eq {master}}
}
+
+test "SENTINEL RESET can resets the master" {
+ assert_equal 1 [S 0 SENTINEL RESET mymaster]
+ assert_equal 0 [llength [S 0 SENTINEL SENTINELS mymaster]]
+ assert_equal 0 [llength [S 0 SENTINEL SLAVES mymaster]]
+ assert_equal 0 [llength [S 0 SENTINEL REPLICAS mymaster]]
+}
diff --git a/tests/sentinel/tests/05-manual.tcl b/tests/sentinel/tests/05-manual.tcl
index 72d80fdf8..7e050b0dc 100644
--- a/tests/sentinel/tests/05-manual.tcl
+++ b/tests/sentinel/tests/05-manual.tcl
@@ -61,3 +61,28 @@ test "The old master eventually gets reconfigured as a slave" {
fail "Old master not reconfigured as slave of new master"
}
}
+
+foreach flag {crash-after-election crash-after-promotion} {
+ test "SENTINEL SIMULATE-FAILURE $flag works" {
+ assert_equal {OK} [S 0 SENTINEL SIMULATE-FAILURE $flag]
+
+ # Trigger a failover, failover will trigger leader election, replica promotion
+ wait_for_condition 300 50 {
+ [catch {S 0 SENTINEL FAILOVER mymaster}] == 0
+ } else {
+ catch {S 0 SENTINEL FAILOVER mymaster} reply
+ puts [S 0 SENTINEL REPLICAS mymaster]
+ fail "Sentinel manual failover did not work, got: $reply"
+ }
+
+ # Wait for sentinel to exit (due to simulate-failure flags)
+ wait_for_condition 1000 50 {
+ [catch {S 0 PING}] == 1
+ } else {
+ fail "Sentinel set $flag but did not exit"
+ }
+ assert_error {*couldn't open socket: connection refused*} {S 0 PING}
+
+ restart_instance sentinel 0
+ }
+}
diff --git a/utils/req-res-log-validator.py b/utils/req-res-log-validator.py
index 1f11b0307..46c110019 100755
--- a/utils/req-res-log-validator.py
+++ b/utils/req-res-log-validator.py
@@ -58,17 +58,6 @@ IGNORED_COMMANDS = {
# Commands to which we decided not write a reply schema
"pfdebug",
"lolwut",
- # TODO: write a reply schema for the following commands
- "sentinel|debug",
- "sentinel|info-cache",
- "sentinel|pending-scripts",
- "sentinel|reset",
- "sentinel|simulate-failure",
- "sentinel|help",
- "sentinel|masters",
- "sentinel|myid",
- "sentinel|sentinels",
- "sentinel|slaves",
}
class Request(object):