1 # Copyright 2012 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
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.
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.
36 from testrunner.local import testsuite
37 from testrunner.local import utils
38 from testrunner.objects import testcase
40 TEST_262_ARCHIVE_REVISION = "61113db" # This is the 2014-10-23 revision.
41 TEST_262_ARCHIVE_MD5 = "261e69b4a97a4bfc18225cf3938daf50"
42 TEST_262_URL = "https://github.com/tc39/test262/tarball/%s"
43 TEST_262_HARNESS_FILES = ["sta.js"]
45 TEST_262_SUITE_PATH = ["data", "test", "suite"]
46 TEST_262_HARNESS_PATH = ["data", "test", "harness"]
47 TEST_262_TOOLS_PATH = ["data", "tools", "packaging"]
49 class Test262TestSuite(testsuite.TestSuite):
51 def __init__(self, name, root):
52 super(Test262TestSuite, self).__init__(name, root)
53 self.testroot = os.path.join(self.root, *TEST_262_SUITE_PATH)
54 self.harnesspath = os.path.join(self.root, *TEST_262_HARNESS_PATH)
55 self.harness = [os.path.join(self.harnesspath, f)
56 for f in TEST_262_HARNESS_FILES]
57 self.harness += [os.path.join(self.root, "harness-adapt.js")]
58 self.ParseTestRecord = None
60 def CommonTestName(self, testcase):
61 return testcase.path.split(os.path.sep)[-1]
63 def ListTests(self, context):
65 for dirname, dirs, files in os.walk(self.testroot):
66 for dotted in [x for x in dirs if x.startswith(".")]:
68 if context.noi18n and "intl402" in dirs:
69 dirs.remove("intl402")
72 for filename in files:
73 if filename.endswith(".js"):
74 testname = os.path.join(dirname[len(self.testroot) + 1:],
76 case = testcase.TestCase(self, testname)
80 def GetFlagsForTestCase(self, testcase, context):
81 return (testcase.flags + context.mode_flags + self.harness +
82 self.GetIncludesForTest(testcase) + ["--harmony"] +
83 [os.path.join(self.testroot, testcase.path + ".js")])
85 def LoadParseTestRecord(self):
86 if not self.ParseTestRecord:
87 root = os.path.join(self.root, *TEST_262_TOOLS_PATH)
90 (f, pathname, description) = imp.find_module("parseTestRecord", [root])
91 module = imp.load_module("parseTestRecord", f, pathname, description)
92 self.ParseTestRecord = module.parseTestRecord
94 raise ImportError("Cannot load parseTestRecord; you may need to "
95 "--download-data for test262")
99 return self.ParseTestRecord
101 def GetTestRecord(self, testcase):
102 if not hasattr(testcase, "test_record"):
103 ParseTestRecord = self.LoadParseTestRecord()
104 testcase.test_record = ParseTestRecord(self.GetSourceForTest(testcase),
106 return testcase.test_record
108 def GetIncludesForTest(self, testcase):
109 test_record = self.GetTestRecord(testcase)
110 if "includes" in test_record:
111 includes = [os.path.join(self.harnesspath, f)
112 for f in test_record["includes"]]
117 def GetSourceForTest(self, testcase):
118 filename = os.path.join(self.testroot, testcase.path + ".js")
119 with open(filename) as f:
122 def IsNegativeTest(self, testcase):
123 test_record = self.GetTestRecord(testcase)
124 return "negative" in test_record
126 def IsFailureOutput(self, output, testpath):
127 if output.exit_code != 0:
129 return "FAILED!" in output.stdout
131 def DownloadData(self):
132 revision = TEST_262_ARCHIVE_REVISION
133 archive_url = TEST_262_URL % revision
134 archive_name = os.path.join(self.root, "tc39-test262-%s.tar.gz" % revision)
135 directory_name = os.path.join(self.root, "data")
136 directory_old_name = os.path.join(self.root, "data.old")
137 if not os.path.exists(archive_name):
138 print "Downloading test data from %s ..." % archive_url
139 utils.URLRetrieve(archive_url, archive_name)
140 if os.path.exists(directory_name):
141 if os.path.exists(directory_old_name):
142 shutil.rmtree(directory_old_name)
143 os.rename(directory_name, directory_old_name)
144 if not os.path.exists(directory_name):
145 print "Extracting test262-%s.tar.gz ..." % revision
147 with open(archive_name, "rb") as f:
148 for chunk in iter(lambda: f.read(8192), ""):
150 print "MD5 hash is %s" % md5.hexdigest()
151 if md5.hexdigest() != TEST_262_ARCHIVE_MD5:
152 os.remove(archive_name)
153 print "MD5 expected %s" % TEST_262_ARCHIVE_MD5
154 raise Exception("MD5 hash mismatch of test data file")
155 archive = tarfile.open(archive_name, "r:gz")
156 if sys.platform in ("win32", "cygwin"):
157 # Magic incantation to allow longer path names on Windows.
158 archive.extractall(u"\\\\?\\%s" % self.root)
160 archive.extractall(self.root)
161 os.rename(os.path.join(self.root, "tc39-test262-%s" % revision),
165 def GetSuite(name, root):
166 return Test262TestSuite(name, root)