Skip to content

Commit 5ac23bf

Browse files
committed
Perform pip install as part of bootstrap.py
Also, install pip packages in local `out/python_deps` directory instead of installing system wide. This means we can consistently expect dev dependencies to be available in test code without needing to include an opt out mechanism. We were already doing this for `psutil`, but for `websockify` we made it optional. This means that only python scripts that explicitly add `out/python_deps` to their python path will be able use the packages, and in particular it means that the emscripten compiler itself won't end up implicitly/accidentally depending on them.
1 parent 41697da commit 5ac23bf

File tree

5 files changed

+16
-52
lines changed

5 files changed

+16
-52
lines changed

.circleci/config.yml

Lines changed: 1 addition & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -61,15 +61,10 @@ commands:
6161
- run: ./bootstrap
6262
pip-install:
6363
description: "pip install"
64-
parameters:
65-
python:
66-
description: "Python executable to use"
67-
type: string
68-
default: python3
6964
steps:
7065
- run:
7166
name: pip install
72-
command: << parameters.python >> -m pip install -r requirements-dev.txt
67+
command: python3 -m pip install -r requirements-dev.txt
7368
install-rust:
7469
steps:
7570
- run:
@@ -186,7 +181,6 @@ commands:
186181
name: clear cache
187182
command: |
188183
./emcc --clear-cache
189-
- pip-install
190184
- run: apt-get install -q -y ninja-build ccache
191185
- run:
192186
name: Ccache stats and configuration
@@ -266,7 +260,6 @@ commands:
266260
- checkout
267261
- emsdk-env
268262
- bootstrap
269-
- pip-install
270263
- when:
271264
# We only set EMTEST_RETRY_FLAKY on pull requests. When we run
272265
# normal CI jobs on branches like main we still want to be able to
@@ -871,7 +864,6 @@ jobs:
871864
executor: linux-python
872865
steps:
873866
- checkout
874-
- pip-install
875867
- install-emsdk
876868
- run:
877869
name: install jsc
@@ -893,7 +885,6 @@ jobs:
893885
executor: linux-python
894886
steps:
895887
- checkout
896-
- pip-install
897888
- install-emsdk
898889
- run:
899890
name: install spidermonkey
@@ -920,7 +911,6 @@ jobs:
920911
EMTEST_SKIP_V8: "1"
921912
steps:
922913
- checkout
923-
- pip-install
924914
- install-emsdk
925915
# `install-node-version` only changes the NODE_JS_TEST (the version of
926916
# node used to run test), not NODE_JS (the version of node used to run the
@@ -1078,7 +1068,6 @@ jobs:
10781068
EMTEST_LACKS_WEBGPU: "1"
10791069
steps:
10801070
- checkout
1081-
- pip-install
10821071
- install-emsdk
10831072
- run-tests-chrome:
10841073
title: "browser"
@@ -1162,7 +1151,6 @@ jobs:
11621151
executor: focal
11631152
steps:
11641153
- checkout
1165-
- pip-install
11661154
- install-emsdk
11671155
- run-tests-firefox:
11681156
title: "browser64"
@@ -1191,8 +1179,6 @@ jobs:
11911179
name: Add python to bash path
11921180
command: echo "export PATH=\"$PATH:/c/Python27amd64/\"" >> $BASH_ENV
11931181
- install-emsdk
1194-
- pip-install:
1195-
python: "$EMSDK_PYTHON"
11961182
- run-tests-firefox-windows:
11971183
title: "browser on firefox on windows"
11981184
# skip browser.test_glbook, as it requires mingw32-make, which is not
@@ -1256,8 +1242,6 @@ jobs:
12561242
# note we do *not* build all libraries and freeze the cache; as we run
12571243
# only limited tests here, it's more efficient to build on demand
12581244
- install-emsdk
1259-
- pip-install:
1260-
python: "$EMSDK_PYTHON"
12611245
- run-tests:
12621246
title: "crossplatform tests"
12631247
test_targets: "--crossplatform-only"
@@ -1285,8 +1269,6 @@ jobs:
12851269
steps:
12861270
- setup-macos
12871271
- install-emsdk
1288-
- pip-install:
1289-
python: "$EMSDK_PYTHON"
12901272
- freeze-cache
12911273
- run-tests:
12921274
title: "crossplatform tests"

bootstrap.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@
3939
'test/third_party/googletest',
4040
'test/third_party/wasi-test-suite',
4141
], ['git', 'submodule', 'update', '--init']),
42+
('pip3 install', [
43+
'requirements-dev.txt',
44+
], [sys.executable, '-m', 'pip', 'install', '--target', 'out/python_deps', '-r', 'requirements-dev.txt']),
4245
]
4346

