5 from lldbsuite
.test
.decorators
import *
6 from lldbsuite
.test
.lldbtest
import *
7 from lldbsuite
.test
import lldbutil
12 """Return the parameter as type 'str', possibly encoding it.
14 In Python2, the 'str' type is the same as 'bytes'. In Python3, the
15 'str' type is (essentially) Python2's 'unicode' type, and 'bytes' is
19 if isinstance(b
, str):
20 # In Python2, this branch is taken for types 'str' and 'bytes'.
21 # In Python3, this branch is taken only for 'str'.
23 if isinstance(b
, bytes
):
24 # In Python2, this branch is never taken ('bytes' is handled as 'str').
25 # In Python3, this is true only for 'bytes'.
27 return b
.decode("utf-8")
28 except UnicodeDecodeError:
29 # If the value is not valid Unicode, return the default
33 # By this point, here's what we *don't* have:
36 # - 'str' or 'bytes' (1st branch above)
38 # - 'str' (1st branch above)
39 # - 'bytes' (2nd branch above)
41 # The last type we might expect is the Python2 'unicode' type. There is no
42 # 'unicode' type in Python3 (all the Python3 cases were already handled). In
43 # order to get a 'str' object, we need to encode the 'unicode' object.
45 return b
.encode("utf-8")
46 except AttributeError:
47 raise TypeError("not sure how to convert %s to %s" % (type(b
), str))
50 class ExecuteCommandTimeoutException(Exception):
51 def __init__(self
, msg
, out
, err
, exitCode
):
52 assert isinstance(msg
, str)
53 assert isinstance(out
, str)
54 assert isinstance(err
, str)
55 assert isinstance(exitCode
, int)
59 self
.exitCode
= exitCode
62 # Close extra file handles on UNIX (on Windows this cannot be done while
63 # also redirecting input).
64 kUseCloseFDs
= not (platform
.system() == "Windows")
67 def executeCommand(command
, cwd
=None, env
=None, input=None, timeout
=0):
68 """Execute command ``command`` (list of arguments or string) with.
70 * working directory ``cwd`` (str), use None to use the current
72 * environment ``env`` (dict), use None for none
73 * Input to the command ``input`` (str), use string to pass
75 * Max execution time ``timeout`` (int) seconds. Use 0 for no timeout.
77 Returns a tuple (out, err, exitCode) where
78 * ``out`` (str) is the standard output of running the command
79 * ``err`` (str) is the standard error of running the command
80 * ``exitCode`` (int) is the exitCode of running the command
82 If the timeout is hit an ``ExecuteCommandTimeoutException``
87 input = to_bytes(input)
91 stdin
=subprocess
.PIPE
,
92 stdout
=subprocess
.PIPE
,
93 stderr
=subprocess
.PIPE
,
95 close_fds
=kUseCloseFDs
,
98 # FIXME: Because of the way nested function scopes work in Python 2.x we
99 # need to use a reference to a mutable object rather than a plain
100 # bool. In Python 3 we could use the "nonlocal" keyword but we need
101 # to support Python 2 as well.
107 # We may be invoking a shell so we need to kill the
108 # process and all its children.
110 killProcessAndChildren(p
.pid
)
112 timerObject
= threading
.Timer(timeout
, killProcess
)
115 out
, err
= p
.communicate(input=input)
118 if timerObject
!= None:
121 # Ensure the resulting output is always of string type.
126 raise ExecuteCommandTimeoutException(
127 msg
="Reached timeout of {} seconds".format(timeout
),
133 # Detect Ctrl-C in subprocess.
134 if exitCode
== -signal
.SIGINT
:
135 raise KeyboardInterrupt
137 return out
, err
, exitCode
140 class TestLuaAPI(TestBase
):
141 NO_DEBUG_INFO_TESTCASE
= True
145 for filename
in os
.listdir():
146 # Ignore dot files and excluded tests.
147 if filename
.startswith("."):
150 # Ignore files that don't start with 'Test'.
151 if not filename
.startswith("Test"):
154 if not os
.path
.isdir(filename
):
155 base
, ext
= os
.path
.splitext(filename
)
157 tests
.append(filename
)
160 def test_lua_api(self
):
161 if "LUA_EXECUTABLE" not in os
.environ
or len(os
.environ
["LUA_EXECUTABLE"]) == 0:
162 self
.skipTest("Lua API tests could not find Lua executable.")
164 lua_executable
= os
.environ
["LUA_EXECUTABLE"]
167 test_exe
= self
.getBuildArtifact("a.out")
168 test_output
= self
.getBuildArtifact("output")
169 test_input
= self
.getBuildArtifact("input")
171 lua_lldb_cpath
= "%s/lua/5.3/?.so" % configuration
.lldb_libs_dir
173 lua_prelude
= "package.cpath = '%s;' .. package.cpath" % lua_lldb_cpath
176 "TEST_EXE": os
.path
.join(self
.getBuildDir(), test_exe
),
177 "TEST_OUTPUT": os
.path
.join(self
.getBuildDir(), test_output
),
178 "TEST_INPUT": os
.path
.join(self
.getBuildDir(), test_input
),
181 for lua_test
in self
.get_tests():
182 cmd
= [lua_executable
] + ["-e", lua_prelude
] + [lua_test
]
183 out
, err
, exitCode
= executeCommand(cmd
, env
=lua_env
)
185 # Redirect Lua output
187 print(err
, file=sys
.stderr
)
189 self
.assertTrue(exitCode
== 0, "Lua test '%s' failure." % lua_test
)