summaryrefslogtreecommitdiff
path: root/tests
diff options
context:
space:
mode:
authorYossi Gottlieb <yossigo@gmail.com>2019-09-12 10:56:54 +0300
committerYossi Gottlieb <yossigo@gmail.com>2019-10-07 21:06:13 +0300
commitb087dd1db60ed23d9e59304deb0b1599437f6e23 (patch)
tree0533b9d4d626af5ab4b5fdb5d4a2eb500b12c163 /tests
parentf4d37173fef8a020fe99a7b98e32a9201113cc09 (diff)
downloadredis-b087dd1db60ed23d9e59304deb0b1599437f6e23.tar.gz
TLS: Connections refactoring and TLS support.
* Introduce a connection abstraction layer for all socket operations and integrate it across the code base. * Provide an optional TLS connections implementation based on OpenSSL. * Pull a newer version of hiredis with TLS support. * Tests, redis-cli updates for TLS support.
Diffstat (limited to 'tests')
-rw-r--r--tests/cluster/run.tcl1
-rw-r--r--tests/cluster/tests/04-resharding.tcl2
-rw-r--r--tests/cluster/tests/12-replica-migration-2.tcl4
-rw-r--r--tests/helpers/bg_block_op.tcl8
-rw-r--r--tests/helpers/bg_complex_data.tcl8
-rw-r--r--tests/helpers/gen_write_load.tcl8
-rw-r--r--tests/instances.tcl26
-rw-r--r--tests/integration/aof-race.tcl7
-rw-r--r--tests/integration/aof.tcl12
-rw-r--r--tests/integration/block-repl.tcl10
-rw-r--r--tests/integration/psync2-reg.tcl3
-rw-r--r--tests/integration/redis-cli.tcl9
-rw-r--r--tests/integration/replication.tcl14
-rw-r--r--tests/sentinel/tests/07-down-conditions.tcl3
-rw-r--r--tests/support/cli.tcl19
-rw-r--r--tests/support/cluster.tcl4
-rw-r--r--tests/support/redis.tcl20
-rw-r--r--tests/support/server.tcl32
-rw-r--r--tests/support/util.tcl4
-rw-r--r--tests/test_helper.tcl23
-rw-r--r--tests/unit/limits.tcl7
-rw-r--r--tests/unit/other.tcl6
-rw-r--r--tests/unit/protocol.tcl6
-rw-r--r--tests/unit/tls.tcl25
-rw-r--r--tests/unit/wait.tcl5
25 files changed, 215 insertions, 51 deletions
diff --git a/tests/cluster/run.tcl b/tests/cluster/run.tcl
index 93603ddc9..d9a7d7ee5 100644
--- a/tests/cluster/run.tcl
+++ b/tests/cluster/run.tcl
@@ -8,6 +8,7 @@ source ../instances.tcl
source ../../support/cluster.tcl ; # Redis Cluster client.
set ::instances_count 20 ; # How many instances we use at max.
+set ::tlsdir "../../tls"
proc main {} {
parse_options
diff --git a/tests/cluster/tests/04-resharding.tcl b/tests/cluster/tests/04-resharding.tcl
index 68fba135e..33f861dc5 100644
--- a/tests/cluster/tests/04-resharding.tcl
+++ b/tests/cluster/tests/04-resharding.tcl
@@ -4,6 +4,7 @@
# are preseved across iterations.
source "../tests/includes/init-tests.tcl"
+source "../../../tests/support/cli.tcl"
test "Create a 5 nodes cluster" {
create_cluster 5 5
@@ -79,6 +80,7 @@ test "Cluster consistency during live resharding" {
--cluster-to $target \
--cluster-slots 100 \
--cluster-yes \
+ {*}[rediscli_tls_config "../../../tests"] \
| [info nameofexecutable] \
../tests/helpers/onlydots.tcl \
&] 0]
diff --git a/tests/cluster/tests/12-replica-migration-2.tcl b/tests/cluster/tests/12-replica-migration-2.tcl
index 3d8b7b04b..dd18a979a 100644
--- a/tests/cluster/tests/12-replica-migration-2.tcl
+++ b/tests/cluster/tests/12-replica-migration-2.tcl
@@ -5,6 +5,7 @@
# other masters have slaves.
source "../tests/includes/init-tests.tcl"
+source "../../../tests/support/cli.tcl"
# Create a cluster with 5 master and 15 slaves, to make sure there are no
# empty masters and make rebalancing simpler to handle during the test.
@@ -33,7 +34,9 @@ test "Resharding all the master #0 slots away from it" {
set output [exec \
../../../src/redis-cli --cluster rebalance \
127.0.0.1:[get_instance_attrib redis 0 port] \
+ {*}[rediscli_tls_config "../../../tests"] \
--cluster-weight ${master0_id}=0 >@ stdout ]
+
}
test "Master #0 should lose its replicas" {
@@ -51,6 +54,7 @@ test "Resharding back some slot to master #0" {
set output [exec \
../../../src/redis-cli --cluster rebalance \
127.0.0.1:[get_instance_attrib redis 0 port] \
+ {*}[rediscli_tls_config "../../../tests"] \
--cluster-weight ${master0_id}=.01 \
--cluster-use-empty-masters >@ stdout]
}
diff --git a/tests/helpers/bg_block_op.tcl b/tests/helpers/bg_block_op.tcl
index 238d3874f..c8b323308 100644
--- a/tests/helpers/bg_block_op.tcl
+++ b/tests/helpers/bg_block_op.tcl
@@ -1,6 +1,8 @@
source tests/support/redis.tcl
source tests/support/util.tcl
+set ::tlsdir "tests/tls"
+
# This function sometimes writes sometimes blocking-reads from lists/sorted
# sets. There are multiple processes like this executing at the same time
# so that we have some chance to trap some corner condition if there is
@@ -8,8 +10,8 @@ source tests/support/util.tcl
# space to just a few elements, and balance the operations so that it is
# unlikely that lists and zsets just get more data without ever causing
# blocking.
-proc bg_block_op {host port db ops} {
- set r [redis $host $port]
+proc bg_block_op {host port db ops tls} {
+ set r [redis $host $port 0 $tls]
$r select $db
for {set j 0} {$j < $ops} {incr j} {
@@ -49,4 +51,4 @@ proc bg_block_op {host port db ops} {
}
}
-bg_block_op [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3]
+bg_block_op [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3] [lindex $argv 4]
diff --git a/tests/helpers/bg_complex_data.tcl b/tests/helpers/bg_complex_data.tcl
index dffd7c668..e888748a7 100644
--- a/tests/helpers/bg_complex_data.tcl
+++ b/tests/helpers/bg_complex_data.tcl
@@ -1,10 +1,12 @@
source tests/support/redis.tcl
source tests/support/util.tcl
-proc bg_complex_data {host port db ops} {
- set r [redis $host $port]
+set ::tlsdir "tests/tls"
+
+proc bg_complex_data {host port db ops tls} {
+ set r [redis $host $port 0 $tls]
$r select $db
createComplexDataset $r $ops
}
-bg_complex_data [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3]
+bg_complex_data [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3] [lindex $argv 4]
diff --git a/tests/helpers/gen_write_load.tcl b/tests/helpers/gen_write_load.tcl
index 6d1a34516..fd6aad40c 100644
--- a/tests/helpers/gen_write_load.tcl
+++ b/tests/helpers/gen_write_load.tcl
@@ -1,8 +1,10 @@
source tests/support/redis.tcl
-proc gen_write_load {host port seconds} {
+set ::tlsdir "tests/tls"
+
+proc gen_write_load {host port seconds tls} {
set start_time [clock seconds]
- set r [redis $host $port 1]
+ set r [redis $host $port 0 $tls]
$r select 9
while 1 {
$r set [expr rand()] [expr rand()]
@@ -12,4 +14,4 @@ proc gen_write_load {host port seconds} {
}
}
-gen_write_load [lindex $argv 0] [lindex $argv 1] [lindex $argv 2]
+gen_write_load [lindex $argv 0] [lindex $argv 1] [lindex $argv 2] [lindex $argv 3]
diff --git a/tests/instances.tcl b/tests/instances.tcl
index 357b34818..0a0cbab12 100644
--- a/tests/instances.tcl
+++ b/tests/instances.tcl
@@ -17,6 +17,7 @@ source ../support/test.tcl
set ::verbose 0
set ::valgrind 0
+set ::tls 0
set ::pause_on_error 0
set ::simulate_error 0
set ::failed 0
@@ -69,7 +70,19 @@ proc spawn_instance {type base_port count {conf {}}} {
# Write the instance config file.
set cfgfile [file join $dirname $type.conf]
set cfg [open $cfgfile w]
- puts $cfg "port $port"
+ if {$::tls} {
+ puts $cfg "tls-port $port"
+ puts $cfg "tls-replication yes"
+ puts $cfg "tls-cluster yes"
+ puts $cfg "port 0"
+ puts $cfg [format "tls-cert-file %s/../../tls/redis.crt" [pwd]]
+ puts $cfg [format "tls-key-file %s/../../tls/redis.key" [pwd]]
+ puts $cfg [format "tls-dh-params-file %s/../../tls/redis.dh" [pwd]]
+ puts $cfg [format "tls-ca-cert-file %s/../../tls/ca.crt" [pwd]]
+ puts $cfg "loglevel debug"
+ } else {
+ puts $cfg "port $port"
+ }
puts $cfg "dir ./$dirname"
puts $cfg "logfile log.txt"
# Add additional config files
@@ -88,7 +101,7 @@ proc spawn_instance {type base_port count {conf {}}} {
}
# Push the instance into the right list
- set link [redis 127.0.0.1 $port]
+ set link [redis 127.0.0.1 $port 0 $::tls]
$link reconnect 1
lappend ::${type}_instances [list \
pid $pid \
@@ -148,6 +161,13 @@ proc parse_options {} {
set ::simulate_error 1
} elseif {$opt eq {--valgrind}} {
set ::valgrind 1
+ } elseif {$opt eq {--tls}} {
+ package require tls 1.6
+ ::tls::init \
+ -cafile "$::tlsdir/ca.crt" \
+ -certfile "$::tlsdir/redis.crt" \
+ -keyfile "$::tlsdir/redis.key"
+ set ::tls 1
} elseif {$opt eq "--help"} {
puts "Hello, I'm sentinel.tcl and I run Sentinel unit tests."
puts "\nOptions:"
@@ -492,7 +512,7 @@ proc restart_instance {type id} {
}
# Connect with it with a fresh link
- set link [redis 127.0.0.1 $port]
+ set link [redis 127.0.0.1 $port 0 $::tls]
$link reconnect 1
set_instance_attrib $type $id link $link
diff --git a/tests/integration/aof-race.tcl b/tests/integration/aof-race.tcl
index fb8d71083..2991e7962 100644
--- a/tests/integration/aof-race.tcl
+++ b/tests/integration/aof-race.tcl
@@ -13,8 +13,9 @@ tags {"aof"} {
# cleaned after a child responsible for an AOF rewrite exited. This buffer
# was subsequently appended to the new AOF, resulting in duplicate commands.
start_server_aof [list dir $server_path] {
- set client [redis [srv host] [srv port]]
- set bench [open "|src/redis-benchmark -q -p [srv port] -c 20 -n 20000 incr foo" "r+"]
+ set client [redis [srv host] [srv port] 0 $::tls]
+ set bench [open "|src/redis-benchmark -q -s [srv unixsocket] -c 20 -n 20000 incr foo" "r+"]
+
after 100
# Benchmark should be running by now: start background rewrite
@@ -29,7 +30,7 @@ tags {"aof"} {
# Restart server to replay AOF
start_server_aof [list dir $server_path] {
- set client [redis [srv host] [srv port]]
+ set client [redis [srv host] [srv port] 0 $::tls]
assert_equal 20000 [$client get foo]
}
}
diff --git a/tests/integration/aof.tcl b/tests/integration/aof.tcl
index e397faeeb..e276a6254 100644
--- a/tests/integration/aof.tcl
+++ b/tests/integration/aof.tcl
@@ -52,7 +52,7 @@ tags {"aof"} {
assert_equal 1 [is_alive $srv]
}
- set client [redis [dict get $srv host] [dict get $srv port]]
+ set client [redis [dict get $srv host] [dict get $srv port] 0 $::tls]
test "Truncated AOF loaded: we expect foo to be equal to 5" {
assert {[$client get foo] eq "5"}
@@ -69,7 +69,7 @@ tags {"aof"} {
assert_equal 1 [is_alive $srv]
}
- set client [redis [dict get $srv host] [dict get $srv port]]
+ set client [redis [dict get $srv host] [dict get $srv port] 0 $::tls]
test "Truncated AOF loaded: we expect foo to be equal to 6 now" {
assert {[$client get foo] eq "6"}
@@ -170,7 +170,7 @@ tags {"aof"} {
}
test "Fixed AOF: Keyspace should contain values that were parseable" {
- set client [redis [dict get $srv host] [dict get $srv port]]
+ set client [redis [dict get $srv host] [dict get $srv port] 0 $::tls]
wait_for_condition 50 100 {
[catch {$client ping} e] == 0
} else {
@@ -194,7 +194,7 @@ tags {"aof"} {
}
test "AOF+SPOP: Set should have 1 member" {
- set client [redis [dict get $srv host] [dict get $srv port]]
+ set client [redis [dict get $srv host] [dict get $srv port] 0 $::tls]
wait_for_condition 50 100 {
[catch {$client ping} e] == 0
} else {
@@ -218,7 +218,7 @@ tags {"aof"} {
}
test "AOF+SPOP: Set should have 1 member" {
- set client [redis [dict get $srv host] [dict get $srv port]]
+ set client [redis [dict get $srv host] [dict get $srv port] 0 $::tls]
wait_for_condition 50 100 {
[catch {$client ping} e] == 0
} else {
@@ -241,7 +241,7 @@ tags {"aof"} {
}
test "AOF+EXPIRE: List should be empty" {
- set client [redis [dict get $srv host] [dict get $srv port]]
+ set client [redis [dict get $srv host] [dict get $srv port] 0 $::tls]
wait_for_condition 50 100 {
[catch {$client ping} e] == 0
} else {
diff --git a/tests/integration/block-repl.tcl b/tests/integration/block-repl.tcl
index c111b805b..07eceb228 100644
--- a/tests/integration/block-repl.tcl
+++ b/tests/integration/block-repl.tcl
@@ -2,9 +2,9 @@
# Unlike stream operations such operations are "pop" style, so they consume
# the list or sorted set, and must be replicated correctly.
-proc start_bg_block_op {host port db ops} {
+proc start_bg_block_op {host port db ops tls} {
set tclsh [info nameofexecutable]
- exec $tclsh tests/helpers/bg_block_op.tcl $host $port $db $ops &
+ exec $tclsh tests/helpers/bg_block_op.tcl $host $port $db $ops $tls &
}
proc stop_bg_block_op {handle} {
@@ -18,9 +18,9 @@ start_server {tags {"repl"}} {
set master_port [srv -1 port]
set slave [srv 0 client]
- set load_handle0 [start_bg_block_op $master_host $master_port 9 100000]
- set load_handle1 [start_bg_block_op $master_host $master_port 9 100000]
- set load_handle2 [start_bg_block_op $master_host $master_port 9 100000]
+ set load_handle0 [start_bg_block_op $master_host $master_port 9 100000 $::tls]
+ set load_handle1 [start_bg_block_op $master_host $master_port 9 100000 $::tls]
+ set load_handle2 [start_bg_block_op $master_host $master_port 9 100000 $::tls]
test {First server should have role slave after SLAVEOF} {
$slave slaveof $master_host $master_port
diff --git a/tests/integration/psync2-reg.tcl b/tests/integration/psync2-reg.tcl
index 3d408368e..b5ad021e2 100644
--- a/tests/integration/psync2-reg.tcl
+++ b/tests/integration/psync2-reg.tcl
@@ -18,6 +18,7 @@ start_server {} {
set R($j) [srv [expr 0-$j] client]
set R_host($j) [srv [expr 0-$j] host]
set R_port($j) [srv [expr 0-$j] port]
+ set R_unixsocket($j) [srv [expr 0-$j] unixsocket]
if {$debug_msg} {puts "Log file: [srv [expr 0-$j] stdout]"}
}
@@ -36,7 +37,7 @@ start_server {} {
}
set cycle_start_time [clock milliseconds]
- set bench_pid [exec src/redis-benchmark -p $R_port(0) -n 10000000 -r 1000 incr __rand_int__ > /dev/null &]
+ set bench_pid [exec src/redis-benchmark -s $R_unixsocket(0) -n 10000000 -r 1000 incr __rand_int__ > /dev/null &]
while 1 {
set elapsed [expr {[clock milliseconds]-$cycle_start_time}]
if {$elapsed > $duration*1000} break
diff --git a/tests/integration/redis-cli.tcl b/tests/integration/redis-cli.tcl
index 40e4222e3..5d1635950 100644
--- a/tests/integration/redis-cli.tcl
+++ b/tests/integration/redis-cli.tcl
@@ -1,7 +1,10 @@
+source tests/support/cli.tcl
+
start_server {tags {"cli"}} {
proc open_cli {} {
set ::env(TERM) dumb
- set fd [open [format "|src/redis-cli -p %d -n 9" [srv port]] "r+"]
+ set cmdline [rediscli [srv port] "-n 9"]
+ set fd [open "|$cmdline" "r+"]
fconfigure $fd -buffering none
fconfigure $fd -blocking false
fconfigure $fd -translation binary
@@ -54,8 +57,8 @@ start_server {tags {"cli"}} {
}
proc _run_cli {opts args} {
- set cmd [format "src/redis-cli -p %d -n 9 $args" [srv port]]
- foreach {key value} $opts {
+ set cmd [rediscli [srv port] [list -n 9 {*}$args]]
+ foreach {key value} $args {
if {$key eq "pipe"} {
set cmd "sh -c \"$value | $cmd\""
}
diff --git a/tests/integration/replication.tcl b/tests/integration/replication.tcl
index 5d32555b0..43bc684b4 100644
--- a/tests/integration/replication.tcl
+++ b/tests/integration/replication.tcl
@@ -29,6 +29,9 @@ start_server {tags {"repl"}} {
$slave slaveof $master_host $master_port
test {Slave enters handshake} {
+ if {$::tls} {
+ fail "TLS with repl-diskless-sync not supported yet."
+ }
wait_for_condition 50 1000 {
[string match *handshake* [$slave role]]
} else {
@@ -184,6 +187,10 @@ start_server {tags {"repl"}} {
}
foreach mdl {no yes} {
+ if {$::tls && $mdl eq "yes"} {
+ puts "** Skipping test: TLS with repl-diskless-sync not supported yet."
+ continue
+ }
foreach sdl {disabled swapdb} {
start_server {tags {"repl"}} {
set master [srv 0 client]
@@ -320,6 +327,9 @@ start_server {tags {"repl"}} {
}
test {slave fails full sync and diskless load swapdb recoveres it} {
+ if {$::tls} {
+ fail ""
+ }
start_server {tags {"repl"}} {
set slave [srv 0 client]
set slave_host [srv 0 host]
@@ -387,6 +397,10 @@ test {slave fails full sync and diskless load swapdb recoveres it} {
}
test {diskless loading short read} {
+ if {$::tls} {
+ fail "TLS with repl-diskless-sync not supported yet."
+ }
+
start_server {tags {"repl"}} {
set replica [srv 0 client]
set replica_host [srv 0 host]
diff --git a/tests/sentinel/tests/07-down-conditions.tcl b/tests/sentinel/tests/07-down-conditions.tcl
index fb2993b6f..a12ea3151 100644
--- a/tests/sentinel/tests/07-down-conditions.tcl
+++ b/tests/sentinel/tests/07-down-conditions.tcl
@@ -1,6 +1,7 @@
# Test conditions where an instance is considered to be down
source "../tests/includes/init-tests.tcl"
+source "../../../tests/support/cli.tcl"
proc ensure_master_up {} {
wait_for_condition 1000 50 {
@@ -28,7 +29,7 @@ test "Crash the majority of Sentinels to prevent failovers for this unit" {
test "SDOWN is triggered by non-responding but not crashed instance" {
lassign [S 4 SENTINEL GET-MASTER-ADDR-BY-NAME mymaster] host port
ensure_master_up
- exec ../../../src/redis-cli -h $host -p $port debug sleep 10 > /dev/null &
+ exec ../../../src/redis-cli -h $host -p $port {*}[rediscli_tls_config "../../../tests"] debug sleep 10 > /dev/null &
ensure_master_down
ensure_master_up
}
diff --git a/tests/support/cli.tcl b/tests/support/cli.tcl
new file mode 100644
index 000000000..37c902a50
--- /dev/null
+++ b/tests/support/cli.tcl
@@ -0,0 +1,19 @@
+proc rediscli_tls_config {testsdir} {
+ set tlsdir [file join $testsdir tls]
+ set cert [file join $tlsdir redis.crt]
+ set key [file join $tlsdir redis.key]
+ set cacert [file join $tlsdir ca.crt]
+
+ if {$::tls} {
+ return [list --tls --cert $cert --key $key --cacert $cacert]
+ } else {
+ return {}
+ }
+}
+
+proc rediscli {port {opts {}}} {
+ set cmd [list src/redis-cli -p $port]
+ lappend cmd {*}[rediscli_tls_config "tests"]
+ lappend cmd {*}$opts
+ return $cmd
+}
diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl
index 1576053b4..74587e1f7 100644
--- a/tests/support/cluster.tcl
+++ b/tests/support/cluster.tcl
@@ -62,7 +62,7 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} {
lassign [split $ip_port :] start_host start_port
if {[catch {
set r {}
- set r [redis $start_host $start_port]
+ set r [redis $start_host $start_port 0 $::tls]
set nodes_descr [$r cluster nodes]
$r close
} e]} {
@@ -107,7 +107,7 @@ proc ::redis_cluster::__method__refresh_nodes_map {id} {
# Connect to the node
set link {}
- catch {set link [redis $host $port]}
+ catch {set link [redis $host $port 0 $::tls]}
# Build this node description as an hash.
set node [dict create \
diff --git a/tests/support/redis.tcl b/tests/support/redis.tcl
index cd8ae3a34..be6a11c7a 100644
--- a/tests/support/redis.tcl
+++ b/tests/support/redis.tcl
@@ -39,8 +39,17 @@ array set ::redis::callback {}
array set ::redis::state {} ;# State in non-blocking reply reading
array set ::redis::statestack {} ;# Stack of states, for nested mbulks
-proc redis {{server 127.0.0.1} {port 6379} {defer 0}} {
- set fd [socket $server $port]
+proc redis {{server 127.0.0.1} {port 6379} {defer 0} {tls 0}} {
+ if {$tls} {
+ package require tls
+ ::tls::init \
+ -cafile "$::tlsdir/ca.crt" \
+ -certfile "$::tlsdir/redis.crt" \
+ -keyfile "$::tlsdir/redis.key"
+ set fd [::tls::socket $server $port]
+ } else {
+ set fd [socket $server $port]
+ }
fconfigure $fd -translation binary
set id [incr ::redis::id]
set ::redis::fd($id) $fd
@@ -48,6 +57,7 @@ proc redis {{server 127.0.0.1} {port 6379} {defer 0}} {
set ::redis::blocking($id) 1
set ::redis::deferred($id) $defer
set ::redis::reconnect($id) 0
+ set ::redis::tls $tls
::redis::redis_reset_state $id
interp alias {} ::redis::redisHandle$id {} ::redis::__dispatch__ $id
}
@@ -72,7 +82,11 @@ proc ::redis::__dispatch__raw__ {id method argv} {
# Reconnect the link if needed.
if {$fd eq {}} {
lassign $::redis::addr($id) host port
- set ::redis::fd($id) [socket $host $port]
+ if {$::redis::tls} {
+ set ::redis::fd($id) [::tls::socket $host $port]
+ } else {
+ set ::redis::fd($id) [socket $host $port]
+ }
fconfigure $::redis::fd($id) -translation binary
set fd $::redis::fd($id)
}
diff --git a/tests/support/server.tcl b/tests/support/server.tcl
index 0edb25d8a..b20f1ad36 100644
--- a/tests/support/server.tcl
+++ b/tests/support/server.tcl
@@ -92,7 +92,11 @@ proc is_alive config {
proc ping_server {host port} {
set retval 0
if {[catch {
- set fd [socket $host $port]
+ if {$::tls} {
+ set fd [::tls::socket $host $port]
+ } else {
+ set fd [socket $host $port]
+ }
fconfigure $fd -translation binary
puts $fd "PING\r\n"
flush $fd
@@ -136,7 +140,6 @@ proc tags {tags code} {
uplevel 1 $code
set ::tags [lrange $::tags 0 end-[llength $tags]]
}
-
proc start_server {options {code undefined}} {
# If we are running against an external server, we just push the
# host/port pair in the stack the first time
@@ -145,7 +148,7 @@ proc start_server {options {code undefined}} {
set srv {}
dict set srv "host" $::host
dict set srv "port" $::port
- set client [redis $::host $::port]
+ set client [redis $::host $::port 0 $::tls]
dict set srv "client" $client
$client select 9
@@ -178,6 +181,13 @@ proc start_server {options {code undefined}} {
set data [split [exec cat "tests/assets/$baseconfig"] "\n"]
set config {}
+ if {$::tls} {
+ dict set config "tls-cert-file" [format "%s/tests/tls/redis.crt" [pwd]]
+ dict set config "tls-key-file" [format "%s/tests/tls/redis.key" [pwd]]
+ dict set config "tls-dh-params-file" [format "%s/tests/tls/redis.dh" [pwd]]
+ dict set config "tls-ca-cert-file" [format "%s/tests/tls/ca.crt" [pwd]]
+ dict set config "loglevel" "debug"
+ }
foreach line $data {
if {[string length $line] > 0 && [string index $line 0] ne "#"} {
set elements [split $line " "]
@@ -192,7 +202,17 @@ proc start_server {options {code undefined}} {
# start every server on a different port
set ::port [find_available_port [expr {$::port+1}]]
- dict set config port $::port
+ if {$::tls} {
+ dict set config "port" 0
+ dict set config "tls-port" $::port
+ dict set config "tls-cluster" "yes"
+ dict set config "tls-replication" "yes"
+ } else {
+ dict set config port $::port
+ }
+
+ set unixsocket [file normalize [format "%s/%s" [dict get $config "dir"] "socket"]]
+ dict set config "unixsocket" $unixsocket
# apply overrides from global space and arguments
foreach {directive arguments} [concat $::global_overrides $overrides] {
@@ -254,10 +274,11 @@ proc start_server {options {code undefined}} {
}
# setup properties to be able to initialize a client object
+ set port_param [expr $::tls ? {"tls-port"} : {"port"}]
set host $::host
set port $::port
if {[dict exists $config bind]} { set host [dict get $config bind] }
- if {[dict exists $config port]} { set port [dict get $config port] }
+ if {[dict exists $config $port_param]} { set port [dict get $config $port_param] }
# setup config dict
dict set srv "config_file" $config_file
@@ -267,6 +288,7 @@ proc start_server {options {code undefined}} {
dict set srv "port" $port
dict set srv "stdout" $stdout
dict set srv "stderr" $stderr
+ dict set srv "unixsocket" $unixsocket
# if a block of code is supplied, we wait for the server to become
# available, create a client object and kill the server afterwards
diff --git a/tests/support/util.tcl b/tests/support/util.tcl
index c2e76afad..7ecf5b79c 100644
--- a/tests/support/util.tcl
+++ b/tests/support/util.tcl
@@ -395,7 +395,7 @@ proc colorstr {color str} {
# of seconds to the specified Redis instance.
proc start_write_load {host port seconds} {
set tclsh [info nameofexecutable]
- exec $tclsh tests/helpers/gen_write_load.tcl $host $port $seconds &
+ exec $tclsh tests/helpers/gen_write_load.tcl $host $port $seconds $::tls &
}
# Stop a process generating write load executed with start_write_load.
@@ -423,7 +423,7 @@ proc lshuffle {list} {
# of ops to the specified Redis instance.
proc start_bg_complex_data {host port db ops} {
set tclsh [info nameofexecutable]
- exec $tclsh tests/helpers/bg_complex_data.tcl $host $port $db $ops &
+ exec $tclsh tests/helpers/bg_complex_data.tcl $host $port $db $ops $::tls &
}
# Stop a process generating write load executed with start_bg_complex_data.
diff --git a/tests/test_helper.tcl b/tests/test_helper.tcl
index 1442067f5..cb7e4e328 100644
--- a/tests/test_helper.tcl
+++ b/tests/test_helper.tcl
@@ -63,6 +63,7 @@ set ::all_tests {
unit/lazyfree
unit/wait
unit/pendingquerybuf
+ unit/tls
}
# Index to the next test to run in the ::all_tests list.
set ::next_test 0
@@ -71,6 +72,7 @@ set ::host 127.0.0.1
set ::port 21111
set ::traceleaks 0
set ::valgrind 0
+set ::tls 0
set ::stack_logging 0
set ::verbose 0
set ::quiet 0
@@ -92,6 +94,7 @@ set ::dont_clean 0
set ::wait_server 0
set ::stop_on_failure 0
set ::loop 0
+set ::tlsdir "tests/tls"
# Set to 1 when we are running in client mode. The Redis test uses a
# server-client model to run tests simultaneously. The server instance
@@ -146,7 +149,7 @@ proc reconnect {args} {
set host [dict get $srv "host"]
set port [dict get $srv "port"]
set config [dict get $srv "config"]
- set client [redis $host $port]
+ set client [redis $host $port 0 $::tls]
dict set srv "client" $client
# select the right db when we don't have to authenticate
@@ -166,7 +169,7 @@ proc redis_deferring_client {args} {
}
# create client that defers reading reply
- set client [redis [srv $level "host"] [srv $level "port"] 1]
+ set client [redis [srv $level "host"] [srv $level "port"] 1 $::tls]
# select the right db and read the response (OK)
$client select 9
@@ -204,7 +207,7 @@ proc test_server_main {} {
if {!$::quiet} {
puts "Starting test server at port $port"
}
- socket -server accept_test_clients -myaddr 127.0.0.1 $port
+ socket -server accept_test_clients -myaddr 127.0.0.1 $port
# Start the client instances
set ::clients_pids {}
@@ -450,6 +453,7 @@ proc print_help_screen {} {
"--stop Blocks once the first test fails."
"--loop Execute the specified set of tests forever."
"--wait-server Wait after server is started (so that you can attach a debugger)."
+ "--tls Run tests in TLS mode."
"--help Print this help screen."
} "\n"]
}
@@ -486,6 +490,13 @@ for {set j 0} {$j < [llength $argv]} {incr j} {
}
} elseif {$opt eq {--quiet}} {
set ::quiet 1
+ } elseif {$opt eq {--tls}} {
+ package require tls 1.6
+ set ::tls 1
+ ::tls::init \
+ -cafile "$::tlsdir/ca.crt" \
+ -certfile "$::tlsdir/redis.crt" \
+ -keyfile "$::tlsdir/redis.key"
} elseif {$opt eq {--host}} {
set ::external 1
set ::host $arg
@@ -565,7 +576,11 @@ if {[llength $::single_tests] > 0} {
}
proc attach_to_replication_stream {} {
- set s [socket [srv 0 "host"] [srv 0 "port"]]
+ if {$::tls} {
+ set s [::tls::socket [srv 0 "host"] [srv 0 "port"]]
+ } else {
+ set s [socket [srv 0 "host"] [srv 0 "port"]]
+ }
fconfigure $s -translation binary
puts -nonewline $s "SYNC\r\n"
flush $s
diff --git a/tests/unit/limits.tcl b/tests/unit/limits.tcl
index b37ea9b0f..38ba76208 100644
--- a/tests/unit/limits.tcl
+++ b/tests/unit/limits.tcl
@@ -1,4 +1,9 @@
start_server {tags {"limits"} overrides {maxclients 10}} {
+ if {$::tls} {
+ set expected_code "*I/O error*"
+ } else {
+ set expected_code "*ERR max*reached*"
+ }
test {Check if maxclients works refusing connections} {
set c 0
catch {
@@ -12,5 +17,5 @@ start_server {tags {"limits"} overrides {maxclients 10}} {
} e
assert {$c > 8 && $c <= 10}
set e
- } {*ERR max*reached*}
+ } $expected_code
}
diff --git a/tests/unit/other.tcl b/tests/unit/other.tcl
index 965902456..7720c055a 100644
--- a/tests/unit/other.tcl
+++ b/tests/unit/other.tcl
@@ -166,7 +166,11 @@ start_server {tags {"other"}} {
tags {protocol} {
test {PIPELINING stresser (also a regression for the old epoll bug)} {
- set fd2 [socket $::host $::port]
+ if {$::tls} {
+ set fd2 [::tls::socket $::host $::port]
+ } else {
+ set fd2 [socket $::host $::port]
+ }
fconfigure $fd2 -encoding binary -translation binary
puts -nonewline $fd2 "SELECT 9\r\n"
flush $fd2
diff --git a/tests/unit/protocol.tcl b/tests/unit/protocol.tcl
index ac99c3abb..4dfdc6f59 100644
--- a/tests/unit/protocol.tcl
+++ b/tests/unit/protocol.tcl
@@ -72,7 +72,11 @@ start_server {tags {"protocol"}} {
foreach seq [list "\x00" "*\x00" "$\x00"] {
incr c
test "Protocol desync regression test #$c" {
- set s [socket [srv 0 host] [srv 0 port]]
+ if {$::tls} {
+ set s [::tls::socket [srv 0 host] [srv 0 port]]
+ } else {
+ set s [socket [srv 0 host] [srv 0 port]]
+ }
puts -nonewline $s $seq
set payload [string repeat A 1024]"\n"
set test_start [clock seconds]
diff --git a/tests/unit/tls.tcl b/tests/unit/tls.tcl
new file mode 100644
index 000000000..58acdb6a9
--- /dev/null
+++ b/tests/unit/tls.tcl
@@ -0,0 +1,25 @@
+start_server {tags {"tls"}} {
+ if {$::tls} {
+ package require tls
+
+ test {TLS: Not accepting non-TLS connections on a TLS port} {
+ set s [redis [srv 0 host] [srv 0 port]]
+ catch {$s PING} e
+ set e
+ } {*I/O error*}
+
+ test {TLS: Verify tls-auth-clients behaves as expected} {
+ set s [redis [srv 0 host] [srv 0 port]]
+ ::tls::import [$s channel]
+ catch {$s PING} e
+ assert_match {*error*} $e
+
+ set resp [r CONFIG SET tls-auth-clients no]
+
+ set s [redis [srv 0 host] [srv 0 port]]
+ ::tls::import [$s channel]
+ catch {$s PING} e
+ assert_match {PONG} $e
+ } {}
+ }
+}
diff --git a/tests/unit/wait.tcl b/tests/unit/wait.tcl
index e2f5d2942..c9cfa6ed4 100644
--- a/tests/unit/wait.tcl
+++ b/tests/unit/wait.tcl
@@ -1,3 +1,5 @@
+source tests/support/cli.tcl
+
start_server {tags {"wait"}} {
start_server {} {
set slave [srv 0 client]
@@ -31,7 +33,8 @@ start_server {} {
}
test {WAIT should not acknowledge 1 additional copy if slave is blocked} {
- exec src/redis-cli -h $slave_host -p $slave_port debug sleep 5 > /dev/null 2> /dev/null &
+ set cmd [rediscli $slave_port "-h $slave_host debug sleep 5"]
+ exec {*}$cmd > /dev/null 2> /dev/null &
after 1000 ;# Give redis-cli the time to execute the command.
$master set foo 0
$master incr foo