"""
Test lldb Python API for file handles.
"""


import os
import io
import re
import sys
from contextlib import contextmanager

import lldb
from lldbsuite.test import  lldbtest
from lldbsuite.test.decorators import *

class OhNoe(Exception):
    pass

class BadIO(io.TextIOBase):
    @property
    def closed(self):
        return False
    def writable(self):
        return True
    def readable(self):
        return True
    def write(self, s):
        raise OhNoe('OH NOE')
    def read(self, n):
        raise OhNoe("OH NOE")
    def flush(self):
        raise OhNoe('OH NOE')

# This class will raise an exception while it's being
# converted into a C++ object by swig
class ReallyBadIO(io.TextIOBase):
    def fileno(self):
        return 999
    def writable(self):
        raise OhNoe("OH NOE!!!")

class MutableBool():
    def __init__(self, value):
        self.value = value
    def set(self, value):
        self.value = bool(value)
    def __bool__(self):
        return self.value

class FlushTestIO(io.StringIO):
    def __init__(self, mutable_flushed, mutable_closed):
        super(FlushTestIO, self).__init__()
        self.mut_flushed = mutable_flushed
        self.mut_closed = mutable_closed
    def close(self):
        self.mut_closed.set(True)
        return super(FlushTestIO, self).close()
    def flush(self):
        self.mut_flushed.set(True)
        return super(FlushTestIO, self).flush()

@contextmanager
def replace_stdout(new):
    old = sys.stdout
    sys.stdout = new
    try:
        yield
    finally:
        sys.stdout = old

def readStrippedLines(f):
    def i():
        for line in f:
            line = line.strip()
            if line:
                yield line
    return list(i())


