# # # patch "tests/common/automate_stdio.lua" # from [9a6086c1c1cbb2fbb79cbd77264228c6bca5abda] # to [ded6609785f6e497d394f67faa4b56e0e41ce69e] # ============================================================ --- tests/common/automate_stdio.lua 9a6086c1c1cbb2fbb79cbd77264228c6bca5abda +++ tests/common/automate_stdio.lua ded6609785f6e497d394f67faa4b56e0e41ce69e @@ -1,5 +1,5 @@ stdio = {} stdio = {} -stdio.got = {} +proc.got = {} stdio.buffer = "" function stdio.start(opts) @@ -16,50 +16,58 @@ function stdio.start(opts) end local argv = fn(unpack(args)) - local out = bg(argv, false, false, false) - local mt = getmetatable(out) + local proc = {} + proc.nextCommandNumber = 0 + proc.callbacks = {} + proc.got = {} + proc.buffer = "" + proc.in, proc.out, proc.pid = spawn_pipe("mtn", argv) + check(proc.pid <> -1) + return proc +end - mt.enqueue = function(obj, cmd, opts, callback) - if (type(opts) ~= "table" and type(opts) ~= "nil") then - err("enqueue wants a table or nil as opts") - end +-- +-- fixme: we're single threaded, so we should just wait for the output and +-- do not pretend to have a queue somewhere... +-- +function stdio.enqueue(proc, cmd, opts, callback) + if (type(opts) ~= "table" and type(opts) ~= "nil") then + err("enqueue wants a table or nil as opts") + end - if (type(cmd) ~= "table") then - err("enqueue wants a table as cmd") - end + if (type(cmd) ~= "table") then + err("enqueue wants a table as cmd") + end - local cmdStr = "" + local cmdStr = "" - if (type(opts) ~= "table" then - cmdStr = cmdStr .. "o" - for k, v in pairs(opts) do - cmdStr = cmdStr .. string.len(v) .. ":" .. v - end - cmdStr = cmdStr .. "e " + if (type(opts) ~= "table" then + cmdStr = cmdStr .. "o" + for k, v in pairs(opts) do + cmdStr = cmdStr .. string.len(v) .. ":" .. v end + cmdStr = cmdStr .. "e " + end - cmdStr = cmdStr .. "l" - for k, v in pairs(cmd) do - cmdStr = cmdStr .. string.len(v) .. ":" .. v - end - cmdStr = cmdStr .. "e" - - stdio.write(obj, cmdStr, callback) + cmdStr = cmdStr .. "l" + for k, v in pairs(cmd) do + cmdStr = cmdStr .. string.len(v) .. ":" .. v end + cmdStr = cmdStr .. "e" - return out -end + proc.callbacks[proc.nextCommandNumber] = callback + proc.nextCommandNumber = proc.nextCommandNumber + 1 -function stdio.write(proc, input, callback) + write(proc.in, cmdStr, callback) end -function stdio.parse(dat) +function stdio.parse(proc, dat) -- append new data to the buffer - stdio.buffer = stdio.buffer .. dat + proc.buffer = proc.buffer .. dat while true do local startIdx, endIdx, cmdNum, cmdExitCode, msgBand, msgLen = - string.find(stdio.buffer, "(%d+):(%d+):([mlewpt]):(%d+):") + string.find(proc.buffer, "(%d+):(%d+):([mlewpt]):(%d+):") cmdNum = cmdNum + 0 cmdExitCode = cmdExitCode + 0 @@ -67,30 +75,30 @@ function stdio.parse(dat) -- check if we need to wait for more data if startIdx == nil or - msgLen > string.len(string.sub(stdio.buffer, endIdx + 1)) then + msgLen > string.len(string.sub(proc.buffer, endIdx + 1)) then break end - if stdio.got[cmdNum] == nil then stdio.got[cmdNum] = {} end + if proc.got[cmdNum] == nil then proc.got[cmdNum] = {} end -- no msg for this command should follow once we processed 'l' - check(stdio.got[cmdNum]['exitCode'] == nil) + check(proc.got[cmdNum]['exitCode'] == nil) -- process the different bands payload = string.sub(buffer, endIdx+1, endIdx+msgLen) if msgBand ~= "t" then if msgBand == "l" then - stdio.got[cmdNum]['exitCode'] = cmdExitCode + proc.got[cmdNum]['exitCode'] = cmdExitCode msgBand = "m" end - if stdio.got[cmdNum][msgBand] == nil then - stdio.got[cmdNum][msgBand] = "" + if proc.got[cmdNum][msgBand] == nil then + proc.got[cmdNum][msgBand] = "" end - stdio.got[cmdNum][msgBand] = stdio.got[cmdNum][msgBand] .. payload + proc.got[cmdNum][msgBand] = proc.got[cmdNum][msgBand] .. payload else - if stdio.got[cmdNum]['tickers'] == nil then - stdio.got[cmdNum]['tickers'] = {} + if proc.got[cmdNum]['tickers'] == nil then + proc.got[cmdNum]['tickers'] = {} end -- it makes no sense to remember the inbetween states of the ticker -- elements, so we only note the max and the currently reached count @@ -101,50 +109,50 @@ function stdio.parse(dat) check(startIdx ~= nil) if (string.len(tickVal) == 0) then - check(stdio.got[cmdNum]['tickers'][tickSym] ~= nil) - check(stdio.got[cmdNum]['tickers'][tickSym]['finished'] == nil) - stdio.got[cmdNum]['tickers'][tickSym]['finished'] = true + check(proc.got[cmdNum]['tickers'][tickSym] ~= nil) + check(proc.got[cmdNum]['tickers'][tickSym]['finished'] == nil) + proc.got[cmdNum]['tickers'][tickSym]['finished'] = true else local tickType = string.sub(tickVal, 1, 1) tickVal = string.sub(tickVal, 2) -- the ticker definition - should be the very first thing if tickType == ":" then - check(stdio.got[cmdNum]['tickers'][tickSym] == nil) - stdio.got[cmdNum]['tickers'][tickSym] = {} - stdio.got[cmdNum]['tickers'][tickSym]['name'] = tickVal + check(proc.got[cmdNum]['tickers'][tickSym] == nil) + proc.got[cmdNum]['tickers'][tickSym] = {} + proc.got[cmdNum]['tickers'][tickSym]['name'] = tickVal -- the ticker initialization - this might come in a couple of times elseif tickType == "=" then - check(stdio.got[cmdNum]['tickers'][tickSym] ~= nil) - check(stdio.got[cmdNum]['tickers'][tickSym]['max'] = tickVal + 0 + check(proc.got[cmdNum]['tickers'][tickSym] ~= nil) + check(proc.got[cmdNum]['tickers'][tickSym]['max'] = tickVal + 0 -- the ticker progress value elseif tickType == "#" then - check(stdio.got[cmdNum]['tickers'][tickSym] ~= nil) - check(stdio.got[cmdNum]['tickers'][tickSym]['max'] ~= nil) + check(proc.got[cmdNum]['tickers'][tickSym] ~= nil) + check(proc.got[cmdNum]['tickers'][tickSym]['max'] ~= nil) - stdio.got[cmdNum]['tickers'][tickSym]['current'] = tickVal + 0 + proc.got[cmdNum]['tickers'][tickSym]['current'] = tickVal + 0 - check(stdio.got[cmdNum]['tickers'][tickSym]['max'] == 0 or - stdio.got[cmdNum]['tickers'][tickSym]['max'] >= - stdio.got[cmdNum]['tickers'][tickSym]['current']) + check(proc.got[cmdNum]['tickers'][tickSym]['max'] == 0 or + proc.got[cmdNum]['tickers'][tickSym]['max'] >= + proc.got[cmdNum]['tickers'][tickSym]['current']) else check(false) end -- this should throw if we get a tick after the ticker -- has already been finished - check(stdio.got[cmdNum]['tickers'][tickSym]['finished'] == nil) + check(proc.got[cmdNum]['tickers'][tickSym]['finished'] == nil) end end end - stdio.buffer = string.sub(stdio.buffer, endIdx+1+msgLen) + proc.buffer = string.sub(proc.buffer, endIdx+1+msgLen) end end -function stdio.get(cmdNum) - local out = stdio.got[cmdNum] +function stdio.getOutput(proc, cmdNum) + local out = proc.got[cmdNum] if out ~= nil then - table.remove(stdio.got, cmdNum) + table.remove(proc.got, cmdNum) end return out end