|
| 1 | +import json |
| 2 | +import re |
| 3 | +from unittest import mock |
| 4 | + |
| 5 | +from jupyterhub.tests.utils import get_page |
| 6 | + |
| 7 | +from .utils import MOSlurmSpawnerMock, post_request |
| 8 | + |
| 9 | + |
| 10 | +class MOSSMockSimple(MOSlurmSpawnerMock): |
| 11 | + """MOSlurmSpawner with mocks and a simple configuration""" |
| 12 | + |
| 13 | + def __init__(self, *args, **kwargs): |
| 14 | + super().__init__(*args, **kwargs) |
| 15 | + |
| 16 | + # Partition name, nnodes (allocated/idle/other/total), ncores_per_node, |
| 17 | + # ncores (allocated/idle/other/total), gpu, memory, timelimit |
| 18 | + self.slurm_info_cmd = ( |
| 19 | + 'echo "partition_1 2/46/0/48 35+ 38/1642/0/1680 (null) 196000+ 1-00:00:00"' |
| 20 | + ) |
| 21 | + |
| 22 | + # Set partitions here so that validation is run |
| 23 | + # Minimalistic default partitions config |
| 24 | + self.partitions = { |
| 25 | + "partition_1": { |
| 26 | + "architecture": "x86_86", |
| 27 | + "description": "Partition 1", |
| 28 | + "simple": True, |
| 29 | + "jupyter_environments": { |
| 30 | + "default": { |
| 31 | + "path": "/default/jupyter_env_path/bin/", |
| 32 | + "description": "default", |
| 33 | + "add_to_path": True, |
| 34 | + }, |
| 35 | + }, |
| 36 | + }, |
| 37 | + } |
| 38 | + |
| 39 | + |
| 40 | +async def test_spawn_page(app): |
| 41 | + """Test display of spawn page and check embedded SLURM resources info""" |
| 42 | + with mock.patch.dict(app.users.settings, {"spawner_class": MOSSMockSimple}): |
| 43 | + cookies = await app.login_user("jones") |
| 44 | + r = await get_page("spawn", app, cookies=cookies) |
| 45 | + |
| 46 | + assert r.status_code == 200 |
| 47 | + assert r.url.endswith("/spawn") |
| 48 | + |
| 49 | + match = re.search(r"window.SLURM_DATA = JSON.parse\('(?P<json>.*)'\)", r.text) |
| 50 | + assert match is not None |
| 51 | + slurm_data = json.loads(match.group("json")) |
| 52 | + |
| 53 | + ref_partitions_info = { |
| 54 | + "partition_1": { |
| 55 | + "nnodes_idle": 46, |
| 56 | + "nnodes_total": 48, |
| 57 | + "ncores_total": 1680, |
| 58 | + "ncores_idle": 1642, |
| 59 | + "max_nprocs": 35, |
| 60 | + "max_mem": 196000, |
| 61 | + "gpu": None, |
| 62 | + "max_ngpus": 0, |
| 63 | + "max_runtime": 86400, |
| 64 | + "architecture": "x86_86", |
| 65 | + "description": "Partition 1", |
| 66 | + "simple": True, |
| 67 | + "jupyter_environments": { |
| 68 | + "default": { |
| 69 | + "path": "/default/jupyter_env_path/bin/", |
| 70 | + "description": "default", |
| 71 | + "add_to_path": True, |
| 72 | + }, |
| 73 | + }, |
| 74 | + } |
| 75 | + } |
| 76 | + assert ref_partitions_info == slurm_data["partitions"] |
| 77 | + |
| 78 | + |
| 79 | +async def test_spawn_from_get_query(app): |
| 80 | + """Test spawning through a GET query""" |
| 81 | + with mock.patch.dict(app.users.settings, {"spawner_class": MOSSMockSimple}): |
| 82 | + cookies = await app.login_user("jones") |
| 83 | + r = await get_page("spawn?partition=partition_1&nprocs=4", app, cookies=cookies) |
| 84 | + |
| 85 | + assert r.status_code == 200 |
| 86 | + assert "/hub/spawn-pending" in r.url |
| 87 | + |
| 88 | + |
| 89 | +async def test_spawn_from_post_request(app): |
| 90 | + """Test spawning through a POST request""" |
| 91 | + with mock.patch.dict(app.users.settings, {"spawner_class": MOSSMockSimple}): |
| 92 | + cookies = await app.login_user("jones") |
| 93 | + r = await post_request( |
| 94 | + "spawn", |
| 95 | + app, |
| 96 | + cookies=cookies, |
| 97 | + data={"partition": "partition_1", "nprocs": 4}, |
| 98 | + ) |
| 99 | + |
| 100 | + assert r.status_code == 200 |
| 101 | + assert "/hub/spawn-pending" in r.url |
0 commit comments