From 707757e4782d9df09e0457b022e67cc4cfb80945 Mon Sep 17 00:00:00 2001 From: Alessio Attilio Date: Sat, 28 Feb 2026 07:07:25 +0100 Subject: [PATCH] Support Tcl 9.0 in Redis test suite (#14787) ## Summary This PR adds support for running the Redis test suite using Tcl 9.0. ## Changes - **runtest**: Added `9.0` to the list of Tcl versions the script searches for. - **Version Requirements**: Updated `package require Tcl` from `8.5` to `8.5-10` in key test files. In Tcl, a simple version requirement like `8.5` is interpreted as "8.5 or higher within major version 8". Specifying the range `8.5-10` allows Tcl 9.0 to be used if the code is compatible. - **Tcl Precision**: Wrapped `set tcl_precision 17` in a conditional check `if {$tcl_version < 9.0}`. In Tcl 9.0, `tcl_precision` has been removed as double-to-string conversions are now lossless by default. - Adjusts the Tcl Redis client to preserve binary arguments under Tcl 9 by only UTF-8 converting strings that contain non-byte characters before building the RESP command. ## Testing Verified that `tclsh9.0` successfully parses the updated `package require` and handles the conditional `tcl_precision` assignment. This allows the test suite to run on modern Linux distributions where Tcl 9.0 is the default version. --- runtest | 2 +- tests/instances.tcl | 4 ++-- tests/support/cluster.tcl | 2 +- tests/support/redis.tcl | 7 ++++++- tests/support/response_transformers.tcl | 2 +- tests/test_helper.tcl | 8 ++++---- tests/unit/other.tcl | 2 +- 7 files changed, 16 insertions(+), 11 deletions(-) diff --git a/runtest b/runtest index 88617c1a6..09b9d491b 100755 --- a/runtest +++ b/runtest @@ -1,5 +1,5 @@ #!/bin/sh -TCL_VERSIONS="8.5 8.6 8.7" +TCL_VERSIONS="8.5 8.6 8.7 9.0" TCLSH="" for VERSION in $TCL_VERSIONS; do diff --git a/tests/instances.tcl b/tests/instances.tcl index d93b36b33..8f0a23bd2 100644 --- a/tests/instances.tcl +++ b/tests/instances.tcl @@ -10,9 +10,9 @@ # (RSALv2); or (b) the Server Side Public License v1 (SSPLv1); or (c) the # GNU Affero General Public License v3 (AGPLv3). -package require Tcl 8.5 +package require Tcl 8.5-10 -set tcl_precision 17 +if {$tcl_version < 9.0} { set tcl_precision 17 } source ../support/redis.tcl source ../support/util.tcl source ../support/aofmanifest.tcl diff --git a/tests/support/cluster.tcl b/tests/support/cluster.tcl index 3a666844b..cee4a6f1f 100644 --- a/tests/support/cluster.tcl +++ b/tests/support/cluster.tcl @@ -14,7 +14,7 @@ # $c get foo # $c close -package require Tcl 8.5 +package require Tcl 8.5-10 package provide redis_cluster 0.1 namespace eval redis_cluster {} diff --git a/tests/support/redis.tcl b/tests/support/redis.tcl index 6c8585587..e497b25e9 100644 --- a/tests/support/redis.tcl +++ b/tests/support/redis.tcl @@ -30,7 +30,7 @@ # # vwait forever -package require Tcl 8.5 +package require Tcl 8.5-10 package provide redis 0.1 source [file join [file dirname [info script]] "response_transformers.tcl"] @@ -165,6 +165,11 @@ proc ::redis::__dispatch__raw__ {id method argv} { set cmd "*[expr {[llength $argv]+1}]\r\n" append cmd "$[string length $method]\r\n$method\r\n" foreach a $argv { + # In Tcl 9.0, only convert to UTF-8 if the string contains non-byte characters + # to preserve binary data while handling unicode correctly + if {$::tcl_version >= 9.0 && [string match "*\[^\u0000-\u00ff\]*" $a]} { + set a [encoding convertto utf-8 $a] + } append cmd "$[string length $a]\r\n$a\r\n" } ::redis::redis_write $fd $cmd diff --git a/tests/support/response_transformers.tcl b/tests/support/response_transformers.tcl index 99c1ebb65..8b81a38f1 100644 --- a/tests/support/response_transformers.tcl +++ b/tests/support/response_transformers.tcl @@ -19,7 +19,7 @@ # changes in many files) we decided to transform the response to RESP2 # when running with --force-resp3 -package require Tcl 8.5 +package require Tcl 8.5-10 namespace eval response_transformers {} diff --git a/tests/test_helper.tcl b/tests/test_helper.tcl index 88cb6a76a..b93727baf 100644 --- a/tests/test_helper.tcl +++ b/tests/test_helper.tcl @@ -13,9 +13,9 @@ # Portions of this file are available under BSD3 terms; see REDISCONTRIBUTIONS for more information. # -package require Tcl 8.5 +package require Tcl 8.5-10 -set tcl_precision 17 +if {$tcl_version < 9.0} { set tcl_precision 17 } source tests/support/redis.tcl source tests/support/aofmanifest.tcl source tests/support/server.tcl @@ -333,7 +333,7 @@ proc test_server_cron {} { } proc accept_test_clients {fd addr port} { - fconfigure $fd -encoding binary + fconfigure $fd -translation binary fileevent $fd readable [list read_from_test_client $fd] } @@ -524,7 +524,7 @@ proc the_end {} { # to read the command, execute, reply... all this in a loop. proc test_client_main server_port { set ::test_server_fd [socket localhost $server_port] - fconfigure $::test_server_fd -encoding binary + fconfigure $::test_server_fd -translation binary send_data_packet $::test_server_fd ready [pid] while 1 { set bytes [gets $::test_server_fd] diff --git a/tests/unit/other.tcl b/tests/unit/other.tcl index b8d5d0fc8..7ab9ab89b 100644 --- a/tests/unit/other.tcl +++ b/tests/unit/other.tcl @@ -227,7 +227,7 @@ start_server {tags {"other"}} { } else { set fd2 [socket [srv host] [srv port]] } - fconfigure $fd2 -encoding binary -translation binary + fconfigure $fd2 -translation binary if {!$::singledb} { puts -nonewline $fd2 "SELECT 9\r\n" flush $fd2