199451b44SJordan Rupprecht"""
299451b44SJordan RupprechtTest lldb Python API for file handles.
399451b44SJordan Rupprecht"""
499451b44SJordan Rupprecht
599451b44SJordan Rupprecht
699451b44SJordan Rupprechtimport os
799451b44SJordan Rupprechtimport io
899451b44SJordan Rupprechtimport re
999451b44SJordan Rupprechtimport sys
1099451b44SJordan Rupprechtfrom contextlib import contextmanager
1199451b44SJordan Rupprecht
1299451b44SJordan Rupprechtimport lldb
1399451b44SJordan Rupprechtfrom lldbsuite.test import  lldbtest
1499451b44SJordan Rupprechtfrom lldbsuite.test.decorators import *
1599451b44SJordan Rupprecht
1699451b44SJordan Rupprechtclass OhNoe(Exception):
1799451b44SJordan Rupprecht    pass
1899451b44SJordan Rupprecht
1999451b44SJordan Rupprechtclass BadIO(io.TextIOBase):
2099451b44SJordan Rupprecht    @property
2199451b44SJordan Rupprecht    def closed(self):
2299451b44SJordan Rupprecht        return False
2399451b44SJordan Rupprecht    def writable(self):
2499451b44SJordan Rupprecht        return True
2599451b44SJordan Rupprecht    def readable(self):
2699451b44SJordan Rupprecht        return True
2799451b44SJordan Rupprecht    def write(self, s):
2899451b44SJordan Rupprecht        raise OhNoe('OH NOE')
2999451b44SJordan Rupprecht    def read(self, n):
3099451b44SJordan Rupprecht        raise OhNoe("OH NOE")
3199451b44SJordan Rupprecht    def flush(self):
3299451b44SJordan Rupprecht        raise OhNoe('OH NOE')
3399451b44SJordan Rupprecht
3499451b44SJordan Rupprecht# This class will raise an exception while it's being
3599451b44SJordan Rupprecht# converted into a C++ object by swig
3699451b44SJordan Rupprechtclass ReallyBadIO(io.TextIOBase):
3799451b44SJordan Rupprecht    def fileno(self):
3899451b44SJordan Rupprecht        return 999
3999451b44SJordan Rupprecht    def writable(self):
4099451b44SJordan Rupprecht        raise OhNoe("OH NOE!!!")
4199451b44SJordan Rupprecht
4299451b44SJordan Rupprechtclass MutableBool():
4399451b44SJordan Rupprecht    def __init__(self, value):
4499451b44SJordan Rupprecht        self.value = value
4599451b44SJordan Rupprecht    def set(self, value):
4699451b44SJordan Rupprecht        self.value = bool(value)
4799451b44SJordan Rupprecht    def __bool__(self):
4899451b44SJordan Rupprecht        return self.value
4999451b44SJordan Rupprecht
5099451b44SJordan Rupprechtclass FlushTestIO(io.StringIO):
5199451b44SJordan Rupprecht    def __init__(self, mutable_flushed, mutable_closed):
5299451b44SJordan Rupprecht        super(FlushTestIO, self).__init__()
5399451b44SJordan Rupprecht        self.mut_flushed = mutable_flushed
5499451b44SJordan Rupprecht        self.mut_closed = mutable_closed
5599451b44SJordan Rupprecht    def close(self):
5699451b44SJordan Rupprecht        self.mut_closed.set(True)
5799451b44SJordan Rupprecht        return super(FlushTestIO, self).close()
5899451b44SJordan Rupprecht    def flush(self):
5999451b44SJordan Rupprecht        self.mut_flushed.set(True)
6099451b44SJordan Rupprecht        return super(FlushTestIO, self).flush()
6199451b44SJordan Rupprecht
6299451b44SJordan Rupprecht@contextmanager
6399451b44SJordan Rupprechtdef replace_stdout(new):
6499451b44SJordan Rupprecht    old = sys.stdout
6599451b44SJordan Rupprecht    sys.stdout = new
6699451b44SJordan Rupprecht    try:
6799451b44SJordan Rupprecht        yield
6899451b44SJordan Rupprecht    finally:
6999451b44SJordan Rupprecht        sys.stdout = old
7099451b44SJordan Rupprecht
7199451b44SJordan Rupprechtdef readStrippedLines(f):
7299451b44SJordan Rupprecht    def i():
7399451b44SJordan Rupprecht        for line in f:
7499451b44SJordan Rupprecht            line = line.strip()
7599451b44SJordan Rupprecht            if line:
7699451b44SJordan Rupprecht                yield line
7799451b44SJordan Rupprecht    return list(i())
7899451b44SJordan Rupprecht
7999451b44SJordan Rupprecht
8099451b44SJordan Rupprechtclass FileHandleTestCase(lldbtest.TestBase):
8199451b44SJordan Rupprecht
8299451b44SJordan Rupprecht    NO_DEBUG_INFO_TESTCASE = True
8399451b44SJordan Rupprecht    mydir = lldbtest.Base.compute_mydir(__file__)
8499451b44SJordan Rupprecht
85a31130f6STatyana Krasnukha    # The way normal tests evaluate debugger commands is
8699451b44SJordan Rupprecht    # by using a SBCommandInterpreter directly, which captures
8799451b44SJordan Rupprecht    # the output in a result object.   For many of tests tests
8899451b44SJordan Rupprecht    # we want the debugger to write the  output directly to
8999451b44SJordan Rupprecht    # its I/O streams like it would have done interactively.
9099451b44SJordan Rupprecht    #
9199451b44SJordan Rupprecht    # For this reason we also define handleCmd() here, even though
9299451b44SJordan Rupprecht    # it is similar to runCmd().
9399451b44SJordan Rupprecht
9499451b44SJordan Rupprecht    def setUp(self):
9599451b44SJordan Rupprecht        super(FileHandleTestCase, self).setUp()
9699451b44SJordan Rupprecht        self.out_filename = self.getBuildArtifact('output')
9799451b44SJordan Rupprecht        self.in_filename = self.getBuildArtifact('input')
9899451b44SJordan Rupprecht
9999451b44SJordan Rupprecht    def tearDown(self):
10099451b44SJordan Rupprecht        super(FileHandleTestCase, self).tearDown()
10199451b44SJordan Rupprecht        for name in (self.out_filename, self.in_filename):
10299451b44SJordan Rupprecht            if os.path.exists(name):
10399451b44SJordan Rupprecht                os.unlink(name)
10499451b44SJordan Rupprecht
105a31130f6STatyana Krasnukha    # Similar to runCmd(), but letting the debugger just print the results
106a31130f6STatyana Krasnukha    # instead of collecting them.
10799451b44SJordan Rupprecht    def handleCmd(self, cmd, check=True, collect_result=True):
10899451b44SJordan Rupprecht        assert not check or collect_result
10999451b44SJordan Rupprecht        ret = lldb.SBCommandReturnObject()
11099451b44SJordan Rupprecht        if collect_result:
111a31130f6STatyana Krasnukha            interpreter = self.dbg.GetCommandInterpreter()
11299451b44SJordan Rupprecht            interpreter.HandleCommand(cmd, ret)
11399451b44SJordan Rupprecht        else:
114a31130f6STatyana Krasnukha            self.dbg.HandleCommand(cmd)
115a31130f6STatyana Krasnukha        self.dbg.GetOutputFile().Flush()
116a31130f6STatyana Krasnukha        self.dbg.GetErrorFile().Flush()
11799451b44SJordan Rupprecht        if collect_result and check:
11899451b44SJordan Rupprecht            self.assertTrue(ret.Succeeded())
11999451b44SJordan Rupprecht        return ret.GetOutput()
12099451b44SJordan Rupprecht
12199451b44SJordan Rupprecht
12299451b44SJordan Rupprecht    def test_legacy_file_out_script(self):
12399451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
124a31130f6STatyana Krasnukha            self.dbg.SetOutputFileHandle(f, False)
12599451b44SJordan Rupprecht            # scripts print to output even if you capture the results
12699451b44SJordan Rupprecht            # I'm not sure I love that behavior, but that's the way
12799451b44SJordan Rupprecht            # it's been for a long time.  That's why this test works
12899451b44SJordan Rupprecht            # even with collect_result=True.
12999451b44SJordan Rupprecht            self.handleCmd('script 1+1')
130a31130f6STatyana Krasnukha            self.dbg.GetOutputFileHandle().write('FOO\n')
1317a11cc06STatyana Krasnukha            self.dbg.GetOutputFileHandle().flush()
13299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
13399451b44SJordan Rupprecht            self.assertEqual(readStrippedLines(f), ['2', 'FOO'])
13499451b44SJordan Rupprecht
13599451b44SJordan Rupprecht
13699451b44SJordan Rupprecht    def test_legacy_file_out(self):
13799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
138a31130f6STatyana Krasnukha            self.dbg.SetOutputFileHandle(f, False)
13999451b44SJordan Rupprecht            self.handleCmd('p/x 3735928559', collect_result=False, check=False)
14099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
14199451b44SJordan Rupprecht            self.assertIn('deadbeef', f.read())
14299451b44SJordan Rupprecht
14399451b44SJordan Rupprecht    def test_legacy_file_err_with_get(self):
14499451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
145a31130f6STatyana Krasnukha            self.dbg.SetErrorFileHandle(f, False)
14699451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
147a31130f6STatyana Krasnukha            f2 = self.dbg.GetErrorFileHandle()
14899451b44SJordan Rupprecht            f2.write('FOOBAR\n')
14999451b44SJordan Rupprecht            f2.flush()
15099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
15199451b44SJordan Rupprecht            errors = f.read()
15299451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
15399451b44SJordan Rupprecht            self.assertTrue(re.search(r'FOOBAR', errors))
15499451b44SJordan Rupprecht
15599451b44SJordan Rupprecht
15699451b44SJordan Rupprecht    def test_legacy_file_err(self):
15799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
158a31130f6STatyana Krasnukha            self.dbg.SetErrorFileHandle(f, False)
15999451b44SJordan Rupprecht            self.handleCmd('lol', check=False, collect_result=False)
16099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
16199451b44SJordan Rupprecht            self.assertIn("is not a valid command", f.read())
16299451b44SJordan Rupprecht
16399451b44SJordan Rupprecht
16499451b44SJordan Rupprecht    def test_legacy_file_error(self):
16599451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
166a31130f6STatyana Krasnukha            self.dbg.SetErrorFileHandle(f, False)
16799451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
16899451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
16999451b44SJordan Rupprecht            errors = f.read()
17099451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
17199451b44SJordan Rupprecht
17299451b44SJordan Rupprecht    def test_sbfile_type_errors(self):
17399451b44SJordan Rupprecht        sbf = lldb.SBFile()
17499451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Write, None)
17599451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Read, None)
17699451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Read, b'this bytes is not mutable')
17799451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Write, u"ham sandwich")
17899451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Read, u"ham sandwich")
17999451b44SJordan Rupprecht
18099451b44SJordan Rupprecht
18199451b44SJordan Rupprecht    def test_sbfile_write_fileno(self):
18299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
18399451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), "w", False)
18499451b44SJordan Rupprecht            self.assertTrue(sbf.IsValid())
18599451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO\nBAR')
186*779bbbf2SDave Lee            self.assertSuccess(e)
18799451b44SJordan Rupprecht            self.assertEqual(n, 7)
18899451b44SJordan Rupprecht            sbf.Close()
18999451b44SJordan Rupprecht            self.assertFalse(sbf.IsValid())
19099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
19199451b44SJordan Rupprecht            self.assertEqual(readStrippedLines(f), ['FOO', 'BAR'])
19299451b44SJordan Rupprecht
19399451b44SJordan Rupprecht
19499451b44SJordan Rupprecht    def test_sbfile_write(self):
19599451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
19699451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
19799451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO\n')
198*779bbbf2SDave Lee            self.assertSuccess(e)
19999451b44SJordan Rupprecht            self.assertEqual(n, 4)
20099451b44SJordan Rupprecht            sbf.Close()
20199451b44SJordan Rupprecht            self.assertTrue(f.closed)
20299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
20399451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), 'FOO')
20499451b44SJordan Rupprecht
20599451b44SJordan Rupprecht
20699451b44SJordan Rupprecht    def test_sbfile_read_fileno(self):
20799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
20899451b44SJordan Rupprecht            f.write('FOO')
20999451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
21099451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), "r", False)
21199451b44SJordan Rupprecht            self.assertTrue(sbf.IsValid())
21299451b44SJordan Rupprecht            buffer = bytearray(100)
21399451b44SJordan Rupprecht            e, n = sbf.Read(buffer)
214*779bbbf2SDave Lee            self.assertSuccess(e)
21599451b44SJordan Rupprecht            self.assertEqual(buffer[:n], b'FOO')
21699451b44SJordan Rupprecht
21799451b44SJordan Rupprecht
21899451b44SJordan Rupprecht    def test_sbfile_read(self):
21999451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
22099451b44SJordan Rupprecht            f.write('foo')
22199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
22299451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
22399451b44SJordan Rupprecht            buf = bytearray(100)
22499451b44SJordan Rupprecht            e, n = sbf.Read(buf)
225*779bbbf2SDave Lee            self.assertSuccess(e)
22699451b44SJordan Rupprecht            self.assertEqual(n, 3)
22799451b44SJordan Rupprecht            self.assertEqual(buf[:n], b'foo')
22899451b44SJordan Rupprecht            sbf.Close()
22999451b44SJordan Rupprecht            self.assertTrue(f.closed)
23099451b44SJordan Rupprecht
23199451b44SJordan Rupprecht
23299451b44SJordan Rupprecht    def test_fileno_out(self):
23399451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
23499451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), "w", False)
235a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(sbf)
236*779bbbf2SDave Lee            self.assertSuccess(status)
23799451b44SJordan Rupprecht            self.handleCmd('script 1+2')
238a31130f6STatyana Krasnukha            self.dbg.GetOutputFile().Write(b'quux')
2397a11cc06STatyana Krasnukha            self.dbg.GetOutputFile().Flush()
24099451b44SJordan Rupprecht
24199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
24299451b44SJordan Rupprecht            self.assertEqual(readStrippedLines(f), ['3', 'quux'])
24399451b44SJordan Rupprecht
24499451b44SJordan Rupprecht
24599451b44SJordan Rupprecht    def test_fileno_help(self):
24699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
24799451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), "w", False)
248a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(sbf)
249*779bbbf2SDave Lee            self.assertSuccess(status)
25099451b44SJordan Rupprecht            self.handleCmd("help help", collect_result=False, check=False)
25199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
25299451b44SJordan Rupprecht            self.assertTrue(re.search(r'Show a list of all debugger commands', f.read()))
25399451b44SJordan Rupprecht
25499451b44SJordan Rupprecht
25599451b44SJordan Rupprecht    def test_help(self):
25699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
257a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(lldb.SBFile(f))
258*779bbbf2SDave Lee            self.assertSuccess(status)
25999451b44SJordan Rupprecht            self.handleCmd("help help", check=False, collect_result=False)
26099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
26199451b44SJordan Rupprecht            self.assertIn('Show a list of all debugger commands', f.read())
26299451b44SJordan Rupprecht
26399451b44SJordan Rupprecht
26499451b44SJordan Rupprecht    def test_immediate(self):
26599451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
26699451b44SJordan Rupprecht            ret = lldb.SBCommandReturnObject()
26799451b44SJordan Rupprecht            ret.SetImmediateOutputFile(f)
268a31130f6STatyana Krasnukha            interpreter = self.dbg.GetCommandInterpreter()
26999451b44SJordan Rupprecht            interpreter.HandleCommand("help help", ret)
27099451b44SJordan Rupprecht            # make sure the file wasn't closed early.
27199451b44SJordan Rupprecht            f.write("\nQUUX\n")
27299451b44SJordan Rupprecht        ret = None # call destructor and flush streams
27399451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
27499451b44SJordan Rupprecht            output = f.read()
27599451b44SJordan Rupprecht            self.assertTrue(re.search(r'Show a list of all debugger commands', output))
27699451b44SJordan Rupprecht            self.assertTrue(re.search(r'QUUX', output))
27799451b44SJordan Rupprecht
27899451b44SJordan Rupprecht
27999451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
28099451b44SJordan Rupprecht    def test_immediate_string(self):
28199451b44SJordan Rupprecht        f = io.StringIO()
28299451b44SJordan Rupprecht        ret = lldb.SBCommandReturnObject()
28399451b44SJordan Rupprecht        ret.SetImmediateOutputFile(f)
284a31130f6STatyana Krasnukha        interpreter = self.dbg.GetCommandInterpreter()
28599451b44SJordan Rupprecht        interpreter.HandleCommand("help help", ret)
28699451b44SJordan Rupprecht        # make sure the file wasn't closed early.
28799451b44SJordan Rupprecht        f.write("\nQUUX\n")
28899451b44SJordan Rupprecht        ret = None # call destructor and flush streams
28999451b44SJordan Rupprecht        output = f.getvalue()
29099451b44SJordan Rupprecht        self.assertTrue(re.search(r'Show a list of all debugger commands', output))
29199451b44SJordan Rupprecht        self.assertTrue(re.search(r'QUUX', output))
29299451b44SJordan Rupprecht
29399451b44SJordan Rupprecht
29499451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
29599451b44SJordan Rupprecht    def test_immediate_sbfile_string(self):
29699451b44SJordan Rupprecht        f = io.StringIO()
29799451b44SJordan Rupprecht        ret = lldb.SBCommandReturnObject()
29899451b44SJordan Rupprecht        ret.SetImmediateOutputFile(lldb.SBFile(f))
299a31130f6STatyana Krasnukha        interpreter = self.dbg.GetCommandInterpreter()
30099451b44SJordan Rupprecht        interpreter.HandleCommand("help help", ret)
30199451b44SJordan Rupprecht        output = f.getvalue()
30299451b44SJordan Rupprecht        ret = None # call destructor and flush streams
30399451b44SJordan Rupprecht        # sbfile default constructor doesn't borrow the file
30499451b44SJordan Rupprecht        self.assertTrue(f.closed)
30599451b44SJordan Rupprecht        self.assertTrue(re.search(r'Show a list of all debugger commands', output))
30699451b44SJordan Rupprecht
30799451b44SJordan Rupprecht
30899451b44SJordan Rupprecht    def test_fileno_inout(self):
30999451b44SJordan Rupprecht        with open(self.in_filename, 'w') as f:
31099451b44SJordan Rupprecht            f.write("help help\n")
31199451b44SJordan Rupprecht
31299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as outf, open(self.in_filename, 'r') as inf:
31399451b44SJordan Rupprecht
31499451b44SJordan Rupprecht            outsbf = lldb.SBFile(outf.fileno(), "w", False)
315a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(outsbf)
316*779bbbf2SDave Lee            self.assertSuccess(status)
31799451b44SJordan Rupprecht
31899451b44SJordan Rupprecht            insbf = lldb.SBFile(inf.fileno(), "r", False)
319a31130f6STatyana Krasnukha            status = self.dbg.SetInputFile(insbf)
320*779bbbf2SDave Lee            self.assertSuccess(status)
32199451b44SJordan Rupprecht
32299451b44SJordan Rupprecht            opts = lldb.SBCommandInterpreterRunOptions()
323a31130f6STatyana Krasnukha            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
324a31130f6STatyana Krasnukha            self.dbg.GetOutputFile().Flush()
32599451b44SJordan Rupprecht
32699451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
32799451b44SJordan Rupprecht            self.assertTrue(re.search(r'Show a list of all debugger commands', f.read()))
32899451b44SJordan Rupprecht
32999451b44SJordan Rupprecht
33099451b44SJordan Rupprecht    def test_inout(self):
33199451b44SJordan Rupprecht        with open(self.in_filename, 'w') as f:
33299451b44SJordan Rupprecht            f.write("help help\n")
33399451b44SJordan Rupprecht        with  open(self.out_filename, 'w') as outf, \
33499451b44SJordan Rupprecht              open(self.in_filename, 'r') as inf:
335a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(lldb.SBFile(outf))
336*779bbbf2SDave Lee            self.assertSuccess(status)
337a31130f6STatyana Krasnukha            status = self.dbg.SetInputFile(lldb.SBFile(inf))
338*779bbbf2SDave Lee            self.assertSuccess(status)
33999451b44SJordan Rupprecht            opts = lldb.SBCommandInterpreterRunOptions()
340a31130f6STatyana Krasnukha            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
341a31130f6STatyana Krasnukha            self.dbg.GetOutputFile().Flush()
34299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
34399451b44SJordan Rupprecht            output = f.read()
34499451b44SJordan Rupprecht            self.assertIn('Show a list of all debugger commands', output)
34599451b44SJordan Rupprecht
34699451b44SJordan Rupprecht
34799451b44SJordan Rupprecht    def test_binary_inout(self):
34899451b44SJordan Rupprecht        with open(self.in_filename, 'w') as f:
34999451b44SJordan Rupprecht            f.write("help help\n")
35099451b44SJordan Rupprecht        with  open(self.out_filename, 'wb') as outf, \
35199451b44SJordan Rupprecht              open(self.in_filename, 'rb') as inf:
352a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(lldb.SBFile(outf))
353*779bbbf2SDave Lee            self.assertSuccess(status)
354a31130f6STatyana Krasnukha            status = self.dbg.SetInputFile(lldb.SBFile(inf))
355*779bbbf2SDave Lee            self.assertSuccess(status)
35699451b44SJordan Rupprecht            opts = lldb.SBCommandInterpreterRunOptions()
357a31130f6STatyana Krasnukha            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
358a31130f6STatyana Krasnukha            self.dbg.GetOutputFile().Flush()
35999451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
36099451b44SJordan Rupprecht            output = f.read()
36199451b44SJordan Rupprecht            self.assertIn('Show a list of all debugger commands', output)
36299451b44SJordan Rupprecht
36399451b44SJordan Rupprecht
36499451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
36599451b44SJordan Rupprecht    def test_string_inout(self):
36699451b44SJordan Rupprecht        inf = io.StringIO("help help\np/x ~0\n")
36799451b44SJordan Rupprecht        outf = io.StringIO()
368a31130f6STatyana Krasnukha        status = self.dbg.SetOutputFile(lldb.SBFile(outf))
369*779bbbf2SDave Lee        self.assertSuccess(status)
370a31130f6STatyana Krasnukha        status = self.dbg.SetInputFile(lldb.SBFile(inf))
371*779bbbf2SDave Lee        self.assertSuccess(status)
37299451b44SJordan Rupprecht        opts = lldb.SBCommandInterpreterRunOptions()
373a31130f6STatyana Krasnukha        self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
374a31130f6STatyana Krasnukha        self.dbg.GetOutputFile().Flush()
37599451b44SJordan Rupprecht        output = outf.getvalue()
37699451b44SJordan Rupprecht        self.assertIn('Show a list of all debugger commands', output)
37799451b44SJordan Rupprecht        self.assertIn('0xfff', output)
37899451b44SJordan Rupprecht
37999451b44SJordan Rupprecht
38099451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
38199451b44SJordan Rupprecht    def test_bytes_inout(self):
38299451b44SJordan Rupprecht        inf = io.BytesIO(b"help help\nhelp b\n")
38399451b44SJordan Rupprecht        outf = io.BytesIO()
384a31130f6STatyana Krasnukha        status = self.dbg.SetOutputFile(lldb.SBFile(outf))
385*779bbbf2SDave Lee        self.assertSuccess(status)
386a31130f6STatyana Krasnukha        status = self.dbg.SetInputFile(lldb.SBFile(inf))
387*779bbbf2SDave Lee        self.assertSuccess(status)
38899451b44SJordan Rupprecht        opts = lldb.SBCommandInterpreterRunOptions()
389a31130f6STatyana Krasnukha        self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
390a31130f6STatyana Krasnukha        self.dbg.GetOutputFile().Flush()
39199451b44SJordan Rupprecht        output = outf.getvalue()
39299451b44SJordan Rupprecht        self.assertIn(b'Show a list of all debugger commands', output)
39399451b44SJordan Rupprecht        self.assertIn(b'Set a breakpoint', output)
39499451b44SJordan Rupprecht
39599451b44SJordan Rupprecht
39699451b44SJordan Rupprecht    def test_fileno_error(self):
39799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
39899451b44SJordan Rupprecht
39999451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), 'w', False)
400a31130f6STatyana Krasnukha            status = self.dbg.SetErrorFile(sbf)
401*779bbbf2SDave Lee            self.assertSuccess(status)
40299451b44SJordan Rupprecht
40399451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
40499451b44SJordan Rupprecht
405a31130f6STatyana Krasnukha            self.dbg.GetErrorFile().Write(b'\nzork\n')
40699451b44SJordan Rupprecht
40799451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
40899451b44SJordan Rupprecht            errors = f.read()
40999451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
41099451b44SJordan Rupprecht            self.assertTrue(re.search(r'zork', errors))
41199451b44SJordan Rupprecht
41299451b44SJordan Rupprecht
41399451b44SJordan Rupprecht    def test_replace_stdout(self):
41499451b44SJordan Rupprecht        f = io.StringIO()
41599451b44SJordan Rupprecht        with replace_stdout(f):
41699451b44SJordan Rupprecht            self.assertEqual(sys.stdout, f)
41799451b44SJordan Rupprecht            self.handleCmd('script sys.stdout.write("lol")',
41899451b44SJordan Rupprecht                collect_result=False, check=False)
41999451b44SJordan Rupprecht            self.assertEqual(sys.stdout, f)
42099451b44SJordan Rupprecht
42199451b44SJordan Rupprecht
42299451b44SJordan Rupprecht    def test_replace_stdout_with_nonfile(self):
42399451b44SJordan Rupprecht        f = io.StringIO()
42499451b44SJordan Rupprecht        with replace_stdout(f):
42599451b44SJordan Rupprecht            class Nothing():
42699451b44SJordan Rupprecht                pass
42799451b44SJordan Rupprecht            with replace_stdout(Nothing):
42899451b44SJordan Rupprecht                self.assertEqual(sys.stdout, Nothing)
42999451b44SJordan Rupprecht                self.handleCmd('script sys.stdout.write("lol")',
43099451b44SJordan Rupprecht                    check=False, collect_result=False)
43199451b44SJordan Rupprecht                self.assertEqual(sys.stdout, Nothing)
43299451b44SJordan Rupprecht            sys.stdout.write(u"FOO")
43399451b44SJordan Rupprecht        self.assertEqual(f.getvalue(), "FOO")
43499451b44SJordan Rupprecht
43599451b44SJordan Rupprecht
43699451b44SJordan Rupprecht    def test_sbfile_write_borrowed(self):
43799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
43899451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True)
43999451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO')
440*779bbbf2SDave Lee            self.assertSuccess(e)
44199451b44SJordan Rupprecht            self.assertEqual(n, 3)
44299451b44SJordan Rupprecht            sbf.Close()
44399451b44SJordan Rupprecht            self.assertFalse(f.closed)
44499451b44SJordan Rupprecht            f.write('BAR\n')
44599451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
44699451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), 'FOOBAR')
44799451b44SJordan Rupprecht
44899451b44SJordan Rupprecht
44999451b44SJordan Rupprecht
45099451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
45199451b44SJordan Rupprecht    def test_sbfile_write_forced(self):
45299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
45399451b44SJordan Rupprecht            written = MutableBool(False)
45499451b44SJordan Rupprecht            orig_write = f.write
45599451b44SJordan Rupprecht            def mywrite(x):
45699451b44SJordan Rupprecht                written.set(True)
45799451b44SJordan Rupprecht                return orig_write(x)
45899451b44SJordan Rupprecht            f.write = mywrite
45999451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, force_io_methods=True)
46099451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO')
46199451b44SJordan Rupprecht            self.assertTrue(written)
462*779bbbf2SDave Lee            self.assertSuccess(e)
46399451b44SJordan Rupprecht            self.assertEqual(n, 3)
46499451b44SJordan Rupprecht            sbf.Close()
46599451b44SJordan Rupprecht            self.assertTrue(f.closed)
46699451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
46799451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), 'FOO')
46899451b44SJordan Rupprecht
46999451b44SJordan Rupprecht
47099451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
47199451b44SJordan Rupprecht    def test_sbfile_write_forced_borrowed(self):
47299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
47399451b44SJordan Rupprecht            written = MutableBool(False)
47499451b44SJordan Rupprecht            orig_write = f.write
47599451b44SJordan Rupprecht            def mywrite(x):
47699451b44SJordan Rupprecht                written.set(True)
47799451b44SJordan Rupprecht                return orig_write(x)
47899451b44SJordan Rupprecht            f.write = mywrite
47999451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True)
48099451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO')
48199451b44SJordan Rupprecht            self.assertTrue(written)
482*779bbbf2SDave Lee            self.assertSuccess(e)
48399451b44SJordan Rupprecht            self.assertEqual(n, 3)
48499451b44SJordan Rupprecht            sbf.Close()
48599451b44SJordan Rupprecht            self.assertFalse(f.closed)
48699451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
48799451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), 'FOO')
48899451b44SJordan Rupprecht
48999451b44SJordan Rupprecht
49099451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
49199451b44SJordan Rupprecht    def test_sbfile_write_string(self):
49299451b44SJordan Rupprecht        f = io.StringIO()
49399451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
49499451b44SJordan Rupprecht        e, n = sbf.Write(b'FOO')
49599451b44SJordan Rupprecht        self.assertEqual(f.getvalue().strip(), "FOO")
496*779bbbf2SDave Lee        self.assertSuccess(e)
49799451b44SJordan Rupprecht        self.assertEqual(n, 3)
49899451b44SJordan Rupprecht        sbf.Close()
49999451b44SJordan Rupprecht        self.assertTrue(f.closed)
50099451b44SJordan Rupprecht
50199451b44SJordan Rupprecht
50299451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
50399451b44SJordan Rupprecht    def test_string_out(self):
50499451b44SJordan Rupprecht        f = io.StringIO()
505a31130f6STatyana Krasnukha        status = self.dbg.SetOutputFile(f)
506*779bbbf2SDave Lee        self.assertSuccess(status)
50799451b44SJordan Rupprecht        self.handleCmd("script 'foobar'")
50899451b44SJordan Rupprecht        self.assertEqual(f.getvalue().strip(), "'foobar'")
50999451b44SJordan Rupprecht
51099451b44SJordan Rupprecht
51199451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
51299451b44SJordan Rupprecht    def test_string_error(self):
51399451b44SJordan Rupprecht        f = io.StringIO()
514a31130f6STatyana Krasnukha        status = self.dbg.SetErrorFile(f)
515*779bbbf2SDave Lee        self.assertSuccess(status)
51699451b44SJordan Rupprecht        self.handleCmd('lolwut', check=False, collect_result=False)
51799451b44SJordan Rupprecht        errors = f.getvalue()
51899451b44SJordan Rupprecht        self.assertTrue(re.search(r'error:.*lolwut', errors))
51999451b44SJordan Rupprecht
52099451b44SJordan Rupprecht
52199451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
52299451b44SJordan Rupprecht    def test_sbfile_write_bytes(self):
52399451b44SJordan Rupprecht        f = io.BytesIO()
52499451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
52599451b44SJordan Rupprecht        e, n = sbf.Write(b'FOO')
52699451b44SJordan Rupprecht        self.assertEqual(f.getvalue().strip(), b"FOO")
527*779bbbf2SDave Lee        self.assertSuccess(e)
52899451b44SJordan Rupprecht        self.assertEqual(n, 3)
52999451b44SJordan Rupprecht        sbf.Close()
53099451b44SJordan Rupprecht        self.assertTrue(f.closed)
53199451b44SJordan Rupprecht
53299451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
53399451b44SJordan Rupprecht    def test_sbfile_read_string(self):
53499451b44SJordan Rupprecht        f = io.StringIO('zork')
53599451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
53699451b44SJordan Rupprecht        buf = bytearray(100)
53799451b44SJordan Rupprecht        e, n = sbf.Read(buf)
538*779bbbf2SDave Lee        self.assertSuccess(e)
53999451b44SJordan Rupprecht        self.assertEqual(buf[:n], b'zork')
54099451b44SJordan Rupprecht
54199451b44SJordan Rupprecht
54299451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
54399451b44SJordan Rupprecht    def test_sbfile_read_string_one_byte(self):
54499451b44SJordan Rupprecht        f = io.StringIO('z')
54599451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
54699451b44SJordan Rupprecht        buf = bytearray(1)
54799451b44SJordan Rupprecht        e, n = sbf.Read(buf)
54899451b44SJordan Rupprecht        self.assertTrue(e.Fail())
54999451b44SJordan Rupprecht        self.assertEqual(n, 0)
55099451b44SJordan Rupprecht        self.assertEqual(e.GetCString(), "can't read less than 6 bytes from a utf8 text stream")
55199451b44SJordan Rupprecht
55299451b44SJordan Rupprecht
55399451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
55499451b44SJordan Rupprecht    def test_sbfile_read_bytes(self):
55599451b44SJordan Rupprecht        f = io.BytesIO(b'zork')
55699451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
55799451b44SJordan Rupprecht        buf = bytearray(100)
55899451b44SJordan Rupprecht        e, n = sbf.Read(buf)
559*779bbbf2SDave Lee        self.assertSuccess(e)
56099451b44SJordan Rupprecht        self.assertEqual(buf[:n], b'zork')
56199451b44SJordan Rupprecht
56299451b44SJordan Rupprecht
56399451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
56499451b44SJordan Rupprecht    def test_sbfile_out(self):
56599451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
56699451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
567a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(sbf)
568*779bbbf2SDave Lee            self.assertSuccess(status)
56999451b44SJordan Rupprecht            self.handleCmd('script 2+2')
57099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
57199451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), '4')
57299451b44SJordan Rupprecht
57399451b44SJordan Rupprecht
57499451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
57599451b44SJordan Rupprecht    def test_file_out(self):
57699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
577a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(f)
578*779bbbf2SDave Lee            self.assertSuccess(status)
57999451b44SJordan Rupprecht            self.handleCmd('script 2+2')
58099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
58199451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), '4')
58299451b44SJordan Rupprecht
58399451b44SJordan Rupprecht
58499451b44SJordan Rupprecht    def test_sbfile_error(self):
58599451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
58699451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
587a31130f6STatyana Krasnukha            status = self.dbg.SetErrorFile(sbf)
588*779bbbf2SDave Lee            self.assertSuccess(status)
58999451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
59099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
59199451b44SJordan Rupprecht            errors = f.read()
59299451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
59399451b44SJordan Rupprecht
59499451b44SJordan Rupprecht
59599451b44SJordan Rupprecht    def test_file_error(self):
59699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
597a31130f6STatyana Krasnukha            status = self.dbg.SetErrorFile(f)
598*779bbbf2SDave Lee            self.assertSuccess(status)
59999451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
60099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
60199451b44SJordan Rupprecht            errors = f.read()
60299451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
60399451b44SJordan Rupprecht
60499451b44SJordan Rupprecht
60599451b44SJordan Rupprecht    def test_exceptions(self):
60699451b44SJordan Rupprecht        self.assertRaises(Exception, lldb.SBFile, None)
60799451b44SJordan Rupprecht        self.assertRaises(Exception, lldb.SBFile, "ham sandwich")
60899451b44SJordan Rupprecht        if sys.version_info[0] < 3:
60999451b44SJordan Rupprecht            self.assertRaises(Exception, lldb.SBFile, ReallyBadIO())
61099451b44SJordan Rupprecht        else:
61199451b44SJordan Rupprecht            self.assertRaises(OhNoe, lldb.SBFile, ReallyBadIO())
61299451b44SJordan Rupprecht            error, n = lldb.SBFile(BadIO()).Write(b"FOO")
61399451b44SJordan Rupprecht            self.assertEqual(n, 0)
61499451b44SJordan Rupprecht            self.assertTrue(error.Fail())
61599451b44SJordan Rupprecht            self.assertIn('OH NOE', error.GetCString())
61699451b44SJordan Rupprecht            error, n = lldb.SBFile(BadIO()).Read(bytearray(100))
61799451b44SJordan Rupprecht            self.assertEqual(n, 0)
61899451b44SJordan Rupprecht            self.assertTrue(error.Fail())
61999451b44SJordan Rupprecht            self.assertIn('OH NOE', error.GetCString())
62099451b44SJordan Rupprecht
62199451b44SJordan Rupprecht
62299451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
62399451b44SJordan Rupprecht    def test_exceptions_logged(self):
62499451b44SJordan Rupprecht        messages = list()
625a31130f6STatyana Krasnukha        self.dbg.SetLoggingCallback(messages.append)
62699451b44SJordan Rupprecht        self.handleCmd('log enable lldb script')
627a31130f6STatyana Krasnukha        self.dbg.SetOutputFile(lldb.SBFile(BadIO()))
62899451b44SJordan Rupprecht        self.handleCmd('script 1+1')
62999451b44SJordan Rupprecht        self.assertTrue(any('OH NOE' in msg for msg in messages))
63099451b44SJordan Rupprecht
63199451b44SJordan Rupprecht
63299451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
63399451b44SJordan Rupprecht    def test_flush(self):
63499451b44SJordan Rupprecht        flushed = MutableBool(False)
63599451b44SJordan Rupprecht        closed = MutableBool(False)
63699451b44SJordan Rupprecht        f = FlushTestIO(flushed, closed)
63799451b44SJordan Rupprecht        self.assertFalse(flushed)
63899451b44SJordan Rupprecht        self.assertFalse(closed)
63999451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
64099451b44SJordan Rupprecht        self.assertFalse(flushed)
64199451b44SJordan Rupprecht        self.assertFalse(closed)
64299451b44SJordan Rupprecht        sbf = None
64399451b44SJordan Rupprecht        self.assertFalse(flushed)
64499451b44SJordan Rupprecht        self.assertTrue(closed)
64599451b44SJordan Rupprecht        self.assertTrue(f.closed)
64699451b44SJordan Rupprecht
64799451b44SJordan Rupprecht        flushed = MutableBool(False)
64899451b44SJordan Rupprecht        closed = MutableBool(False)
64999451b44SJordan Rupprecht        f = FlushTestIO(flushed, closed)
65099451b44SJordan Rupprecht        self.assertFalse(flushed)
65199451b44SJordan Rupprecht        self.assertFalse(closed)
65299451b44SJordan Rupprecht        sbf = lldb.SBFile.Create(f, borrow=True)
65399451b44SJordan Rupprecht        self.assertFalse(flushed)
65499451b44SJordan Rupprecht        self.assertFalse(closed)
65599451b44SJordan Rupprecht        sbf = None
65699451b44SJordan Rupprecht        self.assertTrue(flushed)
65799451b44SJordan Rupprecht        self.assertFalse(closed)
65899451b44SJordan Rupprecht        self.assertFalse(f.closed)
65999451b44SJordan Rupprecht
66099451b44SJordan Rupprecht
66199451b44SJordan Rupprecht    def test_fileno_flush(self):
66299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
66399451b44SJordan Rupprecht            f.write("foo")
66499451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
66599451b44SJordan Rupprecht            sbf.Write(b'bar')
66699451b44SJordan Rupprecht            sbf = None
66799451b44SJordan Rupprecht            self.assertTrue(f.closed)
66899451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
66999451b44SJordan Rupprecht            self.assertEqual(f.read(), 'foobar')
67099451b44SJordan Rupprecht
67199451b44SJordan Rupprecht        with open(self.out_filename, 'w+') as f:
67299451b44SJordan Rupprecht            f.write("foo")
67399451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True)
67499451b44SJordan Rupprecht            sbf.Write(b'bar')
67599451b44SJordan Rupprecht            sbf = None
67699451b44SJordan Rupprecht            self.assertFalse(f.closed)
67799451b44SJordan Rupprecht            f.seek(0)
67899451b44SJordan Rupprecht            self.assertEqual(f.read(), 'foobar')
67999451b44SJordan Rupprecht
68099451b44SJordan Rupprecht
68199451b44SJordan Rupprecht    def test_close(self):
68299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
683a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(f)
684*779bbbf2SDave Lee            self.assertSuccess(status)
68599451b44SJordan Rupprecht            self.handleCmd("help help", check=False, collect_result=False)
68699451b44SJordan Rupprecht            # make sure the file wasn't closed early.
68799451b44SJordan Rupprecht            f.write("\nZAP\n")
688a31130f6STatyana Krasnukha            lldb.SBDebugger.Destroy(self.dbg)
68999451b44SJordan Rupprecht            # check that output file was closed when debugger was destroyed.
69099451b44SJordan Rupprecht            with self.assertRaises(ValueError):
69199451b44SJordan Rupprecht                f.write("\nQUUX\n")
69299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
69399451b44SJordan Rupprecht            output = f.read()
69499451b44SJordan Rupprecht            self.assertTrue(re.search(r'Show a list of all debugger commands', output))
69599451b44SJordan Rupprecht            self.assertTrue(re.search(r'ZAP', output))
69699451b44SJordan Rupprecht
69799451b44SJordan Rupprecht
69899451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
69999451b44SJordan Rupprecht    def test_stdout(self):
70099451b44SJordan Rupprecht        f = io.StringIO()
701a31130f6STatyana Krasnukha        status = self.dbg.SetOutputFile(f)
702*779bbbf2SDave Lee        self.assertSuccess(status)
70399451b44SJordan Rupprecht        self.handleCmd(r"script sys.stdout.write('foobar\n')")
70499451b44SJordan Rupprecht        self.assertEqual(f.getvalue().strip().split(), ["foobar", "7"])
70599451b44SJordan Rupprecht
70699451b44SJordan Rupprecht
70799451b44SJordan Rupprecht    def test_stdout_file(self):
70899451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
709a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(f)
710*779bbbf2SDave Lee            self.assertSuccess(status)
71199451b44SJordan Rupprecht            self.handleCmd(r"script sys.stdout.write('foobar\n')")
71299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
71399451b44SJordan Rupprecht            # In python2 sys.stdout.write() returns None, which
71499451b44SJordan Rupprecht            # the REPL will ignore, but in python3 it will
71599451b44SJordan Rupprecht            # return the number of bytes written, which the REPL
71699451b44SJordan Rupprecht            # will print out.
71799451b44SJordan Rupprecht            lines = [x for x in f.read().strip().split() if x != "7"]
71899451b44SJordan Rupprecht            self.assertEqual(lines, ["foobar"])
71999451b44SJordan Rupprecht
72099451b44SJordan Rupprecht
72199451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
72299451b44SJordan Rupprecht    def test_identity(self):
72399451b44SJordan Rupprecht
72499451b44SJordan Rupprecht        f = io.StringIO()
72599451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
72699451b44SJordan Rupprecht        self.assertTrue(f is sbf.GetFile())
72799451b44SJordan Rupprecht        sbf.Close()
72899451b44SJordan Rupprecht        self.assertTrue(f.closed)
72999451b44SJordan Rupprecht
73099451b44SJordan Rupprecht        f = io.StringIO()
73199451b44SJordan Rupprecht        sbf = lldb.SBFile.Create(f, borrow=True)
73299451b44SJordan Rupprecht        self.assertTrue(f is sbf.GetFile())
73399451b44SJordan Rupprecht        sbf.Close()
73499451b44SJordan Rupprecht        self.assertFalse(f.closed)
73599451b44SJordan Rupprecht
73699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
73799451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
73899451b44SJordan Rupprecht            self.assertTrue(f is sbf.GetFile())
73999451b44SJordan Rupprecht            sbf.Close()
74099451b44SJordan Rupprecht            self.assertTrue(f.closed)
74199451b44SJordan Rupprecht
74299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
74399451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True)
74499451b44SJordan Rupprecht            self.assertFalse(f is sbf.GetFile())
74599451b44SJordan Rupprecht            sbf.Write(b"foobar\n")
74699451b44SJordan Rupprecht            self.assertEqual(f.fileno(), sbf.GetFile().fileno())
74799451b44SJordan Rupprecht            sbf.Close()
74899451b44SJordan Rupprecht            self.assertFalse(f.closed)
74999451b44SJordan Rupprecht
75099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
75199451b44SJordan Rupprecht            self.assertEqual("foobar", f.read().strip())
75299451b44SJordan Rupprecht
75399451b44SJordan Rupprecht        with open(self.out_filename, 'wb') as f:
75499451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True)
75599451b44SJordan Rupprecht            self.assertTrue(f is sbf.GetFile())
75699451b44SJordan Rupprecht            sbf.Write(b"foobar\n")
75799451b44SJordan Rupprecht            self.assertEqual(f.fileno(), sbf.GetFile().fileno())
75899451b44SJordan Rupprecht            sbf.Close()
75999451b44SJordan Rupprecht            self.assertFalse(f.closed)
76099451b44SJordan Rupprecht
76199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
76299451b44SJordan Rupprecht            self.assertEqual("foobar", f.read().strip())
76399451b44SJordan Rupprecht
76499451b44SJordan Rupprecht        with open(self.out_filename, 'wb') as f:
76599451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, force_io_methods=True)
76699451b44SJordan Rupprecht            self.assertTrue(f is sbf.GetFile())
76799451b44SJordan Rupprecht            sbf.Write(b"foobar\n")
76899451b44SJordan Rupprecht            self.assertEqual(f.fileno(), sbf.GetFile().fileno())
76999451b44SJordan Rupprecht            sbf.Close()
77099451b44SJordan Rupprecht            self.assertTrue(f.closed)
77199451b44SJordan Rupprecht
77299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
77399451b44SJordan Rupprecht            self.assertEqual("foobar", f.read().strip())
77499451b44SJordan Rupprecht
77599451b44SJordan Rupprecht
77699451b44SJordan Rupprecht    def test_back_and_forth(self):
77799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
77899451b44SJordan Rupprecht            # at each step here we're borrowing the file, so we have to keep
77999451b44SJordan Rupprecht            # them all alive until the end.
78099451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True)
78199451b44SJordan Rupprecht            def i(sbf):
78299451b44SJordan Rupprecht                for i in range(10):
78399451b44SJordan Rupprecht                    f = sbf.GetFile()
78499451b44SJordan Rupprecht                    self.assertEqual(f.mode, "w")
78599451b44SJordan Rupprecht                    yield f
78699451b44SJordan Rupprecht                    sbf = lldb.SBFile.Create(f, borrow=True)
78799451b44SJordan Rupprecht                    yield sbf
78899451b44SJordan Rupprecht                    sbf.Write(str(i).encode('ascii') + b"\n")
78999451b44SJordan Rupprecht            files = list(i(sbf))
79099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
79199451b44SJordan Rupprecht            self.assertEqual(list(range(10)), list(map(int, f.read().strip().split())))
79299451b44SJordan Rupprecht
79399451b44SJordan Rupprecht
79499451b44SJordan Rupprecht    def test_set_filehandle_none(self):
795a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetOutputFile, None)
796a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetOutputFile, "ham sandwich")
797a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetOutputFileHandle, "ham sandwich")
798a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetInputFile, None)
799a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetInputFile, "ham sandwich")
800a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetInputFileHandle, "ham sandwich")
801a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetErrorFile, None)
802a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetErrorFile, "ham sandwich")
803a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetErrorFileHandle, "ham sandwich")
80499451b44SJordan Rupprecht
80599451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
806a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(f)
807*779bbbf2SDave Lee            self.assertSuccess(status)
808a31130f6STatyana Krasnukha            status = self.dbg.SetErrorFile(f)
809*779bbbf2SDave Lee            self.assertSuccess(status)
810a31130f6STatyana Krasnukha            self.dbg.SetOutputFileHandle(None, False)
811a31130f6STatyana Krasnukha            self.dbg.SetErrorFileHandle(None, False)
812a31130f6STatyana Krasnukha            sbf = self.dbg.GetOutputFile()
81399451b44SJordan Rupprecht            if sys.version_info.major >= 3:
81499451b44SJordan Rupprecht                # python 2 lacks PyFile_FromFd, so GetFile() will
81599451b44SJordan Rupprecht                # have to duplicate the file descriptor and make a FILE*
81699451b44SJordan Rupprecht                # in order to convert a NativeFile it back to a python
81799451b44SJordan Rupprecht                # file.
81899451b44SJordan Rupprecht                self.assertEqual(sbf.GetFile().fileno(), 1)
819a31130f6STatyana Krasnukha            sbf = self.dbg.GetErrorFile()
82099451b44SJordan Rupprecht            if sys.version_info.major >= 3:
82199451b44SJordan Rupprecht                self.assertEqual(sbf.GetFile().fileno(), 2)
82299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
823a31130f6STatyana Krasnukha            status = self.dbg.SetInputFile(f)
824*779bbbf2SDave Lee            self.assertSuccess(status)
825a31130f6STatyana Krasnukha            self.dbg.SetInputFileHandle(None, False)
826a31130f6STatyana Krasnukha            sbf = self.dbg.GetInputFile()
82799451b44SJordan Rupprecht            if sys.version_info.major >= 3:
82899451b44SJordan Rupprecht                self.assertEqual(sbf.GetFile().fileno(), 0)
82999451b44SJordan Rupprecht
83099451b44SJordan Rupprecht
83199451b44SJordan Rupprecht    def test_sbstream(self):
83299451b44SJordan Rupprecht
83399451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
83499451b44SJordan Rupprecht            stream = lldb.SBStream()
83599451b44SJordan Rupprecht            stream.RedirectToFile(f)
83699451b44SJordan Rupprecht            stream.Print("zork")
83799451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
83899451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), "zork")
83999451b44SJordan Rupprecht
84099451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
84199451b44SJordan Rupprecht            stream = lldb.SBStream()
84299451b44SJordan Rupprecht            stream.RedirectToFileHandle(f, True)
84399451b44SJordan Rupprecht            stream.Print("Yendor")
84499451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
84599451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), "Yendor")
84699451b44SJordan Rupprecht
84799451b44SJordan Rupprecht        stream = lldb.SBStream()
84899451b44SJordan Rupprecht        f = open(self.out_filename,  'w')
84999451b44SJordan Rupprecht        stream.RedirectToFile(lldb.SBFile.Create(f, borrow=False))
85099451b44SJordan Rupprecht        stream.Print("Frobozz")
85199451b44SJordan Rupprecht        stream = None
85299451b44SJordan Rupprecht        self.assertTrue(f.closed)
85399451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
85499451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), "Frobozz")
855f23b829aSLevon Ter-Grigoryan
856f23b829aSLevon Ter-Grigoryan    def test_set_sbstream(self):
857f23b829aSLevon Ter-Grigoryan        with open(self.out_filename, 'w') as outf:
858f23b829aSLevon Ter-Grigoryan            outsbf = lldb.SBFile(outf.fileno(), "w", False)
859f23b829aSLevon Ter-Grigoryan            status = self.dbg.SetOutputFile(outsbf)
860*779bbbf2SDave Lee            self.assertSuccess(status)
861c0e3bb4dSPavel Labath            self.dbg.SetInputString("help apropos\nhelp help\n")
862f23b829aSLevon Ter-Grigoryan
863f23b829aSLevon Ter-Grigoryan            opts = lldb.SBCommandInterpreterRunOptions()
864f23b829aSLevon Ter-Grigoryan            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
865f23b829aSLevon Ter-Grigoryan            self.dbg.GetOutputFile().Flush()
866f23b829aSLevon Ter-Grigoryan
867f23b829aSLevon Ter-Grigoryan        with open(self.out_filename, 'r') as f:
868f23b829aSLevon Ter-Grigoryan            output = f.read()
869c0e3bb4dSPavel Labath            self.assertIn('Show a list of all debugger commands', output)
870c0e3bb4dSPavel Labath            self.assertIn('List debugger commands related to a word', output)
871