TestRunner.py revision b35a1733607b07f36c3617932b67debb375a15c5
1b35a1733607b07f36c3617932b67debb375a15c5Daniel Dunbarfrom __future__ import absolute_import 2be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbarimport os, signal, subprocess, sys 3be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbarimport StringIO 4be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 558c661ced16cd07c796bc867b1db0997c15db69fDaniel Dunbarimport platform 65a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbarimport tempfile 758c661ced16cd07c796bc867b1db0997c15db69fDaniel Dunbar 818d49877530c04dd63578e6d9d0a1d3b6955502bDavid Greeneimport re 9b35a1733607b07f36c3617932b67debb375a15c5Daniel Dunbarimport lit.ShUtil as ShUtil 10b35a1733607b07f36c3617932b67debb375a15c5Daniel Dunbarimport lit.Test as Test 11b35a1733607b07f36c3617932b67debb375a15c5Daniel Dunbarimport lit.Util as Util 1218d49877530c04dd63578e6d9d0a1d3b6955502bDavid Greene 136bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbarclass InternalShellError(Exception): 146bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar def __init__(self, command, message): 156bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar self.command = command 166bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar self.message = message 176bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar 18f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel DunbarkIsWindows = platform.system() == 'Windows' 19f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar 2058c661ced16cd07c796bc867b1db0997c15db69fDaniel Dunbar# Don't use close_fds on Windows. 21f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel DunbarkUseCloseFDs = not kIsWindows 226efba21342b15d7dc3185462868a606234e064f1Daniel Dunbar 236efba21342b15d7dc3185462868a606234e064f1Daniel Dunbar# Use temporary files to replace /dev/null on Windows. 24f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel DunbarkAvoidDevNull = kIsWindows 256efba21342b15d7dc3185462868a606234e064f1Daniel Dunbar 26be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbardef executeCommand(command, cwd=None, env=None): 27b1a464279623768a3d04ff6726c99dce35d2f360Daniel Dunbar # Close extra file handles on UNIX (on Windows this cannot be done while 28b1a464279623768a3d04ff6726c99dce35d2f360Daniel Dunbar # also redirecting input). 29b1a464279623768a3d04ff6726c99dce35d2f360Daniel Dunbar close_fds = not kIsWindows 30b1a464279623768a3d04ff6726c99dce35d2f360Daniel Dunbar 31be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar p = subprocess.Popen(command, cwd=cwd, 32be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stdin=subprocess.PIPE, 33be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stdout=subprocess.PIPE, 34be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stderr=subprocess.PIPE, 35b1a464279623768a3d04ff6726c99dce35d2f360Daniel Dunbar env=env, close_fds=close_fds) 36be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out,err = p.communicate() 37be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar exitCode = p.wait() 38be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 39be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Detect Ctrl-C in subprocess. 40be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if exitCode == -signal.SIGINT: 41be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar raise KeyboardInterrupt 42be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 43be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return out, err, exitCode 44be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 45be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbardef executeShCmd(cmd, cfg, cwd, results): 46be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if isinstance(cmd, ShUtil.Seq): 47be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if cmd.op == ';': 48be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar res = executeShCmd(cmd.lhs, cfg, cwd, results) 49be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return executeShCmd(cmd.rhs, cfg, cwd, results) 50be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 51be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if cmd.op == '&': 52a80ae9c71c361e0569af66b9885a15c3877c6c2dDaniel Dunbar raise InternalShellError(cmd,"unsupported shell operator: '&'") 53be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 54be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if cmd.op == '||': 55be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar res = executeShCmd(cmd.lhs, cfg, cwd, results) 56be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if res != 0: 57be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar res = executeShCmd(cmd.rhs, cfg, cwd, results) 58be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return res 59a80ae9c71c361e0569af66b9885a15c3877c6c2dDaniel Dunbar 60be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if cmd.op == '&&': 61be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar res = executeShCmd(cmd.lhs, cfg, cwd, results) 62be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if res is None: 63be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return res 64be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 65be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if res == 0: 66be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar res = executeShCmd(cmd.rhs, cfg, cwd, results) 67be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return res 68be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 6926e0af54c2eb3efe468715edada97442e469bb19Daniel Dunbar raise ValueError('Unknown shell command: %r' % cmd.op) 70be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 71be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar assert isinstance(cmd, ShUtil.Pipeline) 72be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar procs = [] 73be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar input = subprocess.PIPE 745a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar stderrTempFiles = [] 75c3681d334af978e066c4fdbfcadda492585ef338Daniel Dunbar opened_files = [] 761befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar named_temp_files = [] 775a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # To avoid deadlock, we use a single stderr stream for piped 785a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # output. This is null until we have seen some output using 795a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # stderr. 805a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar for i,j in enumerate(cmd.commands): 81f1a26cf9df900101b9cbea42b67f7466edc7deedEli Bendersky # Apply the redirections, we use (N,) as a sentinel to indicate stdin, 82a3f85d206a4b9f717d4dd9b53cdc280e9105c70fDaniel Dunbar # stdout, stderr for N equal to 0, 1, or 2 respectively. Redirects to or 83a3f85d206a4b9f717d4dd9b53cdc280e9105c70fDaniel Dunbar # from a file are represented with a list [file, mode, file-object] 84a3f85d206a4b9f717d4dd9b53cdc280e9105c70fDaniel Dunbar # where file-object is initially None. 85be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar redirects = [(0,), (1,), (2,)] 86be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar for r in j.redirects: 87be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if r[0] == ('>',2): 88be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar redirects[2] = [r[1], 'w', None] 89a3f85d206a4b9f717d4dd9b53cdc280e9105c70fDaniel Dunbar elif r[0] == ('>>',2): 90a3f85d206a4b9f717d4dd9b53cdc280e9105c70fDaniel Dunbar redirects[2] = [r[1], 'a', None] 91be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif r[0] == ('>&',2) and r[1] in '012': 92be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar redirects[2] = redirects[int(r[1])] 93be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif r[0] == ('>&',) or r[0] == ('&>',): 94be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar redirects[1] = redirects[2] = [r[1], 'w', None] 95be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif r[0] == ('>',): 96be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar redirects[1] = [r[1], 'w', None] 97a3f85d206a4b9f717d4dd9b53cdc280e9105c70fDaniel Dunbar elif r[0] == ('>>',): 98a3f85d206a4b9f717d4dd9b53cdc280e9105c70fDaniel Dunbar redirects[1] = [r[1], 'a', None] 99be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif r[0] == ('<',): 100be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar redirects[0] = [r[1], 'r', None] 101be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 102a80ae9c71c361e0569af66b9885a15c3877c6c2dDaniel Dunbar raise InternalShellError(j,"Unsupported redirect: %r" % (r,)) 103be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 104a3f85d206a4b9f717d4dd9b53cdc280e9105c70fDaniel Dunbar # Map from the final redirections to something subprocess can handle. 105be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar final_redirects = [] 106be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar for index,r in enumerate(redirects): 107be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if r == (0,): 108be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar result = input 109be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif r == (1,): 110be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if index == 0: 111a80ae9c71c361e0569af66b9885a15c3877c6c2dDaniel Dunbar raise InternalShellError(j,"Unsupported redirect for stdin") 112be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif index == 1: 113be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar result = subprocess.PIPE 114be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 115be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar result = subprocess.STDOUT 116be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif r == (2,): 117be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if index != 2: 118a80ae9c71c361e0569af66b9885a15c3877c6c2dDaniel Dunbar raise InternalShellError(j,"Unsupported redirect on stdout") 119be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar result = subprocess.PIPE 120be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 121be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if r[2] is None: 1226efba21342b15d7dc3185462868a606234e064f1Daniel Dunbar if kAvoidDevNull and r[0] == '/dev/null': 1236efba21342b15d7dc3185462868a606234e064f1Daniel Dunbar r[2] = tempfile.TemporaryFile(mode=r[1]) 1246efba21342b15d7dc3185462868a606234e064f1Daniel Dunbar else: 1256efba21342b15d7dc3185462868a606234e064f1Daniel Dunbar r[2] = open(r[0], r[1]) 126474f0df3ac86691fc2aaa201cacc7b5d0005d236Daniel Dunbar # Workaround a Win32 and/or subprocess bug when appending. 127e09ccab0ce2986d1ba6950f2eccc46fd1935ae68Daniel Dunbar # 128e09ccab0ce2986d1ba6950f2eccc46fd1935ae68Daniel Dunbar # FIXME: Actually, this is probably an instance of PR6753. 129474f0df3ac86691fc2aaa201cacc7b5d0005d236Daniel Dunbar if r[1] == 'a': 130bf477df346b12ae5f6e7af165862575c15905e20Daniel Dunbar r[2].seek(0, 2) 1319fae6ee6af42b7aca361deb478a212f573a0cd60NAKAMURA Takumi opened_files.append(r[2]) 132be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar result = r[2] 133be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar final_redirects.append(result) 134be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 135be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stdin, stdout, stderr = final_redirects 136be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 137be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # If stderr wants to come from stdout, but stdout isn't a pipe, then put 138be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # stderr on a pipe and treat it as stdout. 139be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if (stderr == subprocess.STDOUT and stdout != subprocess.PIPE): 140be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stderr = subprocess.PIPE 141be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stderrIsStdout = True 142be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 143be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stderrIsStdout = False 1446bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar 1455a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # Don't allow stderr on a PIPE except for the last 1465a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # process, this could deadlock. 1475a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # 1485a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # FIXME: This is slow, but so is deadlock. 1495a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar if stderr == subprocess.PIPE and j != cmd.commands[-1]: 1505a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar stderr = tempfile.TemporaryFile(mode='w+b') 1515a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar stderrTempFiles.append((i, stderr)) 1525a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar 1536bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar # Resolve the executable path ourselves. 1546bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar args = list(j.args) 1556bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar args[0] = Util.which(args[0], cfg.environment['PATH']) 1566bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar if not args[0]: 1576bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar raise InternalShellError(j, '%r: command not found' % j.args[0]) 1586bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar 1591befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar # Replace uses of /dev/null with temporary files. 1601befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar if kAvoidDevNull: 1611befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar for i,arg in enumerate(args): 1621befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar if arg == "/dev/null": 1631befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar f = tempfile.NamedTemporaryFile(delete=False) 1641befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar f.close() 1651befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar named_temp_files.append(f.name) 1661befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar args[i] = f.name 1671befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar 1684b78aa3f56e6dae484f1282cef4ff5237f10f9d8Daniel Dunbar procs.append(subprocess.Popen(args, cwd=cwd, 169be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stdin = stdin, 170be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stdout = stdout, 171be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar stderr = stderr, 172be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar env = cfg.environment, 17358c661ced16cd07c796bc867b1db0997c15db69fDaniel Dunbar close_fds = kUseCloseFDs)) 174be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 175be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Immediately close stdin for any process taking stdin from us. 176be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if stdin == subprocess.PIPE: 177be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar procs[-1].stdin.close() 178be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar procs[-1].stdin = None 179be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 180be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Update the current stdin source. 181be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if stdout == subprocess.PIPE: 182be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar input = procs[-1].stdout 183be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif stderrIsStdout: 184be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar input = procs[-1].stderr 185be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 186be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar input = subprocess.PIPE 187be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 18869c4cbe9e878e49aa87d322c63afd809588f4cd7Daniel Dunbar # Explicitly close any redirected files. We need to do this now because we 18969c4cbe9e878e49aa87d322c63afd809588f4cd7Daniel Dunbar # need to release any handles we may have on the temporary files (important 19069c4cbe9e878e49aa87d322c63afd809588f4cd7Daniel Dunbar # on Win32, for example). Since we have already spawned the subprocess, our 19169c4cbe9e878e49aa87d322c63afd809588f4cd7Daniel Dunbar # handles have already been transferred so we do not need them anymore. 19269c4cbe9e878e49aa87d322c63afd809588f4cd7Daniel Dunbar for f in opened_files: 1939fae6ee6af42b7aca361deb478a212f573a0cd60NAKAMURA Takumi f.close() 19469c4cbe9e878e49aa87d322c63afd809588f4cd7Daniel Dunbar 1955a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # FIXME: There is probably still deadlock potential here. Yawn. 196be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar procData = [None] * len(procs) 197be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar procData[-1] = procs[-1].communicate() 1985a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar 199be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar for i in range(len(procs) - 1): 200be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if procs[i].stdout is not None: 201be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out = procs[i].stdout.read() 202be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 203be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out = '' 204be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if procs[i].stderr is not None: 205be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar err = procs[i].stderr.read() 206be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 207be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar err = '' 208be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar procData[i] = (out,err) 209c3681d334af978e066c4fdbfcadda492585ef338Daniel Dunbar 2105a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar # Read stderr out of the temp files. 2115a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar for i,f in stderrTempFiles: 2125a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar f.seek(0, 0) 2135a461dd513dddaec6fd30196cb8f8680659a6e0dDaniel Dunbar procData[i] = (procData[i][0], f.read()) 214be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 215be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar exitCode = None 216be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar for i,(out,err) in enumerate(procData): 217be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar res = procs[i].wait() 218be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Detect Ctrl-C in subprocess. 219be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if res == -signal.SIGINT: 220be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar raise KeyboardInterrupt 221be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 222be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar results.append((cmd.commands[i], out, err, res)) 223be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if cmd.pipe_err: 224be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Python treats the exit code as a signed char. 225be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if res < 0: 226be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar exitCode = min(exitCode, res) 227be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 228be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar exitCode = max(exitCode, res) 229be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 230be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar exitCode = res 231be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 2321befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar # Remove any named temporary files we created. 2331befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar for f in named_temp_files: 2349fae6ee6af42b7aca361deb478a212f573a0cd60NAKAMURA Takumi try: 2359fae6ee6af42b7aca361deb478a212f573a0cd60NAKAMURA Takumi os.remove(f) 2369fae6ee6af42b7aca361deb478a212f573a0cd60NAKAMURA Takumi except OSError: 2379fae6ee6af42b7aca361deb478a212f573a0cd60NAKAMURA Takumi pass 2381befb9b2df7b287872021518cedce4a0aeca3b95Daniel Dunbar 239be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if cmd.negate: 240be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar exitCode = not exitCode 241be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 242be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return exitCode 243be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 244be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbardef executeScriptInternal(test, litConfig, tmpBase, commands, cwd): 24500fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith cmds = [] 24600fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith for ln in commands: 24700fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith try: 248c1bb2d432501dabdfcb1e78eccfb7377664c4d14Rafael Espindola cmds.append(ShUtil.ShParser(ln, litConfig.isWindows, 249c1bb2d432501dabdfcb1e78eccfb7377664c4d14Rafael Espindola test.config.pipefail).parse()) 25000fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith except: 25100fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith return (Test.FAIL, "shell parser error on: %r" % ln) 25200fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith 25300fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith cmd = cmds[0] 25400fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith for c in cmds[1:]: 25500fb9c429e4400f3daeb87e6fad9498d4c73862aRichard Smith cmd = ShUtil.Seq(cmd, '&&', c) 256be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 257be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar results = [] 2586bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar try: 2596bd2b2e9a27df118951d2fdc88df249d56a4d8feDaniel Dunbar exitCode = executeShCmd(cmd, test.config, cwd, results) 2602e60c882bf989207ad3b33685b2353f62ff3ecd4Daniel Dunbar except InternalShellError: 2612e60c882bf989207ad3b33685b2353f62ff3ecd4Daniel Dunbar e = sys.exc_info()[1] 262b62fb4ba5cf61070486287da393ada566b4ad4edDaniel Dunbar exitCode = 127 263b62fb4ba5cf61070486287da393ada566b4ad4edDaniel Dunbar results.append((e.command, '', e.message, exitCode)) 264be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 265be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out = err = '' 266be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar for i,(cmd, cmd_out,cmd_err,res) in enumerate(results): 267be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out += 'Command %d: %s\n' % (i, ' '.join('"%s"' % s for s in cmd.args)) 268be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out += 'Command %d Result: %r\n' % (i, res) 269be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out += 'Command %d Output:\n%s\n\n' % (i, cmd_out) 270be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out += 'Command %d Stderr:\n%s\n\n' % (i, cmd_err) 271be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 272be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return out, err, exitCode 273be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 274be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbardef executeScript(test, litConfig, tmpBase, commands, cwd): 2759869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi bashPath = litConfig.getBashPath(); 2769869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi isWin32CMDEXE = (litConfig.isWindows and not bashPath) 277be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar script = tmpBase + '.script' 2789869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi if isWin32CMDEXE: 279be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar script += '.bat' 280be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 281be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Write script file 2828755ae8c69ca522a9931aab4b4951443b2f64d26Reid Kleckner mode = 'w' 2838755ae8c69ca522a9931aab4b4951443b2f64d26Reid Kleckner if litConfig.isWindows and not isWin32CMDEXE: 2848755ae8c69ca522a9931aab4b4951443b2f64d26Reid Kleckner mode += 'b' # Avoid CRLFs when writing bash scripts. 2858755ae8c69ca522a9931aab4b4951443b2f64d26Reid Kleckner f = open(script, mode) 2869869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi if isWin32CMDEXE: 287be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar f.write('\nif %ERRORLEVEL% NEQ 0 EXIT\n'.join(commands)) 288be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 289c1bb2d432501dabdfcb1e78eccfb7377664c4d14Rafael Espindola if test.config.pipefail: 290c1bb2d432501dabdfcb1e78eccfb7377664c4d14Rafael Espindola f.write('set -o pipefail;') 291c15e5b0a0dbdaf8612bdcbba1deedcb77bed1045Richard Smith f.write('{ ' + '; } &&\n{ '.join(commands) + '; }') 292be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar f.write('\n') 293be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar f.close() 294be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 2959869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi if isWin32CMDEXE: 296be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar command = ['cmd','/c', script] 297be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 2989869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi if bashPath: 2999869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi command = [bashPath, script] 3009869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi else: 3019869c2f71744821d77fca2d0596cd9f27f84c5d2NAKAMURA Takumi command = ['/bin/sh', script] 302be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if litConfig.useValgrind: 303be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # FIXME: Running valgrind on sh is overkill. We probably could just 304be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # run on clang with no real loss. 30532989deb9641cf3878686b5634311a7a125f8f02Jeffrey Yasskin command = litConfig.valgrindArgs + command 306be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 307be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return executeCommand(command, cwd=cwd, env=test.config.environment) 308be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 309f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbardef isExpectedFail(test, xfails): 310f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar # Check if any of the xfails match an available feature or the target. 31142543b7b736c9304b4877148943ff8a5fee3c22bDaniel Dunbar for item in xfails: 312f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar # If this is the wildcard, it always fails. 313f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar if item == '*': 31444a83f092029fa76bce05ff0c0598afc55215767Daniel Dunbar return True 31544a83f092029fa76bce05ff0c0598afc55215767Daniel Dunbar 316f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar # If this is an exact match for one of the features, it fails. 317f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar if item in test.config.available_features: 318f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar return True 31942543b7b736c9304b4877148943ff8a5fee3c22bDaniel Dunbar 320f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar # If this is a part of the target triple, it fails. 321f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar if item in test.suite.config.target_triple: 322f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar return True 32342543b7b736c9304b4877148943ff8a5fee3c22bDaniel Dunbar 324f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar return False 32542543b7b736c9304b4877148943ff8a5fee3c22bDaniel Dunbar 3262d4a5bf817ba0d85ddeb34a3c7fc2bc07fda32bdDaniel Dunbardef parseIntegratedTestScript(test, normalize_slashes=False, 3272d4a5bf817ba0d85ddeb34a3c7fc2bc07fda32bdDaniel Dunbar extra_substitutions=[]): 328be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar """parseIntegratedTestScript - Scan an LLVM/Clang style integrated test 329f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar script and extract the lines to 'RUN' as well as 'XFAIL' and 'REQUIRES' 330be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar information. The RUN lines also will have variable substitution performed. 331be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar """ 332be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 333be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Get the temporary location, this is always relative to the test suite 334be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # root, not test source root. 335be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # 336be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # FIXME: This should not be here? 337be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar sourcepath = test.getSourcePath() 338f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar sourcedir = os.path.dirname(sourcepath) 339be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar execpath = test.getExecPath() 340be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar execdir,execbase = os.path.split(execpath) 3410f9d34c71d4f4ea83912c45f99ed286557ea189cDouglas Gregor tmpDir = os.path.join(execdir, 'Output') 3420f9d34c71d4f4ea83912c45f99ed286557ea189cDouglas Gregor tmpBase = os.path.join(tmpDir, execbase) 34340c67b5832877935a555fc63bfaa735332c79700Daniel Dunbar if test.index is not None: 34440c67b5832877935a555fc63bfaa735332c79700Daniel Dunbar tmpBase += '_%d' % test.index 345be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 346f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar # Normalize slashes, if requested. 347f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar if normalize_slashes: 348f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar sourcepath = sourcepath.replace('\\', '/') 349f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar sourcedir = sourcedir.replace('\\', '/') 350bbbc283d86a911ccf3bdecdc78a7a8f71f31683fNAKAMURA Takumi tmpDir = tmpDir.replace('\\', '/') 351f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar tmpBase = tmpBase.replace('\\', '/') 352f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar 353be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # We use #_MARKER_# to hide %% while we do the other substitutions. 3542d4a5bf817ba0d85ddeb34a3c7fc2bc07fda32bdDaniel Dunbar substitutions = list(extra_substitutions) 3552d4a5bf817ba0d85ddeb34a3c7fc2bc07fda32bdDaniel Dunbar substitutions.extend([('%%', '#_MARKER_#')]) 356be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar substitutions.extend(test.config.substitutions) 357be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar substitutions.extend([('%s', sourcepath), 358f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar ('%S', sourcedir), 359f32a41a7e6df8ff5f78c673e3a73303bdba759ffDaniel Dunbar ('%p', sourcedir), 3600191bfcf7a5ae1ccfad7afe8ced59a14ffaca2a6Nico Weber ('%{pathsep}', os.pathsep), 361be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar ('%t', tmpBase + '.tmp'), 3620f9d34c71d4f4ea83912c45f99ed286557ea189cDouglas Gregor ('%T', tmpDir), 363be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar ('#_MARKER_#', '%')]) 364be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 365be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Collect the test lines from the script. 366be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar script = [] 367be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar xfails = [] 368b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar requires = [] 36908639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko line_number = 0 370be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar for ln in open(sourcepath): 37108639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko line_number += 1 372be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if 'RUN:' in ln: 373be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Isolate the command to run. 374be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar index = ln.index('RUN:') 375be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar ln = ln[index+4:] 376be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 377be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Trim trailing whitespace. 378be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar ln = ln.rstrip() 379be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 38008639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko # Substitute line number expressions 38108639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko ln = re.sub('%\(line\)', str(line_number), ln) 38208639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko def replace_line_number(match): 38308639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko if match.group(1) == '+': 38408639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko return str(line_number + int(match.group(2))) 38508639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko if match.group(1) == '-': 38608639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko return str(line_number - int(match.group(2))) 38708639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko ln = re.sub('%\(line *([\+-]) *(\d+)\)', replace_line_number, ln) 38808639983ded4250c18614c62450e70ba653aac4cAlexander Kornienko 389be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Collapse lines with trailing '\\'. 390be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if script and script[-1][-1] == '\\': 391be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar script[-1] = script[-1][:-1] + ln 392be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 393be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar script.append(ln) 39442543b7b736c9304b4877148943ff8a5fee3c22bDaniel Dunbar elif 'XFAIL:' in ln: 395be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar items = ln[ln.index('XFAIL:') + 6:].split(',') 396be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar xfails.extend([s.strip() for s in items]) 397b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar elif 'REQUIRES:' in ln: 398b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar items = ln[ln.index('REQUIRES:') + 9:].split(',') 399b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar requires.extend([s.strip() for s in items]) 400be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar elif 'END.' in ln: 401be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Check for END. lines. 402be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if ln[ln.index('END.'):].strip() == 'END.': 403be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar break 404be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 40518d49877530c04dd63578e6d9d0a1d3b6955502bDavid Greene # Apply substitutions to the script. Allow full regular 40618d49877530c04dd63578e6d9d0a1d3b6955502bDavid Greene # expression syntax. Replace each matching occurrence of regular 40718d49877530c04dd63578e6d9d0a1d3b6955502bDavid Greene # expression pattern a with substitution b in line ln. 408be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar def processLine(ln): 409be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Apply substitutions 410be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar for a,b in substitutions: 411ba69d3f6d448ca0a3a56b71fa65e85712bf76512Francois Pichet if kIsWindows: 4127a0be17c087ad7723e0ec65e63f4eb80ce9b5cefFrancois Pichet b = b.replace("\\","\\\\") 4137a0be17c087ad7723e0ec65e63f4eb80ce9b5cefFrancois Pichet ln = re.sub(a, b, ln) 414be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 415be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Strip the trailing newline and any extra whitespace. 416be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return ln.strip() 417be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar script = map(processLine, script) 418be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 419be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Verify the script contains a run line. 420be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if not script: 421be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return (Test.UNRESOLVED, "Test has no run line!") 422be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 423b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar # Check for unterminated run lines. 424be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if script[-1][-1] == '\\': 425be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return (Test.UNRESOLVED, "Test has unterminated run lines (with '\\')") 426be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 427f2a58425cd2a288b1d9fc3d2484ac774d361a0d7Andrew Trick # Check that we have the required features: 428b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar missing_required_features = [f for f in requires 429f2a58425cd2a288b1d9fc3d2484ac774d361a0d7Andrew Trick if f not in test.config.available_features] 430b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar if missing_required_features: 431b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar msg = ', '.join(missing_required_features) 432b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar return (Test.UNSUPPORTED, 433b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar "Test requires the following features: %s" % msg) 434b937549e517fcb03032bab3441d6ced37fc4db8dDaniel Dunbar 435f793fbc5698263e045661cab3fb06144c66cc1dbDaniel Dunbar isXFail = isExpectedFail(test, xfails) 43642543b7b736c9304b4877148943ff8a5fee3c22bDaniel Dunbar return script,isXFail,tmpBase,execdir 437be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 438213a789a711724c864defdc2c3e1208d6c5b7fd4Daniel Dunbardef formatTestOutput(status, out, err, exitCode, script): 439be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar output = StringIO.StringIO() 4400d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("Script:\n") 4410d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("--\n") 4420d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write('\n'.join(script)) 4430d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("\n--\n") 4440d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("Exit Code: %r\n\n" % exitCode) 4458a7ffe651f706a6819e94e6a99bbb2c1bb1d4391Dan Gohman if out: 4460d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("Command Output (stdout):\n") 4470d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("--\n") 4488a7ffe651f706a6819e94e6a99bbb2c1bb1d4391Dan Gohman output.write(out) 4490d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("--\n") 4508a7ffe651f706a6819e94e6a99bbb2c1bb1d4391Dan Gohman if err: 4510d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("Command Output (stderr):\n") 4520d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("--\n") 4538a7ffe651f706a6819e94e6a99bbb2c1bb1d4391Dan Gohman output.write(err) 4540d038e3e8852bf4fde949136ca9c2815f64febd0Daniel Dunbar output.write("--\n") 455be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return (status, output.getvalue()) 456be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 4572d4a5bf817ba0d85ddeb34a3c7fc2bc07fda32bdDaniel Dunbardef executeShTest(test, litConfig, useExternalSh, 4582d4a5bf817ba0d85ddeb34a3c7fc2bc07fda32bdDaniel Dunbar extra_substitutions=[]): 459be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if test.config.unsupported: 460be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return (Test.UNSUPPORTED, 'Test is unsupported') 461be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 4622d4a5bf817ba0d85ddeb34a3c7fc2bc07fda32bdDaniel Dunbar res = parseIntegratedTestScript(test, useExternalSh, extra_substitutions) 463be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if len(res) == 2: 464be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return res 465be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 46642543b7b736c9304b4877148943ff8a5fee3c22bDaniel Dunbar script, isXFail, tmpBase, execdir = res 467be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 468be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar # Create the output directory if it does not already exist. 469be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar Util.mkdir_p(os.path.dirname(tmpBase)) 470be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 471be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if useExternalSh: 472be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar res = executeScript(test, litConfig, tmpBase, script, execdir) 473be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 474be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar res = executeScriptInternal(test, litConfig, tmpBase, script, execdir) 475be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if len(res) == 2: 476be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return res 477be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 478be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar out,err,exitCode = res 47942543b7b736c9304b4877148943ff8a5fee3c22bDaniel Dunbar if isXFail: 480be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar ok = exitCode != 0 481bd2499a0b128ca15e97d8d67e72f8c9024d3310bDan Gohman if ok: 482bd2499a0b128ca15e97d8d67e72f8c9024d3310bDan Gohman status = Test.XFAIL 483bd2499a0b128ca15e97d8d67e72f8c9024d3310bDan Gohman else: 484bd2499a0b128ca15e97d8d67e72f8c9024d3310bDan Gohman status = Test.XPASS 485be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar else: 486be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar ok = exitCode == 0 487bd2499a0b128ca15e97d8d67e72f8c9024d3310bDan Gohman if ok: 488bd2499a0b128ca15e97d8d67e72f8c9024d3310bDan Gohman status = Test.PASS 489bd2499a0b128ca15e97d8d67e72f8c9024d3310bDan Gohman else: 490bd2499a0b128ca15e97d8d67e72f8c9024d3310bDan Gohman status = Test.FAIL 491be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 492be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar if ok: 493be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar return (status,'') 494be7ada718139b8c840a38ba34c4af492b6a05f9fDaniel Dunbar 495213a789a711724c864defdc2c3e1208d6c5b7fd4Daniel Dunbar return formatTestOutput(status, out, err, exitCode, script) 496