brintos

brintos / llvm-project-archived public Read only

0
0
Text · 29.7 KiB · b385855 Raw
821 lines · python
1"""2Test lldb Python API for file handles.3"""4 5 6import os7import io8import re9import sys10from contextlib import contextmanager11 12import lldb13from lldbsuite.test import lldbtest14from lldbsuite.test.decorators import *15 16 17class OhNoe(Exception):18    pass19 20 21class BadIO(io.TextIOBase):22    @property23    def closed(self):24        return False25 26    def writable(self):27        return True28 29    def readable(self):30        return True31 32    def write(self, s):33        raise OhNoe("OH NOE")34 35    def read(self, n):36        raise OhNoe("OH NOE")37 38    def flush(self):39        raise OhNoe("OH NOE")40 41 42# This class will raise an exception while it's being43# converted into a C++ object by swig44class ReallyBadIO(io.TextIOBase):45    def fileno(self):46        return 99947 48    def writable(self):49        raise OhNoe("OH NOE!!!")50 51 52class MutableBool:53    def __init__(self, value):54        self.value = value55 56    def set(self, value):57        self.value = bool(value)58 59    def __bool__(self):60        return self.value61 62 63class FlushTestIO(io.StringIO):64    def __init__(self, mutable_flushed, mutable_closed):65        super(FlushTestIO, self).__init__()66        self.mut_flushed = mutable_flushed67        self.mut_closed = mutable_closed68 69    def close(self):70        self.mut_closed.set(True)71        return super(FlushTestIO, self).close()72 73    def flush(self):74        self.mut_flushed.set(True)75        return super(FlushTestIO, self).flush()76 77 78@contextmanager79def replace_stdout(new):80    old = sys.stdout81    sys.stdout = new82    try:83        yield84    finally:85        sys.stdout = old86 87 88def readStrippedLines(f):89    def i():90        for line in f:91            line = line.strip()92            if line:93                yield line94 95    return list(i())96 97 98class FileHandleTestCase(lldbtest.TestBase):99    NO_DEBUG_INFO_TESTCASE = True100 101    # The way normal tests evaluate debugger commands is102    # by using a SBCommandInterpreter directly, which captures103    # the output in a result object.   For many of tests tests104    # we want the debugger to write the  output directly to105    # its I/O streams like it would have done interactively.106    #107    # For this reason we also define handleCmd() here, even though108    # it is similar to runCmd().109 110    def setUp(self):111        super(FileHandleTestCase, self).setUp()112        self.out_filename = self.getBuildArtifact("output")113        self.in_filename = self.getBuildArtifact("input")114 115    def tearDown(self):116        super(FileHandleTestCase, self).tearDown()117        for name in (self.out_filename, self.in_filename):118            if os.path.exists(name):119                os.unlink(name)120 121    # Similar to runCmd(), but letting the debugger just print the results122    # instead of collecting them.123    def handleCmd(self, cmd, check=True, collect_result=True):124        assert not check or collect_result125        ret = lldb.SBCommandReturnObject()126        if collect_result:127            interpreter = self.dbg.GetCommandInterpreter()128            interpreter.HandleCommand(cmd, ret)129        else:130            self.dbg.HandleCommand(cmd)131        self.dbg.GetOutputFile().Flush()132        self.dbg.GetErrorFile().Flush()133        if collect_result and check:134            self.assertTrue(ret.Succeeded())135        return ret.GetOutput()136 137    def test_legacy_file_out_script(self):138        with open(self.out_filename, "w") as f:139            self.dbg.SetOutputFileHandle(f, False)140            # scripts print to output even if you capture the results141            # I'm not sure I love that behavior, but that's the way142            # it's been for a long time.  That's why this test works143            # even with collect_result=True.144            self.handleCmd("script 1+1")145            self.dbg.GetOutputFileHandle().write("FOO\n")146            self.dbg.GetOutputFileHandle().flush()147        with open(self.out_filename, "r") as f:148            self.assertEqual(readStrippedLines(f), ["2", "FOO"])149 150    def test_legacy_file_out(self):151        with open(self.out_filename, "w") as f:152            self.dbg.SetOutputFileHandle(f, False)153            self.handleCmd("expression/x 3735928559", collect_result=False, check=False)154        with open(self.out_filename, "r") as f:155            self.assertIn("deadbeef", f.read())156 157    def test_legacy_file_err_with_get(self):158        with open(self.out_filename, "w") as f:159            self.dbg.SetErrorFileHandle(f, False)160            self.handleCmd("lolwut", check=False, collect_result=False)161            f2 = self.dbg.GetErrorFileHandle()162            f2.write("FOOBAR\n")163            f2.flush()164        with open(self.out_filename, "r") as f:165            errors = f.read()166            self.assertTrue(re.search(r"error:.*lolwut", errors))167            self.assertTrue(re.search(r"FOOBAR", errors))168 169    def test_legacy_file_err(self):170        with open(self.out_filename, "w") as f:171            self.dbg.SetErrorFileHandle(f, False)172            self.handleCmd("lol", check=False, collect_result=False)173        with open(self.out_filename, "r") as f:174            self.assertIn("is not a valid command", f.read())175 176    def test_legacy_file_error(self):177        with open(self.out_filename, "w") as f:178            self.dbg.SetErrorFileHandle(f, False)179            self.handleCmd("lolwut", check=False, collect_result=False)180        with open(self.out_filename, "r") as f:181            errors = f.read()182            self.assertTrue(re.search(r"error:.*lolwut", errors))183 184    def test_sbfile_type_errors(self):185        sbf = lldb.SBFile()186        self.assertRaises(Exception, sbf.Write, None)187        self.assertRaises(Exception, sbf.Read, None)188        self.assertRaises(Exception, sbf.Read, b"this bytes is not mutable")189        self.assertRaises(Exception, sbf.Write, "ham sandwich")190        self.assertRaises(Exception, sbf.Read, "ham sandwich")191 192    def test_sbfile_write_fileno(self):193        with open(self.out_filename, "w") as f:194            sbf = lldb.SBFile(f.fileno(), "w", False)195            self.assertTrue(sbf.IsValid())196            e, n = sbf.Write(b"FOO\nBAR")197            self.assertSuccess(e)198            self.assertEqual(n, 7)199            sbf.Close()200            self.assertFalse(sbf.IsValid())201        with open(self.out_filename, "r") as f:202            self.assertEqual(readStrippedLines(f), ["FOO", "BAR"])203 204    def test_sbfile_write(self):205        with open(self.out_filename, "w") as f:206            sbf = lldb.SBFile(f)207            e, n = sbf.Write(b"FOO\n")208            self.assertSuccess(e)209            self.assertEqual(n, 4)210            sbf.Close()211            self.assertTrue(f.closed)212        with open(self.out_filename, "r") as f:213            self.assertEqual(f.read().strip(), "FOO")214 215    def test_sbfile_read_fileno(self):216        with open(self.out_filename, "w") as f:217            f.write("FOO")218        with open(self.out_filename, "r") as f:219            sbf = lldb.SBFile(f.fileno(), "r", False)220            self.assertTrue(sbf.IsValid())221            buffer = bytearray(100)222            e, n = sbf.Read(buffer)223            self.assertSuccess(e)224            self.assertEqual(buffer[:n], b"FOO")225 226    def test_sbfile_read(self):227        with open(self.out_filename, "w") as f:228            f.write("foo")229        with open(self.out_filename, "r") as f:230            sbf = lldb.SBFile(f)231            buf = bytearray(100)232            e, n = sbf.Read(buf)233            self.assertSuccess(e)234            self.assertEqual(n, 3)235            self.assertEqual(buf[:n], b"foo")236            sbf.Close()237            self.assertTrue(f.closed)238 239    def test_fileno_out(self):240        with open(self.out_filename, "w") as f:241            sbf = lldb.SBFile(f.fileno(), "w", False)242            status = self.dbg.SetOutputFile(sbf)243            self.assertSuccess(status)244            self.handleCmd("script 1+2")245            self.dbg.GetOutputFile().Write(b"quux")246            self.dbg.GetOutputFile().Flush()247 248        with open(self.out_filename, "r") as f:249            self.assertEqual(readStrippedLines(f), ["3", "quux"])250 251    def test_fileno_help(self):252        with open(self.out_filename, "w") as f:253            sbf = lldb.SBFile(f.fileno(), "w", False)254            status = self.dbg.SetOutputFile(sbf)255            self.assertSuccess(status)256            self.handleCmd("help help", collect_result=False, check=False)257        with open(self.out_filename, "r") as f:258            self.assertTrue(259                re.search(r"Show a list of all debugger commands", f.read())260            )261 262    def test_help(self):263        with open(self.out_filename, "w") as f:264            status = self.dbg.SetOutputFile(lldb.SBFile(f))265            self.assertSuccess(status)266            self.handleCmd("help help", check=False, collect_result=False)267        with open(self.out_filename, "r") as f:268            self.assertIn("Show a list of all debugger commands", f.read())269 270    def test_immediate(self):271        with open(self.out_filename, "w") as f:272            ret = lldb.SBCommandReturnObject()273            ret.SetImmediateOutputFile(f)274            interpreter = self.dbg.GetCommandInterpreter()275            interpreter.HandleCommand("help help", ret)276            # make sure the file wasn't closed early.277            f.write("\nQUUX\n")278        ret = None  # call destructor and flush streams279        with open(self.out_filename, "r") as f:280            output = f.read()281            self.assertTrue(re.search(r"Show a list of all debugger commands", output))282            self.assertTrue(re.search(r"QUUX", output))283 284    def test_immediate_string(self):285        f = io.StringIO()286        ret = lldb.SBCommandReturnObject()287        ret.SetImmediateOutputFile(f)288        interpreter = self.dbg.GetCommandInterpreter()289        interpreter.HandleCommand("help help", ret)290        # make sure the file wasn't closed early.291        f.write("\nQUUX\n")292        ret = None  # call destructor and flush streams293        output = f.getvalue()294        self.assertTrue(re.search(r"Show a list of all debugger commands", output))295        self.assertTrue(re.search(r"QUUX", output))296 297    def test_immediate_sbfile_string(self):298        f = io.StringIO()299        ret = lldb.SBCommandReturnObject()300        ret.SetImmediateOutputFile(lldb.SBFile(f))301        interpreter = self.dbg.GetCommandInterpreter()302        interpreter.HandleCommand("help help", ret)303        output = f.getvalue()304        ret = None  # call destructor and flush streams305        # sbfile default constructor doesn't borrow the file306        self.assertTrue(f.closed)307        self.assertTrue(re.search(r"Show a list of all debugger commands", output))308 309    def test_fileno_inout(self):310        with open(self.in_filename, "w") as f:311            f.write("help help\n")312 313        with open(self.out_filename, "w") as outf, open(self.in_filename, "r") as inf:314            outsbf = lldb.SBFile(outf.fileno(), "w", False)315            status = self.dbg.SetOutputFile(outsbf)316            self.assertSuccess(status)317 318            insbf = lldb.SBFile(inf.fileno(), "r", False)319            status = self.dbg.SetInputFile(insbf)320            self.assertSuccess(status)321 322            opts = lldb.SBCommandInterpreterRunOptions()323            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)324            self.dbg.GetOutputFile().Flush()325 326        with open(self.out_filename, "r") as f:327            self.assertTrue(328                re.search(r"Show a list of all debugger commands", f.read())329            )330 331    def test_inout(self):332        with open(self.in_filename, "w") as f:333            f.write("help help\n")334        with open(self.out_filename, "w") as outf, open(self.in_filename, "r") as inf:335            status = self.dbg.SetOutputFile(lldb.SBFile(outf))336            self.assertSuccess(status)337            status = self.dbg.SetInputFile(lldb.SBFile(inf))338            self.assertSuccess(status)339            opts = lldb.SBCommandInterpreterRunOptions()340            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)341            self.dbg.GetOutputFile().Flush()342        with open(self.out_filename, "r") as f:343            output = f.read()344            self.assertIn("Show a list of all debugger commands", output)345 346    def test_binary_inout(self):347        with open(self.in_filename, "w") as f:348            f.write("help help\n")349        with open(self.out_filename, "wb") as outf, open(self.in_filename, "rb") as inf:350            status = self.dbg.SetOutputFile(lldb.SBFile(outf))351            self.assertSuccess(status)352            status = self.dbg.SetInputFile(lldb.SBFile(inf))353            self.assertSuccess(status)354            opts = lldb.SBCommandInterpreterRunOptions()355            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)356            self.dbg.GetOutputFile().Flush()357        with open(self.out_filename, "r") as f:358            output = f.read()359            self.assertIn("Show a list of all debugger commands", output)360 361    def test_string_inout(self):362        inf = io.StringIO("help help\nexpression/x ~0\n")363        outf = io.StringIO()364        status = self.dbg.SetOutputFile(lldb.SBFile(outf))365        self.assertSuccess(status)366        status = self.dbg.SetInputFile(lldb.SBFile(inf))367        self.assertSuccess(status)368        opts = lldb.SBCommandInterpreterRunOptions()369        self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)370        self.dbg.GetOutputFile().Flush()371        output = outf.getvalue()372        self.assertIn("Show a list of all debugger commands", output)373        self.assertIn("0xfff", output)374 375    def test_bytes_inout(self):376        inf = io.BytesIO(b"help help\nhelp b\n")377        outf = io.BytesIO()378        status = self.dbg.SetOutputFile(lldb.SBFile(outf))379        self.assertSuccess(status)380        status = self.dbg.SetInputFile(lldb.SBFile(inf))381        self.assertSuccess(status)382        opts = lldb.SBCommandInterpreterRunOptions()383        self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)384        self.dbg.GetOutputFile().Flush()385        output = outf.getvalue()386        self.assertIn(b"Show a list of all debugger commands", output)387        self.assertIn(b"Set a breakpoint", output)388 389    def test_fileno_error(self):390        with open(self.out_filename, "w") as f:391            sbf = lldb.SBFile(f.fileno(), "w", False)392            status = self.dbg.SetErrorFile(sbf)393            self.assertSuccess(status)394 395            self.handleCmd("lolwut", check=False, collect_result=False)396 397            self.dbg.GetErrorFile().Write(b"\nzork\n")398 399        with open(self.out_filename, "r") as f:400            errors = f.read()401            self.assertTrue(re.search(r"error:.*lolwut", errors))402            self.assertTrue(re.search(r"zork", errors))403 404    def test_replace_stdout(self):405        f = io.StringIO()406        with replace_stdout(f):407            self.assertEqual(sys.stdout, f)408            self.handleCmd(409                'script sys.stdout.write("lol")', collect_result=False, check=False410            )411            self.assertEqual(sys.stdout, f)412 413    def test_replace_stdout_with_nonfile(self):414        f = io.StringIO()415        with replace_stdout(f):416 417            class Nothing:418                pass419 420            with replace_stdout(Nothing):421                self.assertEqual(sys.stdout, Nothing)422                self.handleCmd(423                    'script sys.stdout.write("lol")', check=False, collect_result=False424                )425                self.assertEqual(sys.stdout, Nothing)426            sys.stdout.write("FOO")427        self.assertEqual(f.getvalue(), "FOO")428 429    def test_sbfile_write_borrowed(self):430        with open(self.out_filename, "w") as f:431            sbf = lldb.SBFile.Create(f, borrow=True)432            e, n = sbf.Write(b"FOO")433            self.assertSuccess(e)434            self.assertEqual(n, 3)435            sbf.Close()436            self.assertFalse(f.closed)437            f.write("BAR\n")438        with open(self.out_filename, "r") as f:439            self.assertEqual(f.read().strip(), "FOOBAR")440 441    def test_sbfile_write_forced(self):442        with open(self.out_filename, "w") as f:443            written = MutableBool(False)444            orig_write = f.write445 446            def mywrite(x):447                written.set(True)448                return orig_write(x)449 450            f.write = mywrite451            sbf = lldb.SBFile.Create(f, force_io_methods=True)452            e, n = sbf.Write(b"FOO")453            self.assertTrue(written)454            self.assertSuccess(e)455            self.assertEqual(n, 3)456            sbf.Close()457            self.assertTrue(f.closed)458        with open(self.out_filename, "r") as f:459            self.assertEqual(f.read().strip(), "FOO")460 461    def test_sbfile_write_forced_borrowed(self):462        with open(self.out_filename, "w") as f:463            written = MutableBool(False)464            orig_write = f.write465 466            def mywrite(x):467                written.set(True)468                return orig_write(x)469 470            f.write = mywrite471            sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True)472            e, n = sbf.Write(b"FOO")473            self.assertTrue(written)474            self.assertSuccess(e)475            self.assertEqual(n, 3)476            sbf.Close()477            self.assertFalse(f.closed)478        with open(self.out_filename, "r") as f:479            self.assertEqual(f.read().strip(), "FOO")480 481    def test_sbfile_write_string(self):482        f = io.StringIO()483        sbf = lldb.SBFile(f)484        e, n = sbf.Write(b"FOO")485        self.assertEqual(f.getvalue().strip(), "FOO")486        self.assertSuccess(e)487        self.assertEqual(n, 3)488        sbf.Close()489        self.assertTrue(f.closed)490 491    def test_string_out(self):492        f = io.StringIO()493        status = self.dbg.SetOutputFile(f)494        self.assertSuccess(status)495        self.handleCmd("script 'foobar'")496        self.assertEqual(f.getvalue().strip(), "'foobar'")497 498    def test_string_error(self):499        f = io.StringIO()500        status = self.dbg.SetErrorFile(f)501        self.assertSuccess(status)502        self.handleCmd("lolwut", check=False, collect_result=False)503        errors = f.getvalue()504        self.assertTrue(re.search(r"error:.*lolwut", errors))505 506    def test_sbfile_write_bytes(self):507        f = io.BytesIO()508        sbf = lldb.SBFile(f)509        e, n = sbf.Write(b"FOO")510        self.assertEqual(f.getvalue().strip(), b"FOO")511        self.assertSuccess(e)512        self.assertEqual(n, 3)513        sbf.Close()514        self.assertTrue(f.closed)515 516    def test_sbfile_read_string(self):517        f = io.StringIO("zork")518        sbf = lldb.SBFile(f)519        buf = bytearray(100)520        e, n = sbf.Read(buf)521        self.assertSuccess(e)522        self.assertEqual(buf[:n], b"zork")523 524    def test_sbfile_read_string_one_byte(self):525        f = io.StringIO("z")526        sbf = lldb.SBFile(f)527        buf = bytearray(1)528        e, n = sbf.Read(buf)529        self.assertTrue(e.Fail())530        self.assertEqual(n, 0)531        self.assertEqual(532            e.GetCString(), "can't read less than 6 bytes from a utf8 text stream"533        )534 535    def test_sbfile_read_bytes(self):536        f = io.BytesIO(b"zork")537        sbf = lldb.SBFile(f)538        buf = bytearray(100)539        e, n = sbf.Read(buf)540        self.assertSuccess(e)541        self.assertEqual(buf[:n], b"zork")542 543    def test_sbfile_out(self):544        with open(self.out_filename, "w") as f:545            sbf = lldb.SBFile(f)546            status = self.dbg.SetOutputFile(sbf)547            self.assertSuccess(status)548            self.handleCmd("script 2+2")549        with open(self.out_filename, "r") as f:550            self.assertEqual(f.read().strip(), "4")551 552    def test_file_out(self):553        with open(self.out_filename, "w") as f:554            status = self.dbg.SetOutputFile(f)555            self.assertSuccess(status)556            self.handleCmd("script 2+2")557        with open(self.out_filename, "r") as f:558            self.assertEqual(f.read().strip(), "4")559 560    def test_sbfile_error(self):561        with open(self.out_filename, "w") as f:562            sbf = lldb.SBFile(f)563            status = self.dbg.SetErrorFile(sbf)564            self.assertSuccess(status)565            self.handleCmd("lolwut", check=False, collect_result=False)566        with open(self.out_filename, "r") as f:567            errors = f.read()568            self.assertTrue(re.search(r"error:.*lolwut", errors))569 570    def test_file_error(self):571        with open(self.out_filename, "w") as f:572            status = self.dbg.SetErrorFile(f)573            self.assertSuccess(status)574            self.handleCmd("lolwut", check=False, collect_result=False)575        with open(self.out_filename, "r") as f:576            errors = f.read()577            self.assertTrue(re.search(r"error:.*lolwut", errors))578 579    def test_exceptions(self):580        self.assertRaises(Exception, lldb.SBFile, None)581        self.assertRaises(Exception, lldb.SBFile, "ham sandwich")582        self.assertRaises(OhNoe, lldb.SBFile, ReallyBadIO())583        error, n = lldb.SBFile(BadIO()).Write(b"FOO")584        self.assertEqual(n, 0)585        self.assertTrue(error.Fail())586        self.assertIn("OH NOE", error.GetCString())587        error, n = lldb.SBFile(BadIO()).Read(bytearray(100))588        self.assertEqual(n, 0)589        self.assertTrue(error.Fail())590        self.assertIn("OH NOE", error.GetCString())591 592    def test_exceptions_logged(self):593        messages = list()594        self.dbg.SetLoggingCallback(messages.append)595        self.handleCmd("log enable lldb script")596        self.dbg.SetOutputFile(lldb.SBFile(BadIO()))597        self.handleCmd("script 1+1")598        self.assertTrue(any("OH NOE" in msg for msg in messages))599 600    def test_flush(self):601        flushed = MutableBool(False)602        closed = MutableBool(False)603        f = FlushTestIO(flushed, closed)604        self.assertFalse(flushed)605        self.assertFalse(closed)606        sbf = lldb.SBFile(f)607        self.assertFalse(flushed)608        self.assertFalse(closed)609        sbf = None610        self.assertFalse(flushed)611        self.assertTrue(closed)612        self.assertTrue(f.closed)613 614        flushed = MutableBool(False)615        closed = MutableBool(False)616        f = FlushTestIO(flushed, closed)617        self.assertFalse(flushed)618        self.assertFalse(closed)619        sbf = lldb.SBFile.Create(f, borrow=True)620        self.assertFalse(flushed)621        self.assertFalse(closed)622        sbf = None623        self.assertTrue(flushed)624        self.assertFalse(closed)625        self.assertFalse(f.closed)626 627    def test_fileno_flush(self):628        with open(self.out_filename, "w") as f:629            f.write("foo")630            sbf = lldb.SBFile(f)631            sbf.Write(b"bar")632            sbf = None633            self.assertTrue(f.closed)634        with open(self.out_filename, "r") as f:635            self.assertEqual(f.read(), "foobar")636 637        with open(self.out_filename, "w+") as f:638            f.write("foo")639            sbf = lldb.SBFile.Create(f, borrow=True)640            sbf.Write(b"bar")641            sbf = None642            self.assertFalse(f.closed)643            f.seek(0)644            self.assertEqual(f.read(), "foobar")645 646    def test_close(self):647        with open(self.out_filename, "w") as f:648            status = self.dbg.SetOutputFile(f)649            self.assertSuccess(status)650            self.handleCmd("help help", check=False, collect_result=False)651            # make sure the file wasn't closed early.652            f.write("\nZAP\n")653            lldb.SBDebugger.Destroy(self.dbg)654            # check that output file was closed when debugger was destroyed.655            with self.assertRaises(ValueError):656                f.write("\nQUUX\n")657        with open(self.out_filename, "r") as f:658            output = f.read()659            self.assertTrue(re.search(r"Show a list of all debugger commands", output))660            self.assertTrue(re.search(r"ZAP", output))661 662    def test_stdout(self):663        f = io.StringIO()664        status = self.dbg.SetOutputFile(f)665        self.assertSuccess(status)666        self.handleCmd(r"script sys.stdout.write('foobar\n')")667        self.assertEqual(f.getvalue().strip().split(), ["foobar", "7"])668 669    def test_stdout_file(self):670        with open(self.out_filename, "w") as f:671            status = self.dbg.SetOutputFile(f)672            self.assertSuccess(status)673            self.handleCmd(r"script sys.stdout.write('foobar\n')")674        with open(self.out_filename, "r") as f:675            # In python2 sys.stdout.write() returns None, which676            # the REPL will ignore, but in python3 it will677            # return the number of bytes written, which the REPL678            # will print out.679            lines = [x for x in f.read().strip().split() if x != "7"]680            self.assertEqual(lines, ["foobar"])681 682    def test_identity(self):683        f = io.StringIO()684        sbf = lldb.SBFile(f)685        self.assertIs(f, sbf.GetFile())686        sbf.Close()687        self.assertTrue(f.closed)688 689        f = io.StringIO()690        sbf = lldb.SBFile.Create(f, borrow=True)691        self.assertIs(f, sbf.GetFile())692        sbf.Close()693        self.assertFalse(f.closed)694 695        with open(self.out_filename, "w") as f:696            sbf = lldb.SBFile(f)697            self.assertIs(f, sbf.GetFile())698            sbf.Close()699            self.assertTrue(f.closed)700 701        with open(self.out_filename, "w") as f:702            sbf = lldb.SBFile.Create(f, borrow=True)703            self.assertIsNot(f, sbf.GetFile())704            sbf.Write(b"foobar\n")705            self.assertEqual(f.fileno(), sbf.GetFile().fileno())706            sbf.Close()707            self.assertFalse(f.closed)708 709        with open(self.out_filename, "r") as f:710            self.assertEqual("foobar", f.read().strip())711 712        with open(self.out_filename, "wb") as f:713            sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True)714            self.assertIs(f, sbf.GetFile())715            sbf.Write(b"foobar\n")716            self.assertEqual(f.fileno(), sbf.GetFile().fileno())717            sbf.Close()718            self.assertFalse(f.closed)719 720        with open(self.out_filename, "r") as f:721            self.assertEqual("foobar", f.read().strip())722 723        with open(self.out_filename, "wb") as f:724            sbf = lldb.SBFile.Create(f, force_io_methods=True)725            self.assertIs(f, sbf.GetFile())726            sbf.Write(b"foobar\n")727            self.assertEqual(f.fileno(), sbf.GetFile().fileno())728            sbf.Close()729            self.assertTrue(f.closed)730 731        with open(self.out_filename, "r") as f:732            self.assertEqual("foobar", f.read().strip())733 734    def test_back_and_forth(self):735        with open(self.out_filename, "w") as f:736            # at each step here we're borrowing the file, so we have to keep737            # them all alive until the end.738            sbf = lldb.SBFile.Create(f, borrow=True)739 740            def i(sbf):741                for i in range(10):742                    f = sbf.GetFile()743                    self.assertEqual(f.mode, "w")744                    yield f745                    sbf = lldb.SBFile.Create(f, borrow=True)746                    yield sbf747                    sbf.Write(str(i).encode("ascii") + b"\n")748 749            files = list(i(sbf))750        with open(self.out_filename, "r") as f:751            self.assertEqual(list(range(10)), list(map(int, f.read().strip().split())))752 753    def test_set_filehandle_none(self):754        self.assertRaises(Exception, self.dbg.SetOutputFile, None)755        self.assertRaises(Exception, self.dbg.SetOutputFile, "ham sandwich")756        self.assertRaises(Exception, self.dbg.SetOutputFileHandle, "ham sandwich")757        self.assertRaises(Exception, self.dbg.SetInputFile, None)758        self.assertRaises(Exception, self.dbg.SetInputFile, "ham sandwich")759        self.assertRaises(Exception, self.dbg.SetInputFileHandle, "ham sandwich")760        self.assertRaises(Exception, self.dbg.SetErrorFile, None)761        self.assertRaises(Exception, self.dbg.SetErrorFile, "ham sandwich")762        self.assertRaises(Exception, self.dbg.SetErrorFileHandle, "ham sandwich")763 764        with open(self.out_filename, "w") as f:765            status = self.dbg.SetOutputFile(f)766            self.assertSuccess(status)767            status = self.dbg.SetErrorFile(f)768            self.assertSuccess(status)769            self.dbg.SetOutputFileHandle(None, False)770            self.dbg.SetErrorFileHandle(None, False)771            sbf = self.dbg.GetOutputFile()772            self.assertEqual(sbf.GetFile().fileno(), 1)773            sbf = self.dbg.GetErrorFile()774            self.assertEqual(sbf.GetFile().fileno(), 2)775        with open(self.out_filename, "r") as f:776            status = self.dbg.SetInputFile(f)777            self.assertSuccess(status)778            self.dbg.SetInputFileHandle(None, False)779            sbf = self.dbg.GetInputFile()780            self.assertEqual(sbf.GetFile().fileno(), 0)781 782    def test_sbstream(self):783        with open(self.out_filename, "w") as f:784            stream = lldb.SBStream()785            stream.RedirectToFile(f)786            stream.Print("zork")787        with open(self.out_filename, "r") as f:788            self.assertEqual(f.read().strip(), "zork")789 790        with open(self.out_filename, "w") as f:791            stream = lldb.SBStream()792            stream.RedirectToFileHandle(f, True)793            stream.Print("Yendor")794        with open(self.out_filename, "r") as f:795            self.assertEqual(f.read().strip(), "Yendor")796 797        stream = lldb.SBStream()798        f = open(self.out_filename, "w")799        stream.RedirectToFile(lldb.SBFile.Create(f, borrow=False))800        stream.Print("Frobozz")801        stream = None802        self.assertTrue(f.closed)803        with open(self.out_filename, "r") as f:804            self.assertEqual(f.read().strip(), "Frobozz")805 806    def test_set_sbstream(self):807        with open(self.out_filename, "w") as outf:808            outsbf = lldb.SBFile(outf.fileno(), "w", False)809            status = self.dbg.SetOutputFile(outsbf)810            self.assertSuccess(status)811            self.dbg.SetInputString("help apropos\nhelp help\n")812 813            opts = lldb.SBCommandInterpreterRunOptions()814            self.dbg.RunCommandInterpreter(True, False, opts, 0, False, False)815            self.dbg.GetOutputFile().Flush()816 817        with open(self.out_filename, "r") as f:818            output = f.read()819            self.assertIn("Show a list of all debugger commands", output)820            self.assertIn("List debugger commands related to a word", output)821