TLS test fix from redis (#524)

* Fix TLS tests on newer tcl-tls/OpenSSL. (#10910)

Before this commit, TLS tests on Ubuntu 22.04 would fail as dropped
connections result with an ECONNABORTED error thrown instead of an empty
read.

* multithread for ci tests

* multithread cluster tests

* clients to 1 in ci

Co-authored-by: Yossi Gottlieb <yossigo@gmail.com>
This commit is contained in:
Malavan Sotheeswaran 2022-12-29 14:47:06 -05:00 committed by GitHub
parent f054ef7872
commit 48e5220d00
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 40 additions and 10 deletions

View File

@ -21,10 +21,10 @@ jobs:
- name: test-tls - name: test-tls
run: | run: |
sudo apt-get -y install tcl tcl-tls sudo apt-get -y install tcl tcl-tls
./runtest --clients 2 --verbose --tls ./runtest --clients 1 --verbose --tls --config server-threads 3
- name: cluster-test - name: cluster-test
run: | run: |
./runtest-cluster --tls ./runtest-cluster --tls --config server-threads 3
- name: sentinel test - name: sentinel test
run: | run: |
./runtest-sentinel ./runtest-sentinel

View File

@ -66,6 +66,33 @@ proc redis {{server 127.0.0.1} {port 6379} {defer 0} {tls 0} {tlsoptions {}} {re
interp alias {} ::redis::redisHandle$id {} ::redis::__dispatch__ $id interp alias {} ::redis::redisHandle$id {} ::redis::__dispatch__ $id
} }
# On recent versions of tcl-tls/OpenSSL, reading from a dropped connection
# results with an error we need to catch and mimic the old behavior.
proc ::redis::redis_safe_read {fd len} {
if {$len == -1} {
set err [catch {set val [read $fd]} msg]
} else {
set err [catch {set val [read $fd $len]} msg]
}
if {!$err} {
return $val
}
if {[string match "*connection abort*" $msg]} {
return {}
}
error $msg
}
proc ::redis::redis_safe_gets {fd} {
if {[catch {set val [gets $fd]} msg]} {
if {[string match "*connection abort*" $msg]} {
return {}
}
error $msg
}
return $val
}
# This is a wrapper to the actual dispatching procedure that handles # This is a wrapper to the actual dispatching procedure that handles
# reconnection if needed. # reconnection if needed.
proc ::redis::__dispatch__ {id method args} { proc ::redis::__dispatch__ {id method args} {
@ -146,6 +173,10 @@ proc ::redis::__method__read {id fd} {
::redis::redis_read_reply $id $fd ::redis::redis_read_reply $id $fd
} }
proc ::redis::__method__rawread {id fd {len -1}} {
return [redis_safe_read $fd $len]
}
proc ::redis::__method__write {id fd buf} { proc ::redis::__method__write {id fd buf} {
::redis::redis_write $fd $buf ::redis::redis_write $fd $buf
} }
@ -192,8 +223,8 @@ proc ::redis::redis_writenl {fd buf} {
} }
proc ::redis::redis_readnl {fd len} { proc ::redis::redis_readnl {fd len} {
set buf [read $fd $len] set buf [redis_safe_read $fd $len]
read $fd 2 ; # discard CR LF redis_safe_read $fd 2 ; # discard CR LF
return $buf return $buf
} }
@ -239,11 +270,11 @@ proc ::redis::redis_read_map {id fd} {
} }
proc ::redis::redis_read_line fd { proc ::redis::redis_read_line fd {
string trim [gets $fd] string trim [redis_safe_gets $fd]
} }
proc ::redis::redis_read_null fd { proc ::redis::redis_read_null fd {
gets $fd redis_safe_gets $fd
return {} return {}
} }
@ -260,7 +291,7 @@ proc ::redis::redis_read_reply {id fd} {
} }
while {1} { while {1} {
set type [read $fd 1] set type [redis_safe_read $fd 1]
switch -exact -- $type { switch -exact -- $type {
_ {return [redis_read_null $fd]} _ {return [redis_read_null $fd]}
: - : -

View File

@ -111,7 +111,7 @@ start_server {tags {"obuf-limits"} overrides { server-threads 1 }} {
# Read nothing # Read nothing
set fd [$rd channel] set fd [$rd channel]
assert_equal {} [read $fd] assert_equal {} [$rd rawread]
} }
# Note: This test assumes that what's written with one write, will be read by redis in one read. # Note: This test assumes that what's written with one write, will be read by redis in one read.
@ -151,8 +151,7 @@ start_server {tags {"obuf-limits"} overrides { server-threads 1 }} {
assert_equal "PONG" [r ping] assert_equal "PONG" [r ping]
set clients [r client list] set clients [r client list]
assert_no_match "*name=multicommands*" $clients assert_no_match "*name=multicommands*" $clients
set fd [$rd2 channel] assert_equal {} [$rd2 rawread]
assert_equal {} [read $fd]
} }
test {Execute transactions completely even if client output buffer limit is enforced} { test {Execute transactions completely even if client output buffer limit is enforced} {