MockJupyter#

class rubin.nublado.client.MockJupyter(base_url, user_dir, *, use_subdomains=False)#

Bases: object

A mock Jupyter state machine.

This should be invoked via mocked HTTP calls so that tests can simulate making REST calls to the real JupyterHub and Lab. It simulates the process of spawning a lab, creating a session, and running code within that session.

It also has two result registration methods, register_python_result and register_extension_result. These allow you to mock responses for specific Python inputs that would be executed in the running Lab, so that you do not need to replicate the target environment in your test suite.

If the username is provided in X-Auth-Request-User in the request headers, that name will be used. This will be the case when the mock is behind something emulating a GafaelfawrIngress, and is how the actual Hub would be called. If it is not, an Authorization header of the form Bearer <token> will be expected, and the username will be taken to be the portion after gt- and before the first period.

Parameters:
  • base_url (str) – Base URL at which to install the Jupyter mocks.

  • user_dir (Path) – Simulated user home directory for the /files route.

  • use_subdomains (bool, default: False) – If True, simulate per-user subdomains. JupyterHub will use the URL nb.hostname where the hostname is taken from base_url, and JupyterLab will use username.nb.hostname.

Methods Summary

create_session(request, user)

delete_lab(request, user)

delete_session(request, user)

fail(user, action)

Configure the given action to fail for the given user.

get_content(request, user)

Simulate the /files retrieval endpoint.

get_python_result(code)

Get the cached results for a specific block of code.

lab(request, user)

lab_callback(request, user)

Simulate not setting the _xsrf cookie on first request.

login(request, user)

missing_lab(request, user)

progress(request, user)

register_extension_result(code, result)

Register the expected notebook execution result for a given input notebook text.

register_python_result(code, result)

Register the expected cell output for a given source input.

run_notebook_via_extension(request, user)

Simulate the /rubin/execution endpoint.

spawn(request, user)

spawn_pending(request, user)

user(request, user)

Methods Documentation

async create_session(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async delete_lab(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async delete_session(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

fail(user, action)#

Configure the given action to fail for the given user.

Parameters:
Return type:

None

async get_content(request, user)#

Simulate the /files retrieval endpoint.

Parameters:
  • request (Request)

  • user (str)

Return type:

Response

get_python_result(code)#

Get the cached results for a specific block of code.

Parameters:

code (str | None) – Code for which to retrieve results.

Returns:

Corresponding results, or None if there are no results for this code.

Return type:

str or None

async lab(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async lab_callback(request, user)#

Simulate not setting the _xsrf cookie on first request.

This happens at the end of a chain from /user/username/lab to /hub/api/oauth2/authorize, which then issues a redirect to /user/username/oauth_callback. It is in the final redirect that the _xsrf cookie is actually set, and then this callback returns a 200 response without setting a cookie.

Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async login(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async missing_lab(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async progress(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

register_extension_result(code, result)#

Register the expected notebook execution result for a given input notebook text.

Parameters:
Return type:

None

register_python_result(code, result)#

Register the expected cell output for a given source input.

Parameters:
Return type:

None

async run_notebook_via_extension(request, user)#

Simulate the /rubin/execution endpoint.

Notes

This does not use the nbconvert/nbformat method of the actual endpoint, because installing kernels into what are already-running pythons in virtual evironments in the testing environment is nasty.

First, we will try using the input notebook text as a key into a cache of registered responses (this is analogous to doing the same with registered responses to python snippets in the Session mock): if the key is present, then we will return the response that corresponds to that key.

If not, we’re just going to return the input notebook as if it ran without errors, but without updating any of its outputs or resources, or throwing an error. This is not a a very good simulation. But since the whole point of this is to run a notebook in a particular kernel context, and for us that usually means the “LSST” kernel with the DM Pipelines Stack in it, that would be incredibly awful to use in a unit test context. If you want to know if your notebook will really work, you’re going to have to run it in the correct kernel, and the client unit tests are not the place for that.

Much more likely is that you have a test notebook that should produce certain results in the wild. In that case, you would register those results, and then the correct output would be delivered by the cache.

Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async spawn(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async spawn_pending(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response

async user(request, user)#
Parameters:
  • request (Request)

  • user (str)

Return type:

Response