Skip to content

Commit e3e7510

Browse files
authored
Merge pull request #1119 from voith/v4-add-websocket-timeout
[BACKPORT TO V4] Add timeout for WebsocketProvider
2 parents 8fae96b + bcde527 commit e3e7510

File tree

17 files changed

+110
-63
lines changed

17 files changed

+110
-63
lines changed

tests/conftest.py

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,16 @@
88
identity,
99
)
1010

11+
from .utils import (
12+
get_open_port,
13+
)
14+
1115

1216
@pytest.fixture(scope="module", params=[lambda x: to_bytes(hexstr=x), identity])
1317
def address_conversion_func(request):
1418
return request.param
19+
20+
21+
@pytest.fixture()
22+
def open_port():
23+
return get_open_port()

tests/core/providers/test_websocket_provider.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,18 @@
1+
import asyncio
2+
from concurrent.futures import (
3+
TimeoutError,
4+
)
15
import pytest
6+
from threading import (
7+
Thread,
8+
)
9+
10+
import websockets
211

12+
from tests.utils import (
13+
wait_for_ws,
14+
)
15+
from web3 import Web3
316
from web3.exceptions import (
417
ValidationError,
518
)
@@ -8,6 +21,42 @@
821
)
922

1023

24+
@pytest.yield_fixture
25+
def start_websocket_server(open_port):
26+
event_loop = asyncio.new_event_loop()
27+
28+
def run_server():
29+
async def empty_server(websocket, path):
30+
data = await websocket.recv()
31+
await asyncio.sleep(0.02)
32+
await websocket.send(data)
33+
server = websockets.serve(empty_server, '127.0.0.1', open_port, loop=event_loop)
34+
event_loop.run_until_complete(server)
35+
event_loop.run_forever()
36+
37+
thd = Thread(target=run_server)
38+
thd.start()
39+
try:
40+
yield
41+
finally:
42+
event_loop.call_soon_threadsafe(event_loop.stop)
43+
44+
45+
@pytest.fixture()
46+
def w3(open_port, start_websocket_server):
47+
# need new event loop as the one used by server is already running
48+
event_loop = asyncio.new_event_loop()
49+
endpoint_uri = 'ws://127.0.0.1:{}'.format(open_port)
50+
event_loop.run_until_complete(wait_for_ws(endpoint_uri, event_loop))
51+
provider = WebsocketProvider(endpoint_uri, websocket_timeout=0.01)
52+
return Web3(provider)
53+
54+
55+
def test_websocket_provider_timeout(w3):
56+
with pytest.raises(TimeoutError):
57+
w3.eth.accounts
58+
59+
1160
def test_restricted_websocket_kwargs():
1261
invalid_kwargs = {'uri': 'ws://127.0.0.1:8546'}
1362
re_exc_message = r'.*found: {0}*'.format(set(invalid_kwargs.keys()))

tests/generate_go_ethereum_fixture.py

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,9 @@
2222
to_wei,
2323
)
2424

