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