forked from emscripten-core/emsdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathtest.py
executable file
·287 lines (230 loc) · 9.99 KB
/
test.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
#!/usr/bin/env python3
import json
import os
import shutil
import subprocess
import sys
import tempfile
import unittest
WINDOWS = sys.platform.startswith('win')
MACOS = sys.platform == 'darwin'
assert 'EM_CONFIG' in os.environ, "emsdk should be activated before running this script"
emconfig = os.environ['EM_CONFIG']
upstream_emcc = os.path.join('upstream', 'emscripten', 'emcc')
fastcomp_emcc = os.path.join('fastcomp', 'emscripten', 'emcc')
emsdk = './emsdk'
if WINDOWS:
upstream_emcc += '.bat'
fastcomp_emcc += '.bat'
emsdk = 'emsdk.bat'
else:
emsdk = './emsdk'
# Utilities
def listify(x):
if type(x) == list or type(x) == tuple:
return x
return [x]
def check_call(cmd, **args):
if type(cmd) != list:
cmd = cmd.split()
print('running: %s' % cmd)
args['universal_newlines'] = True
subprocess.check_call(cmd, **args)
def checked_call_with_output(cmd, expected=None, unexpected=None, stderr=None, env=None):
cmd = cmd.split(' ')
print('running: %s' % cmd)
try:
stdout = subprocess.check_output(cmd, stderr=stderr, universal_newlines=True, env=env)
except subprocess.CalledProcessError as e:
print(e.stderr)
print(e.stdout)
raise e
if expected:
for x in listify(expected):
assert x in stdout, 'call had the right output: ' + stdout + '\n[[[' + x + ']]]'
if unexpected:
for x in listify(unexpected):
assert x not in stdout, 'call had the wrong output: ' + stdout + '\n[[[' + x + ']]]'
def failing_call_with_output(cmd, expected):
proc = subprocess.Popen(cmd.split(' '), stdout=subprocess.PIPE, stderr=subprocess.PIPE, universal_newlines=True)
stdout, stderr = proc.communicate()
if WINDOWS:
print('warning: skipping part of failing_call_with_output() due to error codes not being propagated (see #592)')
else:
assert proc.returncode, 'call must have failed: ' + str([stdout, '\n========\n', stderr])
assert expected in stdout or expected in stderr, 'call did not have the expected output: %s: %s' % (expected, str([stdout, '\n========\n', stderr]))
def hack_emsdk(marker, replacement):
with open('emsdk.py') as f:
src = f.read()
assert marker in src
src = src.replace(marker, replacement)
name = '__test_emsdk'
with open(name, 'w') as f:
f.write(src)
return name
# Set up
TAGS = json.loads(open('emscripten-releases-tags.json').read())
# Tests
def do_lib_building(emcc):
cache_building_messages = ['generating system library: ']
def do_build(args, is_expected=None):
unexpected = None
expected = None
if is_expected is True:
expected = cache_building_messages
elif is_expected is False:
unexpected = cache_building_messages
checked_call_with_output(emcc + ' hello_world.c' + args,
expected=expected,
unexpected=unexpected,
stderr=subprocess.STDOUT)
# The emsdk ships all system libraries so we don't expect to see any
# cache population unless we explicly --clear-cache.
do_build('', is_expected=False)
check_call(emcc + ' --clear-cache')
do_build(' -O2', is_expected=True)
# Do another build at -O0. In nwers SDK versions this generates
# different libs, but not in older ones so don't assert here.
do_build('')
# Now verify that libs are *not* build
do_build(' -s WASM=0', is_expected=False)
do_build(' -O2 -s WASM=0', is_expected=False)
def run_emsdk(cmd):
if type(cmd) != list:
cmd = cmd.split()
check_call([emsdk] + cmd)
class Emsdk(unittest.TestCase):
@classmethod
def setUpClass(cls):
with open('hello_world.c', 'w') as f:
f.write('''\
#include <stdio.h>
int main() {
printf("Hello, world!\\n");
return 0;
}
''')
def setUp(self):
run_emsdk('install latest')
run_emsdk('activate latest')
def test_already_installed(self):
# Test we don't re-download unnecessarily
checked_call_with_output(emsdk + ' install latest', expected='already installed', unexpected='Downloading:')
def test_list(self):
# Test we report installed tools properly. The latest version should be
# installed, but not some random old one.
checked_call_with_output(emsdk + ' list', expected=TAGS['aliases']['latest'] + ' INSTALLED', unexpected='1.39.15 INSTALLED:')
def test_config_contents(self):
print('test .emscripten contents')
with open(emconfig) as f:
config = f.read()
assert 'fastcomp' not in config
assert 'upstream' in config
def test_lib_building(self):
print('building proper system libraries')
do_lib_building(upstream_emcc)
def test_fastcomp(self):
print('test the last fastcomp release')
run_emsdk('install 1.40.1-fastcomp')
run_emsdk('activate 1.40.1-fastcomp')
do_lib_building(fastcomp_emcc)
with open(emconfig) as f:
config = f.read()
assert config.count('LLVM_ROOT') == 1
assert 'upstream' not in config
assert 'fastcomp' in config
print('verify latest fastcomp version is fixed at 1.40.1')
checked_call_with_output(fastcomp_emcc + ' -v', '1.40.1', stderr=subprocess.STDOUT)
def test_fastcomp_missing(self):
print('verify that attempting to use newer fastcomp gives an error')
fastcomp_error = 'the fastcomp backend is not getting new builds or releases. Please use the upstream llvm backend or use an older version than 2.0.0 (such as 1.40.1).'
failing_call_with_output(emsdk + ' install latest-fastcomp', fastcomp_error)
failing_call_with_output(emsdk + ' install tot-fastcomp', fastcomp_error)
failing_call_with_output(emsdk + ' install 2.0.0-fastcomp', fastcomp_error)
def test_redownload(self):
print('go back to using upstream')
run_emsdk('activate latest')
# Test the normal tools like node don't re-download on re-install
print('another install must re-download')
checked_call_with_output(emsdk + ' uninstall node-14.18.2-64bit')
checked_call_with_output(emsdk + ' install node-14.18.2-64bit', expected='Downloading:', unexpected='already installed')
checked_call_with_output(emsdk + ' install node-14.18.2-64bit', unexpected='Downloading:', expected='already installed')
def test_tot_upstream(self):
print('test update-tags')
run_emsdk('update-tags')
print('test tot-upstream')
run_emsdk('install tot-upstream')
with open(emconfig) as f:
config = f.read()
run_emsdk('activate tot-upstream')
with open(emconfig + '.old') as f:
old_config = f.read()
self.assertEqual(config, old_config)
# TODO; test on latest as well
check_call(upstream_emcc + ' hello_world.c')
def test_closure(self):
# Specificlly test with `--closure` so we know that node_modules is working
check_call(upstream_emcc + ' hello_world.c --closure=1')
def test_specific_old(self):
print('test specific release (old, using sdk-* notation)')
run_emsdk('install sdk-fastcomp-1.38.31-64bit')
run_emsdk('activate sdk-fastcomp-1.38.31-64bit')
def test_specific_version(self):
print('test specific release (new, short name)')
run_emsdk('install 1.38.33')
print('another install, but no need for re-download')
checked_call_with_output(emsdk + ' install 1.38.33', expected='Skipped', unexpected='Downloading:')
run_emsdk('activate 1.38.33')
with open(emconfig) as f:
config = f.read()
assert 'upstream' not in config
assert 'fastcomp' in config
def test_specific_version_full(self):
print('test specific release (new, full name)')
run_emsdk('install sdk-1.38.33-upstream-64bit')
run_emsdk('activate sdk-1.38.33-upstream-64bit')
print('test specific release (new, tag name)')
run_emsdk('install sdk-tag-1.38.33-64bit')
run_emsdk('activate sdk-tag-1.38.33-64bit')
def test_binaryen_from_source(self):
if MACOS:
self.skipTest("https://github.com/WebAssembly/binaryen/issues/4299")
print('test binaryen source build')
run_emsdk(['install', '--build=Release', '--generator=Unix Makefiles', 'binaryen-main-64bit'])
def test_no_32bit(self):
print('test 32-bit error')
emsdk_hacked = hack_emsdk('not is_os_64bit()', 'True')
failing_call_with_output('python %s install latest' % emsdk_hacked, 'this tool is only provided for 64-bit OSes')
os.remove(emsdk_hacked)
def test_update_no_git(self):
print('test non-git update')
temp_dir = tempfile.mkdtemp()
for filename in os.listdir('.'):
if not filename.startswith('.') and not os.path.isdir(filename):
shutil.copy2(filename, os.path.join(temp_dir, filename))
os.chdir(temp_dir)
run_emsdk('update')
print('second time')
run_emsdk('update')
def test_install_arbitrary(self):
# Test that its possible to install arbrary emscripten-releases SDKs
run_emsdk('install 5c776e6a91c0cb8edafca16a652ee1ee48f4f6d2')
# Check that its not re-downloaded
checked_call_with_output(emsdk + ' install 5c776e6a91c0cb8edafca16a652ee1ee48f4f6d2', expected='Skipped', unexpected='Downloading:')
def test_install_tool(self):
# Test that its possible to install emscripten as tool instead of SDK
checked_call_with_output(emsdk + ' install releases-upstream-77b065ace39e6ab21446e13f92897f956c80476a', unexpected='Installing SDK')
def test_activate_missing(self):
run_emsdk('install latest')
failing_call_with_output(emsdk + ' activate 2.0.1', expected="error: tool is not installed and therefore cannot be activated: 'releases-upstream-13e29bd55185e3c12802bc090b4507901856b2ba-64bit'")
def test_keep_downloads(self):
env = os.environ.copy()
env['EMSDK_KEEP_DOWNLOADS'] = '1'
# With EMSDK_KEEP_DOWNLOADS the downloading should happen on the first
# install of 2.0.28, and again when we install 2.0.29, but not on the
# second install of 2.0.28 because the zip should already be local.
checked_call_with_output(emsdk + ' install 2.0.28', expected='Downloading:', env=env)
checked_call_with_output(emsdk + ' install 2.0.29', expected='Downloading:', env=env)
checked_call_with_output(emsdk + ' install 2.0.28', expected='already downloaded, skipping', unexpected='Downloading:', env=env)
if __name__ == '__main__':
unittest.main(verbosity=2)