167f94e5aSSiger Yang-- Make lldb available in global 267f94e5aSSiger Yanglldb = require('lldb') 367f94e5aSSiger Yang 467f94e5aSSiger Yang-- Global assertion functions 567f94e5aSSiger Yangfunction assertTrue(x) 667f94e5aSSiger Yang if not x then error('assertTrue failure') end 767f94e5aSSiger Yangend 867f94e5aSSiger Yang 967f94e5aSSiger Yangfunction assertFalse(x) 1067f94e5aSSiger Yang if x then error('assertNotNil failure') end 1167f94e5aSSiger Yangend 1267f94e5aSSiger Yang 1367f94e5aSSiger Yangfunction assertNotNil(x) 1467f94e5aSSiger Yang if x == nil then error('assertNotNil failure') end 1567f94e5aSSiger Yangend 1667f94e5aSSiger Yang 17*80fcecb1SJonas Devliegherefunction assertEqual(x, y) 1867f94e5aSSiger Yang if type(x) == 'table' and type(y) == 'table' then 1967f94e5aSSiger Yang for k, _ in pairs(x) do 20*80fcecb1SJonas Devlieghere assertEqual(x[k], y[k]) 2167f94e5aSSiger Yang end 2267f94e5aSSiger Yang elseif type(x) ~= type(y) then 23*80fcecb1SJonas Devlieghere error('assertEqual failure') 2467f94e5aSSiger Yang elseif x ~= y then 25*80fcecb1SJonas Devlieghere error('assertEqual failure') 2667f94e5aSSiger Yang end 2767f94e5aSSiger Yangend 2867f94e5aSSiger Yang 2967f94e5aSSiger Yangfunction assertStrContains(x, y) 3067f94e5aSSiger Yang if not string.find(x, y, 1, true) then 3167f94e5aSSiger Yang error('assertStrContains failure') 3267f94e5aSSiger Yang end 3367f94e5aSSiger Yangend 3467f94e5aSSiger Yang 3567f94e5aSSiger Yang-- Global helper functions 3667f94e5aSSiger Yangfunction read_file_non_empty_lines(f) 3767f94e5aSSiger Yang local lines = {} 3867f94e5aSSiger Yang while true do 3967f94e5aSSiger Yang local line = f:read('*l') 4067f94e5aSSiger Yang if not line then break end 4167f94e5aSSiger Yang if line ~= '\n' then table.insert(lines, line) end 4267f94e5aSSiger Yang end 4367f94e5aSSiger Yang return lines 4467f94e5aSSiger Yangend 4567f94e5aSSiger Yang 4667f94e5aSSiger Yangfunction split_lines(str) 4767f94e5aSSiger Yang local lines = {} 4867f94e5aSSiger Yang for line in str:gmatch("[^\r\n]+") do 4967f94e5aSSiger Yang table.insert(lines, line) 5067f94e5aSSiger Yang end 5167f94e5aSSiger Yang return lines 5267f94e5aSSiger Yangend 5367f94e5aSSiger Yang 5467f94e5aSSiger Yangfunction get_stopped_threads(process, reason) 5567f94e5aSSiger Yang local threads = {} 5667f94e5aSSiger Yang for i = 0, process:GetNumThreads() - 1 do 5767f94e5aSSiger Yang local t = process:GetThreadAtIndex(i) 5867f94e5aSSiger Yang if t:IsValid() and t:GetStopReason() == reason then 5967f94e5aSSiger Yang table.insert(threads, t) 6067f94e5aSSiger Yang end 6167f94e5aSSiger Yang end 6267f94e5aSSiger Yang return threads 6367f94e5aSSiger Yangend 6467f94e5aSSiger Yang 6567f94e5aSSiger Yangfunction get_stopped_thread(process, reason) 6667f94e5aSSiger Yang local threads = get_stopped_threads(process, reason) 6767f94e5aSSiger Yang if #threads ~= 0 then return threads[1] 6867f94e5aSSiger Yang else return nil end 6967f94e5aSSiger Yangend 7067f94e5aSSiger Yang 7167f94e5aSSiger Yang-- Test helper 7267f94e5aSSiger Yang 7367f94e5aSSiger Yanglocal _M = {} 7467f94e5aSSiger Yanglocal _m = {} 7567f94e5aSSiger Yang 7667f94e5aSSiger Yanglocal _mt = { __index = _m } 7767f94e5aSSiger Yang 7867f94e5aSSiger Yangfunction _M.create_test(name, exe, output, input) 7967f94e5aSSiger Yang print('[lldb/lua] Create test ' .. name) 8067f94e5aSSiger Yang exe = exe or os.getenv('TEST_EXE') 8167f94e5aSSiger Yang output = output or os.getenv('TEST_OUTPUT') 8267f94e5aSSiger Yang input = input or os.getenv('TEST_INPUT') 8367f94e5aSSiger Yang lldb.SBDebugger.Initialize() 8467f94e5aSSiger Yang local debugger = lldb.SBDebugger.Create() 8567f94e5aSSiger Yang -- Ensure that debugger is created 8667f94e5aSSiger Yang assertNotNil(debugger) 8767f94e5aSSiger Yang assertTrue(debugger:IsValid()) 8867f94e5aSSiger Yang 8967f94e5aSSiger Yang debugger:SetAsync(false) 9067f94e5aSSiger Yang 9167f94e5aSSiger Yang local lua_language = debugger:GetScriptingLanguage('lua') 9267f94e5aSSiger Yang assertNotNil(lua_language) 9367f94e5aSSiger Yang debugger:SetScriptLanguage(lua_language) 9467f94e5aSSiger Yang 9567f94e5aSSiger Yang local test = setmetatable({ 9667f94e5aSSiger Yang output = output, 9767f94e5aSSiger Yang input = input, 9867f94e5aSSiger Yang name = name, 9967f94e5aSSiger Yang exe = exe, 10067f94e5aSSiger Yang debugger = debugger 10167f94e5aSSiger Yang }, _mt) 10267f94e5aSSiger Yang _G[name] = test 10367f94e5aSSiger Yang return test 10467f94e5aSSiger Yangend 10567f94e5aSSiger Yang 10667f94e5aSSiger Yangfunction _m:create_target(exe) 10767f94e5aSSiger Yang local target 10867f94e5aSSiger Yang if not exe then exe = self.exe end 10967f94e5aSSiger Yang target = self.debugger:CreateTarget(exe) 11067f94e5aSSiger Yang -- Ensure that target is created 11167f94e5aSSiger Yang assertNotNil(target) 11267f94e5aSSiger Yang assertTrue(target:IsValid()) 11367f94e5aSSiger Yang return target 11467f94e5aSSiger Yangend 11567f94e5aSSiger Yang 11667f94e5aSSiger Yangfunction _m:handle_command(command, collect) 11767f94e5aSSiger Yang if collect == nil then collect = true end 11867f94e5aSSiger Yang if collect then 11967f94e5aSSiger Yang local ret = lldb.SBCommandReturnObject() 12067f94e5aSSiger Yang local interpreter = self.debugger:GetCommandInterpreter() 12167f94e5aSSiger Yang assertTrue(interpreter:IsValid()) 12267f94e5aSSiger Yang interpreter:HandleCommand(command, ret) 12367f94e5aSSiger Yang self.debugger:GetOutputFile():Flush() 12467f94e5aSSiger Yang self.debugger:GetErrorFile():Flush() 12567f94e5aSSiger Yang assertTrue(ret:Succeeded()) 12667f94e5aSSiger Yang return ret:GetOutput() 12767f94e5aSSiger Yang else 12867f94e5aSSiger Yang self.debugger:HandleCommand(command) 12967f94e5aSSiger Yang self.debugger:GetOutputFile():Flush() 13067f94e5aSSiger Yang self.debugger:GetErrorFile():Flush() 13167f94e5aSSiger Yang end 13267f94e5aSSiger Yangend 13367f94e5aSSiger Yang 13467f94e5aSSiger Yangfunction _m:run() 13567f94e5aSSiger Yang local tests = {} 13667f94e5aSSiger Yang for k, v in pairs(self) do 13767f94e5aSSiger Yang if string.sub(k, 1, 4) == 'Test' then 13867f94e5aSSiger Yang table.insert(tests, k) 13967f94e5aSSiger Yang end 14067f94e5aSSiger Yang end 14167f94e5aSSiger Yang table.sort(tests) 14267f94e5aSSiger Yang for _, t in ipairs(tests) do 14367f94e5aSSiger Yang print('[lldb/lua] Doing test ' .. self.name .. ' - ' .. t) 14467f94e5aSSiger Yang local success = xpcall(self[t], function(e) 14567f94e5aSSiger Yang print(debug.traceback()) 14667f94e5aSSiger Yang end, self) 14767f94e5aSSiger Yang if not success then 14867f94e5aSSiger Yang print('[lldb/lua] Failure in test ' .. self.name .. ' - ' .. t) 14967f94e5aSSiger Yang return 1 15067f94e5aSSiger Yang end 15167f94e5aSSiger Yang end 15267f94e5aSSiger Yang return 0 15367f94e5aSSiger Yangend 15467f94e5aSSiger Yang 15567f94e5aSSiger Yangreturn _M 156