Skip to content
Snippets Groups Projects
Commit 11dddb65 authored by Gleb Kashkin's avatar Gleb Kashkin Committed by Igor Munkin
Browse files

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
parent 28ec245d
No related branches found
No related tags found
No related merge requests found
......@@ -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
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment