1# Copyright 2008 the V8 project authors. All rights reserved. 2# Redistribution and use in source and binary forms, with or without 3# modification, are permitted provided that the following conditions are 4# met: 5# 6# * Redistributions of source code must retain the above copyright 7# notice, this list of conditions and the following disclaimer. 8# * Redistributions in binary form must reproduce the above 9# copyright notice, this list of conditions and the following 10# disclaimer in the documentation and/or other materials provided 11# with the distribution. 12# * Neither the name of Google Inc. nor the names of its 13# contributors may be used to endorse or promote products derived 14# from this software without specific prior written permission. 15# 16# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 19# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 20# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 21# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 22# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 26# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 28import test 29import os 30from os.path import join, dirname, exists, basename, isdir 31import re 32 33FLAGS_PATTERN = re.compile(r"//\s+Flags:(.*)") 34 35class MessageTestCase(test.TestCase): 36 37 def __init__(self, path, file, expected, mode, context, config): 38 super(MessageTestCase, self).__init__(context, path) 39 self.file = file 40 self.expected = expected 41 self.config = config 42 self.mode = mode 43 44 def IgnoreLine(self, str): 45 """Ignore empty lines and valgrind output.""" 46 if not str: return True 47 else: return str.startswith('==') or str.startswith('**') 48 49 def IsFailureOutput(self, output): 50 f = file(self.expected) 51 # Skip initial '#' comment and spaces 52 for line in f: 53 if (not line.startswith('#')) and (not line.strip()): 54 break 55 # Convert output lines to regexps that we can match 56 env = { 'basename': basename(self.file) } 57 patterns = [ ] 58 for line in f: 59 if not line.strip(): 60 continue 61 pattern = re.escape(line.rstrip() % env) 62 pattern = pattern.replace('\\*', '.*') 63 pattern = '^%s$' % pattern 64 patterns.append(pattern) 65 # Compare actual output with the expected 66 raw_lines = output.stdout.split('\n') 67 outlines = [ s for s in raw_lines if not self.IgnoreLine(s) ] 68 if len(outlines) != len(patterns): 69 return True 70 for i in xrange(len(patterns)): 71 if not re.match(patterns[i], outlines[i]): 72 return True 73 return False 74 75 def GetLabel(self): 76 return "%s %s" % (self.mode, self.GetName()) 77 78 def GetName(self): 79 return self.path[-1] 80 81 def GetCommand(self): 82 result = [self.config.context.GetVm(self.mode)] 83 source = open(self.file).read() 84 flags_match = FLAGS_PATTERN.search(source) 85 if flags_match: 86 result += flags_match.group(1).strip().split() 87 result.append(self.file) 88 return result 89 90 def GetSource(self): 91 return (open(self.file).read() 92 + "\n--- expected output ---\n" 93 + open(self.expected).read()) 94 95 96class MessageTestConfiguration(test.TestConfiguration): 97 98 def __init__(self, context, root): 99 super(MessageTestConfiguration, self).__init__(context, root) 100 101 def Ls(self, path): 102 if isdir(path): 103 return [f[:-3] for f in os.listdir(path) if f.endswith('.js')] 104 else: 105 return [] 106 107 def ListTests(self, current_path, path, mode): 108 mjsunit = [current_path + [t] for t in self.Ls(self.root)] 109 regress = [current_path + ['regress', t] for t in self.Ls(join(self.root, 'regress'))] 110 bugs = [current_path + ['bugs', t] for t in self.Ls(join(self.root, 'bugs'))] 111 all_tests = mjsunit + regress + bugs 112 result = [] 113 for test in all_tests: 114 if self.Contains(path, test): 115 file_prefix = join(self.root, reduce(join, test[1:], "")) 116 file_path = file_prefix + ".js" 117 output_path = file_prefix + ".out" 118 if not exists(output_path): 119 print "Could not find %s" % output_path 120 continue 121 result.append(MessageTestCase(test, file_path, output_path, mode, 122 self.context, self)) 123 return result 124 125 def GetBuildRequirements(self): 126 return ['sample', 'sample=shell'] 127 128 def GetTestStatus(self, sections, defs): 129 status_file = join(self.root, 'message.status') 130 if exists(status_file): 131 test.ReadConfigurationInto(status_file, sections, defs) 132 133 134def GetConfiguration(context, root): 135 return MessageTestConfiguration(context, root) 136