Skip to content

Commit

Permalink
SBFile: add a bunch of tests that should eventually work.
Browse files Browse the repository at this point in the history
Summary:
It's really annoying and confusing to have to keep referring
back to earlier versions of this SBFile work to find the
tests that need to be added for each patch, and not duplicate
them with new tests.

This patch just imports all my tests.   A bunch of them don't
work yet, so they are marked to be skipped.   They'll be
unmarked as I fix them.

One of these tests will actually trip an assert in the SWIG
code now instead of just failing, so I'm fixing that here too.

Reviewers: JDevlieghere, jasonmolenda, labath

Reviewed By: JDevlieghere, labath

Subscribers: lldb-commits

Tags: #lldb

Differential Revision: https://reviews.llvm.org/D68433

llvm-svn: 374237
  • Loading branch information
lawrence-danna-apple committed Oct 9, 2019
1 parent 865cd09 commit b24022c
Show file tree
Hide file tree
Showing 2 changed files with 291 additions and 15 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import lldb
from lldbsuite.test import lldbtest
from lldbsuite.test.decorators import (
add_test_categories, skipIf, skipIfWindows)
add_test_categories, skipIf, skipIfWindows, expectedFailure)

class OhNoe(Exception):
pass
Expand Down Expand Up @@ -162,7 +162,9 @@ def test_legacy_file_err_with_get(self):
with open(self.out_filename, 'w') as f:
self.debugger.SetErrorFileHandle(f, False)
self.handleCmd('lolwut', check=False, collect_result=False)
self.debugger.GetErrorFileHandle().write('FOOBAR\n')
f2 = self.debugger.GetErrorFileHandle()
f2.write('FOOBAR\n')
f2.flush()
lldb.SBDebugger.Destroy(self.debugger)
with open(self.out_filename, 'r') as f:
errors = f.read()
Expand All @@ -180,6 +182,16 @@ def test_legacy_file_err(self):
self.assertIn("is not a valid command", f.read())


@add_test_categories(['pyapi'])
def test_legacy_file_error(self):
debugger = self.debugger
with open(self.out_filename, 'w') as f:
debugger.SetErrorFileHandle(f, False)
self.handleCmd('lolwut', check=False, collect_result=False)
with open(self.out_filename, 'r') as f:
errors = f.read()
self.assertTrue(re.search(r'error:.*lolwut', errors))

@add_test_categories(['pyapi'])
def test_sbfile_type_errors(self):
sbf = lldb.SBFile()
Expand Down Expand Up @@ -269,6 +281,17 @@ def test_fileno_help(self):
self.assertTrue(re.search(r'Show a list of all debugger commands', f.read()))


@add_test_categories(['pyapi'])
def test_help(self):
debugger = self.debugger
with open(self.out_filename, 'w') as f:
status = debugger.SetOutputFile(lldb.SBFile(f))
self.assertTrue(status.Success())
self.handleCmd("help help", check=False, collect_result=False)
with open(self.out_filename, 'r') as f:
self.assertIn('Show a list of all debugger commands', f.read())


@add_test_categories(['pyapi'])
def test_immediate(self):
with open(self.out_filename, 'w') as f:
Expand All @@ -278,15 +301,44 @@ def test_immediate(self):
interpreter.HandleCommand("help help", ret)
# make sure the file wasn't closed early.
f.write("\nQUUX\n")

ret = None # call destructor and flush streams

with open(self.out_filename, 'r') as f:
output = f.read()
self.assertTrue(re.search(r'Show a list of all debugger commands', output))
self.assertTrue(re.search(r'QUUX', output))


@add_test_categories(['pyapi'])
@expectedFailure # FIXME need SBFile interfaces on SBCommandReturnObject
def test_immediate_string(self):
f = io.StringIO()
ret = lldb.SBCommandReturnObject()
ret.SetImmediateOutputFile(f)
interpreter = self.debugger.GetCommandInterpreter()
interpreter.HandleCommand("help help", ret)
# make sure the file wasn't closed early.
f.write("\nQUUX\n")
ret = None # call destructor and flush streams
output = f.getvalue()
self.assertTrue(re.search(r'Show a list of all debugger commands', output))
self.assertTrue(re.search(r'QUUX', output))


@add_test_categories(['pyapi'])
@expectedFailure # FIXME need SBFile interfaces on SBCommandReturnObject
def test_immediate_sbfile_string(self):
f = io.StringIO()
ret = lldb.SBCommandReturnObject()
ret.SetImmediateOutputFile(lldb.SBFile(f))
interpreter = self.debugger.GetCommandInterpreter()
interpreter.HandleCommand("help help", ret)
output = f.getvalue()
ret = None # call destructor and flush streams
# sbfile default constructor doesn't borrow the file
self.assertTrue(f.closed)
self.assertTrue(re.search(r'Show a list of all debugger commands', output))


@add_test_categories(['pyapi'])
def test_fileno_inout(self):
with open(self.in_filename, 'w') as f:
Expand All @@ -310,6 +362,76 @@ def test_fileno_inout(self):
self.assertTrue(re.search(r'Show a list of all debugger commands', f.read()))


@add_test_categories(['pyapi'])
def test_inout(self):
with open(self.in_filename, 'w') as f:
f.write("help help\n")
with open(self.out_filename, 'w') as outf, \
open(self.in_filename, 'r') as inf:
status = self.debugger.SetOutputFile(lldb.SBFile(outf))
self.assertTrue(status.Success())
status = self.debugger.SetInputFile(lldb.SBFile(inf))
self.assertTrue(status.Success())
opts = lldb.SBCommandInterpreterRunOptions()
self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False)
self.debugger.GetOutputFile().Flush()
with open(self.out_filename, 'r') as f:
output = f.read()
self.assertIn('Show a list of all debugger commands', output)


@add_test_categories(['pyapi'])
def test_binary_inout(self):
debugger = self.debugger
with open(self.in_filename, 'w') as f:
f.write("help help\n")
with open(self.out_filename, 'wb') as outf, \
open(self.in_filename, 'rb') as inf:
status = debugger.SetOutputFile(lldb.SBFile(outf))
self.assertTrue(status.Success())
status = debugger.SetInputFile(lldb.SBFile(inf))
self.assertTrue(status.Success())
opts = lldb.SBCommandInterpreterRunOptions()
debugger.RunCommandInterpreter(True, False, opts, 0, False, False)
debugger.GetOutputFile().Flush()
with open(self.out_filename, 'r') as f:
output = f.read()
self.assertIn('Show a list of all debugger commands', output)


@add_test_categories(['pyapi'])
@expectedFailure # FIXME IOHandler still using FILE*
def test_string_inout(self):
inf = io.StringIO("help help\n")
outf = io.StringIO()
status = self.debugger.SetOutputFile(lldb.SBFile(outf))
self.assertTrue(status.Success())
status = self.debugger.SetInputFile(lldb.SBFile(inf))
self.assertTrue(status.Success())
opts = lldb.SBCommandInterpreterRunOptions()
self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False)
self.debugger.GetOutputFile().Flush()
output = outf.getvalue()
self.assertIn('Show a list of all debugger commands', output)


@add_test_categories(['pyapi'])
@expectedFailure # FIXME IOHandler still using FILE*
def test_bytes_inout(self):
inf = io.BytesIO(b"help help\nhelp b\n")
outf = io.BytesIO()
status = self.debugger.SetOutputFile(lldb.SBFile(outf))
self.assertTrue(status.Success())
status = self.debugger.SetInputFile(lldb.SBFile(inf))
self.assertTrue(status.Success())
opts = lldb.SBCommandInterpreterRunOptions()
self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False)
self.debugger.GetOutputFile().Flush()
output = outf.getvalue()
self.assertIn(b'Show a list of all debugger commands', output)
self.assertIn(b'Set a breakpoint', output)


@add_test_categories(['pyapi'])
def test_fileno_error(self):
with open(self.out_filename, 'w') as f:
Expand Down Expand Up @@ -339,6 +461,23 @@ def test_replace_stdout(self):
self.assertEqual(sys.stdout, f)


