156 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Lua
		
	
	
	
			
		
		
	
	
			156 lines
		
	
	
		
			3.9 KiB
		
	
	
	
		
			Lua
		
	
	
	
-- Make lldb available in global
 | 
						|
lldb = require('lldb')
 | 
						|
 | 
						|
-- Global assertion functions
 | 
						|
function assertTrue(x)
 | 
						|
    if not x then error('assertTrue failure') end
 | 
						|
end
 | 
						|
 | 
						|
function assertFalse(x)
 | 
						|
    if x then error('assertNotNil failure') end
 | 
						|
end
 | 
						|
 | 
						|
function assertNotNil(x)
 | 
						|
    if x == nil then error('assertNotNil failure') end
 | 
						|
end
 | 
						|
 | 
						|
function assertEquals(x, y)
 | 
						|
    if type(x) == 'table' and type(y) == 'table' then
 | 
						|
        for k, _ in pairs(x) do
 | 
						|
            assertEquals(x[k], y[k])
 | 
						|
        end
 | 
						|
    elseif type(x) ~= type(y) then
 | 
						|
        error('assertEquals failure')
 | 
						|
    elseif x ~= y then
 | 
						|
        error('assertEquals failure')
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function assertStrContains(x, y)
 | 
						|
    if not string.find(x, y, 1, true) then
 | 
						|
        error('assertStrContains failure')
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
-- Global helper functions
 | 
						|
function read_file_non_empty_lines(f)
 | 
						|
    local lines = {}
 | 
						|
    while true do
 | 
						|
        local line = f:read('*l')
 | 
						|
        if not line then break end
 | 
						|
        if line ~= '\n' then table.insert(lines, line) end
 | 
						|
    end
 | 
						|
    return lines
 | 
						|
end
 | 
						|
 | 
						|
function split_lines(str)
 | 
						|
    local lines = {}
 | 
						|
    for line in str:gmatch("[^\r\n]+") do
 | 
						|
        table.insert(lines, line)
 | 
						|
    end
 | 
						|
    return lines
 | 
						|
end
 | 
						|
 | 
						|
function get_stopped_threads(process, reason)
 | 
						|
    local threads = {}
 | 
						|
    for i = 0, process:GetNumThreads() - 1 do
 | 
						|
        local t = process:GetThreadAtIndex(i)
 | 
						|
        if t:IsValid() and t:GetStopReason() == reason then
 | 
						|
            table.insert(threads, t)
 | 
						|
        end
 | 
						|
    end
 | 
						|
    return threads
 | 
						|
end
 | 
						|
 | 
						|
function get_stopped_thread(process, reason)
 | 
						|
    local threads = get_stopped_threads(process, reason)
 | 
						|
    if #threads ~= 0 then return threads[1]
 | 
						|
    else return nil end
 | 
						|
end
 | 
						|
 | 
						|
-- Test helper
 | 
						|
 | 
						|
local _M = {}
 | 
						|
local _m = {}
 | 
						|
 | 
						|
local _mt = { __index = _m }
 | 
						|
 | 
						|
function _M.create_test(name, exe, output, input)
 | 
						|
    print('[lldb/lua] Create test ' .. name)
 | 
						|
    exe = exe or os.getenv('TEST_EXE')
 | 
						|
    output = output or os.getenv('TEST_OUTPUT')
 | 
						|
    input = input or os.getenv('TEST_INPUT')
 | 
						|
    lldb.SBDebugger.Initialize()
 | 
						|
    local debugger = lldb.SBDebugger.Create()
 | 
						|
    -- Ensure that debugger is created
 | 
						|
    assertNotNil(debugger)
 | 
						|
    assertTrue(debugger:IsValid())
 | 
						|
 | 
						|
    debugger:SetAsync(false)
 | 
						|
 | 
						|
    local lua_language = debugger:GetScriptingLanguage('lua')
 | 
						|
    assertNotNil(lua_language)
 | 
						|
    debugger:SetScriptLanguage(lua_language)
 | 
						|
 | 
						|
    local test = setmetatable({
 | 
						|
        output = output,
 | 
						|
        input = input,
 | 
						|
        name = name,
 | 
						|
        exe = exe,
 | 
						|
        debugger = debugger
 | 
						|
    }, _mt)
 | 
						|
    _G[name] = test
 | 
						|
    return test
 | 
						|
end
 | 
						|
 | 
						|
function _m:create_target(exe)
 | 
						|
    local target
 | 
						|
    if not exe then exe = self.exe end
 | 
						|
    target = self.debugger:CreateTarget(exe)
 | 
						|
    -- Ensure that target is created
 | 
						|
    assertNotNil(target)
 | 
						|
    assertTrue(target:IsValid())
 | 
						|
    return target
 | 
						|
end
 | 
						|
 | 
						|
function _m:handle_command(command, collect)
 | 
						|
    if collect == nil then collect = true end
 | 
						|
    if collect then
 | 
						|
        local ret = lldb.SBCommandReturnObject()
 | 
						|
        local interpreter = self.debugger:GetCommandInterpreter()
 | 
						|
        assertTrue(interpreter:IsValid())
 | 
						|
        interpreter:HandleCommand(command, ret)
 | 
						|
        self.debugger:GetOutputFile():Flush()
 | 
						|
        self.debugger:GetErrorFile():Flush()
 | 
						|
        assertTrue(ret:Succeeded())
 | 
						|
        return ret:GetOutput()
 | 
						|
    else
 | 
						|
        self.debugger:HandleCommand(command)
 | 
						|
        self.debugger:GetOutputFile():Flush()
 | 
						|
        self.debugger:GetErrorFile():Flush()
 | 
						|
    end
 | 
						|
end
 | 
						|
 | 
						|
function _m:run()
 | 
						|
    local tests = {}
 | 
						|
    for k, v in pairs(self) do
 | 
						|
        if string.sub(k, 1, 4) == 'Test' then
 | 
						|
            table.insert(tests, k)
 | 
						|
        end
 | 
						|
    end
 | 
						|
    table.sort(tests)
 | 
						|
    for _, t in ipairs(tests) do
 | 
						|
        print('[lldb/lua] Doing test ' .. self.name .. ' - ' .. t)
 | 
						|
        local success = xpcall(self[t], function(e)
 | 
						|
            print(debug.traceback())
 | 
						|
        end, self)
 | 
						|
        if not success then
 | 
						|
            print('[lldb/lua] Failure in test ' .. self.name .. ' - ' .. t)
 | 
						|
            return 1
 | 
						|
        end
 | 
						|
    end
 | 
						|
    return 0
 | 
						|
end
 | 
						|
 | 
						|
return _M
 |