Sentinel framework new layout back ported 2.8.

Functionally the same, but makes cherry picking simpler.
This commit is contained in:
antirez 2014-06-18 16:14:33 +02:00
parent f392c7737c
commit eef369b66a
10 changed files with 67 additions and 35 deletions

View File

@ -11,4 +11,4 @@ then
echo "You need tcl 8.5 or newer in order to run the Redis Sentinel test" echo "You need tcl 8.5 or newer in order to run the Redis Sentinel test"
exit 1 exit 1
fi fi
$TCLSH tests/sentinel.tcl $* $TCLSH tests/sentinel/run.tcl $*

View File

@ -1,14 +1,19 @@
# Sentinel test suite. Copyright (C) 2014 Salvatore Sanfilippo antirez@gmail.com # Multi-instance test framework.
# This is used in order to test Sentinel and Redis Cluster, and provides
# basic capabilities for spawning and handling N parallel Redis / Sentinel
# instances.
#
# Copyright (C) 2014 Salvatore Sanfilippo antirez@gmail.com
# This softare is released under the BSD License. See the COPYING file for # This softare is released under the BSD License. See the COPYING file for
# more information. # more information.
package require Tcl 8.5 package require Tcl 8.5
set tcl_precision 17 set tcl_precision 17
source tests/support/redis.tcl source ../support/redis.tcl
source tests/support/util.tcl source ../support/util.tcl
source tests/support/server.tcl source ../support/server.tcl
source tests/support/test.tcl source ../support/test.tcl
set ::verbose 0 set ::verbose 0
set ::pause_on_error 0 set ::pause_on_error 0
@ -17,45 +22,50 @@ set ::sentinel_instances {}
set ::redis_instances {} set ::redis_instances {}
set ::sentinel_base_port 20000 set ::sentinel_base_port 20000
set ::redis_base_port 30000 set ::redis_base_port 30000
set ::instances_count 5 ; # How many Sentinels / Instances we use at max
set ::pids {} ; # We kill everything at exit set ::pids {} ; # We kill everything at exit
set ::dirs {} ; # We remove all the temp dirs at exit set ::dirs {} ; # We remove all the temp dirs at exit
set ::run_matching {} ; # If non empty, only tests matching pattern are run. set ::run_matching {} ; # If non empty, only tests matching pattern are run.
if {[catch {cd tests/sentinel-tmp}]} { if {[catch {cd tmp}]} {
puts "tests/sentinel-tmp directory not found." puts "tmp directory not found."
puts "Please run this test from the Redis source root." puts "Please run this test from the Redis source root."
exit 1 exit 1
} }
# Spawn a redis or sentinel instance, depending on 'type'. # Spawn a redis or sentinel instance, depending on 'type'.
proc spawn_instance {type base_port count} { proc spawn_instance {type base_port count {conf {}}} {
for {set j 0} {$j < $count} {incr j} { for {set j 0} {$j < $count} {incr j} {
set port [find_available_port $base_port] set port [find_available_port $base_port]
incr base_port incr base_port
puts "Starting $type #$j at port $port" puts "Starting $type #$j at port $port"
# Create a directory for this Sentinel. # Create a directory for this instance.
set dirname "${type}_${j}" set dirname "${type}_${j}"
lappend ::dirs $dirname lappend ::dirs $dirname
catch {exec rm -rf $dirname} catch {exec rm -rf $dirname}
file mkdir $dirname file mkdir $dirname
# Write the Sentinel config file. # Write the instance config file.
set cfgfile [file join $dirname $type.conf] set cfgfile [file join $dirname $type.conf]
set cfg [open $cfgfile w] set cfg [open $cfgfile w]
puts $cfg "port $port" puts $cfg "port $port"
puts $cfg "dir ./$dirname" puts $cfg "dir ./$dirname"
puts $cfg "logfile log.txt" puts $cfg "logfile log.txt"
# Add additional config files
foreach directive $conf {
puts $cfg $directive
}
close $cfg close $cfg
# Finally exec it and remember the pid for later cleanup. # Finally exec it and remember the pid for later cleanup.
if {$type eq "redis"} { if {$type eq "redis"} {
set prgname redis-server set prgname redis-server
} else { } elseif {$type eq "sentinel"} {
set prgname redis-sentinel set prgname redis-sentinel
} else {
error "Unknown instance type."
} }
set pid [exec ../../src/${prgname} $cfgfile &] set pid [exec ../../../src/${prgname} $cfgfile &]
lappend ::pids $pid lappend ::pids $pid
# Check availability # Check availability
@ -64,11 +74,13 @@ proc spawn_instance {type base_port count} {
} }
# Push the instance into the right list # Push the instance into the right list
set link [redis 127.0.0.1 $port]
$link reconnect 1
lappend ::${type}_instances [list \ lappend ::${type}_instances [list \
pid $pid \ pid $pid \
host 127.0.0.1 \ host 127.0.0.1 \
port $port \ port $port \
link [redis 127.0.0.1 $port] \ link $link \
] ]
} }
} }
@ -116,14 +128,6 @@ proc parse_options {} {
} }
} }
proc main {} {
parse_options
spawn_instance sentinel $::sentinel_base_port $::instances_count
spawn_instance redis $::redis_base_port $::instances_count
run_tests
cleanup
}
# If --pause-on-error option was passed at startup this function is called # If --pause-on-error option was passed at startup this function is called
# on error in order to give the developer a chance to understand more about # on error in order to give the developer a chance to understand more about
# the error condition while the instances are still running. # the error condition while the instances are still running.
@ -139,6 +143,14 @@ proc pause_on_error {} {
set cmd [lindex $argv 0] set cmd [lindex $argv 0]
if {$cmd eq {continue}} { if {$cmd eq {continue}} {
break break
} elseif {$cmd eq {show-redis-logs}} {
set count 10
if {[lindex $argv 1] ne {}} {set count [lindex $argv 1]}
foreach_redis_id id {
puts "=== REDIS $id ===="
puts [exec tail -$count redis_$id/log.txt]
puts "---------------------\n"
}
} elseif {$cmd eq {show-sentinel-logs}} { } elseif {$cmd eq {show-sentinel-logs}} {
set count 10 set count 10
if {[lindex $argv 1] ne {}} {set count [lindex $argv 1]} if {[lindex $argv 1] ne {}} {set count [lindex $argv 1]}
@ -182,6 +194,7 @@ proc pause_on_error {} {
} elseif {$cmd eq {help}} { } elseif {$cmd eq {help}} {
puts "ls List Sentinel and Redis instances." puts "ls List Sentinel and Redis instances."
puts "show-sentinel-logs \[N\] Show latest N lines of logs." puts "show-sentinel-logs \[N\] Show latest N lines of logs."
puts "show-redis-logs \[N\] Show latest N lines of logs."
puts "S <id> cmd ... arg Call command in Sentinel <id>." puts "S <id> cmd ... arg Call command in Sentinel <id>."
puts "R <id> cmd ... arg Call command in Redis <id>." puts "R <id> cmd ... arg Call command in Redis <id>."
puts "SI <id> <field> Show Sentinel <id> INFO <field>." puts "SI <id> <field> Show Sentinel <id> INFO <field>."
@ -218,7 +231,7 @@ proc test {descr code} {
} }
proc run_tests {} { proc run_tests {} {
set tests [lsort [glob ../sentinel-tests/*]] set tests [lsort [glob ../tests/*]]
foreach test $tests { foreach test $tests {
if {$::run_matching ne {} && [string match $::run_matching $test] == 0} { if {$::run_matching ne {} && [string match $::run_matching $test] == 0} {
continue continue
@ -361,7 +374,7 @@ proc kill_instance {type id} {
# Return true of the instance of the specified type/id is killed. # Return true of the instance of the specified type/id is killed.
proc instance_is_killed {type id} { proc instance_is_killed {type id} {
set pid [get_instance_attrib $type $id pid] set pid [get_instance_attrib $type $id pid]
return $pid == -1 expr {$pid == -1}
} }
# Restart an instance previously killed by kill_instance # Restart an instance previously killed by kill_instance
@ -377,7 +390,7 @@ proc restart_instance {type id} {
} else { } else {
set prgname redis-sentinel set prgname redis-sentinel
} }
set pid [exec ../../src/${prgname} $cfgfile &] set pid [exec ../../../src/${prgname} $cfgfile &]
set_instance_attrib $type $id pid $pid set_instance_attrib $type $id pid $pid
lappend ::pids $pid lappend ::pids $pid
@ -387,11 +400,8 @@ proc restart_instance {type id} {
} }
# Connect with it with a fresh link # Connect with it with a fresh link
set_instance_attrib $type $id link [redis 127.0.0.1 $port] set link [redis 127.0.0.1 $port]
$link reconnect 1
set_instance_attrib $type $id link $link
} }
if {[catch main e]} {
puts $::errorInfo
cleanup
exit 1
}

22
tests/sentinel/run.tcl Normal file
View File

@ -0,0 +1,22 @@
# Sentinel test suite. Copyright (C) 2014 Salvatore Sanfilippo antirez@gmail.com
# This softare is released under the BSD License. See the COPYING file for
# more information.
cd tests/sentinel
source ../instances.tcl
set ::instances_count 5 ; # How many instances we use at max.
proc main {} {
parse_options
spawn_instance sentinel $::sentinel_base_port $::instances_count
spawn_instance redis $::redis_base_port $::instances_count
run_tests
cleanup
}
if {[catch main e]} {
puts $::errorInfo
cleanup
exit 1
}

View File

@ -1,6 +1,6 @@
# Check the basic monitoring and failover capabilities. # Check the basic monitoring and failover capabilities.
source "../sentinel-tests/includes/init-tests.tcl" source "../tests/includes/init-tests.tcl"
if {$::simulate_error} { if {$::simulate_error} {
test "This test will fail" { test "This test will fail" {

View File

@ -1,6 +1,6 @@
# Test Sentinel configuration consistency after partitions heal. # Test Sentinel configuration consistency after partitions heal.
source "../sentinel-tests/includes/init-tests.tcl" source "../tests/includes/init-tests.tcl"
test "We can failover with Sentinel 1 crashed" { test "We can failover with Sentinel 1 crashed" {
set old_port [RI $master_id tcp_port] set old_port [RI $master_id tcp_port]

View File

@ -5,7 +5,7 @@
# 2) That partitioned slaves point to new master when they are partitioned # 2) That partitioned slaves point to new master when they are partitioned
# away during failover and return at a latter time. # away during failover and return at a latter time.
source "../sentinel-tests/includes/init-tests.tcl" source "../tests/includes/init-tests.tcl"
proc 03_test_slaves_replication {} { proc 03_test_slaves_replication {} {
uplevel 1 { uplevel 1 {