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.
This commit is contained in:
Binbin 2023-04-27 14:32:14 +08:00 committed by GitHub
parent 5ddc0af33e
commit d659c73456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 197 additions and 17 deletions

View File

@ -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",

View File

@ -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",

View File

@ -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."
}
}
}
}
}
}

View File

@ -12,6 +12,10 @@
"SENTINEL",
"ONLY_SENTINEL"
],
"reply_schema": {
"type": "integer",
"description": "The number of masters that were reset."
},
"arguments": [
{
"name": "pattern",

View File

@ -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",

View File

@ -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);

View File

@ -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]]
}

View File

@ -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
}
}

View File

@ -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):