1""" 2Test lldb-vscode runInTerminal reverse request 3""" 4 5 6import unittest2 7import vscode 8from lldbsuite.test.decorators import * 9from lldbsuite.test.lldbtest import * 10from lldbsuite.test import lldbutil 11import lldbvscode_testcase 12import time 13import os 14import subprocess 15import shutil 16import json 17from threading import Thread 18 19 20class TestVSCode_runInTerminal(lldbvscode_testcase.VSCodeTestCaseBase): 21 22 mydir = TestBase.compute_mydir(__file__) 23 24 def readPidMessage(self, fifo_file): 25 with open(fifo_file, "r") as file: 26 self.assertIn("pid", file.readline()) 27 28 def sendDidAttachMessage(self, fifo_file): 29 with open(fifo_file, "w") as file: 30 file.write(json.dumps({"kind": "didAttach"}) + "\n") 31 32 def readErrorMessage(self, fifo_file): 33 with open(fifo_file, "r") as file: 34 return file.readline() 35 36 def isTestSupported(self): 37 # For some strange reason, this test fails on python3.6 38 if not (sys.version_info.major == 3 and sys.version_info.minor >= 7): 39 return False 40 try: 41 # We skip this test for debug builds because it takes too long parsing lldb's own 42 # debug info. Release builds are fine. 43 # Checking the size of the lldb-vscode binary seems to be a decent proxy for a quick 44 # detection. It should be far less than 1 MB in Release builds. 45 if os.path.getsize(os.environ["LLDBVSCODE_EXEC"]) < 1000000: 46 return True 47 except: 48 return False 49 50 @skipIfWindows 51 @skipIfRemote 52 @skipIf(archs=no_match(['x86_64'])) 53 def test_runInTerminal(self): 54 if not self.isTestSupported(): 55 return 56 ''' 57 Tests the "runInTerminal" reverse request. It makes sure that the IDE can 58 launch the inferior with the correct environment variables and arguments. 59 ''' 60 program = self.getBuildArtifact("a.out") 61 source = 'main.c' 62 self.build_and_launch( 63 program, stopOnEntry=True, runInTerminal=True, args=["foobar"], 64 env=["FOO=bar"]) 65 66 breakpoint_line = line_number(source, '// breakpoint') 67 68 self.set_source_breakpoints(source, [breakpoint_line]) 69 self.continue_to_next_stop() 70 71 # We verify we actually stopped inside the loop 72 counter = int(self.vscode.get_local_variable_value('counter')) 73 self.assertTrue(counter > 0) 74 75 # We verify we were able to set the launch arguments 76 argc = int(self.vscode.get_local_variable_value('argc')) 77 self.assertEqual(argc, 2) 78 79 argv1 = self.vscode.request_evaluate('argv[1]')['body']['result'] 80 self.assertIn('foobar', argv1) 81 82 # We verify we were able to set the environment 83 env = self.vscode.request_evaluate('foo')['body']['result'] 84 self.assertIn('bar', env) 85 86 @skipIfWindows 87 @skipIfRemote 88 @skipIf(archs=no_match(['x86_64'])) 89 def test_runInTerminalInvalidTarget(self): 90 if not self.isTestSupported(): 91 return 92 self.build_and_create_debug_adaptor() 93 response = self.launch( 94 "INVALIDPROGRAM", stopOnEntry=True, runInTerminal=True, args=["foobar"], env=["FOO=bar"], expectFailure=True) 95 self.assertFalse(response['success']) 96 self.assertIn("Could not create a target for a program 'INVALIDPROGRAM': unable to find executable", 97 response['message']) 98 99 @skipIfWindows 100 @skipIfRemote 101 @skipIf(archs=no_match(['x86_64'])) 102 def test_missingArgInRunInTerminalLauncher(self): 103 if not self.isTestSupported(): 104 return 105 proc = subprocess.run([self.lldbVSCodeExec, "--launch-target", "INVALIDPROGRAM"], 106 capture_output=True, universal_newlines=True) 107 self.assertTrue(proc.returncode != 0) 108 self.assertIn('"--launch-target" requires "--comm-file" to be specified', proc.stderr) 109 110 @skipIfWindows 111 @skipIfRemote 112 @skipIf(archs=no_match(['x86_64'])) 113 def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self): 114 if not self.isTestSupported(): 115 return 116 comm_file = os.path.join(self.getBuildDir(), "comm-file") 117 os.mkfifo(comm_file) 118 119 proc = subprocess.Popen( 120 [self.lldbVSCodeExec, "--comm-file", comm_file, "--launch-target", "INVALIDPROGRAM"], 121 universal_newlines=True, stderr=subprocess.PIPE) 122 123 self.readPidMessage(comm_file) 124 self.sendDidAttachMessage(comm_file) 125 self.assertIn("No such file or directory", self.readErrorMessage(comm_file)) 126 127 _, stderr = proc.communicate() 128 self.assertIn("No such file or directory", stderr) 129 130 @skipIfWindows 131 @skipIfRemote 132 @skipIf(archs=no_match(['x86_64'])) 133 def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self): 134 if not self.isTestSupported(): 135 return 136 comm_file = os.path.join(self.getBuildDir(), "comm-file") 137 os.mkfifo(comm_file) 138 139 proc = subprocess.Popen( 140 [self.lldbVSCodeExec, "--comm-file", comm_file, "--launch-target", "echo", "foo"], 141 universal_newlines=True, stdout=subprocess.PIPE) 142 143 self.readPidMessage(comm_file) 144 self.sendDidAttachMessage(comm_file) 145 146 stdout, _ = proc.communicate() 147 self.assertIn("foo", stdout) 148 149 @skipIfWindows 150 @skipIfRemote 151 @skipIf(archs=no_match(['x86_64'])) 152 def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self): 153 if not self.isTestSupported(): 154 return 155 comm_file = os.path.join(self.getBuildDir(), "comm-file") 156 os.mkfifo(comm_file) 157 158 proc = subprocess.Popen( 159 [self.lldbVSCodeExec, "--comm-file", comm_file, "--launch-target", "env"], 160 universal_newlines=True, stdout=subprocess.PIPE, 161 env={**os.environ, "FOO": "BAR"}) 162 163 self.readPidMessage(comm_file) 164 self.sendDidAttachMessage(comm_file) 165 166 stdout, _ = proc.communicate() 167 self.assertIn("FOO=BAR", stdout) 168 169 @skipIfWindows 170 @skipIfRemote 171 @skipIf(archs=no_match(['x86_64'])) 172 def test_NonAttachedRunInTerminalLauncher(self): 173 if not self.isTestSupported(): 174 return 175 comm_file = os.path.join(self.getBuildDir(), "comm-file") 176 os.mkfifo(comm_file) 177 178 proc = subprocess.Popen( 179 [self.lldbVSCodeExec, "--comm-file", comm_file, "--launch-target", "echo", "foo"], 180 universal_newlines=True, stderr=subprocess.PIPE, 181 env={**os.environ, "LLDB_VSCODE_RIT_TIMEOUT_IN_MS": "1000"}) 182 183 self.readPidMessage(comm_file) 184 185 _, stderr = proc.communicate() 186 self.assertIn("Timed out trying to get messages from the debug adaptor", stderr) 187