xref: /llvm-project/lldb/test/API/lua_api/lua_lldb_test.lua (revision 80fcecb13c388ff087a27a4b0e7ca3dd8c98eaa4)
1-- Make lldb available in global
2lldb = require('lldb')
3
4-- Global assertion functions
5function assertTrue(x)
6    if not x then error('assertTrue failure') end
7end
8
9function assertFalse(x)
10    if x then error('assertNotNil failure') end
11end
12
13function assertNotNil(x)
14    if x == nil then error('assertNotNil failure') end
15end
16
17function assertEqual(x, y)
18    if type(x) == 'table' and type(y) == 'table' then
19        for k, _ in pairs(x) do
20            assertEqual(x[k], y[k])
21        end
22    elseif type(x) ~= type(y) then
23        error('assertEqual failure')
24    elseif x ~= y then
25        error('assertEqual failure')
26    end
27end
28
29function assertStrContains(x, y)
30    if not string.find(x, y, 1, true) then
31        error('assertStrContains failure')
32    end
33end
34
35-- Global helper functions
36function read_file_non_empty_lines(f)
37    local lines = {}
38    while true do
39        local line = f:read('*l')
40        if not line then break end
41        if line ~= '\n' then table.insert(lines, line) end
42    end
43    return lines
44end
45
46function split_lines(str)
47    local lines = {}
48    for line in str:gmatch("[^\r\n]+") do
49        table.insert(lines, line)
50    end
51    return lines
52end
53
54function get_stopped_threads(process, reason)
55    local threads = {}
56    for i = 0, process:GetNumThreads() - 1 do
57        local t = process:GetThreadAtIndex(i)
58        if t:IsValid() and t:GetStopReason() == reason then
59            table.insert(threads, t)
60        end
61    end
62    return threads
63end
64
65function get_stopped_thread(process, reason)
66    local threads = get_stopped_threads(process, reason)
67    if #threads ~= 0 then return threads[1]
68    else return nil end
69end
70
71-- Test helper
72
73local _M = {}
74local _m = {}
75
76local _mt = { __index = _m }
77
78function _M.create_test(name, exe, output, input)
79    print('[lldb/lua] Create test ' .. name)
80    exe = exe or os.getenv('TEST_EXE')
81    output = output or os.getenv('TEST_OUTPUT')
82    input = input or os.getenv('TEST_INPUT')
83    lldb.SBDebugger.Initialize()
84    local debugger = lldb.SBDebugger.Create()
85    -- Ensure that debugger is created
86    assertNotNil(debugger)
87    assertTrue(debugger:IsValid())
88
89    debugger:SetAsync(false)
90
91    local lua_language = debugger:GetScriptingLanguage('lua')
92    assertNotNil(lua_language)
93    debugger:SetScriptLanguage(lua_language)
94
95    local test = setmetatable({
96        output = output,
97        input = input,
98        name = name,
99        exe = exe,
100        debugger = debugger
101    }, _mt)
102    _G[name] = test
103    return test
104end
105
106function _m:create_target(exe)
107    local target
108    if not exe then exe = self.exe end
109    target = self.debugger:CreateTarget(exe)
110    -- Ensure that target is created
111    assertNotNil(target)
112    assertTrue(target:IsValid())
113    return target
114end
115
116function _m:handle_command(command, collect)
117    if collect == nil then collect = true end
118    if collect then
119        local ret = lldb.SBCommandReturnObject()
120        local interpreter = self.debugger:GetCommandInterpreter()
121        assertTrue(interpreter:IsValid())
122        interpreter:HandleCommand(command, ret)
123        self.debugger:GetOutputFile():Flush()
124        self.debugger:GetErrorFile():Flush()
125        assertTrue(ret:Succeeded())
126        return ret:GetOutput()
127    else
128        self.debugger:HandleCommand(command)
129        self.debugger:GetOutputFile():Flush()
130        self.debugger:GetErrorFile():Flush()
131    end
132end
133
134function _m:run()
135    local tests = {}
136    for k, v in pairs(self) do
137        if string.sub(k, 1, 4) == 'Test' then
138            table.insert(tests, k)
139        end
140    end
141    table.sort(tests)
142    for _, t in ipairs(tests) do
143        print('[lldb/lua] Doing test ' .. self.name .. ' - ' .. t)
144        local success = xpcall(self[t], function(e)
145            print(debug.traceback())
146        end, self)
147        if not success then
148            print('[lldb/lua] Failure in test ' .. self.name .. ' - ' .. t)
149            return 1
150        end
151    end
152    return 0
153end
154
155return _M
156