Skip to content

Commit e7794a5

Browse files
committed
Run test_emrun suite sequentially. In order to do that, it must be moved to its own file.
1 parent 4f6d116 commit e7794a5

3 files changed

Lines changed: 143 additions & 118 deletions

File tree

test/runner.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -372,7 +372,7 @@ def sort_tests_failing_and_slowest_first_comparator(x, y):
372372

373373

374374
def use_parallel_suite(module):
375-
suite_supported = module.__name__ not in {'test_sanity', 'test_benchmark', 'test_sockets', 'test_interactive', 'test_stress'}
375+
suite_supported = module.__name__ not in {'test_sanity', 'test_benchmark', 'test_sockets', 'test_interactive', 'test_stress', 'test_emrun'}
376376
if not common.EMTEST_SAVE_DIR and not shared.DEBUG:
377377
has_multiple_cores = parallel_testsuite.num_cores() > 1
378378
if suite_supported and has_multiple_cores:

test/test_browser.py

Lines changed: 0 additions & 117 deletions
Original file line numberDiff line numberDiff line change
@@ -5708,123 +5708,6 @@ def test_shell_minimal(self, args):
57085708
self.btest_exit('browser_test_hello_world.c', cflags=['--shell-file', path_from_root('html/shell_minimal.html')] + args)
57095709

57105710

5711-
class emrun(RunnerCore):
5712-
def test_emrun_info(self):
5713-
if not has_browser():
5714-
self.skipTest('need a browser')
5715-
result = self.run_process([EMRUN, '--system-info', '--browser_info'], stdout=PIPE).stdout
5716-
assert 'CPU' in result
5717-
assert 'Browser' in result
5718-
assert 'Traceback' not in result
5719-
5720-
result = self.run_process([EMRUN, '--list-browsers'], stdout=PIPE).stdout
5721-
assert 'Traceback' not in result
5722-
5723-
def test_no_browser(self):
5724-
# Test --no-browser mode where we have to take care of launching the browser ourselves
5725-
# and then killing emrun when we are done.
5726-
if not has_browser():
5727-
self.skipTest('need a browser')
5728-
5729-
self.run_process([EMCC, test_file('test_emrun.c'), '--emrun', '-o', 'hello_world.html'])
5730-
proc = subprocess.Popen([EMRUN, '--no-browser', '.', '--port=3333'], stdout=PIPE)
5731-
try:
5732-
if get_browser():
5733-
url = 'http://localhost:3333/hello_world.html?argv0'
5734-
print(f'Starting browser to {url}')
5735-
BrowserCore.browser_open(url)
5736-
try:
5737-
while True:
5738-
stdout = proc.stdout.read()
5739-
if b'Dumping out file' in stdout:
5740-
break
5741-
finally:
5742-
print('Terminating browser')
5743-
BrowserCore.browser_terminate()
5744-
finally:
5745-
print('Terminating emrun server')
5746-
proc.terminate()
5747-
proc.wait()
5748-
5749-
def test_program_arg_separator(self):
5750-
# Verify that trying to pass argument to the page without the `--` separator will
5751-
# generate an actionable error message
5752-
err = self.expect_fail([EMRUN, '--foo'])
5753-
self.assertContained('error: unrecognized arguments: --foo', err)
5754-
self.assertContained('remember to add `--` between arguments', err)
5755-
5756-
@also_with_threads
5757-
def test_emrun(self):
5758-
self.emcc('test_emrun.c', ['--emrun', '-o', 'test_emrun.html'])
5759-
if not has_browser():
5760-
self.skipTest('need a browser')
5761-
5762-
# We cannot run emrun from the temp directory the suite will clean up afterwards, since the
5763-
# browser that is launched will have that directory as startup directory, and the browser will
5764-
# not close as part of the test, pinning down the cwd on Windows and it wouldn't be possible to
5765-
# delete it. Therefore switch away from that directory before launching.
5766-
os.chdir(path_from_root())
5767-
5768-
# emrun tests may run in parallel processes, so each test case should use a unique port number
5769-
# to avoid port address already in use errors.
5770-
port = '6939'
5771-
if '-pthread' in self.cflags:
5772-
port = '6940'
5773-
5774-
args_base = [EMRUN, '--timeout', '30', '--safe_firefox_profile',
5775-
'--kill-exit', '--port', port, '--verbose',
5776-
'--log-stdout', self.in_dir('stdout.txt'),
5777-
'--log-stderr', self.in_dir('stderr.txt')]
5778-
5779-
if get_browser() is not None:
5780-
# If EMTEST_BROWSER carried command line arguments to pass to the browser,
5781-
# (e.g. "firefox -profile /path/to/foo") those can't be passed via emrun,
5782-
# so strip them out.
5783-
browser_cmd = shlex.split(get_browser())
5784-
browser_path = browser_cmd[0]
5785-
args_base += ['--browser', browser_path]
5786-
if len(browser_cmd) > 1:
5787-
browser_args = browser_cmd[1:]
5788-
if 'firefox' in browser_path and ('-profile' in browser_args or '--profile' in browser_args):
5789-
# emrun uses its own -profile, strip it out
5790-
parser = argparse.ArgumentParser(add_help=False) # otherwise it throws with -headless
5791-
parser.add_argument('-profile')
5792-
parser.add_argument('--profile')
5793-
browser_args = parser.parse_known_args(browser_args)[1]
5794-
if browser_args:
5795-
args_base += ['--browser_args', ' ' + ' '.join(browser_args)]
5796-
5797-
for args in [
5798-
[],
5799-
['--port', '0'],
5800-
['--private_browsing'],
5801-
['--dump_out_directory', 'other dir/multiple'],
5802-
['--dump_out_directory=foo_bar'],
5803-
]:
5804-
args = args_base + args + [self.in_dir('test_emrun.html'), '--', '1', '2', '--3', 'escaped space', 'with_underscore']
5805-
print(shlex.join(args))
5806-
proc = self.run_process(args, check=False)
5807-
self.assertEqual(proc.returncode, 100)
5808-
dump_dir = 'dump_out'
5809-
if '--dump_out_directory' in args:
5810-
dump_dir = 'other dir/multiple'
5811-
elif '--dump_out_directory=foo_bar' in args:
5812-
dump_dir = 'foo_bar'
5813-
self.assertExists(self.in_dir(f'{dump_dir}/test.dat'))
5814-
self.assertExists(self.in_dir(f'{dump_dir}/heap.dat'))
5815-
self.assertExists(self.in_dir(f'{dump_dir}/nested/with space.dat'))
5816-
stdout = read_file(self.in_dir('stdout.txt'))
5817-
stderr = read_file(self.in_dir('stderr.txt'))
5818-
self.assertContained('argc: 6', stdout)
5819-
self.assertContained('argv[3]: --3', stdout)
5820-
self.assertContained('argv[4]: escaped space', stdout)
5821-
self.assertContained('argv[5]: with_underscore', stdout)
5822-
self.assertContained('Hello, world!', stdout)
5823-
self.assertContained('Testing ASCII characters: !"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', stdout)
5824-
self.assertContained('Testing char sequences: %20%21 &auml;', stdout)
5825-
self.assertContained('hello, error stream!', stderr)
5826-
5827-
58285711
class browser64(browser):
58295712
def setUp(self):
58305713
super().setUp()