4447

pyproject.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ mypy_path = "third_party/,third_party/ply,third_party/websockify"
8686
files = [ "." ]
8787
exclude = '''
8888
(?x)(
89+
out |
8990
cache |
9091
third_party |
9192
conf\.py |

test/runner.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,15 @@
3636

3737
__rootpath__ = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
3838
sys.path.insert(0, __rootpath__)
39+
# Add `out/python_deps` to ensure that we can import our dev dependencies.
40+
sys.path.insert(0, os.path.join(__rootpath__, 'out', 'python_deps'))
41+
# Now explictly import some dev dependencies so we can error early if they
42+
# Are missing
43+
try:
44+
import psutil # noqa: F401
45+
import websockify # type: ignore # noqa: F401
46+
except ModuleNotFoundError as e:
47+
raise Exception('Unable to import python dev dependencies (psutil/websockify). Run "./bootstrap" (or "python3 -m pip -r requirements-dev.txt --target out/python_deps") to install') from e
3948

4049
import common
4150
import jsrun
@@ -44,8 +53,6 @@
4453

4554
from tools import config, shared, utils
4655

47-
sys.path.append(utils.path_from_root('third_party/websockify'))
48-
4956
logger = logging.getLogger("runner")
5057

5158

test/test_sockets.py

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
from subprocess import Popen
1313
from typing import List
1414

15+
import websockify # type: ignore
16+
1517
if __name__ == '__main__':
1618
raise Exception('do not run this file directly; do something like: test/runner sockets')
1719

@@ -33,22 +35,9 @@
3335

3436
npm_checked = False
3537

36-
EMTEST_SKIP_PYTHON_DEV_PACKAGES = int(os.getenv('EMTEST_SKIP_PYTHON_DEV_PACKAGES', '0'))
3738
EMTEST_SKIP_NODE_DEV_PACKAGES = int(os.getenv('EMTEST_SKIP_NODE_DEV_PACKAGES', '0'))
3839

3940

40-
def requires_python_dev_packages(func):
41-
assert callable(func)
42-
43-
@common.wraps(func)
44-
def decorated(self, *args, **kwargs):
45-
if EMTEST_SKIP_PYTHON_DEV_PACKAGES:
46-
return self.skipTest('python websockify based tests are disabled by EMTEST_SKIP_PYTHON_DEV_PACKAGES=1')
47-
return func(self, *args, **kwargs)
48-
49-
return decorated
50-
51-
5241
def clean_processes(processes):
5342
for p in processes:
5443
if getattr(p, 'exitcode', None) is None and getattr(p, 'returncode', None) is None:
@@ -85,11 +74,6 @@ def __enter__(self):
8574
process = Popen([os.path.abspath('server')])
8675
self.processes.append(process)
8776

88-
try:
89-
import websockify # type: ignore # noqa: PLC0415
90-
except ModuleNotFoundError:
91-
raise Exception('Unable to import module websockify. Run "python3 -m pip install websockify" or set environment variable EMTEST_SKIP_PYTHON_DEV_PACKAGES=1 to skip this test.') from None
92-
9377
# start the websocket proxy
9478
print('running websockify on %d, forward to tcp %d' % (self.listen_port, self.target_port), file=sys.stderr)
9579
# source_is_ipv6=True here signals to websockify that it should prefer ipv6 address when
@@ -210,8 +194,6 @@ def setUpClass(cls):
210194
def test_sockets_echo(self, harness_class, port, args):
211195
if harness_class == WebsockifyServerHarness and common.EMTEST_LACKS_NATIVE_CLANG:
212196
self.skipTest('requires native clang')
213-
if harness_class == WebsockifyServerHarness and EMTEST_SKIP_PYTHON_DEV_PACKAGES:
214-
self.skipTest('requires python websockify and EMTEST_SKIP_PYTHON_DEV_PACKAGES=1')
215197
if harness_class == CompiledServerHarness and EMTEST_SKIP_NODE_DEV_PACKAGES:
216198
self.skipTest('requires node ws and EMTEST_SKIP_NODE_DEV_PACKAGES=1')
217199

@@ -238,8 +220,6 @@ def test_sdl2_sockets_echo(self):
238220
def test_sockets_async_echo(self, harness_class, port, args):
239221
if harness_class == WebsockifyServerHarness and common.EMTEST_LACKS_NATIVE_CLANG:
240222
self.skipTest('requires native clang')
241-
if harness_class == WebsockifyServerHarness and EMTEST_SKIP_PYTHON_DEV_PACKAGES:
242-
self.skipTest('requires python websockify and EMTEST_SKIP_PYTHON_DEV_PACKAGES=1')
243223
if harness_class == CompiledServerHarness and EMTEST_SKIP_NODE_DEV_PACKAGES:
244224
self.skipTest('requires node ws and EMTEST_SKIP_NODE_DEV_PACKAGES=1')
245225

@@ -260,8 +240,6 @@ def test_sockets_async_bad_port(self):
260240
def test_sockets_echo_bigdata(self, harness_class, port, args):
261241
if harness_class == WebsockifyServerHarness and common.EMTEST_LACKS_NATIVE_CLANG:
262242
self.skipTest('requires native clang')
263-
if harness_class == WebsockifyServerHarness and EMTEST_SKIP_PYTHON_DEV_PACKAGES:
264-
self.skipTest('requires python websockify and EMTEST_SKIP_PYTHON_DEV_PACKAGES=1')
265243
if harness_class == CompiledServerHarness and EMTEST_SKIP_NODE_DEV_PACKAGES:
266244
self.skipTest('requires node ws and EMTEST_SKIP_NODE_DEV_PACKAGES=1')
267245
sockets_include = '-I' + test_file('sockets')
@@ -279,7 +257,6 @@ def test_sockets_echo_bigdata(self, harness_class, port, args):
279257
self.btest_exit('test_sockets_echo_bigdata.c', cflags=[sockets_include, '-DSOCKK=%d' % harness.listen_port] + args)
280258

281259
@no_windows('This test is Unix-specific.')
282-
@requires_python_dev_packages
283260
@requires_dev_dependency('ws')
284261
def test_sockets_partial(self):
285262
for harness in [
@@ -290,7 +267,6 @@ def test_sockets_partial(self):
290267
self.btest_exit('sockets/test_sockets_partial_client.c', assert_returncode=165, cflags=['-DSOCKK=%d' % harness.listen_port])
291268

292269
@no_windows('This test is Unix-specific.')
293-
@requires_python_dev_packages
294270
@requires_dev_dependency('ws')
295271
def test_sockets_select_server_down(self):
296272
for harness in [
@@ -301,7 +277,6 @@ def test_sockets_select_server_down(self):
301277
self.btest_exit('sockets/test_sockets_select_server_down_client.c', cflags=['-DSOCKK=%d' % harness.listen_port])
302278

303279
@no_windows('This test is Unix-specific.')
304-
@requires_python_dev_packages
305280
@requires_dev_dependency('ws')
306281
def test_sockets_select_server_closes_connection_rw(self):
307282
for harness in [
@@ -334,8 +309,6 @@ def test_enet(self):
334309
def test_nodejs_sockets_echo(self, harness_class, port, args):
335310
if harness_class == WebsockifyServerHarness and common.EMTEST_LACKS_NATIVE_CLANG:
336311
self.skipTest('requires native clang')
337-
if harness_class == WebsockifyServerHarness and EMTEST_SKIP_PYTHON_DEV_PACKAGES:
338-
self.skipTest('requires python websockify and EMTEST_SKIP_PYTHON_DEV_PACKAGES=1')
339312
if harness_class == CompiledServerHarness and EMTEST_SKIP_NODE_DEV_PACKAGES:
340313
self.skipTest('requires node ws and EMTEST_SKIP_NODE_DEV_PACKAGES=1')
341314

@@ -348,7 +321,6 @@ def test_nodejs_sockets_connect_failure(self):
348321
self.do_runf('sockets/test_sockets_echo_client.c', r'connect failed: (Connection refused|Host is unreachable)', regex=True, cflags=['-DSOCKK=666'], assert_returncode=NON_ZERO)
349322

350323
@requires_native_clang
351-
@requires_python_dev_packages
352324
def test_nodejs_sockets_echo_subprotocol(self):
353325
# Test against a Websockified server with compile time configured WebSocket subprotocol. We use a Websockified
354326
# server because as long as the subprotocol list contains binary it will configure itself to accept binary
@@ -361,7 +333,6 @@ def test_nodejs_sockets_echo_subprotocol(self):
361333
self.assertContained(['connect: ws://127.0.0.1:59168, base64,binary', 'connect: ws://127.0.0.1:59168/, base64,binary'], out)
362334

363335
@requires_native_clang
364-
@requires_python_dev_packages
365336
def test_nodejs_sockets_echo_subprotocol_runtime(self):
366337
# Test against a Websockified server with runtime WebSocket configuration. We specify both url and subprotocol.
367338
# In this test we have *deliberately* used the wrong port '-DSOCKK=12345' to configure the echo_client.c, so

0 commit comments

Comments
 (0)