1 # Copyright 2014 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 29 import hashlib 30 import os 31 import shutil 32 import sys 33 import tarfile 34 35 from testrunner.local import testsuite 36 from testrunner.local import utils 37 from testrunner.objects import testcase 38 39 40 SINON_TAG = '1.7.3' 41 SINON_NAME = 'sinon' 42 SINON_FILENAME = 'sinon.js' 43 SINON_URL = 'http://sinonjs.org/releases/sinon-' + SINON_TAG + '.js' 44 SINON_HASH = 'b7ab4dd9a1a2cf0460784af3728ad15caf4bbea923f680c5abde5c8332f35984' 45 46 TEST_TAG = '2.0.3' 47 TEST_ARCHIVE_TOP = 'promises-tests-' + TEST_TAG 48 TEST_NAME = 'promises-tests' 49 TEST_ARCHIVE = TEST_NAME + '.tar.gz' 50 TEST_URL = 'https://github.com/promises-aplus/promises-tests/archive/' + \ 51 TEST_TAG + '.tar.gz' 52 TEST_ARCHIVE_HASH = \ 53 'e446ca557ac5836dd439fecd19689c243a28b1d5a6644dd7fed4274d0fa67270' 54 55 56 class PromiseAplusTestSuite(testsuite.TestSuite): 57 58 def __init__(self, name, root): 59 self.root = root 60 self.test_files_root = os.path.join(self.root, TEST_NAME, 'lib', 'tests') 61 self.name = name 62 self.helper_files_pre = [ 63 os.path.join(root, 'lib', name) for name in 64 ['global.js', 'require.js', 'mocha.js', 'adapter.js'] 65 ] 66 self.helper_files_post = [ 67 os.path.join(root, 'lib', name) for name in 68 ['run-tests.js'] 69 ] 70 71 def CommonTestName(self, testcase): 72 return testcase.path.split(os.path.sep)[-1] 73 74 def ListTests(self, context): 75 return [testcase.TestCase(self, fname[:-len('.js')]) for fname in 76 os.listdir(os.path.join(self.root, TEST_NAME, 'lib', 'tests')) 77 if fname.endswith('.js')] 78 79 def GetFlagsForTestCase(self, testcase, context): 80 return (testcase.flags + context.mode_flags + ['--allow-natives-syntax'] + 81 self.helper_files_pre + 82 [os.path.join(self.test_files_root, testcase.path + '.js')] + 83 self.helper_files_post) 84 85 def GetSourceForTest(self, testcase): 86 filename = os.path.join(self.root, TEST_NAME, 87 'lib', 'tests', testcase.path + '.js') 88 with open(filename) as f: 89 return f.read() 90 91 def IsNegativeTest(self, testcase): 92 return '@negative' in self.GetSourceForTest(testcase) 93 94 def IsFailureOutput(self, output, testpath): 95 if output.exit_code != 0: 96 return True 97 return not 'All tests have run.' in output.stdout or \ 98 'FAIL:' in output.stdout 99 100 def DownloadTestData(self): 101 archive = os.path.join(self.root, TEST_ARCHIVE) 102 directory = os.path.join(self.root, TEST_NAME) 103 if not os.path.exists(archive): 104 print('Downloading {0} from {1} ...'.format(TEST_NAME, TEST_URL)) 105 utils.URLRetrieve(TEST_URL, archive) 106 if os.path.exists(directory): 107 shutil.rmtree(directory) 108 109 if not os.path.exists(directory): 110 print('Extracting {0} ...'.format(TEST_ARCHIVE)) 111 hash = hashlib.sha256() 112 with open(archive, 'rb') as f: 113 for chunk in iter(lambda: f.read(8192), ''): 114 hash.update(chunk) 115 if hash.hexdigest() != TEST_ARCHIVE_HASH: 116 os.remove(archive) 117 raise Exception('Hash mismatch of test data file') 118 archive = tarfile.open(archive, 'r:gz') 119 if sys.platform in ('win32', 'cygwin'): 120 # Magic incantation to allow longer path names on Windows. 121 archive.extractall(u'\\\\?\\%s' % self.root) 122 else: 123 archive.extractall(self.root) 124 shutil.move(os.path.join(self.root, TEST_ARCHIVE_TOP), directory) 125 126 def DownloadSinon(self): 127 directory = os.path.join(self.root, SINON_NAME) 128 if not os.path.exists(directory): 129 os.mkdir(directory) 130 path = os.path.join(directory, SINON_FILENAME) 131 if not os.path.exists(path): 132 utils.URLRetrieve(SINON_URL, path) 133 hash = hashlib.sha256() 134 with open(path, 'rb') as f: 135 for chunk in iter(lambda: f.read(8192), ''): 136 hash.update(chunk) 137 if hash.hexdigest() != SINON_HASH: 138 os.remove(path) 139 raise Exception('Hash mismatch of test data file') 140 141 def DownloadData(self): 142 self.DownloadTestData() 143 self.DownloadSinon() 144 145 146 def GetSuite(name, root): 147 return PromiseAplusTestSuite(name, root) 148