Skip to content

Commit

Permalink
Add missing reply schema and coverage tests (redis#12079)
Browse files Browse the repository at this point in the history
The change in redis#12018 break the CI (fixed by redis#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.
  • Loading branch information
enjoy-binbin authored Apr 27, 2023
1 parent 5ddc0af commit d659c73
Show file tree
Hide file tree
Showing 9 changed files with 197 additions and 17 deletions.
15 changes: 15 additions & 0 deletions src/commands/sentinel-debug.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
41 changes: 41 additions & 0 deletions src/commands/sentinel-info-cache.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
39 changes: 38 additions & 1 deletion src/commands/sentinel-pending-scripts.json
Original file line number Diff line number Diff line change
Expand Up @@ -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."
}
}
}
}
}
}
4 changes: 4 additions & 0 deletions src/commands/sentinel-reset.json
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@
"SENTINEL",
"ONLY_SENTINEL"
],
"reply_schema": {
"type": "integer",
"description": "The number of masters that were reset."
},
"arguments": [
{
"name": "pattern",
Expand Down
15 changes: 15 additions & 0 deletions src/commands/sentinel-simulate-failure.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
13 changes: 8 additions & 5 deletions src/sentinel.c
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
51 changes: 51 additions & 0 deletions tests/sentinel/tests/00-base.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -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]
Expand Down Expand Up @@ -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]]
}
25 changes: 25 additions & 0 deletions tests/sentinel/tests/05-manual.tcl
Original file line number Diff line number Diff line change
Expand Up @@ -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
}
}
11 changes: 0 additions & 11 deletions utils/req-res-log-validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,17 +58,6 @@
# 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):
Expand Down

0 comments on commit d659c73

Please sign in to comment.