blob: b62e9b0d6b4ffbe99ccb95de871713db440c3e30 [file] [log] [blame]
Ben Murdochb8a8cc12014-11-26 15:28:44 +00001# Copyright 2012 the V8 project authors. All rights reserved.
Steve Block44f0eee2011-05-26 01:26:41 +01002# 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
28
Ben Murdoch3ef787d2012-04-12 10:51:47 +010029import hashlib
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000030import imp
Ben Murdochb8a8cc12014-11-26 15:28:44 +000031import os
32import shutil
33import sys
Ben Murdoch3ef787d2012-04-12 10:51:47 +010034import tarfile
Steve Block44f0eee2011-05-26 01:26:41 +010035
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000036
37from testrunner.local import statusfile
Ben Murdochb8a8cc12014-11-26 15:28:44 +000038from testrunner.local import testsuite
39from testrunner.local import utils
40from testrunner.objects import testcase
Steve Block44f0eee2011-05-26 01:26:41 +010041
Ben Murdochda12d292016-06-02 14:46:10 +010042DATA = os.path.join(os.path.dirname(os.path.abspath(__file__)), "data")
43ARCHIVE = DATA + ".tar"
Ben Murdoch097c5b22016-05-18 11:27:45 +010044
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000045TEST_262_HARNESS_FILES = ["sta.js", "assert.js"]
Ben Murdochc5610432016-08-08 18:44:38 +010046TEST_262_NATIVE_FILES = ["detachArrayBuffer.js"]
Steve Block44f0eee2011-05-26 01:26:41 +010047
Ben Murdoch4a90d5f2016-03-22 12:00:34 +000048TEST_262_SUITE_PATH = ["data", "test"]
49TEST_262_HARNESS_PATH = ["data", "harness"]
50TEST_262_TOOLS_PATH = ["data", "tools", "packaging"]
51
52ALL_VARIANT_FLAGS_STRICT = dict(
53 (v, [flags + ["--use-strict"] for flags in flag_sets])
54 for v, flag_sets in testsuite.ALL_VARIANT_FLAGS.iteritems()
55)
56
57FAST_VARIANT_FLAGS_STRICT = dict(
58 (v, [flags + ["--use-strict"] for flags in flag_sets])
59 for v, flag_sets in testsuite.FAST_VARIANT_FLAGS.iteritems()
60)
61
62ALL_VARIANT_FLAGS_BOTH = dict(
63 (v, [flags for flags in testsuite.ALL_VARIANT_FLAGS[v] +
64 ALL_VARIANT_FLAGS_STRICT[v]])
65 for v in testsuite.ALL_VARIANT_FLAGS
66)
67
68FAST_VARIANT_FLAGS_BOTH = dict(
69 (v, [flags for flags in testsuite.FAST_VARIANT_FLAGS[v] +
70 FAST_VARIANT_FLAGS_STRICT[v]])
71 for v in testsuite.FAST_VARIANT_FLAGS
72)
73
74ALL_VARIANTS = {
75 'nostrict': testsuite.ALL_VARIANT_FLAGS,
76 'strict': ALL_VARIANT_FLAGS_STRICT,
77 'both': ALL_VARIANT_FLAGS_BOTH,
78}
79
80FAST_VARIANTS = {
81 'nostrict': testsuite.FAST_VARIANT_FLAGS,
82 'strict': FAST_VARIANT_FLAGS_STRICT,
83 'both': FAST_VARIANT_FLAGS_BOTH,
84}
85
86class Test262VariantGenerator(testsuite.VariantGenerator):
87 def GetFlagSets(self, testcase, variant):
88 if testcase.outcomes and statusfile.OnlyFastVariants(testcase.outcomes):
89 variant_flags = FAST_VARIANTS
90 else:
91 variant_flags = ALL_VARIANTS
92
93 test_record = self.suite.GetTestRecord(testcase)
94 if "noStrict" in test_record:
95 return variant_flags["nostrict"][variant]
96 if "onlyStrict" in test_record:
97 return variant_flags["strict"][variant]
98 return variant_flags["both"][variant]
Steve Block44f0eee2011-05-26 01:26:41 +010099
Steve Block44f0eee2011-05-26 01:26:41 +0100100
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000101class Test262TestSuite(testsuite.TestSuite):
Steve Block44f0eee2011-05-26 01:26:41 +0100102
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000103 def __init__(self, name, root):
104 super(Test262TestSuite, self).__init__(name, root)
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000105 self.testroot = os.path.join(self.root, *TEST_262_SUITE_PATH)
106 self.harnesspath = os.path.join(self.root, *TEST_262_HARNESS_PATH)
107 self.harness = [os.path.join(self.harnesspath, f)
108 for f in TEST_262_HARNESS_FILES]
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000109 self.harness += [os.path.join(self.root, "harness-adapt.js")]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000110 self.ParseTestRecord = None
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000111
112 def ListTests(self, context):
113 tests = []
114 for dirname, dirs, files in os.walk(self.testroot):
115 for dotted in [x for x in dirs if x.startswith(".")]:
116 dirs.remove(dotted)
117 if context.noi18n and "intl402" in dirs:
118 dirs.remove("intl402")
119 dirs.sort()
120 files.sort()
121 for filename in files:
122 if filename.endswith(".js"):
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000123 fullpath = os.path.join(dirname, filename)
124 relpath = fullpath[len(self.testroot) + 1 : -3]
125 testname = relpath.replace(os.path.sep, "/")
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000126 case = testcase.TestCase(self, testname)
127 tests.append(case)
128 return tests
129
130 def GetFlagsForTestCase(self, testcase, context):
131 return (testcase.flags + context.mode_flags + self.harness +
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000132 self.GetIncludesForTest(testcase) + ["--harmony"] +
Ben Murdochc5610432016-08-08 18:44:38 +0100133 (["--module"] if "module" in self.GetTestRecord(testcase) else []) +
Ben Murdochda12d292016-06-02 14:46:10 +0100134 [os.path.join(self.testroot, testcase.path + ".js")] +
Ben Murdochc5610432016-08-08 18:44:38 +0100135 (["--throws"] if "negative" in self.GetTestRecord(testcase)
136 else []) +
137 (["--allow-natives-syntax"]
138 if "detachArrayBuffer.js" in
139 self.GetTestRecord(testcase).get("includes", [])
140 else []))
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000141
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000142 def _VariantGeneratorFactory(self):
143 return Test262VariantGenerator
144
145 def LoadParseTestRecord(self):
146 if not self.ParseTestRecord:
147 root = os.path.join(self.root, *TEST_262_TOOLS_PATH)
148 f = None
149 try:
150 (f, pathname, description) = imp.find_module("parseTestRecord", [root])
151 module = imp.load_module("parseTestRecord", f, pathname, description)
152 self.ParseTestRecord = module.parseTestRecord
153 except:
154 raise ImportError("Cannot load parseTestRecord; you may need to "
Ben Murdochda12d292016-06-02 14:46:10 +0100155 "gclient sync for test262")
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000156 finally:
157 if f:
158 f.close()
159 return self.ParseTestRecord
160
161 def GetTestRecord(self, testcase):
162 if not hasattr(testcase, "test_record"):
163 ParseTestRecord = self.LoadParseTestRecord()
164 testcase.test_record = ParseTestRecord(self.GetSourceForTest(testcase),
165 testcase.path)
166 return testcase.test_record
167
Ben Murdochc5610432016-08-08 18:44:38 +0100168 def BasePath(self, filename):
169 return self.root if filename in TEST_262_NATIVE_FILES else self.harnesspath
170
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000171 def GetIncludesForTest(self, testcase):
172 test_record = self.GetTestRecord(testcase)
173 if "includes" in test_record:
Ben Murdochc5610432016-08-08 18:44:38 +0100174 return [os.path.join(self.BasePath(filename), filename)
175 for filename in test_record.get("includes", [])]
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000176 else:
177 includes = []
178 return includes
179
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000180 def GetSourceForTest(self, testcase):
181 filename = os.path.join(self.testroot, testcase.path + ".js")
182 with open(filename) as f:
183 return f.read()
184
Ben Murdochda12d292016-06-02 14:46:10 +0100185 def _ParseException(self, str):
186 for line in str.split("\n")[::-1]:
187 if line and not line[0].isspace() and ":" in line:
188 return line.split(":")[0]
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000189
Ben Murdochda12d292016-06-02 14:46:10 +0100190
191 def IsFailureOutput(self, testcase):
192 output = testcase.output
193 test_record = self.GetTestRecord(testcase)
Steve Block44f0eee2011-05-26 01:26:41 +0100194 if output.exit_code != 0:
195 return True
Ben Murdochda12d292016-06-02 14:46:10 +0100196 if "negative" in test_record:
197 if self._ParseException(output.stdout) != test_record["negative"]:
198 return True
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000199 return "FAILED!" in output.stdout
Ben Murdoch5d4cdbf2012-04-11 10:23:59 +0100200
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000201 def HasUnexpectedOutput(self, testcase):
202 outcome = self.GetOutcome(testcase)
203 if (statusfile.FAIL_SLOPPY in testcase.outcomes and
204 "--use-strict" not in testcase.flags):
205 return outcome != statusfile.FAIL
206 return not outcome in (testcase.outcomes or [statusfile.PASS])
207
Ben Murdoch3ef787d2012-04-12 10:51:47 +0100208 def DownloadData(self):
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000209 print "Test262 download is deprecated. It's part of DEPS."
210
211 # Clean up old directories and archive files.
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000212 directory_old_name = os.path.join(self.root, "data.old")
Ben Murdoch4a90d5f2016-03-22 12:00:34 +0000213 if os.path.exists(directory_old_name):
214 shutil.rmtree(directory_old_name)
215
216 archive_files = [f for f in os.listdir(self.root)
217 if f.startswith("tc39-test262-")]
218 if len(archive_files) > 0:
219 print "Clobber outdated test archives ..."
220 for f in archive_files:
221 os.remove(os.path.join(self.root, f))
Steve Block44f0eee2011-05-26 01:26:41 +0100222
Ben Murdochda12d292016-06-02 14:46:10 +0100223 # The archive is created only on swarming. Local checkouts have the
224 # data folder.
225 if os.path.exists(ARCHIVE) and not os.path.exists(DATA):
226 print "Extracting archive..."
227 tar = tarfile.open(ARCHIVE)
228 tar.extractall(path=os.path.dirname(ARCHIVE))
229 tar.close()
Ben Murdoch097c5b22016-05-18 11:27:45 +0100230
Steve Block44f0eee2011-05-26 01:26:41 +0100231
Ben Murdochb8a8cc12014-11-26 15:28:44 +0000232def GetSuite(name, root):
233 return Test262TestSuite(name, root)