@add_test_categories(['pyapi'])
@expectedFailure #FIXME bug in ScriptInterpreterPython
def test_replace_stdout_with_nonfile(self):
debugger = self.debugger
f = io.StringIO()
with replace_stdout(f):
class Nothing():
pass
with replace_stdout(Nothing):
self.assertEqual(sys.stdout, Nothing)
self.handleCmd('script sys.stdout.write("lol")',
check=False, collect_result=False)
self.assertEqual(sys.stdout, Nothing)
sys.stdout.write(u"FOO")
self.assertEqual(f.getvalue(), "FOO")


@add_test_categories(['pyapi'])
def test_sbfile_write_borrowed(self):
with open(self.out_filename, 'w') as f:
Expand Down Expand Up @@ -408,6 +547,31 @@ def test_sbfile_write_string(self):
sbf.Close()
self.assertTrue(f.closed)


@add_test_categories(['pyapi'])
@skipIf(py_version=['<', (3,)])
@expectedFailure # fixme multiple problems with this
def test_string_out(self):
f = io.StringIO()
status = self.debugger.SetOutputFile(f)
self.assertTrue(status.Success())
self.handleCmd("script 'foobar'")
self.assertEqual(f.getvalue().strip(), "'foobar'")


@add_test_categories(['pyapi'])
@expectedFailure # FIXME need FileSP version of SBDebugger::SetErrorFile
@skipIf(py_version=['<', (3,)])
def test_string_error(self):
f = io.StringIO()
debugger = self.debugger
status = debugger.SetErrorFile(f)
self.assertTrue(status.Success())
self.handleCmd('lolwut', check=False, collect_result=False)
errors = f.getvalue()
self.assertTrue(re.search(r'error:.*lolwut', errors))


@add_test_categories(['pyapi'])
@skipIf(py_version=['<', (3,)])
def test_sbfile_write_bytes(self):
Expand Down Expand Up @@ -466,6 +630,18 @@ def test_sbfile_out(self):
self.assertEqual(f.read().strip(), '4')


@add_test_categories(['pyapi'])
@expectedFailure # FIXME need FileSP version of SBDebugger::SetErrorFile
@skipIf(py_version=['<', (3,)])
def test_file_out(self):
with open(self.out_filename, 'w') as f:
status = self.debugger.SetOutputFile(f)
self.assertTrue(status.Success())
self.handleCmd('script 2+2')
with open(self.out_filename, 'r') as f:
self.assertEqual(f.read().strip(), '4')


@add_test_categories(['pyapi'])
def test_sbfile_error(self):
with open(self.out_filename, 'w') as f:
Expand All @@ -478,6 +654,18 @@ def test_sbfile_error(self):
self.assertTrue(re.search(r'error:.*lolwut', errors))


@add_test_categories(['pyapi'])
@expectedFailure # FIXME need FileSP version of SBDebugger::SetErrorFile
def test_file_error(self):
with open(self.out_filename, 'w') as f:
status = self.debugger.SetErrorFile(f)
self.assertTrue(status.Success())
self.handleCmd('lolwut', check=False, collect_result=False)
with open(self.out_filename, 'r') as f:
errors = f.read()
self.assertTrue(re.search(r'error:.*lolwut', errors))


@add_test_categories(['pyapi'])
def test_exceptions(self):
self.assertRaises(TypeError, lldb.SBFile, None)
Expand Down Expand Up @@ -556,3 +744,91 @@ def test_fileno_flush(self):
self.assertFalse(f.closed)
f.seek(0)
self.assertEqual(f.read(), 'foobar')


@add_test_categories(['pyapi'])
@expectedFailure # FIXME need FileSP version of SBDebugger::SetOutputFile
def test_close(self):
debugger = self.debugger
with open(self.out_filename, 'w') as f:
status = debugger.SetOutputFile(f)
self.assertTrue(status.Success())
self.handleCmd("help help", check=False, collect_result=False)
# make sure the file wasn't closed early.
f.write("\nZAP\n")
lldb.SBDebugger.Destroy(debugger)
# check that output file was closed when debugger was destroyed.
with self.assertRaises(ValueError):
f.write("\nQUUX\n")
with open(self.out_filename, 'r') as f:
output = f.read()
self.assertTrue(re.search(r'Show a list of all debugger commands', output))
self.assertTrue(re.search(r'ZAP', output))


