Skip to content

Commit 6c530cc

Browse files
authored
Clean up echo kernel handling and update readme (#22)
1 parent e833bf8 commit 6c530cc

File tree

6 files changed

+46
-16
lines changed

6 files changed

+46
-16
lines changed

README.md

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,26 @@ To use a plugin, add it to the `pytest_plugins` list in the `conftest.py` of you
3131
pytest_plugins = ["pytest_jupyter.jupyter_server"]
3232
```
3333

34+
This library includes an `echo_kernel`, which is useful to speed up testing.
35+
You must have either `"pytest-jupyter[server]"` or `"pytest-jupyter[client]"`
36+
installed to use the echo kernel.
37+
38+
The `pytest_jupyter.jupyter_client` plugin provides an installed
39+
`echo_kernel_spec` as a fixture, and a `start_kernel` fixture
40+
that provides a factory function that starts a kernel using the `echo` kernel
41+
by default.
42+
43+
The server fixures use the echo kernel by default. To override this behavior,
44+
override the `jp_server_config` fixture and add the following config:
45+
46+
```json
47+
{
48+
"MultiKernelManager": {
49+
"default_kernel_name": "<desired_kernel_name"
50+
}
51+
}
52+
```
53+
3454
All fixtures inside the plugin (e.g. jupyter_server) will be available to all of your project's unit tests. You can use a fixtures by passing it as an argument to your unit test function:
3555

3656
```python

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ filterwarnings= [
9696
# Fail on warnings
9797
"error",
9898
# TODO: from jupyter_server
99-
"always:unclosed <socket.socket:ResourceWarning",
99+
"always:unclosed <socket.socket:ResourceWarning"
100100
]
101101

102102
[tool.coverage.report]

pytest_jupyter/jupyter_client.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -54,23 +54,24 @@ def zmq_context():
5454

5555

5656
@pytest.fixture
57-
async def start_kernel(kernel_spec):
58-
km = None
59-
kc = None
57+
async def start_kernel(echo_kernel_spec):
58+
kms = []
59+
kcs = []
6060

6161
async def inner(kernel_name="echo", **kwargs):
62-
nonlocal km, kc
6362
km, kc = await start_new_async_kernel(kernel_name=kernel_name, **kwargs)
63+
kms.append(km)
64+
kcs.append(kc)
6465
return km, kc
6566

6667
yield inner
6768

68-
if kc and km:
69+
for kc in kcs:
6970
kc.stop_channels()
71+
72+
for km in kms:
7073
await km.shutdown_kernel(now=True)
7174
assert km.context.closed
72-
km.context.destroy()
73-
km.context.term()
7475

7576

7677
@pytest.fixture()
@@ -79,7 +80,7 @@ def kernel_dir():
7980

8081

8182
@pytest.fixture
82-
def kernel_spec(kernel_dir):
83+
def echo_kernel_spec(kernel_dir):
8384
test_dir = Path(kernel_dir) / "echo"
8485
test_dir.mkdir(parents=True, exist_ok=True)
8586
argv = [sys.executable, "-m", "pytest_jupyter.echo_kernel", "-f", "{connection_file}"]

pytest_jupyter/jupyter_server.py

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@
4545
)
4646

4747

48-
from .jupyter_client import kernel_spec # noqa
48+
from .jupyter_client import echo_kernel_spec # noqa
4949
from .utils import mkdir
5050

5151
# List of dependencies needed for this plugin.
@@ -102,13 +102,14 @@ async def get_server():
102102
def jp_server_config():
103103
"""Allows tests to setup their specific configuration values."""
104104
if is_v2:
105-
return Config(
106-
{
105+
config = {
106+
"ServerApp": {
107107
"jpserver_extensions": {"jupyter_server_terminals": True},
108108
}
109-
)
109+
}
110110
else:
111-
return Config({})
111+
config = {}
112+
return Config(config)
112113

113114

114115
@pytest.fixture
@@ -191,7 +192,7 @@ def jp_configurable_serverapp(
191192
jp_logging_stream,
192193
asyncio_loop,
193194
io_loop,
194-
kernel_spec, # noqa
195+
echo_kernel_spec, # noqa
195196
):
196197
"""Starts a Jupyter Server instance based on
197198
the provided configuration values.
@@ -228,6 +229,9 @@ def _configurable_serverapp(
228229
c = Config(config)
229230
c.NotebookNotary.db_file = ":memory:"
230231

232+
if "default_kernel_name" not in c.MultiKernelManager:
233+
c.MultiKernelManager.default_kernel_name = "echo"
234+
231235
default_token = hexlify(os.urandom(4)).decode("ascii")
232236
if not is_v2:
233237
kwargs["token"] = default_token

tests/test_jupyter_client.py

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ async def test_start_kernel(start_kernel):
1515
msg = await kc.execute("hello", reply=True)
1616
assert msg["content"]["status"] == "ok"
1717

18+
km, kc = await start_kernel("python3")
19+
assert km.kernel_name == "python3"
20+
msg = await kc.execute("print('hi')", reply=True)
21+
assert msg["content"]["status"] == "ok"
22+
1823

1924
def test_echo_kernel():
2025
kernel = EchoKernel()

tests/test_jupyter_server.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ async def test_send_request(send_request):
2323

2424
async def test_connection(jp_fetch, jp_ws_fetch, jp_http_port, jp_auth_header):
2525
# Create kernel
26-
r = await jp_fetch("api", "kernels", method="POST", body=json.dumps({"name": "echo"}))
26+
r = await jp_fetch("api", "kernels", method="POST", body="{}")
2727
kid = json.loads(r.body.decode())["id"]
2828

2929
# Get kernel info

0 commit comments

Comments
 (0)