1from __future__ import absolute_import 2import os 3 4import lit.Test 5import lit.util 6 7class TestFormat(object): 8 pass 9 10### 11 12class FileBasedTest(TestFormat): 13 def getTestsInDirectory(self, testSuite, path_in_suite, 14 litConfig, localConfig): 15 source_path = testSuite.getSourcePath(path_in_suite) 16 for filename in os.listdir(source_path): 17 # Ignore dot files and excluded tests. 18 if (filename.startswith('.') or 19 filename in localConfig.excludes): 20 continue 21 22 filepath = os.path.join(source_path, filename) 23 if not os.path.isdir(filepath): 24 base,ext = os.path.splitext(filename) 25 if ext in localConfig.suffixes: 26 yield lit.Test.Test(testSuite, path_in_suite + (filename,), 27 localConfig) 28 29### 30 31import re 32import tempfile 33 34class OneCommandPerFileTest(TestFormat): 35 # FIXME: Refactor into generic test for running some command on a directory 36 # of inputs. 37 38 def __init__(self, command, dir, recursive=False, 39 pattern=".*", useTempInput=False): 40 if isinstance(command, str): 41 self.command = [command] 42 else: 43 self.command = list(command) 44 if dir is not None: 45 dir = str(dir) 46 self.dir = dir 47 self.recursive = bool(recursive) 48 self.pattern = re.compile(pattern) 49 self.useTempInput = useTempInput 50 51 def getTestsInDirectory(self, testSuite, path_in_suite, 52 litConfig, localConfig): 53 dir = self.dir 54 if dir is None: 55 dir = testSuite.getSourcePath(path_in_suite) 56 57 for dirname,subdirs,filenames in os.walk(dir): 58 if not self.recursive: 59 subdirs[:] = [] 60 61 subdirs[:] = [d for d in subdirs 62 if (d != '.svn' and 63 d not in localConfig.excludes)] 64 65 for filename in filenames: 66 if (filename.startswith('.') or 67 not self.pattern.match(filename) or 68 filename in localConfig.excludes): 69 continue 70 71 path = os.path.join(dirname,filename) 72 suffix = path[len(dir):] 73 if suffix.startswith(os.sep): 74 suffix = suffix[1:] 75 test = lit.Test.Test( 76 testSuite, path_in_suite + tuple(suffix.split(os.sep)), 77 localConfig) 78 # FIXME: Hack? 79 test.source_path = path 80 yield test 81 82 def createTempInput(self, tmp, test): 83 raise NotImplementedError('This is an abstract method.') 84 85 def execute(self, test, litConfig): 86 if test.config.unsupported: 87 return (lit.Test.UNSUPPORTED, 'Test is unsupported') 88 89 cmd = list(self.command) 90 91 # If using temp input, create a temporary file and hand it to the 92 # subclass. 93 if self.useTempInput: 94 tmp = tempfile.NamedTemporaryFile(suffix='.cpp') 95 self.createTempInput(tmp, test) 96 tmp.flush() 97 cmd.append(tmp.name) 98 elif hasattr(test, 'source_path'): 99 cmd.append(test.source_path) 100 else: 101 cmd.append(test.getSourcePath()) 102 103 out, err, exitCode = lit.util.executeCommand(cmd) 104 105 diags = out + err 106 if not exitCode and not diags.strip(): 107 return lit.Test.PASS,'' 108 109 # Try to include some useful information. 110 report = """Command: %s\n""" % ' '.join(["'%s'" % a 111 for a in cmd]) 112 if self.useTempInput: 113 report += """Temporary File: %s\n""" % tmp.name 114 report += "--\n%s--\n""" % open(tmp.name).read() 115 report += """Output:\n--\n%s--""" % diags 116 117 return lit.Test.FAIL, report 118 119 120### 121 122# Check exit code of a simple executable with no input 123class ExecutableTest(FileBasedTest): 124 def execute(self, test, litConfig): 125 if test.config.unsupported: 126 return lit.Test.UNSUPPORTED 127 128 out, err, exitCode = lit.util.executeCommand(test.getSourcePath()) 129 130 if not exitCode: 131 return lit.Test.PASS, '' 132 133 return lit.Test.FAIL, out+err 134 135