@add_test_categories(['pyapi'])
@skipIf(py_version=['<', (3,)])
@expectedFailure # FIXME need FileSP version of SBDebugger::SetOutputFile
def test_stdout(self):
f = io.StringIO()
status = self.debugger.SetOutputFile(f)
self.assertTrue(status.Success())
self.handleCmd(r"script sys.stdout.write('foobar\n')")
self.assertEqual(f.getvalue().strip().split(), ["foobar", "7"])


@add_test_categories(['pyapi'])
@expectedFailure # FIXME implement SBFile::GetFile
@skipIf(py_version=['<', (3,)])
def test_identity(self):

f = io.StringIO()
sbf = lldb.SBFile(f)
self.assertTrue(f is sbf.GetFile())
sbf.Close()
self.assertTrue(f.closed)

f = io.StringIO()
sbf = lldb.SBFile.Create(f, borrow=True)
self.assertTrue(f is sbf.GetFile())
sbf.Close()
self.assertFalse(f.closed)

with open(self.out_filename, 'w') as f:
sbf = lldb.SBFile(f)
self.assertTrue(f is sbf.GetFile())
sbf.Close()
self.assertTrue(f.closed)

with open(self.out_filename, 'w') as f:
sbf = lldb.SBFile.Create(f, borrow=True)
self.assertFalse(f is sbf.GetFile())
sbf.Write(b"foobar\n")
self.assertEqual(f.fileno(), sbf.GetFile().fileno())
sbf.Close()
self.assertFalse(f.closed)

with open(self.out_filename, 'r') as f:
self.assertEqual("foobar", f.read().strip())

with open(self.out_filename, 'wb') as f:
sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True)
self.assertTrue(f is sbf.GetFile())
sbf.Write(b"foobar\n")
self.assertEqual(f.fileno(), sbf.GetFile().fileno())
sbf.Close()
self.assertFalse(f.closed)

with open(self.out_filename, 'r') as f:
self.assertEqual("foobar", f.read().strip())

with open(self.out_filename, 'wb') as f:
sbf = lldb.SBFile.Create(f, force_io_methods=True)
self.assertTrue(f is sbf.GetFile())
sbf.Write(b"foobar\n")
self.assertEqual(f.fileno(), sbf.GetFile().fileno())
sbf.Close()
self.assertTrue(f.closed)

with open(self.out_filename, 'r') as f:
self.assertEqual("foobar", f.read().strip())
22 changes: 11 additions & 11 deletions lldb/scripts/Python/python-typemaps.swig
Original file line number Diff line number Diff line change
Expand Up @@ -444,19 +444,19 @@ bool SetNumberFromPyObject<double>(double &number, PyObject *obj) {
$1 = nullptr;
else if (!lldb_private::PythonFile::Check($input)) {
int fd = PyObject_AsFileDescriptor($input);
if (fd < 0 || PyErr_Occurred())
return nullptr;
PythonObject py_input(PyRefType::Borrowed, $input);
PythonString py_mode = py_input.GetAttributeValue("mode").AsType<PythonString>();

if (-1 != fd && py_mode.IsValid()) {
FILE *f;
if ((f = fdopen(fd, py_mode.GetString().str().c_str())))
$1 = f;
else
PyErr_SetString(PyExc_TypeError, strerror(errno));
} else {
PyErr_SetString(PyExc_TypeError,"not a file-like object");
return nullptr;
}
if (!py_mode.IsValid() || PyErr_Occurred())
return nullptr;
FILE *f;
if ((f = fdopen(fd, py_mode.GetString().str().c_str())))
$1 = f;
else {
PyErr_SetString(PyExc_TypeError, strerror(errno));
return nullptr;
}
}
else
{
Expand Down

0 comments on commit b24022c

Please sign in to comment.