X-Git-Url: https://git.saurik.com/redis.git/blobdiff_plain/c4669d257fd0a375e7a94d26538be9ad28ac6b19..994ed2bc552f4114b1f0c8dd3fd8aefaec6beeae:/tests/support/server.tcl diff --git a/tests/support/server.tcl b/tests/support/server.tcl index b752def0..c9275461 100644 --- a/tests/support/server.tcl +++ b/tests/support/server.tcl @@ -1,3 +1,6 @@ +set ::global_overrides {} +set ::tags {} + proc error_and_quit {config_file error} { puts "!!COULD NOT START REDIS-SERVER\n" puts "CONFIGURATION:" @@ -22,16 +25,23 @@ proc check_valgrind_errors stderr { } proc kill_server config { + # nothing to kill when running against external server + if {$::external} return + # nevermind if its already dead if {![is_alive $config]} { return } set pid [dict get $config pid] # check for leaks - catch { - if {[string match {*Darwin*} [exec uname -a]]} { - test "Check for memory leaks (pid $pid)" { - exec leaks $pid - } {*0 leaks*} + if {![dict exists $config "skipleaks"]} { + catch { + if {[string match {*Darwin*} [exec uname -a]]} { + tags {"leaks"} { + test "Check for memory leaks (pid $pid)" { + exec leaks $pid + } {*0 leaks*} + } + } } } @@ -73,14 +83,64 @@ proc ping_server {host port} { } close $fd } e]} { - puts "Can't PING server at $host:$port... $e" + if {$::verbose} { + puts -nonewline "." + } + } else { + if {$::verbose} { + puts -nonewline "ok" + } } return $retval } -set ::global_overrides {} -proc start_server {filename overrides {code undefined}} { - set data [split [exec cat "tests/assets/$filename"] "\n"] +# doesn't really belong here, but highly coupled to code in start_server +proc tags {tags code} { + set ::tags [concat $::tags $tags] + uplevel 1 $code + set ::tags [lrange $::tags 0 end-[llength $tags]] +} + +proc start_server {options {code undefined}} { + # If we are runnign against an external server, we just push the + # host/port pair in the stack the first time + if {$::external} { + if {[llength $::servers] == 0} { + set srv {} + dict set srv "host" $::host + dict set srv "port" $::port + set client [redis $::host $::port] + dict set srv "client" $client + $client select 9 + + # append the server to the stack + lappend ::servers $srv + } + uplevel 1 $code + return + } + + # setup defaults + set baseconfig "default.conf" + set overrides {} + set tags {} + + # parse options + foreach {option value} $options { + switch $option { + "config" { + set baseconfig $value } + "overrides" { + set overrides $value } + "tags" { + set tags $value + set ::tags [concat $::tags $value] } + default { + error "Unknown option $option" } + } + } + + set data [split [exec cat "tests/assets/$baseconfig"] "\n"] set config {} foreach line $data { if {[string length $line] > 0 && [string index $line 0] ne "#"} { @@ -98,9 +158,7 @@ proc start_server {filename overrides {code undefined}} { dict set config port [incr ::port] # apply overrides from global space and arguments - foreach override [concat $::global_overrides $overrides] { - set directive [lrange $override 0 0] - set arguments [lrange $override 1 end] + foreach {directive arguments} [concat $::global_overrides $overrides] { dict set config $directive $arguments } @@ -117,21 +175,46 @@ proc start_server {filename overrides {code undefined}} { set stderr [format "%s/%s" [dict get $config "dir"] "stderr"] if {$::valgrind} { - exec valgrind --leak-check=full ./redis-server $config_file > $stdout 2> $stderr & - after 2000 + exec valgrind --suppressions=src/valgrind.sup src/redis-server $config_file > $stdout 2> $stderr & } else { - exec ./redis-server $config_file > $stdout 2> $stderr & - after 500 + exec src/redis-server $config_file > $stdout 2> $stderr & } # check that the server actually started - if {$code ne "undefined" && ![ping_server $::host $::port]} { + # ugly but tries to be as fast as possible... + set retrynum 20 + set serverisup 0 + + if {$::verbose} { + puts -nonewline "=== ($tags) Starting server ${::host}:${::port} " + } + + after 10 + if {$code ne "undefined"} { + while {[incr retrynum -1]} { + catch { + if {[ping_server $::host $::port]} { + set serverisup 1 + } + } + if {$serverisup} break + after 50 + } + } else { + set serverisup 1 + } + + if {$::verbose} { + puts "" + } + + if {!$serverisup} { error_and_quit $config_file [exec cat $stderr] } # find out the pid while {![info exists pid]} { - regexp {^\[(\d+)\]} [exec head -n1 $stdout] _ pid + regexp {\[(\d+)\]} [exec cat $stdout] _ pid after 100 } @@ -142,7 +225,8 @@ proc start_server {filename overrides {code undefined}} { if {[dict exists $config port]} { set port [dict get $config port] } # setup config dict - dict set srv "config" $config_file + dict set srv "config_file" $config_file + dict set srv "config" $config dict set srv "pid" $pid dict set srv "host" $host dict set srv "port" $port @@ -165,31 +249,46 @@ proc start_server {filename overrides {code undefined}} { after 10 } - set client [redis $host $port] - dict set srv "client" $client - - # select the right db when we don't have to authenticate - if {![dict exists $config requirepass]} { - $client select 9 - } - # append the server to the stack lappend ::servers $srv - + + # connect client (after server dict is put on the stack) + reconnect + # execute provided block - catch { uplevel 1 $code } err + set num_tests $::num_tests + if {[catch { uplevel 1 $code } error]} { + set backtrace $::errorInfo + + # Kill the server without checking for leaks + dict set srv "skipleaks" 1 + kill_server $srv + + # Print warnings from log + puts [format "\nLogged warnings (pid %d):" [dict get $srv "pid"]] + set warnings [warnings_from_file [dict get $srv "stdout"]] + if {[string length $warnings] > 0} { + puts "$warnings" + } else { + puts "(none)" + } + puts "" + + error $error $backtrace + } + + # Don't do the leak check when no tests were run + if {$num_tests == $::num_tests} { + dict set srv "skipleaks" 1 + } # pop the server object set ::servers [lrange $::servers 0 end-1] - - kill_server $srv - if {[string length $err] > 0} { - puts "Error executing the suite, aborting..." - puts $err - exit 1 - } + set ::tags [lrange $::tags 0 end-[llength $tags]] + kill_server $srv } else { + set ::tags [lrange $::tags 0 end-[llength $tags]] set _ $srv } }