25+
from tests.utils import (
26+
get_open_port,
27+
)
2528
from web3 import Web3
2629
from web3.utils.module_testing.emitter_contract import (
2730
EMITTER_ABI,
@@ -100,14 +103,6 @@ def tempdir():
100103
shutil.rmtree(dir_path)
101104

102105

103-
def get_open_port():
104-
sock = socket.socket()
105-
sock.bind(('127.0.0.1', 0))
106-
port = sock.getsockname()[1]
107-
sock.close()
108-
return str(port)
109-
110-
111106
def get_geth_binary():
112107
from geth.install import (
113108
get_executable_path,

tests/integration/generate_fixtures/common.py

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -76,14 +76,6 @@ def tempdir():
7676
shutil.rmtree(dir_path)
7777

7878

79-
def get_open_port():
80-
sock = socket.socket()
81-
sock.bind(('127.0.0.1', 0))
82-
port = sock.getsockname()[1]
83-
sock.close()
84-
return str(port)
85-
86-
8779
def get_geth_binary():
8880
from geth.install import (
8981
get_executable_path,

tests/integration/generate_fixtures/go_ethereum.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,9 @@
1111
)
1212

1313
import common
14+
from tests.utils import (
15+
get_open_port,
16+
)
1417
from web3 import Web3
1518
from web3.utils.module_testing.emitter_contract import (
1619
EMITTER_ABI,
@@ -42,7 +45,7 @@ def generate_go_ethereum_fixture(destination_dir):
4245
geth_ipc_path_dir = stack.enter_context(common.tempdir())
4346
geth_ipc_path = os.path.join(geth_ipc_path_dir, 'geth.ipc')
4447

45-
geth_port = common.get_open_port()
48+
geth_port = get_open_port()
4649
geth_binary = common.get_geth_binary()
4750

4851
geth_proc = stack.enter_context(common.get_geth_process( # noqa: F841

tests/integration/generate_fixtures/parity.py

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212

1313
import common
1414
import go_ethereum
15+
from tests.utils import (
16+
get_open_port,
17+
)
1518
from web3 import Web3
1619
from web3.utils.toolz import (
1720
merge,
@@ -176,7 +179,7 @@ def generate_parity_fixture(destination_dir):
176179

177180
geth_datadir = stack.enter_context(common.tempdir())
178181

179-
geth_port = common.get_open_port()
182+
geth_port = get_open_port()
180183

181184
geth_ipc_path_dir = stack.enter_context(common.tempdir())
182185
geth_ipc_path = os.path.join(geth_ipc_path_dir, 'geth.ipc')
@@ -221,7 +224,7 @@ def generate_parity_fixture(destination_dir):
221224
parity_ipc_path_dir = stack.enter_context(common.tempdir())
222225
parity_ipc_path = os.path.join(parity_ipc_path_dir, 'jsonrpc.ipc')
223226

224-
parity_port = common.get_open_port()
227+
parity_port = get_open_port()
225228
parity_binary = get_parity_binary()
226229

227230
parity_proc = stack.enter_context(get_parity_process( # noqa: F841

tests/integration/go_ethereum/common.py

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import pytest
2-
import socket
32

43
from web3.utils.module_testing import (
54
EthModuleTest,
@@ -10,14 +9,6 @@
109
)
1110

1211

13-
def get_open_port():
14-
sock = socket.socket()
15-
sock.bind(('127.0.0.1', 0))
16-
port = sock.getsockname()[1]
17-
sock.close()
18-
return str(port)
19-
20-
2112
class GoEthereumTest(Web3ModuleTest):
2213
def _check_web3_clientVersion(self, client_version):
2314
assert client_version.startswith('Geth/')

tests/integration/go_ethereum/test_goethereum_http.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
import pytest
22

3+
from tests.utils import (
4+
get_open_port,
5+
)
36
from web3 import Web3
47

58
from .common import (
@@ -8,7 +11,6 @@
811
GoEthereumPersonalModuleTest,
912
GoEthereumTest,
1013
GoEthereumVersionModuleTest,
11-
get_open_port,
1214
)
1315
from .utils import (
1416
wait_for_http,

tests/integration/go_ethereum/test_goethereum_ipc.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@
22
import pytest
33
import tempfile
44

5+
from tests.utils import (
6+
get_open_port,
7+
)
58
from web3 import Web3
69

710
from .common import (
@@ -12,7 +15,6 @@
1215
GoEthereumVersionModuleTest,
1316
)
1417
from .utils import (
15-
get_open_port,
1618
wait_for_socket,
1719
)
1820

tests/integration/go_ethereum/test_goethereum_ws.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,8 @@
33
from tests.integration.common import (
44
MiscWebsocketTest,
55
)
6-
from tests.integration.utils import (
6+
from tests.utils import (
7+
get_open_port,
78
wait_for_ws,
89
)
910
from web3 import Web3
@@ -14,7 +15,6 @@
1415
GoEthereumPersonalModuleTest,
1516
GoEthereumTest,
1617
GoEthereumVersionModuleTest,
17-
get_open_port,
1818
)
1919

2020

0 commit comments

Comments
 (0)