diff --git a/runtest-sentinel b/runtest-sentinel index 1650eea7..3fb1ef61 100755 --- a/runtest-sentinel +++ b/runtest-sentinel @@ -11,4 +11,4 @@ then echo "You need tcl 8.5 or newer in order to run the Redis Sentinel test" exit 1 fi -$TCLSH tests/sentinel.tcl $* +$TCLSH tests/sentinel/run.tcl $* diff --git a/tests/sentinel.tcl b/tests/instances.tcl similarity index 88% rename from tests/sentinel.tcl rename to tests/instances.tcl index b19cafc1..26d0737c 100644 --- a/tests/sentinel.tcl +++ b/tests/instances.tcl @@ -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 # more information. package require Tcl 8.5 set tcl_precision 17 -source tests/support/redis.tcl -source tests/support/util.tcl -source tests/support/server.tcl -source tests/support/test.tcl +source ../support/redis.tcl +source ../support/util.tcl +source ../support/server.tcl +source ../support/test.tcl set ::verbose 0 set ::pause_on_error 0 @@ -17,45 +22,50 @@ set ::sentinel_instances {} set ::redis_instances {} set ::sentinel_base_port 20000 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 ::dirs {} ; # We remove all the temp dirs at exit set ::run_matching {} ; # If non empty, only tests matching pattern are run. -if {[catch {cd tests/sentinel-tmp}]} { - puts "tests/sentinel-tmp directory not found." +if {[catch {cd tmp}]} { + puts "tmp directory not found." puts "Please run this test from the Redis source root." exit 1 } # 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} { set port [find_available_port $base_port] incr base_port puts "Starting $type #$j at port $port" - # Create a directory for this Sentinel. + # Create a directory for this instance. set dirname "${type}_${j}" lappend ::dirs $dirname catch {exec rm -rf $dirname} file mkdir $dirname - # Write the Sentinel config file. + # Write the instance config file. set cfgfile [file join $dirname $type.conf] set cfg [open $cfgfile w] puts $cfg "port $port" puts $cfg "dir ./$dirname" puts $cfg "logfile log.txt" + # Add additional config files + foreach directive $conf { + puts $cfg $directive + } close $cfg # Finally exec it and remember the pid for later cleanup. if {$type eq "redis"} { set prgname redis-server - } else { + } elseif {$type eq "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 # Check availability @@ -64,11 +74,13 @@ proc spawn_instance {type base_port count} { } # Push the instance into the right list + set link [redis 127.0.0.1 $port] + $link reconnect 1 lappend ::${type}_instances [list \ pid $pid \ host 127.0.0.1 \ 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 # on error in order to give the developer a chance to understand more about # the error condition while the instances are still running. @@ -139,6 +143,14 @@ proc pause_on_error {} { set cmd [lindex $argv 0] if {$cmd eq {continue}} { 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}} { set count 10 if {[lindex $argv 1] ne {}} {set count [lindex $argv 1]} @@ -182,6 +194,7 @@ proc pause_on_error {} { } elseif {$cmd eq {help}} { puts "ls List Sentinel and Redis instances." puts "show-sentinel-logs \[N\] Show latest N lines of logs." + puts "show-redis-logs \[N\] Show latest N lines of logs." puts "S cmd ... arg Call command in Sentinel ." puts "R cmd ... arg Call command in Redis ." puts "SI Show Sentinel INFO ." @@ -218,7 +231,7 @@ proc test {descr code} { } proc run_tests {} { - set tests [lsort [glob ../sentinel-tests/*]] + set tests [lsort [glob ../tests/*]] foreach test $tests { if {$::run_matching ne {} && [string match $::run_matching $test] == 0} { continue @@ -361,7 +374,7 @@ proc kill_instance {type id} { # Return true of the instance of the specified type/id is killed. proc instance_is_killed {type id} { set pid [get_instance_attrib $type $id pid] - return $pid == -1 + expr {$pid == -1} } # Restart an instance previously killed by kill_instance @@ -377,7 +390,7 @@ proc restart_instance {type id} { } else { set prgname redis-sentinel } - set pid [exec ../../src/${prgname} $cfgfile &] + set pid [exec ../../../src/${prgname} $cfgfile &] set_instance_attrib $type $id pid $pid lappend ::pids $pid @@ -387,11 +400,8 @@ proc restart_instance {type id} { } # 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 -} diff --git a/tests/sentinel/run.tcl b/tests/sentinel/run.tcl new file mode 100644 index 00000000..66198af9 --- /dev/null +++ b/tests/sentinel/run.tcl @@ -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 +} diff --git a/tests/sentinel-tests/00-base.tcl b/tests/sentinel/tests/00-base.tcl similarity index 98% rename from tests/sentinel-tests/00-base.tcl rename to tests/sentinel/tests/00-base.tcl index 26758de0..a79d0c37 100644 --- a/tests/sentinel-tests/00-base.tcl +++ b/tests/sentinel/tests/00-base.tcl @@ -1,6 +1,6 @@ # Check the basic monitoring and failover capabilities. -source "../sentinel-tests/includes/init-tests.tcl" +source "../tests/includes/init-tests.tcl" if {$::simulate_error} { test "This test will fail" { diff --git a/tests/sentinel-tests/01-conf-update.tcl b/tests/sentinel/tests/01-conf-update.tcl similarity index 95% rename from tests/sentinel-tests/01-conf-update.tcl rename to tests/sentinel/tests/01-conf-update.tcl index 4625ebd4..4998104d 100644 --- a/tests/sentinel-tests/01-conf-update.tcl +++ b/tests/sentinel/tests/01-conf-update.tcl @@ -1,6 +1,6 @@ # 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" { set old_port [RI $master_id tcp_port] diff --git a/tests/sentinel-tests/02-slaves-reconf.tcl b/tests/sentinel/tests/02-slaves-reconf.tcl similarity index 98% rename from tests/sentinel-tests/02-slaves-reconf.tcl rename to tests/sentinel/tests/02-slaves-reconf.tcl index 843c62dc..868bae5e 100644 --- a/tests/sentinel-tests/02-slaves-reconf.tcl +++ b/tests/sentinel/tests/02-slaves-reconf.tcl @@ -5,7 +5,7 @@ # 2) That partitioned slaves point to new master when they are partitioned # 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 {} { uplevel 1 { diff --git a/tests/sentinel-tests/03-runtime-reconf.tcl b/tests/sentinel/tests/03-runtime-reconf.tcl similarity index 100% rename from tests/sentinel-tests/03-runtime-reconf.tcl rename to tests/sentinel/tests/03-runtime-reconf.tcl diff --git a/tests/sentinel-tests/04-slave-selection.tcl b/tests/sentinel/tests/04-slave-selection.tcl similarity index 100% rename from tests/sentinel-tests/04-slave-selection.tcl rename to tests/sentinel/tests/04-slave-selection.tcl diff --git a/tests/sentinel-tests/includes/init-tests.tcl b/tests/sentinel/tests/includes/init-tests.tcl similarity index 100% rename from tests/sentinel-tests/includes/init-tests.tcl rename to tests/sentinel/tests/includes/init-tests.tcl diff --git a/tests/sentinel-tmp/.gitignore b/tests/sentinel/tmp/.gitignore similarity index 100% rename from tests/sentinel-tmp/.gitignore rename to tests/sentinel/tmp/.gitignore