test/test_emrun.py

Lines changed: 142 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,142 @@
1+
# Copyright 2026 The Emscripten Authors. All rights reserved.
2+
# Emscripten is available under two separate licenses, the MIT license and the
3+
# University of Illinois/NCSA Open Source License. Both these licenses can be
4+
# found in the LICENSE file.
5+
6+
import os
7+
import shlex
8+
import subprocess
9+
10+
from tools.shared import EMCC, PIPE
11+
12+
from common import (
13+
EMRUN,
14+
RunnerCore,
15+
path_from_root,
16+
read_file,
17+
test_file
18+
)
19+
20+
from browser_common import (
21+
BrowserCore,
22+
get_browser,
23+
has_browser
24+
)
25+
26+
from test_browser import also_with_threads
27+
28+
class emrun(RunnerCore):
29+
def test_emrun_info(self):
30+
if not has_browser():
31+
self.skipTest('need a browser')
32+
result = self.run_process([EMRUN, '--system-info', '--browser_info'], stdout=PIPE).stdout
33+
assert 'CPU' in result
34+
assert 'Browser' in result
35+
assert 'Traceback' not in result
36+
37+
result = self.run_process([EMRUN, '--list-browsers'], stdout=PIPE).stdout
38+
assert 'Traceback' not in result
39+
40+
def test_no_browser(self):
41+
# Test --no-browser mode where we have to take care of launching the browser ourselves
42+
# and then killing emrun when we are done.
43+
if not has_browser():
44+
self.skipTest('need a browser')
45+
46+
self.run_process([EMCC, test_file('test_emrun.c'), '--emrun', '-o', 'hello_world.html'])
47+
proc = subprocess.Popen([EMRUN, '--no-browser', '.', '--port=3333'], stdout=PIPE)
48+
try:
49+
if get_browser():
50+
url = 'http://localhost:3333/hello_world.html?argv0'
51+
print(f'Starting browser to {url}')
52+
BrowserCore.browser_open(url)
53+
try:
54+
while True:
55+
stdout = proc.stdout.read()
56+
if b'Dumping out file' in stdout:
57+
break
58+
finally:
59+
print('Terminating browser')
60+
BrowserCore.browser_terminate()
61+
finally:
62+
print('Terminating emrun server')
63+
proc.terminate()
64+
proc.wait()
65+
66+
def test_program_arg_separator(self):
67+
# Verify that trying to pass argument to the page without the `--` separator will
68+
# generate an actionable error message
69+
err = self.expect_fail([EMRUN, '--foo'])
70+
self.assertContained('error: unrecognized arguments: --foo', err)
71+
self.assertContained('remember to add `--` between arguments', err)
72+
73+
@also_with_threads
74+
def test_emrun(self):
75+
self.emcc('test_emrun.c', ['--emrun', '-o', 'test_emrun.html'])
76+
if not has_browser():
77+
self.skipTest('need a browser')
78+
79+
# We cannot run emrun from the temp directory the suite will clean up afterwards, since the
80+
# browser that is launched will have that directory as startup directory, and the browser will
81+
# not close as part of the test, pinning down the cwd on Windows and it wouldn't be possible to
82+
# delete it. Therefore switch away from that directory before launching.
83+
os.chdir(path_from_root())
84+
85+
# emrun tests may run in parallel processes, so each test case should use a unique port number
86+
# to avoid port address already in use errors.
87+
port = '6939'
88+
if '-pthread' in self.cflags:
89+
port = '6940'
90+
91+
args_base = [EMRUN, '--timeout', '30', '--safe_firefox_profile',
92+
'--kill-exit', '--port', port, '--verbose',
93+
'--log-stdout', self.in_dir('stdout.txt'),
94+
'--log-stderr', self.in_dir('stderr.txt')]
95+
96+
if get_browser() is not None:
97+
# If EMTEST_BROWSER carried command line arguments to pass to the browser,
98+
# (e.g. "firefox -profile /path/to/foo") those can't be passed via emrun,
99+
# so strip them out.
100+
browser_cmd = shlex.split(get_browser())
101+
browser_path = browser_cmd[0]
102+
args_base += ['--browser', browser_path]
103+
if len(browser_cmd) > 1:
104+
browser_args = browser_cmd[1:]
105+
if 'firefox' in browser_path and ('-profile' in browser_args or '--profile' in browser_args):
106+
# emrun uses its own -profile, strip it out
107+
parser = argparse.ArgumentParser(add_help=False) # otherwise it throws with -headless
108+
parser.add_argument('-profile')
109+
parser.add_argument('--profile')
110+
browser_args = parser.parse_known_args(browser_args)[1]
111+
if browser_args:
112+
args_base += ['--browser_args', ' ' + ' '.join(browser_args)]
113+
114+
for args in [
115+
[],
116+
['--port', '0'],
117+
['--private_browsing'],
118+
['--dump_out_directory', 'other dir/multiple'],
119+
['--dump_out_directory=foo_bar'],
120+
]:
121+
args = args_base + args + [self.in_dir('test_emrun.html'), '--', '1', '2', '--3', 'escaped space', 'with_underscore']
122+
print(shlex.join(args))
123+
proc = self.run_process(args, check=False)
124+
self.assertEqual(proc.returncode, 100)
125+
dump_dir = 'dump_out'
126+
if '--dump_out_directory' in args:
127+
dump_dir = 'other dir/multiple'
128+
elif '--dump_out_directory=foo_bar' in args:
129+
dump_dir = 'foo_bar'
130+
self.assertExists(self.in_dir(f'{dump_dir}/test.dat'))
131+
self.assertExists(self.in_dir(f'{dump_dir}/heap.dat'))
132+
self.assertExists(self.in_dir(f'{dump_dir}/nested/with space.dat'))
133+
stdout = read_file(self.in_dir('stdout.txt'))
134+
stderr = read_file(self.in_dir('stderr.txt'))
135+
self.assertContained('argc: 6', stdout)
136+
self.assertContained('argv[3]: --3', stdout)
137+
self.assertContained('argv[4]: escaped space', stdout)
138+
self.assertContained('argv[5]: with_underscore', stdout)
139+
self.assertContained('Hello, world!', stdout)
140+
self.assertContained('Testing ASCII characters: !"$%&\'()*+,-./:;<=>?@[\\]^_`{|}~', stdout)
141+
self.assertContained('Testing char sequences: %20%21 &auml;', stdout)
142+
self.assertContained('hello, error stream!', stderr)

0 commit comments

Comments
 (0)