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
85*a31130f6STatyana 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
105*a31130f6STatyana Krasnukha    # Similar to runCmd(), but letting the debugger just print the results
106*a31130f6STatyana 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:
111*a31130f6STatyana Krasnukha            interpreter = self.dbg.GetCommandInterpreter()
11299451b44SJordan Rupprecht            interpreter.HandleCommand(cmd, ret)
11399451b44SJordan Rupprecht        else:
114*a31130f6STatyana Krasnukha            self.dbg.HandleCommand(cmd)
115*a31130f6STatyana Krasnukha        self.dbg.GetOutputFile().Flush()
116*a31130f6STatyana 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    @add_test_categories(['pyapi'])
12399451b44SJordan Rupprecht    def test_legacy_file_out_script(self):
12499451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
125*a31130f6STatyana Krasnukha            self.dbg.SetOutputFileHandle(f, False)
12699451b44SJordan Rupprecht            # scripts print to output even if you capture the results
12799451b44SJordan Rupprecht            # I'm not sure I love that behavior, but that's the way
12899451b44SJordan Rupprecht            # it's been for a long time.  That's why this test works
12999451b44SJordan Rupprecht            # even with collect_result=True.
13099451b44SJordan Rupprecht            self.handleCmd('script 1+1')
131*a31130f6STatyana Krasnukha            self.dbg.GetOutputFileHandle().write('FOO\n')
13299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
13399451b44SJordan Rupprecht            self.assertEqual(readStrippedLines(f), ['2', 'FOO'])
13499451b44SJordan Rupprecht
13599451b44SJordan Rupprecht
13699451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
13799451b44SJordan Rupprecht    def test_legacy_file_out(self):
13899451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
139*a31130f6STatyana Krasnukha            self.dbg.SetOutputFileHandle(f, False)
14099451b44SJordan Rupprecht            self.handleCmd('p/x 3735928559', collect_result=False, check=False)
14199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
14299451b44SJordan Rupprecht            self.assertIn('deadbeef', f.read())
14399451b44SJordan Rupprecht
14499451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
14599451b44SJordan Rupprecht    def test_legacy_file_err_with_get(self):
14699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
147*a31130f6STatyana Krasnukha            self.dbg.SetErrorFileHandle(f, False)
14899451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
149*a31130f6STatyana Krasnukha            f2 = self.dbg.GetErrorFileHandle()
15099451b44SJordan Rupprecht            f2.write('FOOBAR\n')
15199451b44SJordan Rupprecht            f2.flush()
15299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
15399451b44SJordan Rupprecht            errors = f.read()
15499451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
15599451b44SJordan Rupprecht            self.assertTrue(re.search(r'FOOBAR', errors))
15699451b44SJordan Rupprecht
15799451b44SJordan Rupprecht
15899451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
15999451b44SJordan Rupprecht    def test_legacy_file_err(self):
16099451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
161*a31130f6STatyana Krasnukha            self.dbg.SetErrorFileHandle(f, False)
16299451b44SJordan Rupprecht            self.handleCmd('lol', check=False, collect_result=False)
16399451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
16499451b44SJordan Rupprecht            self.assertIn("is not a valid command", f.read())
16599451b44SJordan Rupprecht
16699451b44SJordan Rupprecht
16799451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
16899451b44SJordan Rupprecht    def test_legacy_file_error(self):
16999451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
170*a31130f6STatyana Krasnukha            self.dbg.SetErrorFileHandle(f, False)
17199451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
17299451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
17399451b44SJordan Rupprecht            errors = f.read()
17499451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
17599451b44SJordan Rupprecht
17699451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
17799451b44SJordan Rupprecht    def test_sbfile_type_errors(self):
17899451b44SJordan Rupprecht        sbf = lldb.SBFile()
17999451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Write, None)
18099451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Read, None)
18199451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Read, b'this bytes is not mutable')
18299451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Write, u"ham sandwich")
18399451b44SJordan Rupprecht        self.assertRaises(Exception, sbf.Read, u"ham sandwich")
18499451b44SJordan Rupprecht
18599451b44SJordan Rupprecht
18699451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
18799451b44SJordan Rupprecht    def test_sbfile_write_fileno(self):
18899451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
18999451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), "w", False)
19099451b44SJordan Rupprecht            self.assertTrue(sbf.IsValid())
19199451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO\nBAR')
19299451b44SJordan Rupprecht            self.assertTrue(e.Success())
19399451b44SJordan Rupprecht            self.assertEqual(n, 7)
19499451b44SJordan Rupprecht            sbf.Close()
19599451b44SJordan Rupprecht            self.assertFalse(sbf.IsValid())
19699451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
19799451b44SJordan Rupprecht            self.assertEqual(readStrippedLines(f), ['FOO', 'BAR'])
19899451b44SJordan Rupprecht
19999451b44SJordan Rupprecht
20099451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
20199451b44SJordan Rupprecht    def test_sbfile_write(self):
20299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
20399451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
20499451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO\n')
20599451b44SJordan Rupprecht            self.assertTrue(e.Success())
20699451b44SJordan Rupprecht            self.assertEqual(n, 4)
20799451b44SJordan Rupprecht            sbf.Close()
20899451b44SJordan Rupprecht            self.assertTrue(f.closed)
20999451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
21099451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), 'FOO')
21199451b44SJordan Rupprecht
21299451b44SJordan Rupprecht
21399451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
21499451b44SJordan Rupprecht    def test_sbfile_read_fileno(self):
21599451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
21699451b44SJordan Rupprecht            f.write('FOO')
21799451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
21899451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), "r", False)
21999451b44SJordan Rupprecht            self.assertTrue(sbf.IsValid())
22099451b44SJordan Rupprecht            buffer = bytearray(100)
22199451b44SJordan Rupprecht            e, n = sbf.Read(buffer)
22299451b44SJordan Rupprecht            self.assertTrue(e.Success())
22399451b44SJordan Rupprecht            self.assertEqual(buffer[:n], b'FOO')
22499451b44SJordan Rupprecht
22599451b44SJordan Rupprecht
22699451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
22799451b44SJordan Rupprecht    def test_sbfile_read(self):
22899451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
22999451b44SJordan Rupprecht            f.write('foo')
23099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
23199451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
23299451b44SJordan Rupprecht            buf = bytearray(100)
23399451b44SJordan Rupprecht            e, n = sbf.Read(buf)
23499451b44SJordan Rupprecht            self.assertTrue(e.Success())
23599451b44SJordan Rupprecht            self.assertEqual(n, 3)
23699451b44SJordan Rupprecht            self.assertEqual(buf[:n], b'foo')
23799451b44SJordan Rupprecht            sbf.Close()
23899451b44SJordan Rupprecht            self.assertTrue(f.closed)
23999451b44SJordan Rupprecht
24099451b44SJordan Rupprecht
24199451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
24299451b44SJordan Rupprecht    def test_fileno_out(self):
24399451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
24499451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), "w", False)
245*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(sbf)
24699451b44SJordan Rupprecht            self.assertTrue(status.Success())
24799451b44SJordan Rupprecht            self.handleCmd('script 1+2')
248*a31130f6STatyana Krasnukha            self.dbg.GetOutputFile().Write(b'quux')
24999451b44SJordan Rupprecht
25099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
25199451b44SJordan Rupprecht            self.assertEqual(readStrippedLines(f), ['3', 'quux'])
25299451b44SJordan Rupprecht
25399451b44SJordan Rupprecht
25499451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
25599451b44SJordan Rupprecht    def test_fileno_help(self):
25699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
25799451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), "w", False)
258*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(sbf)
25999451b44SJordan Rupprecht            self.assertTrue(status.Success())
26099451b44SJordan Rupprecht            self.handleCmd("help help", collect_result=False, check=False)
26199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
26299451b44SJordan Rupprecht            self.assertTrue(re.search(r'Show a list of all debugger commands', f.read()))
26399451b44SJordan Rupprecht
26499451b44SJordan Rupprecht
26599451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
26699451b44SJordan Rupprecht    def test_help(self):
26799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
268*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(lldb.SBFile(f))
26999451b44SJordan Rupprecht            self.assertTrue(status.Success())
27099451b44SJordan Rupprecht            self.handleCmd("help help", check=False, collect_result=False)
27199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
27299451b44SJordan Rupprecht            self.assertIn('Show a list of all debugger commands', f.read())
27399451b44SJordan Rupprecht
27499451b44SJordan Rupprecht
27599451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
27699451b44SJordan Rupprecht    def test_immediate(self):
27799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
27899451b44SJordan Rupprecht            ret = lldb.SBCommandReturnObject()
27999451b44SJordan Rupprecht            ret.SetImmediateOutputFile(f)
280*a31130f6STatyana Krasnukha            interpreter = self.dbg.GetCommandInterpreter()
28199451b44SJordan Rupprecht            interpreter.HandleCommand("help help", ret)
28299451b44SJordan Rupprecht            # make sure the file wasn't closed early.
28399451b44SJordan Rupprecht            f.write("\nQUUX\n")
28499451b44SJordan Rupprecht        ret = None # call destructor and flush streams
28599451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
28699451b44SJordan Rupprecht            output = f.read()
28799451b44SJordan Rupprecht            self.assertTrue(re.search(r'Show a list of all debugger commands', output))
28899451b44SJordan Rupprecht            self.assertTrue(re.search(r'QUUX', output))
28999451b44SJordan Rupprecht
29099451b44SJordan Rupprecht
29199451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
29299451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
29399451b44SJordan Rupprecht    def test_immediate_string(self):
29499451b44SJordan Rupprecht        f = io.StringIO()
29599451b44SJordan Rupprecht        ret = lldb.SBCommandReturnObject()
29699451b44SJordan Rupprecht        ret.SetImmediateOutputFile(f)
297*a31130f6STatyana Krasnukha        interpreter = self.dbg.GetCommandInterpreter()
29899451b44SJordan Rupprecht        interpreter.HandleCommand("help help", ret)
29999451b44SJordan Rupprecht        # make sure the file wasn't closed early.
30099451b44SJordan Rupprecht        f.write("\nQUUX\n")
30199451b44SJordan Rupprecht        ret = None # call destructor and flush streams
30299451b44SJordan Rupprecht        output = f.getvalue()
30399451b44SJordan Rupprecht        self.assertTrue(re.search(r'Show a list of all debugger commands', output))
30499451b44SJordan Rupprecht        self.assertTrue(re.search(r'QUUX', output))
30599451b44SJordan Rupprecht
30699451b44SJordan Rupprecht
30799451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
30899451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
30999451b44SJordan Rupprecht    def test_immediate_sbfile_string(self):
31099451b44SJordan Rupprecht        f = io.StringIO()
31199451b44SJordan Rupprecht        ret = lldb.SBCommandReturnObject()
31299451b44SJordan Rupprecht        ret.SetImmediateOutputFile(lldb.SBFile(f))
313*a31130f6STatyana Krasnukha        interpreter = self.dbg.GetCommandInterpreter()
31499451b44SJordan Rupprecht        interpreter.HandleCommand("help help", ret)
31599451b44SJordan Rupprecht        output = f.getvalue()
31699451b44SJordan Rupprecht        ret = None # call destructor and flush streams
31799451b44SJordan Rupprecht        # sbfile default constructor doesn't borrow the file
31899451b44SJordan Rupprecht        self.assertTrue(f.closed)
31999451b44SJordan Rupprecht        self.assertTrue(re.search(r'Show a list of all debugger commands', output))
32099451b44SJordan Rupprecht
32199451b44SJordan Rupprecht
32299451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
32399451b44SJordan Rupprecht    def test_fileno_inout(self):
32499451b44SJordan Rupprecht        with open(self.in_filename, 'w') as f:
32599451b44SJordan Rupprecht            f.write("help help\n")
32699451b44SJordan Rupprecht
32799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as outf, open(self.in_filename, 'r') as inf:
32899451b44SJordan Rupprecht
32999451b44SJordan Rupprecht            outsbf = lldb.SBFile(outf.fileno(), "w", False)
330*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(outsbf)
33199451b44SJordan Rupprecht            self.assertTrue(status.Success())
33299451b44SJordan Rupprecht
33399451b44SJordan Rupprecht            insbf = lldb.SBFile(inf.fileno(), "r", False)
334*a31130f6STatyana Krasnukha            status = self.dbg.SetInputFile(insbf)
33599451b44SJordan Rupprecht            self.assertTrue(status.Success())
33699451b44SJordan Rupprecht
33799451b44SJordan Rupprecht            opts = lldb.SBCommandInterpreterRunOptions()
338*a31130f6STatyana Krasnukha            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
339*a31130f6STatyana Krasnukha            self.dbg.GetOutputFile().Flush()
34099451b44SJordan Rupprecht
34199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
34299451b44SJordan Rupprecht            self.assertTrue(re.search(r'Show a list of all debugger commands', f.read()))
34399451b44SJordan Rupprecht
34499451b44SJordan Rupprecht
34599451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
34699451b44SJordan Rupprecht    def test_inout(self):
34799451b44SJordan Rupprecht        with open(self.in_filename, 'w') as f:
34899451b44SJordan Rupprecht            f.write("help help\n")
34999451b44SJordan Rupprecht        with  open(self.out_filename, 'w') as outf, \
35099451b44SJordan Rupprecht              open(self.in_filename, 'r') as inf:
351*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(lldb.SBFile(outf))
35299451b44SJordan Rupprecht            self.assertTrue(status.Success())
353*a31130f6STatyana Krasnukha            status = self.dbg.SetInputFile(lldb.SBFile(inf))
35499451b44SJordan Rupprecht            self.assertTrue(status.Success())
35599451b44SJordan Rupprecht            opts = lldb.SBCommandInterpreterRunOptions()
356*a31130f6STatyana Krasnukha            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
357*a31130f6STatyana Krasnukha            self.dbg.GetOutputFile().Flush()
35899451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
35999451b44SJordan Rupprecht            output = f.read()
36099451b44SJordan Rupprecht            self.assertIn('Show a list of all debugger commands', output)
36199451b44SJordan Rupprecht
36299451b44SJordan Rupprecht
36399451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
36499451b44SJordan Rupprecht    def test_binary_inout(self):
36599451b44SJordan Rupprecht        with open(self.in_filename, 'w') as f:
36699451b44SJordan Rupprecht            f.write("help help\n")
36799451b44SJordan Rupprecht        with  open(self.out_filename, 'wb') as outf, \
36899451b44SJordan Rupprecht              open(self.in_filename, 'rb') as inf:
369*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(lldb.SBFile(outf))
37099451b44SJordan Rupprecht            self.assertTrue(status.Success())
371*a31130f6STatyana Krasnukha            status = self.dbg.SetInputFile(lldb.SBFile(inf))
37299451b44SJordan Rupprecht            self.assertTrue(status.Success())
37399451b44SJordan Rupprecht            opts = lldb.SBCommandInterpreterRunOptions()
374*a31130f6STatyana Krasnukha            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
375*a31130f6STatyana Krasnukha            self.dbg.GetOutputFile().Flush()
37699451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
37799451b44SJordan Rupprecht            output = f.read()
37899451b44SJordan Rupprecht            self.assertIn('Show a list of all debugger commands', output)
37999451b44SJordan Rupprecht
38099451b44SJordan Rupprecht
38199451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
38299451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
38399451b44SJordan Rupprecht    def test_string_inout(self):
38499451b44SJordan Rupprecht        inf = io.StringIO("help help\np/x ~0\n")
38599451b44SJordan Rupprecht        outf = io.StringIO()
386*a31130f6STatyana Krasnukha        status = self.dbg.SetOutputFile(lldb.SBFile(outf))
38799451b44SJordan Rupprecht        self.assertTrue(status.Success())
388*a31130f6STatyana Krasnukha        status = self.dbg.SetInputFile(lldb.SBFile(inf))
38999451b44SJordan Rupprecht        self.assertTrue(status.Success())
39099451b44SJordan Rupprecht        opts = lldb.SBCommandInterpreterRunOptions()
391*a31130f6STatyana Krasnukha        self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
392*a31130f6STatyana Krasnukha        self.dbg.GetOutputFile().Flush()
39399451b44SJordan Rupprecht        output = outf.getvalue()
39499451b44SJordan Rupprecht        self.assertIn('Show a list of all debugger commands', output)
39599451b44SJordan Rupprecht        self.assertIn('0xfff', output)
39699451b44SJordan Rupprecht
39799451b44SJordan Rupprecht
39899451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
39999451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
40099451b44SJordan Rupprecht    def test_bytes_inout(self):
40199451b44SJordan Rupprecht        inf = io.BytesIO(b"help help\nhelp b\n")
40299451b44SJordan Rupprecht        outf = io.BytesIO()
403*a31130f6STatyana Krasnukha        status = self.dbg.SetOutputFile(lldb.SBFile(outf))
40499451b44SJordan Rupprecht        self.assertTrue(status.Success())
405*a31130f6STatyana Krasnukha        status = self.dbg.SetInputFile(lldb.SBFile(inf))
40699451b44SJordan Rupprecht        self.assertTrue(status.Success())
40799451b44SJordan Rupprecht        opts = lldb.SBCommandInterpreterRunOptions()
408*a31130f6STatyana Krasnukha        self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
409*a31130f6STatyana Krasnukha        self.dbg.GetOutputFile().Flush()
41099451b44SJordan Rupprecht        output = outf.getvalue()
41199451b44SJordan Rupprecht        self.assertIn(b'Show a list of all debugger commands', output)
41299451b44SJordan Rupprecht        self.assertIn(b'Set a breakpoint', output)
41399451b44SJordan Rupprecht
41499451b44SJordan Rupprecht
41599451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
41699451b44SJordan Rupprecht    def test_fileno_error(self):
41799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
41899451b44SJordan Rupprecht
41999451b44SJordan Rupprecht            sbf = lldb.SBFile(f.fileno(), 'w', False)
420*a31130f6STatyana Krasnukha            status = self.dbg.SetErrorFile(sbf)
42199451b44SJordan Rupprecht            self.assertTrue(status.Success())
42299451b44SJordan Rupprecht
42399451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
42499451b44SJordan Rupprecht
425*a31130f6STatyana Krasnukha            self.dbg.GetErrorFile().Write(b'\nzork\n')
42699451b44SJordan Rupprecht
42799451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
42899451b44SJordan Rupprecht            errors = f.read()
42999451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
43099451b44SJordan Rupprecht            self.assertTrue(re.search(r'zork', errors))
43199451b44SJordan Rupprecht
43299451b44SJordan Rupprecht
43399451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
43499451b44SJordan Rupprecht    def test_replace_stdout(self):
43599451b44SJordan Rupprecht        f = io.StringIO()
43699451b44SJordan Rupprecht        with replace_stdout(f):
43799451b44SJordan Rupprecht            self.assertEqual(sys.stdout, f)
43899451b44SJordan Rupprecht            self.handleCmd('script sys.stdout.write("lol")',
43999451b44SJordan Rupprecht                collect_result=False, check=False)
44099451b44SJordan Rupprecht            self.assertEqual(sys.stdout, f)
44199451b44SJordan Rupprecht
44299451b44SJordan Rupprecht
44399451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
44499451b44SJordan Rupprecht    def test_replace_stdout_with_nonfile(self):
44599451b44SJordan Rupprecht        f = io.StringIO()
44699451b44SJordan Rupprecht        with replace_stdout(f):
44799451b44SJordan Rupprecht            class Nothing():
44899451b44SJordan Rupprecht                pass
44999451b44SJordan Rupprecht            with replace_stdout(Nothing):
45099451b44SJordan Rupprecht                self.assertEqual(sys.stdout, Nothing)
45199451b44SJordan Rupprecht                self.handleCmd('script sys.stdout.write("lol")',
45299451b44SJordan Rupprecht                    check=False, collect_result=False)
45399451b44SJordan Rupprecht                self.assertEqual(sys.stdout, Nothing)
45499451b44SJordan Rupprecht            sys.stdout.write(u"FOO")
45599451b44SJordan Rupprecht        self.assertEqual(f.getvalue(), "FOO")
45699451b44SJordan Rupprecht
45799451b44SJordan Rupprecht
45899451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
45999451b44SJordan Rupprecht    def test_sbfile_write_borrowed(self):
46099451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
46199451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True)
46299451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO')
46399451b44SJordan Rupprecht            self.assertTrue(e.Success())
46499451b44SJordan Rupprecht            self.assertEqual(n, 3)
46599451b44SJordan Rupprecht            sbf.Close()
46699451b44SJordan Rupprecht            self.assertFalse(f.closed)
46799451b44SJordan Rupprecht            f.write('BAR\n')
46899451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
46999451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), 'FOOBAR')
47099451b44SJordan Rupprecht
47199451b44SJordan Rupprecht
47299451b44SJordan Rupprecht
47399451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
47499451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
47599451b44SJordan Rupprecht    def test_sbfile_write_forced(self):
47699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
47799451b44SJordan Rupprecht            written = MutableBool(False)
47899451b44SJordan Rupprecht            orig_write = f.write
47999451b44SJordan Rupprecht            def mywrite(x):
48099451b44SJordan Rupprecht                written.set(True)
48199451b44SJordan Rupprecht                return orig_write(x)
48299451b44SJordan Rupprecht            f.write = mywrite
48399451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, force_io_methods=True)
48499451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO')
48599451b44SJordan Rupprecht            self.assertTrue(written)
48699451b44SJordan Rupprecht            self.assertTrue(e.Success())
48799451b44SJordan Rupprecht            self.assertEqual(n, 3)
48899451b44SJordan Rupprecht            sbf.Close()
48999451b44SJordan Rupprecht            self.assertTrue(f.closed)
49099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
49199451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), 'FOO')
49299451b44SJordan Rupprecht
49399451b44SJordan Rupprecht
49499451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
49599451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
49699451b44SJordan Rupprecht    def test_sbfile_write_forced_borrowed(self):
49799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
49899451b44SJordan Rupprecht            written = MutableBool(False)
49999451b44SJordan Rupprecht            orig_write = f.write
50099451b44SJordan Rupprecht            def mywrite(x):
50199451b44SJordan Rupprecht                written.set(True)
50299451b44SJordan Rupprecht                return orig_write(x)
50399451b44SJordan Rupprecht            f.write = mywrite
50499451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True)
50599451b44SJordan Rupprecht            e, n = sbf.Write(b'FOO')
50699451b44SJordan Rupprecht            self.assertTrue(written)
50799451b44SJordan Rupprecht            self.assertTrue(e.Success())
50899451b44SJordan Rupprecht            self.assertEqual(n, 3)
50999451b44SJordan Rupprecht            sbf.Close()
51099451b44SJordan Rupprecht            self.assertFalse(f.closed)
51199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
51299451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), 'FOO')
51399451b44SJordan Rupprecht
51499451b44SJordan Rupprecht
51599451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
51699451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
51799451b44SJordan Rupprecht    def test_sbfile_write_string(self):
51899451b44SJordan Rupprecht        f = io.StringIO()
51999451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
52099451b44SJordan Rupprecht        e, n = sbf.Write(b'FOO')
52199451b44SJordan Rupprecht        self.assertEqual(f.getvalue().strip(), "FOO")
52299451b44SJordan Rupprecht        self.assertTrue(e.Success())
52399451b44SJordan Rupprecht        self.assertEqual(n, 3)
52499451b44SJordan Rupprecht        sbf.Close()
52599451b44SJordan Rupprecht        self.assertTrue(f.closed)
52699451b44SJordan Rupprecht
52799451b44SJordan Rupprecht
52899451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
52999451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
53099451b44SJordan Rupprecht    def test_string_out(self):
53199451b44SJordan Rupprecht        f = io.StringIO()
532*a31130f6STatyana Krasnukha        status = self.dbg.SetOutputFile(f)
53399451b44SJordan Rupprecht        self.assertTrue(status.Success())
53499451b44SJordan Rupprecht        self.handleCmd("script 'foobar'")
53599451b44SJordan Rupprecht        self.assertEqual(f.getvalue().strip(), "'foobar'")
53699451b44SJordan Rupprecht
53799451b44SJordan Rupprecht
53899451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
53999451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
54099451b44SJordan Rupprecht    def test_string_error(self):
54199451b44SJordan Rupprecht        f = io.StringIO()
542*a31130f6STatyana Krasnukha        status = self.dbg.SetErrorFile(f)
54399451b44SJordan Rupprecht        self.assertTrue(status.Success())
54499451b44SJordan Rupprecht        self.handleCmd('lolwut', check=False, collect_result=False)
54599451b44SJordan Rupprecht        errors = f.getvalue()
54699451b44SJordan Rupprecht        self.assertTrue(re.search(r'error:.*lolwut', errors))
54799451b44SJordan Rupprecht
54899451b44SJordan Rupprecht
54999451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
55099451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
55199451b44SJordan Rupprecht    def test_sbfile_write_bytes(self):
55299451b44SJordan Rupprecht        f = io.BytesIO()
55399451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
55499451b44SJordan Rupprecht        e, n = sbf.Write(b'FOO')
55599451b44SJordan Rupprecht        self.assertEqual(f.getvalue().strip(), b"FOO")
55699451b44SJordan Rupprecht        self.assertTrue(e.Success())
55799451b44SJordan Rupprecht        self.assertEqual(n, 3)
55899451b44SJordan Rupprecht        sbf.Close()
55999451b44SJordan Rupprecht        self.assertTrue(f.closed)
56099451b44SJordan Rupprecht
56199451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
56299451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
56399451b44SJordan Rupprecht    def test_sbfile_read_string(self):
56499451b44SJordan Rupprecht        f = io.StringIO('zork')
56599451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
56699451b44SJordan Rupprecht        buf = bytearray(100)
56799451b44SJordan Rupprecht        e, n = sbf.Read(buf)
56899451b44SJordan Rupprecht        self.assertTrue(e.Success())
56999451b44SJordan Rupprecht        self.assertEqual(buf[:n], b'zork')
57099451b44SJordan Rupprecht
57199451b44SJordan Rupprecht
57299451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
57399451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
57499451b44SJordan Rupprecht    def test_sbfile_read_string_one_byte(self):
57599451b44SJordan Rupprecht        f = io.StringIO('z')
57699451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
57799451b44SJordan Rupprecht        buf = bytearray(1)
57899451b44SJordan Rupprecht        e, n = sbf.Read(buf)
57999451b44SJordan Rupprecht        self.assertTrue(e.Fail())
58099451b44SJordan Rupprecht        self.assertEqual(n, 0)
58199451b44SJordan Rupprecht        self.assertEqual(e.GetCString(), "can't read less than 6 bytes from a utf8 text stream")
58299451b44SJordan Rupprecht
58399451b44SJordan Rupprecht
58499451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
58599451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
58699451b44SJordan Rupprecht    def test_sbfile_read_bytes(self):
58799451b44SJordan Rupprecht        f = io.BytesIO(b'zork')
58899451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
58999451b44SJordan Rupprecht        buf = bytearray(100)
59099451b44SJordan Rupprecht        e, n = sbf.Read(buf)
59199451b44SJordan Rupprecht        self.assertTrue(e.Success())
59299451b44SJordan Rupprecht        self.assertEqual(buf[:n], b'zork')
59399451b44SJordan Rupprecht
59499451b44SJordan Rupprecht
59599451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
59699451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
59799451b44SJordan Rupprecht    def test_sbfile_out(self):
59899451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
59999451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
600*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(sbf)
60199451b44SJordan Rupprecht            self.assertTrue(status.Success())
60299451b44SJordan Rupprecht            self.handleCmd('script 2+2')
60399451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
60499451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), '4')
60599451b44SJordan Rupprecht
60699451b44SJordan Rupprecht
60799451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
60899451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
60999451b44SJordan Rupprecht    def test_file_out(self):
61099451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
611*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(f)
61299451b44SJordan Rupprecht            self.assertTrue(status.Success())
61399451b44SJordan Rupprecht            self.handleCmd('script 2+2')
61499451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
61599451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), '4')
61699451b44SJordan Rupprecht
61799451b44SJordan Rupprecht
61899451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
61999451b44SJordan Rupprecht    def test_sbfile_error(self):
62099451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
62199451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
622*a31130f6STatyana Krasnukha            status = self.dbg.SetErrorFile(sbf)
62399451b44SJordan Rupprecht            self.assertTrue(status.Success())
62499451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
62599451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
62699451b44SJordan Rupprecht            errors = f.read()
62799451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
62899451b44SJordan Rupprecht
62999451b44SJordan Rupprecht
63099451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
63199451b44SJordan Rupprecht    def test_file_error(self):
63299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
633*a31130f6STatyana Krasnukha            status = self.dbg.SetErrorFile(f)
63499451b44SJordan Rupprecht            self.assertTrue(status.Success())
63599451b44SJordan Rupprecht            self.handleCmd('lolwut', check=False, collect_result=False)
63699451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
63799451b44SJordan Rupprecht            errors = f.read()
63899451b44SJordan Rupprecht            self.assertTrue(re.search(r'error:.*lolwut', errors))
63999451b44SJordan Rupprecht
64099451b44SJordan Rupprecht
64199451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
64299451b44SJordan Rupprecht    def test_exceptions(self):
64399451b44SJordan Rupprecht        self.assertRaises(Exception, lldb.SBFile, None)
64499451b44SJordan Rupprecht        self.assertRaises(Exception, lldb.SBFile, "ham sandwich")
64599451b44SJordan Rupprecht        if sys.version_info[0] < 3:
64699451b44SJordan Rupprecht            self.assertRaises(Exception, lldb.SBFile, ReallyBadIO())
64799451b44SJordan Rupprecht        else:
64899451b44SJordan Rupprecht            self.assertRaises(OhNoe, lldb.SBFile, ReallyBadIO())
64999451b44SJordan Rupprecht            error, n = lldb.SBFile(BadIO()).Write(b"FOO")
65099451b44SJordan Rupprecht            self.assertEqual(n, 0)
65199451b44SJordan Rupprecht            self.assertTrue(error.Fail())
65299451b44SJordan Rupprecht            self.assertIn('OH NOE', error.GetCString())
65399451b44SJordan Rupprecht            error, n = lldb.SBFile(BadIO()).Read(bytearray(100))
65499451b44SJordan Rupprecht            self.assertEqual(n, 0)
65599451b44SJordan Rupprecht            self.assertTrue(error.Fail())
65699451b44SJordan Rupprecht            self.assertIn('OH NOE', error.GetCString())
65799451b44SJordan Rupprecht
65899451b44SJordan Rupprecht
65999451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
66099451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
66199451b44SJordan Rupprecht    def test_exceptions_logged(self):
66299451b44SJordan Rupprecht        messages = list()
663*a31130f6STatyana Krasnukha        self.dbg.SetLoggingCallback(messages.append)
66499451b44SJordan Rupprecht        self.handleCmd('log enable lldb script')
665*a31130f6STatyana Krasnukha        self.dbg.SetOutputFile(lldb.SBFile(BadIO()))
66699451b44SJordan Rupprecht        self.handleCmd('script 1+1')
66799451b44SJordan Rupprecht        self.assertTrue(any('OH NOE' in msg for msg in messages))
66899451b44SJordan Rupprecht
66999451b44SJordan Rupprecht
67099451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
67199451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
67299451b44SJordan Rupprecht    def test_flush(self):
67399451b44SJordan Rupprecht        flushed = MutableBool(False)
67499451b44SJordan Rupprecht        closed = MutableBool(False)
67599451b44SJordan Rupprecht        f = FlushTestIO(flushed, closed)
67699451b44SJordan Rupprecht        self.assertFalse(flushed)
67799451b44SJordan Rupprecht        self.assertFalse(closed)
67899451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
67999451b44SJordan Rupprecht        self.assertFalse(flushed)
68099451b44SJordan Rupprecht        self.assertFalse(closed)
68199451b44SJordan Rupprecht        sbf = None
68299451b44SJordan Rupprecht        self.assertFalse(flushed)
68399451b44SJordan Rupprecht        self.assertTrue(closed)
68499451b44SJordan Rupprecht        self.assertTrue(f.closed)
68599451b44SJordan Rupprecht
68699451b44SJordan Rupprecht        flushed = MutableBool(False)
68799451b44SJordan Rupprecht        closed = MutableBool(False)
68899451b44SJordan Rupprecht        f = FlushTestIO(flushed, closed)
68999451b44SJordan Rupprecht        self.assertFalse(flushed)
69099451b44SJordan Rupprecht        self.assertFalse(closed)
69199451b44SJordan Rupprecht        sbf = lldb.SBFile.Create(f, borrow=True)
69299451b44SJordan Rupprecht        self.assertFalse(flushed)
69399451b44SJordan Rupprecht        self.assertFalse(closed)
69499451b44SJordan Rupprecht        sbf = None
69599451b44SJordan Rupprecht        self.assertTrue(flushed)
69699451b44SJordan Rupprecht        self.assertFalse(closed)
69799451b44SJordan Rupprecht        self.assertFalse(f.closed)
69899451b44SJordan Rupprecht
69999451b44SJordan Rupprecht
70099451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
70199451b44SJordan Rupprecht    def test_fileno_flush(self):
70299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
70399451b44SJordan Rupprecht            f.write("foo")
70499451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
70599451b44SJordan Rupprecht            sbf.Write(b'bar')
70699451b44SJordan Rupprecht            sbf = None
70799451b44SJordan Rupprecht            self.assertTrue(f.closed)
70899451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
70999451b44SJordan Rupprecht            self.assertEqual(f.read(), 'foobar')
71099451b44SJordan Rupprecht
71199451b44SJordan Rupprecht        with open(self.out_filename, 'w+') as f:
71299451b44SJordan Rupprecht            f.write("foo")
71399451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True)
71499451b44SJordan Rupprecht            sbf.Write(b'bar')
71599451b44SJordan Rupprecht            sbf = None
71699451b44SJordan Rupprecht            self.assertFalse(f.closed)
71799451b44SJordan Rupprecht            f.seek(0)
71899451b44SJordan Rupprecht            self.assertEqual(f.read(), 'foobar')
71999451b44SJordan Rupprecht
72099451b44SJordan Rupprecht
72199451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
72299451b44SJordan Rupprecht    def test_close(self):
72399451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
724*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(f)
72599451b44SJordan Rupprecht            self.assertTrue(status.Success())
72699451b44SJordan Rupprecht            self.handleCmd("help help", check=False, collect_result=False)
72799451b44SJordan Rupprecht            # make sure the file wasn't closed early.
72899451b44SJordan Rupprecht            f.write("\nZAP\n")
729*a31130f6STatyana Krasnukha            lldb.SBDebugger.Destroy(self.dbg)
73099451b44SJordan Rupprecht            # check that output file was closed when debugger was destroyed.
73199451b44SJordan Rupprecht            with self.assertRaises(ValueError):
73299451b44SJordan Rupprecht                f.write("\nQUUX\n")
73399451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
73499451b44SJordan Rupprecht            output = f.read()
73599451b44SJordan Rupprecht            self.assertTrue(re.search(r'Show a list of all debugger commands', output))
73699451b44SJordan Rupprecht            self.assertTrue(re.search(r'ZAP', output))
73799451b44SJordan Rupprecht
73899451b44SJordan Rupprecht
73999451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
74099451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
74199451b44SJordan Rupprecht    def test_stdout(self):
74299451b44SJordan Rupprecht        f = io.StringIO()
743*a31130f6STatyana Krasnukha        status = self.dbg.SetOutputFile(f)
74499451b44SJordan Rupprecht        self.assertTrue(status.Success())
74599451b44SJordan Rupprecht        self.handleCmd(r"script sys.stdout.write('foobar\n')")
74699451b44SJordan Rupprecht        self.assertEqual(f.getvalue().strip().split(), ["foobar", "7"])
74799451b44SJordan Rupprecht
74899451b44SJordan Rupprecht
74999451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
75099451b44SJordan Rupprecht    def test_stdout_file(self):
75199451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
752*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(f)
75399451b44SJordan Rupprecht            self.assertTrue(status.Success())
75499451b44SJordan Rupprecht            self.handleCmd(r"script sys.stdout.write('foobar\n')")
75599451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
75699451b44SJordan Rupprecht            # In python2 sys.stdout.write() returns None, which
75799451b44SJordan Rupprecht            # the REPL will ignore, but in python3 it will
75899451b44SJordan Rupprecht            # return the number of bytes written, which the REPL
75999451b44SJordan Rupprecht            # will print out.
76099451b44SJordan Rupprecht            lines = [x for x in f.read().strip().split() if x != "7"]
76199451b44SJordan Rupprecht            self.assertEqual(lines, ["foobar"])
76299451b44SJordan Rupprecht
76399451b44SJordan Rupprecht
76499451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
76599451b44SJordan Rupprecht    @skipIf(py_version=['<', (3,)])
76699451b44SJordan Rupprecht    def test_identity(self):
76799451b44SJordan Rupprecht
76899451b44SJordan Rupprecht        f = io.StringIO()
76999451b44SJordan Rupprecht        sbf = lldb.SBFile(f)
77099451b44SJordan Rupprecht        self.assertTrue(f is sbf.GetFile())
77199451b44SJordan Rupprecht        sbf.Close()
77299451b44SJordan Rupprecht        self.assertTrue(f.closed)
77399451b44SJordan Rupprecht
77499451b44SJordan Rupprecht        f = io.StringIO()
77599451b44SJordan Rupprecht        sbf = lldb.SBFile.Create(f, borrow=True)
77699451b44SJordan Rupprecht        self.assertTrue(f is sbf.GetFile())
77799451b44SJordan Rupprecht        sbf.Close()
77899451b44SJordan Rupprecht        self.assertFalse(f.closed)
77999451b44SJordan Rupprecht
78099451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
78199451b44SJordan Rupprecht            sbf = lldb.SBFile(f)
78299451b44SJordan Rupprecht            self.assertTrue(f is sbf.GetFile())
78399451b44SJordan Rupprecht            sbf.Close()
78499451b44SJordan Rupprecht            self.assertTrue(f.closed)
78599451b44SJordan Rupprecht
78699451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
78799451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True)
78899451b44SJordan Rupprecht            self.assertFalse(f is sbf.GetFile())
78999451b44SJordan Rupprecht            sbf.Write(b"foobar\n")
79099451b44SJordan Rupprecht            self.assertEqual(f.fileno(), sbf.GetFile().fileno())
79199451b44SJordan Rupprecht            sbf.Close()
79299451b44SJordan Rupprecht            self.assertFalse(f.closed)
79399451b44SJordan Rupprecht
79499451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
79599451b44SJordan Rupprecht            self.assertEqual("foobar", f.read().strip())
79699451b44SJordan Rupprecht
79799451b44SJordan Rupprecht        with open(self.out_filename, 'wb') as f:
79899451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True)
79999451b44SJordan Rupprecht            self.assertTrue(f is sbf.GetFile())
80099451b44SJordan Rupprecht            sbf.Write(b"foobar\n")
80199451b44SJordan Rupprecht            self.assertEqual(f.fileno(), sbf.GetFile().fileno())
80299451b44SJordan Rupprecht            sbf.Close()
80399451b44SJordan Rupprecht            self.assertFalse(f.closed)
80499451b44SJordan Rupprecht
80599451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
80699451b44SJordan Rupprecht            self.assertEqual("foobar", f.read().strip())
80799451b44SJordan Rupprecht
80899451b44SJordan Rupprecht        with open(self.out_filename, 'wb') as f:
80999451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, force_io_methods=True)
81099451b44SJordan Rupprecht            self.assertTrue(f is sbf.GetFile())
81199451b44SJordan Rupprecht            sbf.Write(b"foobar\n")
81299451b44SJordan Rupprecht            self.assertEqual(f.fileno(), sbf.GetFile().fileno())
81399451b44SJordan Rupprecht            sbf.Close()
81499451b44SJordan Rupprecht            self.assertTrue(f.closed)
81599451b44SJordan Rupprecht
81699451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
81799451b44SJordan Rupprecht            self.assertEqual("foobar", f.read().strip())
81899451b44SJordan Rupprecht
81999451b44SJordan Rupprecht
82099451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
82199451b44SJordan Rupprecht    def test_back_and_forth(self):
82299451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
82399451b44SJordan Rupprecht            # at each step here we're borrowing the file, so we have to keep
82499451b44SJordan Rupprecht            # them all alive until the end.
82599451b44SJordan Rupprecht            sbf = lldb.SBFile.Create(f, borrow=True)
82699451b44SJordan Rupprecht            def i(sbf):
82799451b44SJordan Rupprecht                for i in range(10):
82899451b44SJordan Rupprecht                    f = sbf.GetFile()
82999451b44SJordan Rupprecht                    self.assertEqual(f.mode, "w")
83099451b44SJordan Rupprecht                    yield f
83199451b44SJordan Rupprecht                    sbf = lldb.SBFile.Create(f, borrow=True)
83299451b44SJordan Rupprecht                    yield sbf
83399451b44SJordan Rupprecht                    sbf.Write(str(i).encode('ascii') + b"\n")
83499451b44SJordan Rupprecht            files = list(i(sbf))
83599451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
83699451b44SJordan Rupprecht            self.assertEqual(list(range(10)), list(map(int, f.read().strip().split())))
83799451b44SJordan Rupprecht
83899451b44SJordan Rupprecht
83999451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
84099451b44SJordan Rupprecht    def test_set_filehandle_none(self):
841*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetOutputFile, None)
842*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetOutputFile, "ham sandwich")
843*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetOutputFileHandle, "ham sandwich")
844*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetInputFile, None)
845*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetInputFile, "ham sandwich")
846*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetInputFileHandle, "ham sandwich")
847*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetErrorFile, None)
848*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetErrorFile, "ham sandwich")
849*a31130f6STatyana Krasnukha        self.assertRaises(Exception, self.dbg.SetErrorFileHandle, "ham sandwich")
85099451b44SJordan Rupprecht
85199451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
852*a31130f6STatyana Krasnukha            status = self.dbg.SetOutputFile(f)
85399451b44SJordan Rupprecht            self.assertTrue(status.Success())
854*a31130f6STatyana Krasnukha            status = self.dbg.SetErrorFile(f)
85599451b44SJordan Rupprecht            self.assertTrue(status.Success())
856*a31130f6STatyana Krasnukha            self.dbg.SetOutputFileHandle(None, False)
857*a31130f6STatyana Krasnukha            self.dbg.SetErrorFileHandle(None, False)
858*a31130f6STatyana Krasnukha            sbf = self.dbg.GetOutputFile()
85999451b44SJordan Rupprecht            if sys.version_info.major >= 3:
86099451b44SJordan Rupprecht                # python 2 lacks PyFile_FromFd, so GetFile() will
86199451b44SJordan Rupprecht                # have to duplicate the file descriptor and make a FILE*
86299451b44SJordan Rupprecht                # in order to convert a NativeFile it back to a python
86399451b44SJordan Rupprecht                # file.
86499451b44SJordan Rupprecht                self.assertEqual(sbf.GetFile().fileno(), 1)
865*a31130f6STatyana Krasnukha            sbf = self.dbg.GetErrorFile()
86699451b44SJordan Rupprecht            if sys.version_info.major >= 3:
86799451b44SJordan Rupprecht                self.assertEqual(sbf.GetFile().fileno(), 2)
86899451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
869*a31130f6STatyana Krasnukha            status = self.dbg.SetInputFile(f)
87099451b44SJordan Rupprecht            self.assertTrue(status.Success())
871*a31130f6STatyana Krasnukha            self.dbg.SetInputFileHandle(None, False)
872*a31130f6STatyana Krasnukha            sbf = self.dbg.GetInputFile()
87399451b44SJordan Rupprecht            if sys.version_info.major >= 3:
87499451b44SJordan Rupprecht                self.assertEqual(sbf.GetFile().fileno(), 0)
87599451b44SJordan Rupprecht
87699451b44SJordan Rupprecht
87799451b44SJordan Rupprecht    @add_test_categories(['pyapi'])
87899451b44SJordan Rupprecht    def test_sbstream(self):
87999451b44SJordan Rupprecht
88099451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
88199451b44SJordan Rupprecht            stream = lldb.SBStream()
88299451b44SJordan Rupprecht            stream.RedirectToFile(f)
88399451b44SJordan Rupprecht            stream.Print("zork")
88499451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
88599451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), "zork")
88699451b44SJordan Rupprecht
88799451b44SJordan Rupprecht        with open(self.out_filename, 'w') as f:
88899451b44SJordan Rupprecht            stream = lldb.SBStream()
88999451b44SJordan Rupprecht            stream.RedirectToFileHandle(f, True)
89099451b44SJordan Rupprecht            stream.Print("Yendor")
89199451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
89299451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), "Yendor")
89399451b44SJordan Rupprecht
89499451b44SJordan Rupprecht        stream = lldb.SBStream()
89599451b44SJordan Rupprecht        f = open(self.out_filename,  'w')
89699451b44SJordan Rupprecht        stream.RedirectToFile(lldb.SBFile.Create(f, borrow=False))
89799451b44SJordan Rupprecht        stream.Print("Frobozz")
89899451b44SJordan Rupprecht        stream = None
89999451b44SJordan Rupprecht        self.assertTrue(f.closed)
90099451b44SJordan Rupprecht        with open(self.out_filename, 'r') as f:
90199451b44SJordan Rupprecht            self.assertEqual(f.read().strip(), "Frobozz")
902