From 11dddb65d7ea1344d36f3239fc3422fd2792e6fe Mon Sep 17 00:00:00 2001 From: Gleb Kashkin <g.kashkin@tarantool.org> Date: Wed, 19 Jul 2023 11:20:02 +0000 Subject: [PATCH] test: update interactive_tarantool for dbgr tests The following changes were applied to `interactive_tarantool` helper to adapt it for debugger tests: * compared commands are now stripped from tabs and color codes too * now each command independent of control symbols is being stripped before comparison in `execute_command()` * created internal new function that is called from both `new()` and `new_debugger()` * now user defined prompt can be set up from `new` and `new_debugger()` * now there are several less typos in comments Part of #7738 NO_CHANGELOG=test helper update NO_DOC=test helper update NO_TEST=test helper update --- test/interactive_tarantool.lua | 100 +++++++++++++++++++++++++++------ 1 file changed, 83 insertions(+), 17 deletions(-) diff --git a/test/interactive_tarantool.lua b/test/interactive_tarantool.lua index 801c769ffd..91cd9ec2b6 100644 --- a/test/interactive_tarantool.lua +++ b/test/interactive_tarantool.lua @@ -6,6 +6,7 @@ local fiber = require('fiber') local log = require('log') local yaml = require('yaml') local popen = require('popen') +local tnt = require('tarantool') -- Default timeout for expecting an input on child's stdout. -- @@ -18,6 +19,8 @@ local M = {} local mt = {} mt.__index = mt +local dbg_header = tnt.package .. " debugger " .. tnt.version + -- {{{ Instance methods function mt._start_stderr_logger(self) @@ -45,7 +48,14 @@ function mt._start_stderr_logger(self) end function mt._stop_stderr_logger(self) - self._stderr_logger:cancel() + if self._stderr_logger == nil then + return + end + -- The server could have finished already, thus + -- kill only what needs to be killed. + if self._stderr_logger:status() ~= 'dead' then + self._stderr_logger:cancel() + end self._stderr_logger = nil end @@ -79,7 +89,7 @@ function mt.read_line(self, opts) return line end --- Returns all readed lines (including expected one). +-- Returns all read lines (including expected one). function mt.read_until_line(self, exp_line, opts) local opts = opts or {} local deadline = opts.deadline or (fiber.clock() + TIMEOUT) @@ -94,6 +104,31 @@ function mt.read_until_line(self, exp_line, opts) return res end +-- Returns all read lines (excluding one with expected prompt, with deadline). +-- Checks if stderr is empty. +function mt.read_until_prompt(self, opts) + local opts = opts or {} + local deadline = opts.deadline or (fiber.clock() + TIMEOUT) + + while not self._readahead_buffer:find(self._prompt) do + self:read_chunk({deadline = deadline}) + end + + local res, new_buffer = unpack(self._readahead_buffer:split(self._prompt, + 1)) + new_buffer = self._prompt .. new_buffer + + self._readahead_buffer = new_buffer + + local stderr, err = self.ph:read({timeout = 0.05, stderr = true}) + if stderr ~= "" and not (stderr == nil and + tostring(err) == "timed out") then + error(("Unexpected stderr output: %s"):format(stderr)) + end + + return res +end + function mt.assert_line(self, exp_line, opts) local opts = opts or {} local deadline = opts.deadline or (fiber.clock() + TIMEOUT) @@ -119,6 +154,14 @@ function mt.assert_data(self, exp_data, opts) end end +local function decolor(string) + assert(type(string) == 'string') + -- The gsub is meant to clean ANSI color codes, for more details on + -- the format see the doc: + -- https://www.xfree86.org/current/ctlseqs.html + return string:gsub(M.ESC .. '%[[0-9;]*m', '') +end + -- ReadLine echoes commands to stdout. It is easier to match the -- echo against the original command, when the command is a -- one-liner. Let's replace newlines with spaces. @@ -138,11 +181,16 @@ end -- * ReadLine 7: x<CR><duplicate x>, extra spaces. -- * ReadLine 6: <space><CR>. -- --- This function drop duplicates that goes in row, strips <CR> and --- spaces. Applying of this function to a source command and --- readline's echoed command allows to compare them for equality. +-- This function drop duplicates that goes in row, strips <CR>, +-- spaces, tabs and ANSI color codes. Applying of this function +-- to a source command and readline's echoed command allows to +-- compare them for equality. local function _prepare_command_for_compare(x) - x = x:gsub(' ', ''):gsub(M.CR, '') + x = x:gsub(' ', '') + :gsub(M.CR, '') + :gsub(M.TAB, '') + + x = decolor(x) local acc = fun.iter(x):reduce(function(acc, c) if acc[#acc] ~= c then table.insert(acc, c) @@ -161,12 +209,9 @@ function mt._assert_command_echo(self, prepared_command, opts) -- If readline wraps the line, prepare the commands for -- compare. - local comment = '' - if echo:find(M.CR) ~= nil then - exp_echo = _prepare_command_for_compare(exp_echo) - echo = _prepare_command_for_compare(echo) - comment = ' (the commands are mangled for the comparison)' - end + exp_echo = _prepare_command_for_compare(exp_echo) + echo = _prepare_command_for_compare(echo) + local comment = ' (the commands are mangled for the comparison)' if echo ~= exp_echo then error(('Unexpected command echo %q, expected %q%s'):format( @@ -236,9 +281,10 @@ function M.escape_control(str) :gsub(M.ESC, '<ESC>') end -function M.new(opts) +function M._new_internal(opts) local opts = opts or {} local args = opts.args or {} + local prompt = opts.prompt local tarantool_exe = arg[-1] local ph = popen.new(fun.chain({tarantool_exe, '-i'}, args):totable(), { @@ -263,18 +309,35 @@ function M.new(opts) local res = setmetatable({ ph = ph, _readahead_buffer = '', - _prompt = 'tarantool> ', + _prompt = prompt or 'tarantool> ', }, mt) - -- Log child's stderr. - res:_start_stderr_logger() + return res +end + +function M.new_debugger(opts) + opts = opts or {} + opts.prompt = opts.prompt or 'luadebug> ' + local debugger = M._new_internal(opts) + if opts.expect_header then + local stderr, err = debugger.ph:read({timeout = TIMEOUT, stderr = true}) + if (stderr == nil) then + error(err) + end + assert(stderr:find(dbg_header, 0, true)) + end + return debugger +end + +function M.new(opts) + local res = M._new_internal(opts) -- Write a command and ignore the echoed output. -- -- ReadLine 6 writes <ESC>[?1034h at beginning, it may hit -- assertions on the child's output. -- - -- This sequence of charcters is smm ('set meta mode') + -- This sequence of characters is smm ('set meta mode') -- terminal capacity value. It has relation to writing -- characters out of the ASCII range -- ones with 8th bit set, -- but its description is vague. See terminfo(5). @@ -286,6 +349,9 @@ function M.new(opts) res:execute_command("io.stdout:setvbuf('no')") assert(res:read_response(), true) + -- Log child's stderr. + res:_start_stderr_logger() + return res end -- GitLab