From b49eaad367c334d5226a785123bc9cf4a1f89a25 Mon Sep 17 00:00:00 2001 From: "Kyle Kim (kimkyle@)" <105247741+kyle-yh-kim@users.noreply.github.com> Date: Tue, 25 Jun 2024 13:24:53 -0400 Subject: [PATCH] Introduce a minimal debugger for .tcl integration test suite. (#683) Introduce a break-point function called `bp`, based on the tcl wiki's minimal debugger. ```tcl proc bp {{s {}}} { if ![info exists ::bp_skip] { set ::bp_skip [list] } elseif {[lsearch -exact $::bp_skip $s]>=0} return if [catch {info level -1} who] {set who ::} while 1 { puts -nonewline "$who/$s> "; flush stdout gets stdin line if {$line=="c"} {puts "continuing.."; break} if {$line=="i"} {set line "info locals"} catch {uplevel 1 $line} res puts $res } } ``` ``` ... your test code before break-point bp 1 ... your test code after break-point ``` The `bp 1` will give back the tcl interpreter to the developer, and allow you to interactively print local variables (through `puts`), run functions and so forth. Source: https://wiki.tcl-lang.org/page/A+minimal+debugger --------- Signed-off-by: Kyle Kim Signed-off-by: Madelyn Olson Co-authored-by: Madelyn Olson --- tests/README.md | 32 ++++++++++++++++++++++++++++++++ tests/support/util.tcl | 22 ++++++++++++++++++++++ 2 files changed, 54 insertions(+) diff --git a/tests/README.md b/tests/README.md index 9d9c657760..efe936aa5b 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,6 +1,18 @@ Valkey Test Suite ================= +Overview +-------- + +Integration tests are written in Tcl, a high-level, general-purpose, interpreted, dynamic programming language [[source](https://wiki.tcl-lang.org/page/What+is+Tcl)]. +`runtest` is the main entrance point for running integration tests. +For example, to run a single test; + +```shell +./runtest --single unit/your_test_name +# For additional arguments, you may refer to the `runtest` script itself. +``` + The normal execution mode of the test suite involves starting and manipulating local `valkey-server` instances, inspecting process state, log files, etc. @@ -19,6 +31,26 @@ match different external server configurations: | `--cluster-mode` | Run in strict Valkey Cluster compatibility mode. | | `--large-memory` | Enables tests that consume more than 100mb | +Debugging +--------- + +You can set a breakpoint and invoke a minimal debugger using the `bp` function. + +``` +... your test code before break-point +bp 1 +... your test code after break-point +``` + +The `bp 1` will give back the tcl interpreter to the developer, and allow you to interactively print local variables (through `puts`), run functions and so forth [[source](https://wiki.tcl-lang.org/page/A+minimal+debugger)]. +`bp` takes a single argument, which is `1` for the case above, and is used to label a breakpoint with a string. +Labels are printed out when breakpoints are hit, so you can identify which breakpoint was triggered. +Breakpoints can be skipped by setting the global variable `::bp_skip`, and by providing the labels you want to skip. + +The minimal debugger comes with the following predefined functions. +* Press `c` to continue past the breakpoint. +* Press `i` to print local variables. + Tags ---- diff --git a/tests/support/util.tcl b/tests/support/util.tcl index 9d69e44232..c6c405b191 100644 --- a/tests/support/util.tcl +++ b/tests/support/util.tcl @@ -1162,3 +1162,25 @@ proc generate_largevalue_test_array {} { set largevalue(quicklist) [string repeat "x" 8192] return [array get largevalue] } + +# Breakpoint function, which invokes a minimal debugger. +# This function can be placed within the desired Tcl tests for debugging purposes. +# +# Arguments: +# * 's': breakpoint label, which is printed when breakpoints are hit for unique identification. +# +# Source: https://wiki.tcl-lang.org/page/A+minimal+debugger +proc bp {{s {}}} { + if ![info exists ::bp_skip] { + set ::bp_skip [list] + } elseif {[lsearch -exact $::bp_skip $s]>=0} return + if [catch {info level -1} who] {set who ::} + while 1 { + puts -nonewline "$who/$s> "; flush stdout + gets stdin line + if {$line=="c"} {puts "continuing.."; break} + if {$line=="i"} {set line "info locals"} + catch {uplevel 1 $line} res + puts $res + } +}