1132e57bcSWalter Erquinigo""" 2132e57bcSWalter ErquinigoTest lldb-vscode runInTerminal reverse request 3132e57bcSWalter Erquinigo""" 4132e57bcSWalter Erquinigo 5132e57bcSWalter Erquinigo 6132e57bcSWalter Erquinigoimport unittest2 7132e57bcSWalter Erquinigoimport vscode 8132e57bcSWalter Erquinigofrom lldbsuite.test.decorators import * 9132e57bcSWalter Erquinigofrom lldbsuite.test.lldbtest import * 10132e57bcSWalter Erquinigofrom lldbsuite.test import lldbutil 11132e57bcSWalter Erquinigoimport lldbvscode_testcase 12132e57bcSWalter Erquinigoimport time 13132e57bcSWalter Erquinigoimport os 140f0462caSWalter Erquinigoimport subprocess 150f0462caSWalter Erquinigoimport shutil 160f0462caSWalter Erquinigoimport json 170f0462caSWalter Erquinigofrom threading import Thread 18132e57bcSWalter Erquinigo 19132e57bcSWalter Erquinigo 20132e57bcSWalter Erquinigoclass TestVSCode_runInTerminal(lldbvscode_testcase.VSCodeTestCaseBase): 21132e57bcSWalter Erquinigo 220f0462caSWalter Erquinigo def readPidMessage(self, fifo_file): 230f0462caSWalter Erquinigo with open(fifo_file, "r") as file: 240f0462caSWalter Erquinigo self.assertIn("pid", file.readline()) 250f0462caSWalter Erquinigo 260f0462caSWalter Erquinigo def sendDidAttachMessage(self, fifo_file): 270f0462caSWalter Erquinigo with open(fifo_file, "w") as file: 280f0462caSWalter Erquinigo file.write(json.dumps({"kind": "didAttach"}) + "\n") 290f0462caSWalter Erquinigo 300f0462caSWalter Erquinigo def readErrorMessage(self, fifo_file): 310f0462caSWalter Erquinigo with open(fifo_file, "r") as file: 320f0462caSWalter Erquinigo return file.readline() 330f0462caSWalter Erquinigo 34*ab5591e1SWalter Erquinigo def isTestSupported(self): 35*ab5591e1SWalter Erquinigo # For some strange reason, this test fails on python3.6 36*ab5591e1SWalter Erquinigo if not (sys.version_info.major == 3 and sys.version_info.minor >= 7): 37*ab5591e1SWalter Erquinigo return False 38*ab5591e1SWalter Erquinigo try: 39*ab5591e1SWalter Erquinigo # We skip this test for debug builds because it takes too long parsing lldb's own 40*ab5591e1SWalter Erquinigo # debug info. Release builds are fine. 41*ab5591e1SWalter Erquinigo # Checking the size of the lldb-vscode binary seems to be a decent proxy for a quick 42*ab5591e1SWalter Erquinigo # detection. It should be far less than 1 MB in Release builds. 43*ab5591e1SWalter Erquinigo if os.path.getsize(os.environ["LLDBVSCODE_EXEC"]) < 1000000: 44*ab5591e1SWalter Erquinigo return True 45*ab5591e1SWalter Erquinigo except: 46*ab5591e1SWalter Erquinigo return False 47*ab5591e1SWalter Erquinigo 480f0462caSWalter Erquinigo @skipIfWindows 49132e57bcSWalter Erquinigo @skipIfRemote 5012049d88SWalter Erquinigo @skipIf(archs=no_match(['x86_64'])) 51132e57bcSWalter Erquinigo def test_runInTerminal(self): 52*ab5591e1SWalter Erquinigo if not self.isTestSupported(): 53*ab5591e1SWalter Erquinigo return 54132e57bcSWalter Erquinigo ''' 55132e57bcSWalter Erquinigo Tests the "runInTerminal" reverse request. It makes sure that the IDE can 56132e57bcSWalter Erquinigo launch the inferior with the correct environment variables and arguments. 57132e57bcSWalter Erquinigo ''' 58132e57bcSWalter Erquinigo program = self.getBuildArtifact("a.out") 59132e57bcSWalter Erquinigo source = 'main.c' 600f0462caSWalter Erquinigo self.build_and_launch( 610f0462caSWalter Erquinigo program, stopOnEntry=True, runInTerminal=True, args=["foobar"], 620f0462caSWalter Erquinigo env=["FOO=bar"]) 630f0462caSWalter Erquinigo 64132e57bcSWalter Erquinigo breakpoint_line = line_number(source, '// breakpoint') 65132e57bcSWalter Erquinigo 66132e57bcSWalter Erquinigo self.set_source_breakpoints(source, [breakpoint_line]) 67132e57bcSWalter Erquinigo self.continue_to_next_stop() 68132e57bcSWalter Erquinigo 69132e57bcSWalter Erquinigo # We verify we actually stopped inside the loop 70132e57bcSWalter Erquinigo counter = int(self.vscode.get_local_variable_value('counter')) 71132e57bcSWalter Erquinigo self.assertTrue(counter > 0) 72132e57bcSWalter Erquinigo 73132e57bcSWalter Erquinigo # We verify we were able to set the launch arguments 74132e57bcSWalter Erquinigo argc = int(self.vscode.get_local_variable_value('argc')) 75132e57bcSWalter Erquinigo self.assertEqual(argc, 2) 76132e57bcSWalter Erquinigo 77132e57bcSWalter Erquinigo argv1 = self.vscode.request_evaluate('argv[1]')['body']['result'] 78132e57bcSWalter Erquinigo self.assertIn('foobar', argv1) 79132e57bcSWalter Erquinigo 80132e57bcSWalter Erquinigo # We verify we were able to set the environment 81132e57bcSWalter Erquinigo env = self.vscode.request_evaluate('foo')['body']['result'] 82132e57bcSWalter Erquinigo self.assertIn('bar', env) 830f0462caSWalter Erquinigo 840f0462caSWalter Erquinigo @skipIfWindows 850f0462caSWalter Erquinigo @skipIfRemote 8650337fb9SWalter Erquinigo @skipIf(archs=no_match(['x86_64'])) 870f0462caSWalter Erquinigo def test_runInTerminalInvalidTarget(self): 88*ab5591e1SWalter Erquinigo if not self.isTestSupported(): 89*ab5591e1SWalter Erquinigo return 900f0462caSWalter Erquinigo self.build_and_create_debug_adaptor() 910f0462caSWalter Erquinigo response = self.launch( 920f0462caSWalter Erquinigo "INVALIDPROGRAM", stopOnEntry=True, runInTerminal=True, args=["foobar"], env=["FOO=bar"], expectFailure=True) 930f0462caSWalter Erquinigo self.assertFalse(response['success']) 940f0462caSWalter Erquinigo self.assertIn("Could not create a target for a program 'INVALIDPROGRAM': unable to find executable", 950f0462caSWalter Erquinigo response['message']) 960f0462caSWalter Erquinigo 970f0462caSWalter Erquinigo @skipIfWindows 980f0462caSWalter Erquinigo @skipIfRemote 9950337fb9SWalter Erquinigo @skipIf(archs=no_match(['x86_64'])) 1000f0462caSWalter Erquinigo def test_missingArgInRunInTerminalLauncher(self): 101*ab5591e1SWalter Erquinigo if not self.isTestSupported(): 102*ab5591e1SWalter Erquinigo return 1030f0462caSWalter Erquinigo proc = subprocess.run([self.lldbVSCodeExec, "--launch-target", "INVALIDPROGRAM"], 1040f0462caSWalter Erquinigo capture_output=True, universal_newlines=True) 1050f0462caSWalter Erquinigo self.assertTrue(proc.returncode != 0) 1060f0462caSWalter Erquinigo self.assertIn('"--launch-target" requires "--comm-file" to be specified', proc.stderr) 1070f0462caSWalter Erquinigo 1080f0462caSWalter Erquinigo @skipIfWindows 1090f0462caSWalter Erquinigo @skipIfRemote 11050337fb9SWalter Erquinigo @skipIf(archs=no_match(['x86_64'])) 1110f0462caSWalter Erquinigo def test_FakeAttachedRunInTerminalLauncherWithInvalidProgram(self): 112*ab5591e1SWalter Erquinigo if not self.isTestSupported(): 113*ab5591e1SWalter Erquinigo return 1140f0462caSWalter Erquinigo comm_file = os.path.join(self.getBuildDir(), "comm-file") 1150f0462caSWalter Erquinigo os.mkfifo(comm_file) 1160f0462caSWalter Erquinigo 1170f0462caSWalter Erquinigo proc = subprocess.Popen( 1180f0462caSWalter Erquinigo [self.lldbVSCodeExec, "--comm-file", comm_file, "--launch-target", "INVALIDPROGRAM"], 1190f0462caSWalter Erquinigo universal_newlines=True, stderr=subprocess.PIPE) 1200f0462caSWalter Erquinigo 1210f0462caSWalter Erquinigo self.readPidMessage(comm_file) 1220f0462caSWalter Erquinigo self.sendDidAttachMessage(comm_file) 1230f0462caSWalter Erquinigo self.assertIn("No such file or directory", self.readErrorMessage(comm_file)) 1240f0462caSWalter Erquinigo 1250f0462caSWalter Erquinigo _, stderr = proc.communicate() 1260f0462caSWalter Erquinigo self.assertIn("No such file or directory", stderr) 1270f0462caSWalter Erquinigo 1280f0462caSWalter Erquinigo @skipIfWindows 1290f0462caSWalter Erquinigo @skipIfRemote 13050337fb9SWalter Erquinigo @skipIf(archs=no_match(['x86_64'])) 1310f0462caSWalter Erquinigo def test_FakeAttachedRunInTerminalLauncherWithValidProgram(self): 132*ab5591e1SWalter Erquinigo if not self.isTestSupported(): 133*ab5591e1SWalter Erquinigo return 1340f0462caSWalter Erquinigo comm_file = os.path.join(self.getBuildDir(), "comm-file") 1350f0462caSWalter Erquinigo os.mkfifo(comm_file) 1360f0462caSWalter Erquinigo 1370f0462caSWalter Erquinigo proc = subprocess.Popen( 1380f0462caSWalter Erquinigo [self.lldbVSCodeExec, "--comm-file", comm_file, "--launch-target", "echo", "foo"], 1390f0462caSWalter Erquinigo universal_newlines=True, stdout=subprocess.PIPE) 1400f0462caSWalter Erquinigo 1410f0462caSWalter Erquinigo self.readPidMessage(comm_file) 1420f0462caSWalter Erquinigo self.sendDidAttachMessage(comm_file) 1430f0462caSWalter Erquinigo 1440f0462caSWalter Erquinigo stdout, _ = proc.communicate() 1450f0462caSWalter Erquinigo self.assertIn("foo", stdout) 1460f0462caSWalter Erquinigo 1470f0462caSWalter Erquinigo @skipIfWindows 1480f0462caSWalter Erquinigo @skipIfRemote 14950337fb9SWalter Erquinigo @skipIf(archs=no_match(['x86_64'])) 1500f0462caSWalter Erquinigo def test_FakeAttachedRunInTerminalLauncherAndCheckEnvironment(self): 151*ab5591e1SWalter Erquinigo if not self.isTestSupported(): 152*ab5591e1SWalter Erquinigo return 1530f0462caSWalter Erquinigo comm_file = os.path.join(self.getBuildDir(), "comm-file") 1540f0462caSWalter Erquinigo os.mkfifo(comm_file) 1550f0462caSWalter Erquinigo 1560f0462caSWalter Erquinigo proc = subprocess.Popen( 1570f0462caSWalter Erquinigo [self.lldbVSCodeExec, "--comm-file", comm_file, "--launch-target", "env"], 1580f0462caSWalter Erquinigo universal_newlines=True, stdout=subprocess.PIPE, 1590f0462caSWalter Erquinigo env={**os.environ, "FOO": "BAR"}) 1600f0462caSWalter Erquinigo 1610f0462caSWalter Erquinigo self.readPidMessage(comm_file) 1620f0462caSWalter Erquinigo self.sendDidAttachMessage(comm_file) 1630f0462caSWalter Erquinigo 1640f0462caSWalter Erquinigo stdout, _ = proc.communicate() 1650f0462caSWalter Erquinigo self.assertIn("FOO=BAR", stdout) 1660f0462caSWalter Erquinigo 1670f0462caSWalter Erquinigo @skipIfWindows 1680f0462caSWalter Erquinigo @skipIfRemote 16950337fb9SWalter Erquinigo @skipIf(archs=no_match(['x86_64'])) 1700f0462caSWalter Erquinigo def test_NonAttachedRunInTerminalLauncher(self): 171*ab5591e1SWalter Erquinigo if not self.isTestSupported(): 172*ab5591e1SWalter Erquinigo return 1730f0462caSWalter Erquinigo comm_file = os.path.join(self.getBuildDir(), "comm-file") 1740f0462caSWalter Erquinigo os.mkfifo(comm_file) 1750f0462caSWalter Erquinigo 1760f0462caSWalter Erquinigo proc = subprocess.Popen( 1770f0462caSWalter Erquinigo [self.lldbVSCodeExec, "--comm-file", comm_file, "--launch-target", "echo", "foo"], 1780f0462caSWalter Erquinigo universal_newlines=True, stderr=subprocess.PIPE, 1790f0462caSWalter Erquinigo env={**os.environ, "LLDB_VSCODE_RIT_TIMEOUT_IN_MS": "1000"}) 1800f0462caSWalter Erquinigo 1810f0462caSWalter Erquinigo self.readPidMessage(comm_file) 1820f0462caSWalter Erquinigo 1830f0462caSWalter Erquinigo _, stderr = proc.communicate() 1840f0462caSWalter Erquinigo self.assertIn("Timed out trying to get messages from the debug adaptor", stderr) 185