test slow and never-finishing spawners

This commit is contained in:
Min RK
2014-12-19 17:20:42 -08:00
parent 53880f52b8
commit 6d95bf1893
2 changed files with 72 additions and 0 deletions

View File

@@ -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

View File

@@ -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