diff options
author | Alex Grönholm <alex.gronholm@nextday.fi> | 2014-10-20 12:36:14 +0300 |
---|---|---|
committer | Alex Grönholm <alex.gronholm@nextday.fi> | 2014-10-20 13:10:42 +0300 |
commit | 30d42c85eb85e279adb945528b8f807a06ebee15 (patch) | |
tree | 38d3f4f6fb62f1ae8a51b703aa7bb1fc8e2c1141 | |
parent | 6bdb59d2fc9243d24cf08ff528d5f19f9b0f2465 (diff) | |
download | apscheduler-30d42c85eb85e279adb945528b8f807a06ebee15.tar.gz |
Fixed _run_job_error() being called with the wrong number of arguments in most executors
-rw-r--r-- | apscheduler/executors/asyncio.py | 2 | ||||
-rw-r--r-- | apscheduler/executors/gevent.py | 2 | ||||
-rw-r--r-- | apscheduler/executors/pool.py | 5 | ||||
-rw-r--r-- | apscheduler/executors/twisted.py | 2 | ||||
-rw-r--r-- | tests/test_executors.py | 61 |
5 files changed, 48 insertions, 24 deletions
diff --git a/apscheduler/executors/asyncio.py b/apscheduler/executors/asyncio.py index 2618f61..fade99f 100644 --- a/apscheduler/executors/asyncio.py +++ b/apscheduler/executors/asyncio.py @@ -20,7 +20,7 @@ class AsyncIOExecutor(BaseExecutor): try: events = f.result() except: - self._run_job_error(job.id, *sys.exc_info()) + self._run_job_error(job.id, *sys.exc_info()[1:]) else: self._run_job_success(job.id, events) diff --git a/apscheduler/executors/gevent.py b/apscheduler/executors/gevent.py index 6281cdc..9f4db2f 100644 --- a/apscheduler/executors/gevent.py +++ b/apscheduler/executors/gevent.py @@ -22,7 +22,7 @@ class GeventExecutor(BaseExecutor): try: events = greenlet.get() except: - self._run_job_error(job.id, *sys.exc_info()) + self._run_job_error(job.id, *sys.exc_info()[1:]) else: self._run_job_success(job.id, events) diff --git a/apscheduler/executors/pool.py b/apscheduler/executors/pool.py index 9858a7a..2f4ef45 100644 --- a/apscheduler/executors/pool.py +++ b/apscheduler/executors/pool.py @@ -12,9 +12,10 @@ class BasePoolExecutor(BaseExecutor): def _do_submit_job(self, job, run_times): def callback(f): - exc = f.exception() + exc, tb = (f.exception_info() if hasattr(f, 'exception_info') else + (f.exception(), getattr(f.exception(), '__traceback__', None))) if exc: - self._run_job_error(job.id, exc) + self._run_job_error(job.id, exc, tb) else: self._run_job_success(job.id, f.result()) diff --git a/apscheduler/executors/twisted.py b/apscheduler/executors/twisted.py index a0b1570..2921722 100644 --- a/apscheduler/executors/twisted.py +++ b/apscheduler/executors/twisted.py @@ -19,7 +19,7 @@ class TwistedExecutor(BaseExecutor): if success: self._run_job_success(job.id, result) else: - self._run_job_error(job.id, result.type, result.value, result.tb) + self._run_job_error(job.id, result.value, result.tb) self._reactor.getThreadPool().callInThreadWithCallback(callback, run_job, job, job._jobstore_alias, run_times, self._logger.name) diff --git a/tests/test_executors.py b/tests/test_executors.py index 0fbe22e..9e04523 100644 --- a/tests/test_executors.py +++ b/tests/test_executors.py @@ -1,5 +1,7 @@ -import time from datetime import datetime +from threading import Event +from types import TracebackType +import time import pytest @@ -21,25 +23,15 @@ def mock_scheduler(timezone): return scheduler_ -@pytest.fixture -def threadpoolexecutor(request): - from apscheduler.executors.pool import ThreadPoolExecutor - executor = ThreadPoolExecutor() - request.addfinalizer(executor.shutdown) - return executor - - -@pytest.fixture -def processpoolexecutor(request): - from apscheduler.executors.pool import ProcessPoolExecutor - executor = ProcessPoolExecutor() - request.addfinalizer(executor.shutdown) - return executor - - -@pytest.fixture(params=[threadpoolexecutor, processpoolexecutor], ids=['threadpool', 'processpool']) +@pytest.fixture(params=['threadpool', 'processpool']) def executor(request, mock_scheduler): - executor_ = request.param(request) + if request.param == 'threadpool': + from apscheduler.executors.pool import ThreadPoolExecutor + executor_ = ThreadPoolExecutor() + else: + from apscheduler.executors.pool import ProcessPoolExecutor + executor_ = ProcessPoolExecutor() + executor_.start(mock_scheduler, 'dummy') request.addfinalizer(executor_.shutdown) return executor_ @@ -100,3 +92,34 @@ def test_submit_job(mock_scheduler, executor, create_job, freeze_time, timezone, elif event_code == EVENT_JOB_ERROR: assert str(event.exception) == 'test failure' assert isinstance(event.traceback, str) + + +class FauxJob(object): + id = 'abc' + max_instances = 1 + _jobstore_alias = 'foo' + + +def dummy_run_job(job, jobstore_alias, run_times, logger_name): + raise Exception('dummy') + + +def test_run_job_error(monkeypatch, executor): + """Tests that _run_job_error is properly called if an exception is raised in run_job()""" + + def run_job_error(job_id, exc, traceback): + assert job_id == 'abc' + exc_traceback[:] = [exc, traceback] + event.set() + + event = Event() + exc_traceback = [None, None] + monkeypatch.setattr('apscheduler.executors.base.run_job', dummy_run_job) + monkeypatch.setattr('apscheduler.executors.pool.run_job', dummy_run_job) + monkeypatch.setattr(executor, '_run_job_error', run_job_error) + executor.submit_job(FauxJob(), []) + + event.wait(2) + assert str(exc_traceback[0]) == "dummy" + if exc_traceback[1] is not None: + assert isinstance(exc_traceback[1], TracebackType) |