1*99451b44SJordan Rupprecht""" 2*99451b44SJordan RupprechtTest lldb Python API for file handles. 3*99451b44SJordan Rupprecht""" 4*99451b44SJordan Rupprecht 5*99451b44SJordan Rupprecht 6*99451b44SJordan Rupprechtimport os 7*99451b44SJordan Rupprechtimport io 8*99451b44SJordan Rupprechtimport re 9*99451b44SJordan Rupprechtimport sys 10*99451b44SJordan Rupprechtfrom contextlib import contextmanager 11*99451b44SJordan Rupprecht 12*99451b44SJordan Rupprechtimport lldb 13*99451b44SJordan Rupprechtfrom lldbsuite.test import lldbtest 14*99451b44SJordan Rupprechtfrom lldbsuite.test.decorators import * 15*99451b44SJordan Rupprecht 16*99451b44SJordan Rupprechtclass OhNoe(Exception): 17*99451b44SJordan Rupprecht pass 18*99451b44SJordan Rupprecht 19*99451b44SJordan Rupprechtclass BadIO(io.TextIOBase): 20*99451b44SJordan Rupprecht @property 21*99451b44SJordan Rupprecht def closed(self): 22*99451b44SJordan Rupprecht return False 23*99451b44SJordan Rupprecht def writable(self): 24*99451b44SJordan Rupprecht return True 25*99451b44SJordan Rupprecht def readable(self): 26*99451b44SJordan Rupprecht return True 27*99451b44SJordan Rupprecht def write(self, s): 28*99451b44SJordan Rupprecht raise OhNoe('OH NOE') 29*99451b44SJordan Rupprecht def read(self, n): 30*99451b44SJordan Rupprecht raise OhNoe("OH NOE") 31*99451b44SJordan Rupprecht def flush(self): 32*99451b44SJordan Rupprecht raise OhNoe('OH NOE') 33*99451b44SJordan Rupprecht 34*99451b44SJordan Rupprecht# This class will raise an exception while it's being 35*99451b44SJordan Rupprecht# converted into a C++ object by swig 36*99451b44SJordan Rupprechtclass ReallyBadIO(io.TextIOBase): 37*99451b44SJordan Rupprecht def fileno(self): 38*99451b44SJordan Rupprecht return 999 39*99451b44SJordan Rupprecht def writable(self): 40*99451b44SJordan Rupprecht raise OhNoe("OH NOE!!!") 41*99451b44SJordan Rupprecht 42*99451b44SJordan Rupprechtclass MutableBool(): 43*99451b44SJordan Rupprecht def __init__(self, value): 44*99451b44SJordan Rupprecht self.value = value 45*99451b44SJordan Rupprecht def set(self, value): 46*99451b44SJordan Rupprecht self.value = bool(value) 47*99451b44SJordan Rupprecht def __bool__(self): 48*99451b44SJordan Rupprecht return self.value 49*99451b44SJordan Rupprecht 50*99451b44SJordan Rupprechtclass FlushTestIO(io.StringIO): 51*99451b44SJordan Rupprecht def __init__(self, mutable_flushed, mutable_closed): 52*99451b44SJordan Rupprecht super(FlushTestIO, self).__init__() 53*99451b44SJordan Rupprecht self.mut_flushed = mutable_flushed 54*99451b44SJordan Rupprecht self.mut_closed = mutable_closed 55*99451b44SJordan Rupprecht def close(self): 56*99451b44SJordan Rupprecht self.mut_closed.set(True) 57*99451b44SJordan Rupprecht return super(FlushTestIO, self).close() 58*99451b44SJordan Rupprecht def flush(self): 59*99451b44SJordan Rupprecht self.mut_flushed.set(True) 60*99451b44SJordan Rupprecht return super(FlushTestIO, self).flush() 61*99451b44SJordan Rupprecht 62*99451b44SJordan Rupprecht@contextmanager 63*99451b44SJordan Rupprechtdef replace_stdout(new): 64*99451b44SJordan Rupprecht old = sys.stdout 65*99451b44SJordan Rupprecht sys.stdout = new 66*99451b44SJordan Rupprecht try: 67*99451b44SJordan Rupprecht yield 68*99451b44SJordan Rupprecht finally: 69*99451b44SJordan Rupprecht sys.stdout = old 70*99451b44SJordan Rupprecht 71*99451b44SJordan Rupprechtdef readStrippedLines(f): 72*99451b44SJordan Rupprecht def i(): 73*99451b44SJordan Rupprecht for line in f: 74*99451b44SJordan Rupprecht line = line.strip() 75*99451b44SJordan Rupprecht if line: 76*99451b44SJordan Rupprecht yield line 77*99451b44SJordan Rupprecht return list(i()) 78*99451b44SJordan Rupprecht 79*99451b44SJordan Rupprecht 80*99451b44SJordan Rupprechtclass FileHandleTestCase(lldbtest.TestBase): 81*99451b44SJordan Rupprecht 82*99451b44SJordan Rupprecht NO_DEBUG_INFO_TESTCASE = True 83*99451b44SJordan Rupprecht mydir = lldbtest.Base.compute_mydir(__file__) 84*99451b44SJordan Rupprecht 85*99451b44SJordan Rupprecht # The way this class interacts with the debugger is different 86*99451b44SJordan Rupprecht # than normal. Most of these test cases will mess with the 87*99451b44SJordan Rupprecht # debugger I/O streams, so we want a fresh debugger for each 88*99451b44SJordan Rupprecht # test so those mutations don't interfere with each other. 89*99451b44SJordan Rupprecht # 90*99451b44SJordan Rupprecht # Also, the way normal tests evaluate debugger commands is 91*99451b44SJordan Rupprecht # by using a SBCommandInterpreter directly, which captures 92*99451b44SJordan Rupprecht # the output in a result object. For many of tests tests 93*99451b44SJordan Rupprecht # we want the debugger to write the output directly to 94*99451b44SJordan Rupprecht # its I/O streams like it would have done interactively. 95*99451b44SJordan Rupprecht # 96*99451b44SJordan Rupprecht # For this reason we also define handleCmd() here, even though 97*99451b44SJordan Rupprecht # it is similar to runCmd(). 98*99451b44SJordan Rupprecht 99*99451b44SJordan Rupprecht def setUp(self): 100*99451b44SJordan Rupprecht super(FileHandleTestCase, self).setUp() 101*99451b44SJordan Rupprecht self.debugger = lldb.SBDebugger.Create() 102*99451b44SJordan Rupprecht self.out_filename = self.getBuildArtifact('output') 103*99451b44SJordan Rupprecht self.in_filename = self.getBuildArtifact('input') 104*99451b44SJordan Rupprecht 105*99451b44SJordan Rupprecht def tearDown(self): 106*99451b44SJordan Rupprecht lldb.SBDebugger.Destroy(self.debugger) 107*99451b44SJordan Rupprecht super(FileHandleTestCase, self).tearDown() 108*99451b44SJordan Rupprecht for name in (self.out_filename, self.in_filename): 109*99451b44SJordan Rupprecht if os.path.exists(name): 110*99451b44SJordan Rupprecht os.unlink(name) 111*99451b44SJordan Rupprecht 112*99451b44SJordan Rupprecht # Similar to runCmd(), but this uses the per-test debugger, and it 113*99451b44SJordan Rupprecht # supports, letting the debugger just print the results instead 114*99451b44SJordan Rupprecht # of collecting them. 115*99451b44SJordan Rupprecht def handleCmd(self, cmd, check=True, collect_result=True): 116*99451b44SJordan Rupprecht assert not check or collect_result 117*99451b44SJordan Rupprecht ret = lldb.SBCommandReturnObject() 118*99451b44SJordan Rupprecht if collect_result: 119*99451b44SJordan Rupprecht interpreter = self.debugger.GetCommandInterpreter() 120*99451b44SJordan Rupprecht interpreter.HandleCommand(cmd, ret) 121*99451b44SJordan Rupprecht else: 122*99451b44SJordan Rupprecht self.debugger.HandleCommand(cmd) 123*99451b44SJordan Rupprecht self.debugger.GetOutputFile().Flush() 124*99451b44SJordan Rupprecht self.debugger.GetErrorFile().Flush() 125*99451b44SJordan Rupprecht if collect_result and check: 126*99451b44SJordan Rupprecht self.assertTrue(ret.Succeeded()) 127*99451b44SJordan Rupprecht return ret.GetOutput() 128*99451b44SJordan Rupprecht 129*99451b44SJordan Rupprecht 130*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 131*99451b44SJordan Rupprecht def test_legacy_file_out_script(self): 132*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 133*99451b44SJordan Rupprecht self.debugger.SetOutputFileHandle(f, False) 134*99451b44SJordan Rupprecht # scripts print to output even if you capture the results 135*99451b44SJordan Rupprecht # I'm not sure I love that behavior, but that's the way 136*99451b44SJordan Rupprecht # it's been for a long time. That's why this test works 137*99451b44SJordan Rupprecht # even with collect_result=True. 138*99451b44SJordan Rupprecht self.handleCmd('script 1+1') 139*99451b44SJordan Rupprecht self.debugger.GetOutputFileHandle().write('FOO\n') 140*99451b44SJordan Rupprecht lldb.SBDebugger.Destroy(self.debugger) 141*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 142*99451b44SJordan Rupprecht self.assertEqual(readStrippedLines(f), ['2', 'FOO']) 143*99451b44SJordan Rupprecht 144*99451b44SJordan Rupprecht 145*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 146*99451b44SJordan Rupprecht def test_legacy_file_out(self): 147*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 148*99451b44SJordan Rupprecht self.debugger.SetOutputFileHandle(f, False) 149*99451b44SJordan Rupprecht self.handleCmd('p/x 3735928559', collect_result=False, check=False) 150*99451b44SJordan Rupprecht lldb.SBDebugger.Destroy(self.debugger) 151*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 152*99451b44SJordan Rupprecht self.assertIn('deadbeef', f.read()) 153*99451b44SJordan Rupprecht 154*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 155*99451b44SJordan Rupprecht def test_legacy_file_err_with_get(self): 156*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 157*99451b44SJordan Rupprecht self.debugger.SetErrorFileHandle(f, False) 158*99451b44SJordan Rupprecht self.handleCmd('lolwut', check=False, collect_result=False) 159*99451b44SJordan Rupprecht f2 = self.debugger.GetErrorFileHandle() 160*99451b44SJordan Rupprecht f2.write('FOOBAR\n') 161*99451b44SJordan Rupprecht f2.flush() 162*99451b44SJordan Rupprecht lldb.SBDebugger.Destroy(self.debugger) 163*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 164*99451b44SJordan Rupprecht errors = f.read() 165*99451b44SJordan Rupprecht self.assertTrue(re.search(r'error:.*lolwut', errors)) 166*99451b44SJordan Rupprecht self.assertTrue(re.search(r'FOOBAR', errors)) 167*99451b44SJordan Rupprecht 168*99451b44SJordan Rupprecht 169*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 170*99451b44SJordan Rupprecht def test_legacy_file_err(self): 171*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 172*99451b44SJordan Rupprecht self.debugger.SetErrorFileHandle(f, False) 173*99451b44SJordan Rupprecht self.handleCmd('lol', check=False, collect_result=False) 174*99451b44SJordan Rupprecht lldb.SBDebugger.Destroy(self.debugger) 175*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 176*99451b44SJordan Rupprecht self.assertIn("is not a valid command", f.read()) 177*99451b44SJordan Rupprecht 178*99451b44SJordan Rupprecht 179*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 180*99451b44SJordan Rupprecht def test_legacy_file_error(self): 181*99451b44SJordan Rupprecht debugger = self.debugger 182*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 183*99451b44SJordan Rupprecht debugger.SetErrorFileHandle(f, False) 184*99451b44SJordan Rupprecht self.handleCmd('lolwut', check=False, collect_result=False) 185*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 186*99451b44SJordan Rupprecht errors = f.read() 187*99451b44SJordan Rupprecht self.assertTrue(re.search(r'error:.*lolwut', errors)) 188*99451b44SJordan Rupprecht 189*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 190*99451b44SJordan Rupprecht def test_sbfile_type_errors(self): 191*99451b44SJordan Rupprecht sbf = lldb.SBFile() 192*99451b44SJordan Rupprecht self.assertRaises(Exception, sbf.Write, None) 193*99451b44SJordan Rupprecht self.assertRaises(Exception, sbf.Read, None) 194*99451b44SJordan Rupprecht self.assertRaises(Exception, sbf.Read, b'this bytes is not mutable') 195*99451b44SJordan Rupprecht self.assertRaises(Exception, sbf.Write, u"ham sandwich") 196*99451b44SJordan Rupprecht self.assertRaises(Exception, sbf.Read, u"ham sandwich") 197*99451b44SJordan Rupprecht 198*99451b44SJordan Rupprecht 199*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 200*99451b44SJordan Rupprecht def test_sbfile_write_fileno(self): 201*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 202*99451b44SJordan Rupprecht sbf = lldb.SBFile(f.fileno(), "w", False) 203*99451b44SJordan Rupprecht self.assertTrue(sbf.IsValid()) 204*99451b44SJordan Rupprecht e, n = sbf.Write(b'FOO\nBAR') 205*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 206*99451b44SJordan Rupprecht self.assertEqual(n, 7) 207*99451b44SJordan Rupprecht sbf.Close() 208*99451b44SJordan Rupprecht self.assertFalse(sbf.IsValid()) 209*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 210*99451b44SJordan Rupprecht self.assertEqual(readStrippedLines(f), ['FOO', 'BAR']) 211*99451b44SJordan Rupprecht 212*99451b44SJordan Rupprecht 213*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 214*99451b44SJordan Rupprecht def test_sbfile_write(self): 215*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 216*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 217*99451b44SJordan Rupprecht e, n = sbf.Write(b'FOO\n') 218*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 219*99451b44SJordan Rupprecht self.assertEqual(n, 4) 220*99451b44SJordan Rupprecht sbf.Close() 221*99451b44SJordan Rupprecht self.assertTrue(f.closed) 222*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 223*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), 'FOO') 224*99451b44SJordan Rupprecht 225*99451b44SJordan Rupprecht 226*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 227*99451b44SJordan Rupprecht def test_sbfile_read_fileno(self): 228*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 229*99451b44SJordan Rupprecht f.write('FOO') 230*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 231*99451b44SJordan Rupprecht sbf = lldb.SBFile(f.fileno(), "r", False) 232*99451b44SJordan Rupprecht self.assertTrue(sbf.IsValid()) 233*99451b44SJordan Rupprecht buffer = bytearray(100) 234*99451b44SJordan Rupprecht e, n = sbf.Read(buffer) 235*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 236*99451b44SJordan Rupprecht self.assertEqual(buffer[:n], b'FOO') 237*99451b44SJordan Rupprecht 238*99451b44SJordan Rupprecht 239*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 240*99451b44SJordan Rupprecht def test_sbfile_read(self): 241*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 242*99451b44SJordan Rupprecht f.write('foo') 243*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 244*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 245*99451b44SJordan Rupprecht buf = bytearray(100) 246*99451b44SJordan Rupprecht e, n = sbf.Read(buf) 247*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 248*99451b44SJordan Rupprecht self.assertEqual(n, 3) 249*99451b44SJordan Rupprecht self.assertEqual(buf[:n], b'foo') 250*99451b44SJordan Rupprecht sbf.Close() 251*99451b44SJordan Rupprecht self.assertTrue(f.closed) 252*99451b44SJordan Rupprecht 253*99451b44SJordan Rupprecht 254*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 255*99451b44SJordan Rupprecht def test_fileno_out(self): 256*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 257*99451b44SJordan Rupprecht sbf = lldb.SBFile(f.fileno(), "w", False) 258*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(sbf) 259*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 260*99451b44SJordan Rupprecht self.handleCmd('script 1+2') 261*99451b44SJordan Rupprecht self.debugger.GetOutputFile().Write(b'quux') 262*99451b44SJordan Rupprecht 263*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 264*99451b44SJordan Rupprecht self.assertEqual(readStrippedLines(f), ['3', 'quux']) 265*99451b44SJordan Rupprecht 266*99451b44SJordan Rupprecht 267*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 268*99451b44SJordan Rupprecht def test_fileno_help(self): 269*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 270*99451b44SJordan Rupprecht sbf = lldb.SBFile(f.fileno(), "w", False) 271*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(sbf) 272*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 273*99451b44SJordan Rupprecht self.handleCmd("help help", collect_result=False, check=False) 274*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 275*99451b44SJordan Rupprecht self.assertTrue(re.search(r'Show a list of all debugger commands', f.read())) 276*99451b44SJordan Rupprecht 277*99451b44SJordan Rupprecht 278*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 279*99451b44SJordan Rupprecht def test_help(self): 280*99451b44SJordan Rupprecht debugger = self.debugger 281*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 282*99451b44SJordan Rupprecht status = debugger.SetOutputFile(lldb.SBFile(f)) 283*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 284*99451b44SJordan Rupprecht self.handleCmd("help help", check=False, collect_result=False) 285*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 286*99451b44SJordan Rupprecht self.assertIn('Show a list of all debugger commands', f.read()) 287*99451b44SJordan Rupprecht 288*99451b44SJordan Rupprecht 289*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 290*99451b44SJordan Rupprecht def test_immediate(self): 291*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 292*99451b44SJordan Rupprecht ret = lldb.SBCommandReturnObject() 293*99451b44SJordan Rupprecht ret.SetImmediateOutputFile(f) 294*99451b44SJordan Rupprecht interpreter = self.debugger.GetCommandInterpreter() 295*99451b44SJordan Rupprecht interpreter.HandleCommand("help help", ret) 296*99451b44SJordan Rupprecht # make sure the file wasn't closed early. 297*99451b44SJordan Rupprecht f.write("\nQUUX\n") 298*99451b44SJordan Rupprecht ret = None # call destructor and flush streams 299*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 300*99451b44SJordan Rupprecht output = f.read() 301*99451b44SJordan Rupprecht self.assertTrue(re.search(r'Show a list of all debugger commands', output)) 302*99451b44SJordan Rupprecht self.assertTrue(re.search(r'QUUX', output)) 303*99451b44SJordan Rupprecht 304*99451b44SJordan Rupprecht 305*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 306*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 307*99451b44SJordan Rupprecht def test_immediate_string(self): 308*99451b44SJordan Rupprecht f = io.StringIO() 309*99451b44SJordan Rupprecht ret = lldb.SBCommandReturnObject() 310*99451b44SJordan Rupprecht ret.SetImmediateOutputFile(f) 311*99451b44SJordan Rupprecht interpreter = self.debugger.GetCommandInterpreter() 312*99451b44SJordan Rupprecht interpreter.HandleCommand("help help", ret) 313*99451b44SJordan Rupprecht # make sure the file wasn't closed early. 314*99451b44SJordan Rupprecht f.write("\nQUUX\n") 315*99451b44SJordan Rupprecht ret = None # call destructor and flush streams 316*99451b44SJordan Rupprecht output = f.getvalue() 317*99451b44SJordan Rupprecht self.assertTrue(re.search(r'Show a list of all debugger commands', output)) 318*99451b44SJordan Rupprecht self.assertTrue(re.search(r'QUUX', output)) 319*99451b44SJordan Rupprecht 320*99451b44SJordan Rupprecht 321*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 322*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 323*99451b44SJordan Rupprecht def test_immediate_sbfile_string(self): 324*99451b44SJordan Rupprecht f = io.StringIO() 325*99451b44SJordan Rupprecht ret = lldb.SBCommandReturnObject() 326*99451b44SJordan Rupprecht ret.SetImmediateOutputFile(lldb.SBFile(f)) 327*99451b44SJordan Rupprecht interpreter = self.debugger.GetCommandInterpreter() 328*99451b44SJordan Rupprecht interpreter.HandleCommand("help help", ret) 329*99451b44SJordan Rupprecht output = f.getvalue() 330*99451b44SJordan Rupprecht ret = None # call destructor and flush streams 331*99451b44SJordan Rupprecht # sbfile default constructor doesn't borrow the file 332*99451b44SJordan Rupprecht self.assertTrue(f.closed) 333*99451b44SJordan Rupprecht self.assertTrue(re.search(r'Show a list of all debugger commands', output)) 334*99451b44SJordan Rupprecht 335*99451b44SJordan Rupprecht 336*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 337*99451b44SJordan Rupprecht def test_fileno_inout(self): 338*99451b44SJordan Rupprecht with open(self.in_filename, 'w') as f: 339*99451b44SJordan Rupprecht f.write("help help\n") 340*99451b44SJordan Rupprecht 341*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as outf, open(self.in_filename, 'r') as inf: 342*99451b44SJordan Rupprecht 343*99451b44SJordan Rupprecht outsbf = lldb.SBFile(outf.fileno(), "w", False) 344*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(outsbf) 345*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 346*99451b44SJordan Rupprecht 347*99451b44SJordan Rupprecht insbf = lldb.SBFile(inf.fileno(), "r", False) 348*99451b44SJordan Rupprecht status = self.debugger.SetInputFile(insbf) 349*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 350*99451b44SJordan Rupprecht 351*99451b44SJordan Rupprecht opts = lldb.SBCommandInterpreterRunOptions() 352*99451b44SJordan Rupprecht self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False) 353*99451b44SJordan Rupprecht self.debugger.GetOutputFile().Flush() 354*99451b44SJordan Rupprecht 355*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 356*99451b44SJordan Rupprecht self.assertTrue(re.search(r'Show a list of all debugger commands', f.read())) 357*99451b44SJordan Rupprecht 358*99451b44SJordan Rupprecht 359*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 360*99451b44SJordan Rupprecht def test_inout(self): 361*99451b44SJordan Rupprecht with open(self.in_filename, 'w') as f: 362*99451b44SJordan Rupprecht f.write("help help\n") 363*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as outf, \ 364*99451b44SJordan Rupprecht open(self.in_filename, 'r') as inf: 365*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(lldb.SBFile(outf)) 366*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 367*99451b44SJordan Rupprecht status = self.debugger.SetInputFile(lldb.SBFile(inf)) 368*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 369*99451b44SJordan Rupprecht opts = lldb.SBCommandInterpreterRunOptions() 370*99451b44SJordan Rupprecht self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False) 371*99451b44SJordan Rupprecht self.debugger.GetOutputFile().Flush() 372*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 373*99451b44SJordan Rupprecht output = f.read() 374*99451b44SJordan Rupprecht self.assertIn('Show a list of all debugger commands', output) 375*99451b44SJordan Rupprecht 376*99451b44SJordan Rupprecht 377*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 378*99451b44SJordan Rupprecht def test_binary_inout(self): 379*99451b44SJordan Rupprecht debugger = self.debugger 380*99451b44SJordan Rupprecht with open(self.in_filename, 'w') as f: 381*99451b44SJordan Rupprecht f.write("help help\n") 382*99451b44SJordan Rupprecht with open(self.out_filename, 'wb') as outf, \ 383*99451b44SJordan Rupprecht open(self.in_filename, 'rb') as inf: 384*99451b44SJordan Rupprecht status = debugger.SetOutputFile(lldb.SBFile(outf)) 385*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 386*99451b44SJordan Rupprecht status = debugger.SetInputFile(lldb.SBFile(inf)) 387*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 388*99451b44SJordan Rupprecht opts = lldb.SBCommandInterpreterRunOptions() 389*99451b44SJordan Rupprecht debugger.RunCommandInterpreter(True, False, opts, 0, False, False) 390*99451b44SJordan Rupprecht debugger.GetOutputFile().Flush() 391*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 392*99451b44SJordan Rupprecht output = f.read() 393*99451b44SJordan Rupprecht self.assertIn('Show a list of all debugger commands', output) 394*99451b44SJordan Rupprecht 395*99451b44SJordan Rupprecht 396*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 397*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 398*99451b44SJordan Rupprecht def test_string_inout(self): 399*99451b44SJordan Rupprecht inf = io.StringIO("help help\np/x ~0\n") 400*99451b44SJordan Rupprecht outf = io.StringIO() 401*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(lldb.SBFile(outf)) 402*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 403*99451b44SJordan Rupprecht status = self.debugger.SetInputFile(lldb.SBFile(inf)) 404*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 405*99451b44SJordan Rupprecht opts = lldb.SBCommandInterpreterRunOptions() 406*99451b44SJordan Rupprecht self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False) 407*99451b44SJordan Rupprecht self.debugger.GetOutputFile().Flush() 408*99451b44SJordan Rupprecht output = outf.getvalue() 409*99451b44SJordan Rupprecht self.assertIn('Show a list of all debugger commands', output) 410*99451b44SJordan Rupprecht self.assertIn('0xfff', output) 411*99451b44SJordan Rupprecht 412*99451b44SJordan Rupprecht 413*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 414*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 415*99451b44SJordan Rupprecht def test_bytes_inout(self): 416*99451b44SJordan Rupprecht inf = io.BytesIO(b"help help\nhelp b\n") 417*99451b44SJordan Rupprecht outf = io.BytesIO() 418*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(lldb.SBFile(outf)) 419*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 420*99451b44SJordan Rupprecht status = self.debugger.SetInputFile(lldb.SBFile(inf)) 421*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 422*99451b44SJordan Rupprecht opts = lldb.SBCommandInterpreterRunOptions() 423*99451b44SJordan Rupprecht self.debugger.RunCommandInterpreter(True, False, opts, 0, False, False) 424*99451b44SJordan Rupprecht self.debugger.GetOutputFile().Flush() 425*99451b44SJordan Rupprecht output = outf.getvalue() 426*99451b44SJordan Rupprecht self.assertIn(b'Show a list of all debugger commands', output) 427*99451b44SJordan Rupprecht self.assertIn(b'Set a breakpoint', output) 428*99451b44SJordan Rupprecht 429*99451b44SJordan Rupprecht 430*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 431*99451b44SJordan Rupprecht def test_fileno_error(self): 432*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 433*99451b44SJordan Rupprecht 434*99451b44SJordan Rupprecht sbf = lldb.SBFile(f.fileno(), 'w', False) 435*99451b44SJordan Rupprecht status = self.debugger.SetErrorFile(sbf) 436*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 437*99451b44SJordan Rupprecht 438*99451b44SJordan Rupprecht self.handleCmd('lolwut', check=False, collect_result=False) 439*99451b44SJordan Rupprecht 440*99451b44SJordan Rupprecht self.debugger.GetErrorFile().Write(b'\nzork\n') 441*99451b44SJordan Rupprecht 442*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 443*99451b44SJordan Rupprecht errors = f.read() 444*99451b44SJordan Rupprecht self.assertTrue(re.search(r'error:.*lolwut', errors)) 445*99451b44SJordan Rupprecht self.assertTrue(re.search(r'zork', errors)) 446*99451b44SJordan Rupprecht 447*99451b44SJordan Rupprecht 448*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 449*99451b44SJordan Rupprecht def test_replace_stdout(self): 450*99451b44SJordan Rupprecht f = io.StringIO() 451*99451b44SJordan Rupprecht with replace_stdout(f): 452*99451b44SJordan Rupprecht self.assertEqual(sys.stdout, f) 453*99451b44SJordan Rupprecht self.handleCmd('script sys.stdout.write("lol")', 454*99451b44SJordan Rupprecht collect_result=False, check=False) 455*99451b44SJordan Rupprecht self.assertEqual(sys.stdout, f) 456*99451b44SJordan Rupprecht 457*99451b44SJordan Rupprecht 458*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 459*99451b44SJordan Rupprecht def test_replace_stdout_with_nonfile(self): 460*99451b44SJordan Rupprecht debugger = self.debugger 461*99451b44SJordan Rupprecht f = io.StringIO() 462*99451b44SJordan Rupprecht with replace_stdout(f): 463*99451b44SJordan Rupprecht class Nothing(): 464*99451b44SJordan Rupprecht pass 465*99451b44SJordan Rupprecht with replace_stdout(Nothing): 466*99451b44SJordan Rupprecht self.assertEqual(sys.stdout, Nothing) 467*99451b44SJordan Rupprecht self.handleCmd('script sys.stdout.write("lol")', 468*99451b44SJordan Rupprecht check=False, collect_result=False) 469*99451b44SJordan Rupprecht self.assertEqual(sys.stdout, Nothing) 470*99451b44SJordan Rupprecht sys.stdout.write(u"FOO") 471*99451b44SJordan Rupprecht self.assertEqual(f.getvalue(), "FOO") 472*99451b44SJordan Rupprecht 473*99451b44SJordan Rupprecht 474*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 475*99451b44SJordan Rupprecht def test_sbfile_write_borrowed(self): 476*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 477*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True) 478*99451b44SJordan Rupprecht e, n = sbf.Write(b'FOO') 479*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 480*99451b44SJordan Rupprecht self.assertEqual(n, 3) 481*99451b44SJordan Rupprecht sbf.Close() 482*99451b44SJordan Rupprecht self.assertFalse(f.closed) 483*99451b44SJordan Rupprecht f.write('BAR\n') 484*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 485*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), 'FOOBAR') 486*99451b44SJordan Rupprecht 487*99451b44SJordan Rupprecht 488*99451b44SJordan Rupprecht 489*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 490*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 491*99451b44SJordan Rupprecht def test_sbfile_write_forced(self): 492*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 493*99451b44SJordan Rupprecht written = MutableBool(False) 494*99451b44SJordan Rupprecht orig_write = f.write 495*99451b44SJordan Rupprecht def mywrite(x): 496*99451b44SJordan Rupprecht written.set(True) 497*99451b44SJordan Rupprecht return orig_write(x) 498*99451b44SJordan Rupprecht f.write = mywrite 499*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, force_io_methods=True) 500*99451b44SJordan Rupprecht e, n = sbf.Write(b'FOO') 501*99451b44SJordan Rupprecht self.assertTrue(written) 502*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 503*99451b44SJordan Rupprecht self.assertEqual(n, 3) 504*99451b44SJordan Rupprecht sbf.Close() 505*99451b44SJordan Rupprecht self.assertTrue(f.closed) 506*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 507*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), 'FOO') 508*99451b44SJordan Rupprecht 509*99451b44SJordan Rupprecht 510*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 511*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 512*99451b44SJordan Rupprecht def test_sbfile_write_forced_borrowed(self): 513*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 514*99451b44SJordan Rupprecht written = MutableBool(False) 515*99451b44SJordan Rupprecht orig_write = f.write 516*99451b44SJordan Rupprecht def mywrite(x): 517*99451b44SJordan Rupprecht written.set(True) 518*99451b44SJordan Rupprecht return orig_write(x) 519*99451b44SJordan Rupprecht f.write = mywrite 520*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True) 521*99451b44SJordan Rupprecht e, n = sbf.Write(b'FOO') 522*99451b44SJordan Rupprecht self.assertTrue(written) 523*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 524*99451b44SJordan Rupprecht self.assertEqual(n, 3) 525*99451b44SJordan Rupprecht sbf.Close() 526*99451b44SJordan Rupprecht self.assertFalse(f.closed) 527*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 528*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), 'FOO') 529*99451b44SJordan Rupprecht 530*99451b44SJordan Rupprecht 531*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 532*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 533*99451b44SJordan Rupprecht def test_sbfile_write_string(self): 534*99451b44SJordan Rupprecht f = io.StringIO() 535*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 536*99451b44SJordan Rupprecht e, n = sbf.Write(b'FOO') 537*99451b44SJordan Rupprecht self.assertEqual(f.getvalue().strip(), "FOO") 538*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 539*99451b44SJordan Rupprecht self.assertEqual(n, 3) 540*99451b44SJordan Rupprecht sbf.Close() 541*99451b44SJordan Rupprecht self.assertTrue(f.closed) 542*99451b44SJordan Rupprecht 543*99451b44SJordan Rupprecht 544*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 545*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 546*99451b44SJordan Rupprecht def test_string_out(self): 547*99451b44SJordan Rupprecht f = io.StringIO() 548*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(f) 549*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 550*99451b44SJordan Rupprecht self.handleCmd("script 'foobar'") 551*99451b44SJordan Rupprecht self.assertEqual(f.getvalue().strip(), "'foobar'") 552*99451b44SJordan Rupprecht 553*99451b44SJordan Rupprecht 554*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 555*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 556*99451b44SJordan Rupprecht def test_string_error(self): 557*99451b44SJordan Rupprecht f = io.StringIO() 558*99451b44SJordan Rupprecht debugger = self.debugger 559*99451b44SJordan Rupprecht status = debugger.SetErrorFile(f) 560*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 561*99451b44SJordan Rupprecht self.handleCmd('lolwut', check=False, collect_result=False) 562*99451b44SJordan Rupprecht errors = f.getvalue() 563*99451b44SJordan Rupprecht self.assertTrue(re.search(r'error:.*lolwut', errors)) 564*99451b44SJordan Rupprecht 565*99451b44SJordan Rupprecht 566*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 567*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 568*99451b44SJordan Rupprecht def test_sbfile_write_bytes(self): 569*99451b44SJordan Rupprecht f = io.BytesIO() 570*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 571*99451b44SJordan Rupprecht e, n = sbf.Write(b'FOO') 572*99451b44SJordan Rupprecht self.assertEqual(f.getvalue().strip(), b"FOO") 573*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 574*99451b44SJordan Rupprecht self.assertEqual(n, 3) 575*99451b44SJordan Rupprecht sbf.Close() 576*99451b44SJordan Rupprecht self.assertTrue(f.closed) 577*99451b44SJordan Rupprecht 578*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 579*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 580*99451b44SJordan Rupprecht def test_sbfile_read_string(self): 581*99451b44SJordan Rupprecht f = io.StringIO('zork') 582*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 583*99451b44SJordan Rupprecht buf = bytearray(100) 584*99451b44SJordan Rupprecht e, n = sbf.Read(buf) 585*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 586*99451b44SJordan Rupprecht self.assertEqual(buf[:n], b'zork') 587*99451b44SJordan Rupprecht 588*99451b44SJordan Rupprecht 589*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 590*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 591*99451b44SJordan Rupprecht def test_sbfile_read_string_one_byte(self): 592*99451b44SJordan Rupprecht f = io.StringIO('z') 593*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 594*99451b44SJordan Rupprecht buf = bytearray(1) 595*99451b44SJordan Rupprecht e, n = sbf.Read(buf) 596*99451b44SJordan Rupprecht self.assertTrue(e.Fail()) 597*99451b44SJordan Rupprecht self.assertEqual(n, 0) 598*99451b44SJordan Rupprecht self.assertEqual(e.GetCString(), "can't read less than 6 bytes from a utf8 text stream") 599*99451b44SJordan Rupprecht 600*99451b44SJordan Rupprecht 601*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 602*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 603*99451b44SJordan Rupprecht def test_sbfile_read_bytes(self): 604*99451b44SJordan Rupprecht f = io.BytesIO(b'zork') 605*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 606*99451b44SJordan Rupprecht buf = bytearray(100) 607*99451b44SJordan Rupprecht e, n = sbf.Read(buf) 608*99451b44SJordan Rupprecht self.assertTrue(e.Success()) 609*99451b44SJordan Rupprecht self.assertEqual(buf[:n], b'zork') 610*99451b44SJordan Rupprecht 611*99451b44SJordan Rupprecht 612*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 613*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 614*99451b44SJordan Rupprecht def test_sbfile_out(self): 615*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 616*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 617*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(sbf) 618*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 619*99451b44SJordan Rupprecht self.handleCmd('script 2+2') 620*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 621*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), '4') 622*99451b44SJordan Rupprecht 623*99451b44SJordan Rupprecht 624*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 625*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 626*99451b44SJordan Rupprecht def test_file_out(self): 627*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 628*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(f) 629*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 630*99451b44SJordan Rupprecht self.handleCmd('script 2+2') 631*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 632*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), '4') 633*99451b44SJordan Rupprecht 634*99451b44SJordan Rupprecht 635*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 636*99451b44SJordan Rupprecht def test_sbfile_error(self): 637*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 638*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 639*99451b44SJordan Rupprecht status = self.debugger.SetErrorFile(sbf) 640*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 641*99451b44SJordan Rupprecht self.handleCmd('lolwut', check=False, collect_result=False) 642*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 643*99451b44SJordan Rupprecht errors = f.read() 644*99451b44SJordan Rupprecht self.assertTrue(re.search(r'error:.*lolwut', errors)) 645*99451b44SJordan Rupprecht 646*99451b44SJordan Rupprecht 647*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 648*99451b44SJordan Rupprecht def test_file_error(self): 649*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 650*99451b44SJordan Rupprecht status = self.debugger.SetErrorFile(f) 651*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 652*99451b44SJordan Rupprecht self.handleCmd('lolwut', check=False, collect_result=False) 653*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 654*99451b44SJordan Rupprecht errors = f.read() 655*99451b44SJordan Rupprecht self.assertTrue(re.search(r'error:.*lolwut', errors)) 656*99451b44SJordan Rupprecht 657*99451b44SJordan Rupprecht 658*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 659*99451b44SJordan Rupprecht def test_exceptions(self): 660*99451b44SJordan Rupprecht self.assertRaises(Exception, lldb.SBFile, None) 661*99451b44SJordan Rupprecht self.assertRaises(Exception, lldb.SBFile, "ham sandwich") 662*99451b44SJordan Rupprecht if sys.version_info[0] < 3: 663*99451b44SJordan Rupprecht self.assertRaises(Exception, lldb.SBFile, ReallyBadIO()) 664*99451b44SJordan Rupprecht else: 665*99451b44SJordan Rupprecht self.assertRaises(OhNoe, lldb.SBFile, ReallyBadIO()) 666*99451b44SJordan Rupprecht error, n = lldb.SBFile(BadIO()).Write(b"FOO") 667*99451b44SJordan Rupprecht self.assertEqual(n, 0) 668*99451b44SJordan Rupprecht self.assertTrue(error.Fail()) 669*99451b44SJordan Rupprecht self.assertIn('OH NOE', error.GetCString()) 670*99451b44SJordan Rupprecht error, n = lldb.SBFile(BadIO()).Read(bytearray(100)) 671*99451b44SJordan Rupprecht self.assertEqual(n, 0) 672*99451b44SJordan Rupprecht self.assertTrue(error.Fail()) 673*99451b44SJordan Rupprecht self.assertIn('OH NOE', error.GetCString()) 674*99451b44SJordan Rupprecht 675*99451b44SJordan Rupprecht 676*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 677*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 678*99451b44SJordan Rupprecht def test_exceptions_logged(self): 679*99451b44SJordan Rupprecht messages = list() 680*99451b44SJordan Rupprecht self.debugger.SetLoggingCallback(messages.append) 681*99451b44SJordan Rupprecht self.handleCmd('log enable lldb script') 682*99451b44SJordan Rupprecht self.debugger.SetOutputFile(lldb.SBFile(BadIO())) 683*99451b44SJordan Rupprecht self.handleCmd('script 1+1') 684*99451b44SJordan Rupprecht self.assertTrue(any('OH NOE' in msg for msg in messages)) 685*99451b44SJordan Rupprecht 686*99451b44SJordan Rupprecht 687*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 688*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 689*99451b44SJordan Rupprecht def test_flush(self): 690*99451b44SJordan Rupprecht flushed = MutableBool(False) 691*99451b44SJordan Rupprecht closed = MutableBool(False) 692*99451b44SJordan Rupprecht f = FlushTestIO(flushed, closed) 693*99451b44SJordan Rupprecht self.assertFalse(flushed) 694*99451b44SJordan Rupprecht self.assertFalse(closed) 695*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 696*99451b44SJordan Rupprecht self.assertFalse(flushed) 697*99451b44SJordan Rupprecht self.assertFalse(closed) 698*99451b44SJordan Rupprecht sbf = None 699*99451b44SJordan Rupprecht self.assertFalse(flushed) 700*99451b44SJordan Rupprecht self.assertTrue(closed) 701*99451b44SJordan Rupprecht self.assertTrue(f.closed) 702*99451b44SJordan Rupprecht 703*99451b44SJordan Rupprecht flushed = MutableBool(False) 704*99451b44SJordan Rupprecht closed = MutableBool(False) 705*99451b44SJordan Rupprecht f = FlushTestIO(flushed, closed) 706*99451b44SJordan Rupprecht self.assertFalse(flushed) 707*99451b44SJordan Rupprecht self.assertFalse(closed) 708*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True) 709*99451b44SJordan Rupprecht self.assertFalse(flushed) 710*99451b44SJordan Rupprecht self.assertFalse(closed) 711*99451b44SJordan Rupprecht sbf = None 712*99451b44SJordan Rupprecht self.assertTrue(flushed) 713*99451b44SJordan Rupprecht self.assertFalse(closed) 714*99451b44SJordan Rupprecht self.assertFalse(f.closed) 715*99451b44SJordan Rupprecht 716*99451b44SJordan Rupprecht 717*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 718*99451b44SJordan Rupprecht def test_fileno_flush(self): 719*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 720*99451b44SJordan Rupprecht f.write("foo") 721*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 722*99451b44SJordan Rupprecht sbf.Write(b'bar') 723*99451b44SJordan Rupprecht sbf = None 724*99451b44SJordan Rupprecht self.assertTrue(f.closed) 725*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 726*99451b44SJordan Rupprecht self.assertEqual(f.read(), 'foobar') 727*99451b44SJordan Rupprecht 728*99451b44SJordan Rupprecht with open(self.out_filename, 'w+') as f: 729*99451b44SJordan Rupprecht f.write("foo") 730*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True) 731*99451b44SJordan Rupprecht sbf.Write(b'bar') 732*99451b44SJordan Rupprecht sbf = None 733*99451b44SJordan Rupprecht self.assertFalse(f.closed) 734*99451b44SJordan Rupprecht f.seek(0) 735*99451b44SJordan Rupprecht self.assertEqual(f.read(), 'foobar') 736*99451b44SJordan Rupprecht 737*99451b44SJordan Rupprecht 738*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 739*99451b44SJordan Rupprecht def test_close(self): 740*99451b44SJordan Rupprecht debugger = self.debugger 741*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 742*99451b44SJordan Rupprecht status = debugger.SetOutputFile(f) 743*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 744*99451b44SJordan Rupprecht self.handleCmd("help help", check=False, collect_result=False) 745*99451b44SJordan Rupprecht # make sure the file wasn't closed early. 746*99451b44SJordan Rupprecht f.write("\nZAP\n") 747*99451b44SJordan Rupprecht lldb.SBDebugger.Destroy(debugger) 748*99451b44SJordan Rupprecht # check that output file was closed when debugger was destroyed. 749*99451b44SJordan Rupprecht with self.assertRaises(ValueError): 750*99451b44SJordan Rupprecht f.write("\nQUUX\n") 751*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 752*99451b44SJordan Rupprecht output = f.read() 753*99451b44SJordan Rupprecht self.assertTrue(re.search(r'Show a list of all debugger commands', output)) 754*99451b44SJordan Rupprecht self.assertTrue(re.search(r'ZAP', output)) 755*99451b44SJordan Rupprecht 756*99451b44SJordan Rupprecht 757*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 758*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 759*99451b44SJordan Rupprecht def test_stdout(self): 760*99451b44SJordan Rupprecht f = io.StringIO() 761*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(f) 762*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 763*99451b44SJordan Rupprecht self.handleCmd(r"script sys.stdout.write('foobar\n')") 764*99451b44SJordan Rupprecht self.assertEqual(f.getvalue().strip().split(), ["foobar", "7"]) 765*99451b44SJordan Rupprecht 766*99451b44SJordan Rupprecht 767*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 768*99451b44SJordan Rupprecht def test_stdout_file(self): 769*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 770*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(f) 771*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 772*99451b44SJordan Rupprecht self.handleCmd(r"script sys.stdout.write('foobar\n')") 773*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 774*99451b44SJordan Rupprecht # In python2 sys.stdout.write() returns None, which 775*99451b44SJordan Rupprecht # the REPL will ignore, but in python3 it will 776*99451b44SJordan Rupprecht # return the number of bytes written, which the REPL 777*99451b44SJordan Rupprecht # will print out. 778*99451b44SJordan Rupprecht lines = [x for x in f.read().strip().split() if x != "7"] 779*99451b44SJordan Rupprecht self.assertEqual(lines, ["foobar"]) 780*99451b44SJordan Rupprecht 781*99451b44SJordan Rupprecht 782*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 783*99451b44SJordan Rupprecht @skipIf(py_version=['<', (3,)]) 784*99451b44SJordan Rupprecht def test_identity(self): 785*99451b44SJordan Rupprecht 786*99451b44SJordan Rupprecht f = io.StringIO() 787*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 788*99451b44SJordan Rupprecht self.assertTrue(f is sbf.GetFile()) 789*99451b44SJordan Rupprecht sbf.Close() 790*99451b44SJordan Rupprecht self.assertTrue(f.closed) 791*99451b44SJordan Rupprecht 792*99451b44SJordan Rupprecht f = io.StringIO() 793*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True) 794*99451b44SJordan Rupprecht self.assertTrue(f is sbf.GetFile()) 795*99451b44SJordan Rupprecht sbf.Close() 796*99451b44SJordan Rupprecht self.assertFalse(f.closed) 797*99451b44SJordan Rupprecht 798*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 799*99451b44SJordan Rupprecht sbf = lldb.SBFile(f) 800*99451b44SJordan Rupprecht self.assertTrue(f is sbf.GetFile()) 801*99451b44SJordan Rupprecht sbf.Close() 802*99451b44SJordan Rupprecht self.assertTrue(f.closed) 803*99451b44SJordan Rupprecht 804*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 805*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True) 806*99451b44SJordan Rupprecht self.assertFalse(f is sbf.GetFile()) 807*99451b44SJordan Rupprecht sbf.Write(b"foobar\n") 808*99451b44SJordan Rupprecht self.assertEqual(f.fileno(), sbf.GetFile().fileno()) 809*99451b44SJordan Rupprecht sbf.Close() 810*99451b44SJordan Rupprecht self.assertFalse(f.closed) 811*99451b44SJordan Rupprecht 812*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 813*99451b44SJordan Rupprecht self.assertEqual("foobar", f.read().strip()) 814*99451b44SJordan Rupprecht 815*99451b44SJordan Rupprecht with open(self.out_filename, 'wb') as f: 816*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True, force_io_methods=True) 817*99451b44SJordan Rupprecht self.assertTrue(f is sbf.GetFile()) 818*99451b44SJordan Rupprecht sbf.Write(b"foobar\n") 819*99451b44SJordan Rupprecht self.assertEqual(f.fileno(), sbf.GetFile().fileno()) 820*99451b44SJordan Rupprecht sbf.Close() 821*99451b44SJordan Rupprecht self.assertFalse(f.closed) 822*99451b44SJordan Rupprecht 823*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 824*99451b44SJordan Rupprecht self.assertEqual("foobar", f.read().strip()) 825*99451b44SJordan Rupprecht 826*99451b44SJordan Rupprecht with open(self.out_filename, 'wb') as f: 827*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, force_io_methods=True) 828*99451b44SJordan Rupprecht self.assertTrue(f is sbf.GetFile()) 829*99451b44SJordan Rupprecht sbf.Write(b"foobar\n") 830*99451b44SJordan Rupprecht self.assertEqual(f.fileno(), sbf.GetFile().fileno()) 831*99451b44SJordan Rupprecht sbf.Close() 832*99451b44SJordan Rupprecht self.assertTrue(f.closed) 833*99451b44SJordan Rupprecht 834*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 835*99451b44SJordan Rupprecht self.assertEqual("foobar", f.read().strip()) 836*99451b44SJordan Rupprecht 837*99451b44SJordan Rupprecht 838*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 839*99451b44SJordan Rupprecht def test_back_and_forth(self): 840*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 841*99451b44SJordan Rupprecht # at each step here we're borrowing the file, so we have to keep 842*99451b44SJordan Rupprecht # them all alive until the end. 843*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True) 844*99451b44SJordan Rupprecht def i(sbf): 845*99451b44SJordan Rupprecht for i in range(10): 846*99451b44SJordan Rupprecht f = sbf.GetFile() 847*99451b44SJordan Rupprecht self.assertEqual(f.mode, "w") 848*99451b44SJordan Rupprecht yield f 849*99451b44SJordan Rupprecht sbf = lldb.SBFile.Create(f, borrow=True) 850*99451b44SJordan Rupprecht yield sbf 851*99451b44SJordan Rupprecht sbf.Write(str(i).encode('ascii') + b"\n") 852*99451b44SJordan Rupprecht files = list(i(sbf)) 853*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 854*99451b44SJordan Rupprecht self.assertEqual(list(range(10)), list(map(int, f.read().strip().split()))) 855*99451b44SJordan Rupprecht 856*99451b44SJordan Rupprecht 857*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 858*99451b44SJordan Rupprecht def test_set_filehandle_none(self): 859*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetOutputFile, None) 860*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetOutputFile, "ham sandwich") 861*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetOutputFileHandle, "ham sandwich") 862*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetInputFile, None) 863*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetInputFile, "ham sandwich") 864*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetInputFileHandle, "ham sandwich") 865*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetErrorFile, None) 866*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetErrorFile, "ham sandwich") 867*99451b44SJordan Rupprecht self.assertRaises(Exception, self.debugger.SetErrorFileHandle, "ham sandwich") 868*99451b44SJordan Rupprecht 869*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 870*99451b44SJordan Rupprecht status = self.debugger.SetOutputFile(f) 871*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 872*99451b44SJordan Rupprecht status = self.debugger.SetErrorFile(f) 873*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 874*99451b44SJordan Rupprecht self.debugger.SetOutputFileHandle(None, False) 875*99451b44SJordan Rupprecht self.debugger.SetErrorFileHandle(None, False) 876*99451b44SJordan Rupprecht sbf = self.debugger.GetOutputFile() 877*99451b44SJordan Rupprecht if sys.version_info.major >= 3: 878*99451b44SJordan Rupprecht # python 2 lacks PyFile_FromFd, so GetFile() will 879*99451b44SJordan Rupprecht # have to duplicate the file descriptor and make a FILE* 880*99451b44SJordan Rupprecht # in order to convert a NativeFile it back to a python 881*99451b44SJordan Rupprecht # file. 882*99451b44SJordan Rupprecht self.assertEqual(sbf.GetFile().fileno(), 1) 883*99451b44SJordan Rupprecht sbf = self.debugger.GetErrorFile() 884*99451b44SJordan Rupprecht if sys.version_info.major >= 3: 885*99451b44SJordan Rupprecht self.assertEqual(sbf.GetFile().fileno(), 2) 886*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 887*99451b44SJordan Rupprecht status = self.debugger.SetInputFile(f) 888*99451b44SJordan Rupprecht self.assertTrue(status.Success()) 889*99451b44SJordan Rupprecht self.debugger.SetInputFileHandle(None, False) 890*99451b44SJordan Rupprecht sbf = self.debugger.GetInputFile() 891*99451b44SJordan Rupprecht if sys.version_info.major >= 3: 892*99451b44SJordan Rupprecht self.assertEqual(sbf.GetFile().fileno(), 0) 893*99451b44SJordan Rupprecht 894*99451b44SJordan Rupprecht 895*99451b44SJordan Rupprecht @add_test_categories(['pyapi']) 896*99451b44SJordan Rupprecht def test_sbstream(self): 897*99451b44SJordan Rupprecht 898*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 899*99451b44SJordan Rupprecht stream = lldb.SBStream() 900*99451b44SJordan Rupprecht stream.RedirectToFile(f) 901*99451b44SJordan Rupprecht stream.Print("zork") 902*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 903*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), "zork") 904*99451b44SJordan Rupprecht 905*99451b44SJordan Rupprecht with open(self.out_filename, 'w') as f: 906*99451b44SJordan Rupprecht stream = lldb.SBStream() 907*99451b44SJordan Rupprecht stream.RedirectToFileHandle(f, True) 908*99451b44SJordan Rupprecht stream.Print("Yendor") 909*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 910*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), "Yendor") 911*99451b44SJordan Rupprecht 912*99451b44SJordan Rupprecht stream = lldb.SBStream() 913*99451b44SJordan Rupprecht f = open(self.out_filename, 'w') 914*99451b44SJordan Rupprecht stream.RedirectToFile(lldb.SBFile.Create(f, borrow=False)) 915*99451b44SJordan Rupprecht stream.Print("Frobozz") 916*99451b44SJordan Rupprecht stream = None 917*99451b44SJordan Rupprecht self.assertTrue(f.closed) 918*99451b44SJordan Rupprecht with open(self.out_filename, 'r') as f: 919*99451b44SJordan Rupprecht self.assertEqual(f.read().strip(), "Frobozz") 920