class FileHandleTestCase(lldbtest.TestBase):

    NO_DEBUG_INFO_TESTCASE = True
    mydir = lldbtest.Base.compute_mydir(__file__)

    # The way normal tests evaluate debugger commands is
    # by using a SBCommandInterpreter directly, which captures
    # the output in a result object.   For many of tests tests
    # we want the debugger to write the  output directly to
    # its I/O streams like it would have done interactively.
    #
    # For this reason we also define handleCmd() here, even though
    # it is similar to runCmd().

    def setUp(self):
        super(FileHandleTestCase, self).setUp()
        self.out_filename = self.getBuildArtifact('output')
        self.in_filename = self.getBuildArtifact('input')

    def tearDown(self):
        super(FileHandleTestCase, self).tearDown()
        for name in (self.out_filename, self.in_filename):
            if os.path.exists(name):
                os.unlink(name)

    # Similar to runCmd(), but letting the debugger just print the results
    # instead of collecting them.
    def handleCmd(self, cmd, check=True, collect_result=True):
        assert not check or collect_result
        ret = lldb.SBCommandReturnObject()
        if collect_result:
            interpreter = self.dbg.GetCommandInterpreter()
            interpreter.HandleCommand(cmd, ret)
        else:
            self.dbg.HandleCommand(cmd)
        self.dbg.GetOutputFile().Flush()
        self.dbg.GetErrorFile().Flush()
        if collect_result and check:
            self.assertTrue(ret.Succeeded())
        return ret.GetOutput()


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_legacy_file_out_script(self):
        with open(self.out_filename, 'w') as f:
            self.dbg.SetOutputFileHandle(f, False)
            # scripts print to output even if you capture the results
            # I'm not sure I love that behavior, but that's the way
            # it's been for a long time.  That's why this test works
            # even with collect_result=True.
            self.handleCmd('script 1+1')
            self.dbg.GetOutputFileHandle().write('FOO\n')
            self.dbg.GetOutputFileHandle().flush()
        with open(self.out_filename, 'r') as f:
            self.assertEqual(readStrippedLines(f), ['2', 'FOO'])


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_legacy_file_out(self):
        with open(self.out_filename, 'w') as f:
            self.dbg.SetOutputFileHandle(f, False)
            self.handleCmd('p/x 3735928559', collect_result=False, check=False)
        with open(self.out_filename, 'r') as f:
            self.assertIn('deadbeef', f.read())

    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_legacy_file_err_with_get(self):
        with open(self.out_filename, 'w') as f:
            self.dbg.SetErrorFileHandle(f, False)
            self.handleCmd('lolwut', check=False, collect_result=False)
            f2 = self.dbg.GetErrorFileHandle()
            f2.write('FOOBAR\n')
            f2.flush()
        with open(self.out_filename, 'r') as f:
            errors = f.read()
            self.assertTrue(re.search(r'error:.*lolwut', errors))
            self.assertTrue(re.search(r'FOOBAR', errors))


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_legacy_file_err(self):
        with open(self.out_filename, 'w') as f:
            self.dbg.SetErrorFileHandle(f, False)
            self.handleCmd('lol', check=False, collect_result=False)
        with open(self.out_filename, 'r') as f:
            self.assertIn("is not a valid command", f.read())


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_legacy_file_error(self):
        with open(self.out_filename, 'w') as f:
            self.dbg.SetErrorFileHandle(f, False)
            self.handleCmd('lolwut', check=False, collect_result=False)
        with open(self.out_filename, 'r') as f:
            errors = f.read()
            self.assertTrue(re.search(r'error:.*lolwut', errors))

    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_type_errors(self):
        sbf = lldb.SBFile()
        self.assertRaises(Exception, sbf.Write, None)
        self.assertRaises(Exception, sbf.Read, None)
        self.assertRaises(Exception, sbf.Read, b'this bytes is not mutable')
        self.assertRaises(Exception, sbf.Write, u"ham sandwich")
        self.assertRaises(Exception, sbf.Read, u"ham sandwich")


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_write_fileno(self):
        with open(self.out_filename, 'w') as f:
            sbf = lldb.SBFile(f.fileno(), "w", False)
            self.assertTrue(sbf.IsValid())
            e, n = sbf.Write(b'FOO\nBAR')
            self.assertTrue(e.Success())
            self.assertEqual(n, 7)
            sbf.Close()
            self.assertFalse(sbf.IsValid())
        with open(self.out_filename, 'r') as f:
            self.assertEqual(readStrippedLines(f), ['FOO', 'BAR'])


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_write(self):
        with open(self.out_filename, 'w') as f:
            sbf = lldb.SBFile(f)
            e, n = sbf.Write(b'FOO\n')
            self.assertTrue(e.Success())
            self.assertEqual(n, 4)
            sbf.Close()
            self.assertTrue(f.closed)
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), 'FOO')


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_read_fileno(self):
        with open(self.out_filename, 'w') as f:
            f.write('FOO')
        with open(self.out_filename, 'r') as f:
            sbf = lldb.SBFile(f.fileno(), "r", False)
            self.assertTrue(sbf.IsValid())
            buffer = bytearray(100)
            e, n = sbf.Read(buffer)
            self.assertTrue(e.Success())
            self.assertEqual(buffer[:n], b'FOO')


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_read(self):
        with open(self.out_filename, 'w') as f:
            f.write('foo')
        with open(self.out_filename, 'r') as f:
            sbf = lldb.SBFile(f)
            buf = bytearray(100)
            e, n = sbf.Read(buf)
            self.assertTrue(e.Success())
            self.assertEqual(n, 3)
            self.assertEqual(buf[:n], b'foo')
            sbf.Close()
            self.assertTrue(f.closed)


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_fileno_out(self):
        with open(self.out_filename, 'w') as f:
            sbf = lldb.SBFile(f.fileno(), "w", False)
            status = self.dbg.SetOutputFile(sbf)
            self.assertTrue(status.Success())
            self.handleCmd('script 1+2')
            self.dbg.GetOutputFile().Write(b'quux')
            self.dbg.GetOutputFile().Flush()

        with open(self.out_filename, 'r') as f:
            self.assertEqual(readStrippedLines(f), ['3', 'quux'])


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_fileno_help(self):
        with open(self.out_filename, 'w') as f:
            sbf = lldb.SBFile(f.fileno(), "w", False)
            status = self.dbg.SetOutputFile(sbf)
            self.assertTrue(status.Success())
            self.handleCmd("help help", collect_result=False, check=False)
        with open(self.out_filename, 'r') as f:
            self.assertTrue(re.search(r'Show a list of all debugger commands', f.read()))


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


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_immediate(self):
        with open(self.out_filename, 'w') as f:
            ret = lldb.SBCommandReturnObject()
            ret.SetImmediateOutputFile(f)
            interpreter = self.dbg.GetCommandInterpreter()
            interpreter.HandleCommand("help help", ret)
            # make sure the file wasn't closed early.
            f.write("\nQUUX\n")
        ret = None # call destructor and flush streams
        with open(self.out_filename, 'r') as f:
            output = f.read()
            self.assertTrue(re.search(r'Show a list of all debugger commands', output))
            self.assertTrue(re.search(r'QUUX', output))


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_immediate_string(self):
        f = io.StringIO()
        ret = lldb.SBCommandReturnObject()
        ret.SetImmediateOutputFile(f)
        interpreter = self.dbg.GetCommandInterpreter()
        interpreter.HandleCommand("help help", ret)
        # make sure the file wasn't closed early.
        f.write("\nQUUX\n")
        ret = None # call destructor and flush streams
        output = f.getvalue()
        self.assertTrue(re.search(r'Show a list of all debugger commands', output))
        self.assertTrue(re.search(r'QUUX', output))


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_immediate_sbfile_string(self):
        f = io.StringIO()
        ret = lldb.SBCommandReturnObject()
        ret.SetImmediateOutputFile(lldb.SBFile(f))
        interpreter = self.dbg.GetCommandInterpreter()
        interpreter.HandleCommand("help help", ret)
        output = f.getvalue()
        ret = None # call destructor and flush streams
        # sbfile default constructor doesn't borrow the file
        self.assertTrue(f.closed)
        self.assertTrue(re.search(r'Show a list of all debugger commands', output))


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_fileno_inout(self):
        with open(self.in_filename, 'w') as f:
            f.write("help help\n")

        with open(self.out_filename, 'w') as outf, open(self.in_filename, 'r') as inf:

            outsbf = lldb.SBFile(outf.fileno(), "w", False)
            status = self.dbg.SetOutputFile(outsbf)
            self.assertTrue(status.Success())

            insbf = lldb.SBFile(inf.fileno(), "r", False)
            status = self.dbg.SetInputFile(insbf)
            self.assertTrue(status.Success())

            opts = lldb.SBCommandInterpreterRunOptions()
            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
            self.dbg.GetOutputFile().Flush()

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


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


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


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_string_inout(self):
        inf = io.StringIO("help help\np/x ~0\n")
        outf = io.StringIO()
        status = self.dbg.SetOutputFile(lldb.SBFile(outf))
        self.assertTrue(status.Success())
        status = self.dbg.SetInputFile(lldb.SBFile(inf))
        self.assertTrue(status.Success())
        opts = lldb.SBCommandInterpreterRunOptions()
        self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
        self.dbg.GetOutputFile().Flush()
        output = outf.getvalue()
        self.assertIn('Show a list of all debugger commands', output)
        self.assertIn('0xfff', output)


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_bytes_inout(self):
        inf = io.BytesIO(b"help help\nhelp b\n")
        outf = io.BytesIO()
        status = self.dbg.SetOutputFile(lldb.SBFile(outf))
        self.assertTrue(status.Success())
        status = self.dbg.SetInputFile(lldb.SBFile(inf))
        self.assertTrue(status.Success())
        opts = lldb.SBCommandInterpreterRunOptions()
        self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)
        self.dbg.GetOutputFile().Flush()
        output = outf.getvalue()
        self.assertIn(b'Show a list of all debugger commands', output)
        self.assertIn(b'Set a breakpoint', output)


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_fileno_error(self):
        with open(self.out_filename, 'w') as f:

            sbf = lldb.SBFile(f.fileno(), 'w', False)
            status = self.dbg.SetErrorFile(sbf)
            self.assertTrue(status.Success())

            self.handleCmd('lolwut', check=False, collect_result=False)

            self.dbg.GetErrorFile().Write(b'\nzork\n')

        with open(self.out_filename, 'r') as f:
            errors = f.read()
            self.assertTrue(re.search(r'error:.*lolwut', errors))
            self.assertTrue(re.search(r'zork', errors))


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_replace_stdout(self):
        f = io.StringIO()
        with replace_stdout(f):
            self.assertEqual(sys.stdout, f)
            self.handleCmd('script sys.stdout.write("lol")',
                collect_result=False, check=False)
            self.assertEqual(sys.stdout, f)


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_replace_stdout_with_nonfile(self):
        f = io.StringIO()
        with replace_stdout(f):
            class Nothing():
                pass
            with replace_stdout(Nothing):
                self.assertEqual(sys.stdout, Nothing)
                self.handleCmd('script sys.stdout.write("lol")',
                    check=False, collect_result=False)
                self.assertEqual(sys.stdout, Nothing)
            sys.stdout.write(u"FOO")
        self.assertEqual(f.getvalue(), "FOO")


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_write_borrowed(self):
        with open(self.out_filename, 'w') as f:
            sbf = lldb.SBFile.Create(f, borrow=True)
            e, n = sbf.Write(b'FOO')
            self.assertTrue(e.Success())
            self.assertEqual(n, 3)
            sbf.Close()
            self.assertFalse(f.closed)
            f.write('BAR\n')
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), 'FOOBAR')



    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_write_forced(self):
        with open(self.out_filename, 'w') as f:
            written = MutableBool(False)
            orig_write = f.write
            def mywrite(x):
                written.set(True)
                return orig_write(x)
            f.write = mywrite
            sbf = lldb.SBFile.Create(f, force_io_methods=True)
            e, n = sbf.Write(b'FOO')
            self.assertTrue(written)
            self.assertTrue(e.Success())
            self.assertEqual(n, 3)
            sbf.Close()
            self.assertTrue(f.closed)
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), 'FOO')


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_write_forced_borrowed(self):
        with open(self.out_filename, 'w') as f:
            written = MutableBool(False)
            orig_write = f.write
            def mywrite(x):
                written.set(True)
                return orig_write(x)
            f.write = mywrite
            sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True)
            e, n = sbf.Write(b'FOO')
            self.assertTrue(written)
            self.assertTrue(e.Success())
            self.assertEqual(n, 3)
            sbf.Close()
            self.assertFalse(f.closed)
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), 'FOO')


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_write_string(self):
        f = io.StringIO()
        sbf = lldb.SBFile(f)
        e, n = sbf.Write(b'FOO')
        self.assertEqual(f.getvalue().strip(), "FOO")
        self.assertTrue(e.Success())
        self.assertEqual(n, 3)
        sbf.Close()
        self.assertTrue(f.closed)


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_string_out(self):
        f = io.StringIO()
        status = self.dbg.SetOutputFile(f)
        self.assertTrue(status.Success())
        self.handleCmd("script 'foobar'")
        self.assertEqual(f.getvalue().strip(), "'foobar'")


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_string_error(self):
        f = io.StringIO()
        status = self.dbg.SetErrorFile(f)
        self.assertTrue(status.Success())
        self.handleCmd('lolwut', check=False, collect_result=False)
        errors = f.getvalue()
        self.assertTrue(re.search(r'error:.*lolwut', errors))


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_write_bytes(self):
        f = io.BytesIO()
        sbf = lldb.SBFile(f)
        e, n = sbf.Write(b'FOO')
        self.assertEqual(f.getvalue().strip(), b"FOO")
        self.assertTrue(e.Success())
        self.assertEqual(n, 3)
        sbf.Close()
        self.assertTrue(f.closed)

    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_read_string(self):
        f = io.StringIO('zork')
        sbf = lldb.SBFile(f)
        buf = bytearray(100)
        e, n = sbf.Read(buf)
        self.assertTrue(e.Success())
        self.assertEqual(buf[:n], b'zork')


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_read_string_one_byte(self):
        f = io.StringIO('z')
        sbf = lldb.SBFile(f)
        buf = bytearray(1)
        e, n = sbf.Read(buf)
        self.assertTrue(e.Fail())
        self.assertEqual(n, 0)
        self.assertEqual(e.GetCString(), "can't read less than 6 bytes from a utf8 text stream")


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_read_bytes(self):
        f = io.BytesIO(b'zork')
        sbf = lldb.SBFile(f)
        buf = bytearray(100)
        e, n = sbf.Read(buf)
        self.assertTrue(e.Success())
        self.assertEqual(buf[:n], b'zork')


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_out(self):
        with open(self.out_filename, 'w') as f:
            sbf = lldb.SBFile(f)
            status = self.dbg.SetOutputFile(sbf)
            self.assertTrue(status.Success())
            self.handleCmd('script 2+2')
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), '4')


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_file_out(self):
        with open(self.out_filename, 'w') as f:
            status = self.dbg.SetOutputFile(f)
            self.assertTrue(status.Success())
            self.handleCmd('script 2+2')
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), '4')


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbfile_error(self):
        with open(self.out_filename, 'w') as f:
            sbf = lldb.SBFile(f)
            status = self.dbg.SetErrorFile(sbf)
            self.assertTrue(status.Success())
            self.handleCmd('lolwut', check=False, collect_result=False)
        with open(self.out_filename, 'r') as f:
            errors = f.read()
            self.assertTrue(re.search(r'error:.*lolwut', errors))


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_file_error(self):
        with open(self.out_filename, 'w') as f:
            status = self.dbg.SetErrorFile(f)
            self.assertTrue(status.Success())
            self.handleCmd('lolwut', check=False, collect_result=False)
        with open(self.out_filename, 'r') as f:
            errors = f.read()
            self.assertTrue(re.search(r'error:.*lolwut', errors))


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_exceptions(self):
        self.assertRaises(Exception, lldb.SBFile, None)
        self.assertRaises(Exception, lldb.SBFile, "ham sandwich")
        if sys.version_info[0] < 3:
            self.assertRaises(Exception, lldb.SBFile, ReallyBadIO())
        else:
            self.assertRaises(OhNoe, lldb.SBFile, ReallyBadIO())
            error, n = lldb.SBFile(BadIO()).Write(b"FOO")
            self.assertEqual(n, 0)
            self.assertTrue(error.Fail())
            self.assertIn('OH NOE', error.GetCString())
            error, n = lldb.SBFile(BadIO()).Read(bytearray(100))
            self.assertEqual(n, 0)
            self.assertTrue(error.Fail())
            self.assertIn('OH NOE', error.GetCString())


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_exceptions_logged(self):
        messages = list()
        self.dbg.SetLoggingCallback(messages.append)
        self.handleCmd('log enable lldb script')
        self.dbg.SetOutputFile(lldb.SBFile(BadIO()))
        self.handleCmd('script 1+1')
        self.assertTrue(any('OH NOE' in msg for msg in messages))


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_flush(self):
        flushed = MutableBool(False)
        closed = MutableBool(False)
        f = FlushTestIO(flushed, closed)
        self.assertFalse(flushed)
        self.assertFalse(closed)
        sbf = lldb.SBFile(f)
        self.assertFalse(flushed)
        self.assertFalse(closed)
        sbf = None
        self.assertFalse(flushed)
        self.assertTrue(closed)
        self.assertTrue(f.closed)

        flushed = MutableBool(False)
        closed = MutableBool(False)
        f = FlushTestIO(flushed, closed)
        self.assertFalse(flushed)
        self.assertFalse(closed)
        sbf = lldb.SBFile.Create(f, borrow=True)
        self.assertFalse(flushed)
        self.assertFalse(closed)
        sbf = None
        self.assertTrue(flushed)
        self.assertFalse(closed)
        self.assertFalse(f.closed)


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_fileno_flush(self):
        with open(self.out_filename, 'w') as f:
            f.write("foo")
            sbf = lldb.SBFile(f)
            sbf.Write(b'bar')
            sbf = None
            self.assertTrue(f.closed)
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read(), 'foobar')

        with open(self.out_filename, 'w+') as f:
            f.write("foo")
            sbf = lldb.SBFile.Create(f, borrow=True)
            sbf.Write(b'bar')
            sbf = None
            self.assertFalse(f.closed)
            f.seek(0)
            self.assertEqual(f.read(), 'foobar')


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


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_stdout(self):
        f = io.StringIO()
        status = self.dbg.SetOutputFile(f)
        self.assertTrue(status.Success())
        self.handleCmd(r"script sys.stdout.write('foobar\n')")
        self.assertEqual(f.getvalue().strip().split(), ["foobar", "7"])


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_stdout_file(self):
        with open(self.out_filename, 'w') as f:
            status = self.dbg.SetOutputFile(f)
            self.assertTrue(status.Success())
            self.handleCmd(r"script sys.stdout.write('foobar\n')")
        with open(self.out_filename, 'r') as f:
            # In python2 sys.stdout.write() returns None, which
            # the REPL will ignore, but in python3 it will
            # return the number of bytes written, which the REPL
            # will print out.
            lines = [x for x in f.read().strip().split() if x != "7"]
            self.assertEqual(lines, ["foobar"])


    @add_test_categories(['pyapi'])
    @skipIf(py_version=['<', (3,)])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_identity(self):

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

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

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

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

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

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

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

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

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


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_back_and_forth(self):
        with open(self.out_filename, 'w') as f:
            # at each step here we're borrowing the file, so we have to keep
            # them all alive until the end.
            sbf = lldb.SBFile.Create(f, borrow=True)
            def i(sbf):
                for i in range(10):
                    f = sbf.GetFile()
                    self.assertEqual(f.mode, "w")
                    yield f
                    sbf = lldb.SBFile.Create(f, borrow=True)
                    yield sbf
                    sbf.Write(str(i).encode('ascii') + b"\n")
            files = list(i(sbf))
        with open(self.out_filename, 'r') as f:
            self.assertEqual(list(range(10)), list(map(int, f.read().strip().split())))


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_set_filehandle_none(self):
        self.assertRaises(Exception, self.dbg.SetOutputFile, None)
        self.assertRaises(Exception, self.dbg.SetOutputFile, "ham sandwich")
        self.assertRaises(Exception, self.dbg.SetOutputFileHandle, "ham sandwich")
        self.assertRaises(Exception, self.dbg.SetInputFile, None)
        self.assertRaises(Exception, self.dbg.SetInputFile, "ham sandwich")
        self.assertRaises(Exception, self.dbg.SetInputFileHandle, "ham sandwich")
        self.assertRaises(Exception, self.dbg.SetErrorFile, None)
        self.assertRaises(Exception, self.dbg.SetErrorFile, "ham sandwich")
        self.assertRaises(Exception, self.dbg.SetErrorFileHandle, "ham sandwich")

        with open(self.out_filename, 'w') as f:
            status = self.dbg.SetOutputFile(f)
            self.assertTrue(status.Success())
            status = self.dbg.SetErrorFile(f)
            self.assertTrue(status.Success())
            self.dbg.SetOutputFileHandle(None, False)
            self.dbg.SetErrorFileHandle(None, False)
            sbf = self.dbg.GetOutputFile()
            if sys.version_info.major >= 3:
                # python 2 lacks PyFile_FromFd, so GetFile() will
                # have to duplicate the file descriptor and make a FILE*
                # in order to convert a NativeFile it back to a python
                # file.
                self.assertEqual(sbf.GetFile().fileno(), 1)
            sbf = self.dbg.GetErrorFile()
            if sys.version_info.major >= 3:
                self.assertEqual(sbf.GetFile().fileno(), 2)
        with open(self.out_filename, 'r') as f:
            status = self.dbg.SetInputFile(f)
            self.assertTrue(status.Success())
            self.dbg.SetInputFileHandle(None, False)
            sbf = self.dbg.GetInputFile()
            if sys.version_info.major >= 3:
                self.assertEqual(sbf.GetFile().fileno(), 0)


    @add_test_categories(['pyapi'])
    @skipIfReproducer # lldb::FileSP used in typemap cannot be instrumented.
    def test_sbstream(self):

        with open(self.out_filename, 'w') as f:
            stream = lldb.SBStream()
            stream.RedirectToFile(f)
            stream.Print("zork")
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), "zork")

        with open(self.out_filename, 'w') as f:
            stream = lldb.SBStream()
            stream.RedirectToFileHandle(f, True)
            stream.Print("Yendor")
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), "Yendor")

        stream = lldb.SBStream()
        f = open(self.out_filename,  'w')
        stream.RedirectToFile(lldb.SBFile.Create(f, borrow=False))
        stream.Print("Frobozz")
        stream = None
        self.assertTrue(f.closed)
        with open(self.out_filename, 'r') as f:
            self.assertEqual(f.read().strip(), "Frobozz")
