mirror of
https://github.com/jupyterhub/jupyterhub.git
synced 2025-10-13 13:03:01 +00:00
test slow and never-finishing spawners
This commit is contained in:
@@ -1,11 +1,14 @@
|
|||||||
"""mock utilities for testing"""
|
"""mock utilities for testing"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
|
from datetime import timedelta
|
||||||
from tempfile import NamedTemporaryFile
|
from tempfile import NamedTemporaryFile
|
||||||
import threading
|
import threading
|
||||||
|
|
||||||
from unittest import mock
|
from unittest import mock
|
||||||
|
|
||||||
|
from tornado import gen
|
||||||
|
from tornado.concurrent import Future
|
||||||
from tornado.ioloop import IOLoop
|
from tornado.ioloop import IOLoop
|
||||||
|
|
||||||
from ..spawner import LocalProcessSpawner
|
from ..spawner import LocalProcessSpawner
|
||||||
@@ -41,6 +44,26 @@ class MockSpawner(LocalProcessSpawner):
|
|||||||
return [sys.executable, '-m', 'jupyterhub.tests.mocksu']
|
return [sys.executable, '-m', 'jupyterhub.tests.mocksu']
|
||||||
|
|
||||||
|
|
||||||
|
class SlowSpawner(MockSpawner):
|
||||||
|
"""A spawner that takes a few seconds to start"""
|
||||||
|
|
||||||
|
@gen.coroutine
|
||||||
|
def start(self):
|
||||||
|
yield gen.Task(IOLoop.current().add_timeout, timedelta(seconds=5))
|
||||||
|
yield super().start()
|
||||||
|
|
||||||
|
|
||||||
|
class NeverSpawner(MockSpawner):
|
||||||
|
"""A spawner that will never start"""
|
||||||
|
|
||||||
|
def _start_timeout_default(self):
|
||||||
|
return 1
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
"""Return a Future that will never finish"""
|
||||||
|
return Future()
|
||||||
|
|
||||||
|
|
||||||
class MockPAMAuthenticator(PAMAuthenticator):
|
class MockPAMAuthenticator(PAMAuthenticator):
|
||||||
def system_user_exists(self, user):
|
def system_user_exists(self, user):
|
||||||
# skip the add-system-user bit
|
# skip the add-system-user bit
|
||||||
|
@@ -1,11 +1,15 @@
|
|||||||
"""Tests for the REST API"""
|
"""Tests for the REST API"""
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
from datetime import timedelta
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
|
from tornado import gen
|
||||||
|
|
||||||
from ..utils import url_path_join as ujoin
|
from ..utils import url_path_join as ujoin
|
||||||
from .. import orm
|
from .. import orm
|
||||||
|
from . import mocking
|
||||||
|
|
||||||
|
|
||||||
def check_db_locks(func):
|
def check_db_locks(func):
|
||||||
@@ -174,6 +178,7 @@ def test_spawn(app, io_loop):
|
|||||||
assert r.status_code == 201
|
assert r.status_code == 201
|
||||||
assert 'pid' in user.state
|
assert 'pid' in user.state
|
||||||
assert user.spawner is not None
|
assert user.spawner is not None
|
||||||
|
assert not user.spawn_pending
|
||||||
status = io_loop.run_sync(user.spawner.poll)
|
status = io_loop.run_sync(user.spawner.poll)
|
||||||
assert status is None
|
assert status is None
|
||||||
|
|
||||||
@@ -194,3 +199,47 @@ def test_spawn(app, io_loop):
|
|||||||
assert 'pid' not in user.state
|
assert 'pid' not in user.state
|
||||||
status = io_loop.run_sync(user.spawner.poll)
|
status = io_loop.run_sync(user.spawner.poll)
|
||||||
assert status == 0
|
assert status == 0
|
||||||
|
|
||||||
|
def test_slow_spawn(app, io_loop):
|
||||||
|
app.tornado_application.settings['spawner_class'] = mocking.SlowSpawner
|
||||||
|
app.tornado_application.settings['slow_spawn_timeout'] = 0
|
||||||
|
|
||||||
|
db = app.db
|
||||||
|
name = 'zoe'
|
||||||
|
user = add_user(db, name=name)
|
||||||
|
r = api_request(app, 'users', name, 'server', method='post')
|
||||||
|
assert user.spawner is not None
|
||||||
|
assert user.spawn_pending
|
||||||
|
|
||||||
|
dt = timedelta(seconds=0.1)
|
||||||
|
@gen.coroutine
|
||||||
|
def wait_pending():
|
||||||
|
while user.spawn_pending:
|
||||||
|
yield gen.Task(io_loop.add_timeout, dt)
|
||||||
|
|
||||||
|
io_loop.run_sync(wait_pending)
|
||||||
|
assert not user.spawn_pending
|
||||||
|
status = io_loop.run_sync(user.spawner.poll)
|
||||||
|
assert status is None
|
||||||
|
|
||||||
|
def test_never_spawn(app, io_loop):
|
||||||
|
app.tornado_application.settings['spawner_class'] = mocking.NeverSpawner
|
||||||
|
app.tornado_application.settings['slow_spawn_timeout'] = 0
|
||||||
|
|
||||||
|
db = app.db
|
||||||
|
name = 'badger'
|
||||||
|
user = add_user(db, name=name)
|
||||||
|
r = api_request(app, 'users', name, 'server', method='post')
|
||||||
|
assert user.spawner is not None
|
||||||
|
assert user.spawn_pending
|
||||||
|
|
||||||
|
dt = timedelta(seconds=0.1)
|
||||||
|
@gen.coroutine
|
||||||
|
def wait_pending():
|
||||||
|
while user.spawn_pending:
|
||||||
|
yield gen.Task(io_loop.add_timeout, dt)
|
||||||
|
|
||||||
|
io_loop.run_sync(wait_pending)
|
||||||
|
assert not user.spawn_pending
|
||||||
|
status = io_loop.run_sync(user.spawner.poll)
|
||||||
|
assert status is not None
|
||||||
|
Reference in New Issue
Block a user