1# Copyright 2011 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
28
29import test
30import os
31from os.path import join, exists
32import urllib
33import hashlib
34import tarfile
35
36
37TEST_262_ARCHIVE_REVISION = '3a890174343c'  # This is the r309 revision.
38TEST_262_ARCHIVE_MD5 = 'be5d4cfbe69cef70430907b8f3a92b50'
39TEST_262_URL = 'http://hg.ecmascript.org/tests/test262/archive/%s.tar.bz2'
40TEST_262_HARNESS = ['sta.js']
41
42
43class Test262TestCase(test.TestCase):
44
45  def __init__(self, filename, path, context, root, mode, framework):
46    super(Test262TestCase, self).__init__(context, path, mode)
47    self.filename = filename
48    self.framework = framework
49    self.root = root
50
51  def IsNegative(self):
52    return '@negative' in self.GetSource()
53
54  def GetLabel(self):
55    return "%s test262 %s" % (self.mode, self.GetName())
56
57  def IsFailureOutput(self, output):
58    if output.exit_code != 0:
59      return True
60    return 'FAILED!' in output.stdout
61
62  def GetCommand(self):
63    result = self.context.GetVmCommand(self, self.mode)
64    result += self.framework
65    result.append(self.filename)
66    return result
67
68  def GetName(self):
69    return self.path[-1]
70
71  def GetSource(self):
72    return open(self.filename).read()
73
74
75class Test262TestConfiguration(test.TestConfiguration):
76
77  def __init__(self, context, root):
78    super(Test262TestConfiguration, self).__init__(context, root)
79
80  def ListTests(self, current_path, path, mode, variant_flags):
81    testroot = join(self.root, 'data', 'test', 'suite')
82    harness = [join(self.root, 'data', 'test', 'harness', f)
83                   for f in TEST_262_HARNESS]
84    harness += [join(self.root, 'harness-adapt.js')]
85    tests = []
86    for root, dirs, files in os.walk(testroot):
87      for dotted in [x for x in dirs if x.startswith('.')]:
88        dirs.remove(dotted)
89      dirs.sort()
90      root_path = root[len(self.root):].split(os.path.sep)
91      root_path = current_path + [x for x in root_path if x]
92      files.sort()
93      for file in files:
94        if file.endswith('.js'):
95          test_path = ['test262', file[:-3]]
96          if self.Contains(path, test_path):
97            test = Test262TestCase(join(root, file), test_path, self.context,
98                                   self.root, mode, harness)
99            tests.append(test)
100    return tests
101
102  def DownloadData(self):
103    revision = TEST_262_ARCHIVE_REVISION
104    archive_url = TEST_262_URL % revision
105    archive_name = join(self.root, 'test262-%s.tar.bz2' % revision)
106    directory_name = join(self.root, "test262-%s" % revision)
107    if not exists(directory_name) or not exists(archive_name):
108      if not exists(archive_name):
109        print "Downloading test data from %s ..." % archive_url
110        urllib.urlretrieve(archive_url, archive_name)
111      if not exists(directory_name):
112        print "Extracting test262-%s.tar.bz2 ..." % revision
113        md5 = hashlib.md5()
114        with open(archive_name,'rb') as f:
115          for chunk in iter(lambda: f.read(8192), ''):
116            md5.update(chunk)
117        if md5.hexdigest() != TEST_262_ARCHIVE_MD5:
118          raise Exception("Hash mismatch of test data file")
119        archive = tarfile.open(archive_name, 'r:bz2')
120        archive.extractall(join(self.root))
121      if not exists(join(self.root, 'data')):
122        os.symlink(directory_name, join(self.root, 'data'))
123
124  def GetBuildRequirements(self):
125    return ['d8']
126
127  def GetTestStatus(self, sections, defs):
128    status_file = join(self.root, 'test262.status')
129    if exists(status_file):
130      test.ReadConfigurationInto(status_file, sections, defs)
131
132
133def GetConfiguration(context, root):
134  return Test262TestConfiguration(context, root)
135