summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Grönholm <alex.gronholm@nextday.fi>2014-10-20 13:10:42 +0300
committerAlex Grönholm <alex.gronholm@nextday.fi>2014-10-20 13:22:52 +0300
commit3082ac98cdb0cf2ffcb5071a9b979a18a1e74426 (patch)
treec25bfdc24b69152535cc94db4a571d9e3e51b959
parent7947840c0bc6981210bfca46c540f546fa7644cc (diff)
downloadapscheduler-3082ac98cdb0cf2ffcb5071a9b979a18a1e74426.tar.gz
Fixed _run_job_error() being called with the wrong number of arguments in most executors
-rw-r--r--apscheduler/executors/asyncio.py2
-rw-r--r--apscheduler/executors/gevent.py2
-rw-r--r--apscheduler/executors/pool.py5
-rw-r--r--apscheduler/executors/twisted.py2
-rw-r--r--tests/test_executors.py61
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)