Skip to content

Commit dfa1188

Browse files
authored
Fix tests (#316)
* Removed rq.compat * Install setuptools before running CI * Properly decode strings * Try using redis-py version 4 * Add compatibility with RQ 2.0 * Fix tests * Fix test_callbacks.py * Use newer version of Redis action * Use `Worker` instead of `SimpleWorker` in test * Use multiple queue names * More fixes
1 parent 656898e commit dfa1188

File tree

7 files changed

+27
-72
lines changed

7 files changed

+27
-72
lines changed

.github/workflows/workflow.yml

+2-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ jobs:
1717
matrix:
1818
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11", "3.12"]
1919
redis-version: [4, 5, 6, 7]
20-
redis-py-version: [3.5.0]
20+
redis-py-version: [4]
2121

2222
steps:
2323
- uses: actions/checkout@v3
@@ -28,7 +28,7 @@ jobs:
2828
python-version: ${{ matrix.python-version }}
2929

3030
- name: Start Redis
31-
uses: supercharge/redis-github-action@1.5.0
31+
uses: supercharge/redis-github-action@1.8.0
3232
with:
3333
redis-version: ${{ matrix.redis-version }}
3434

rq_scheduler/scheduler.py

+6-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
from itertools import repeat
1010

1111
from rq.exceptions import NoSuchJobError
12-
from rq.job import Job
12+
from rq.job import Job, JobStatus
1313
from rq.queue import Queue
1414
from rq.utils import backend_class, import_attribute
1515

@@ -30,8 +30,9 @@ class Scheduler(object):
3030

3131
def __init__(self, queue_name='default', queue=None, interval=60, connection=None,
3232
job_class=None, queue_class=None, name=None):
33-
from rq.connections import resolve_connection
34-
self.connection = resolve_connection(connection)
33+
if connection is None:
34+
raise ValueError('`connection` argument is required')
35+
self.connection = connection
3536
self._queue = queue
3637
if self._queue is None:
3738
self.queue_name = queue_name
@@ -143,7 +144,8 @@ def _create_job(self, func, args=None, kwargs=None, commit=True,
143144
func, args=args, connection=self.connection,
144145
kwargs=kwargs, result_ttl=result_ttl, ttl=ttl, id=id,
145146
description=description, timeout=timeout, meta=meta,
146-
depends_on=depends_on,on_success=on_success,on_failure=on_failure,
147+
depends_on=depends_on, on_success=on_success, on_failure=on_failure,
148+
status=JobStatus.SCHEDULED
147149
)
148150
if queue_name:
149151
job.origin = queue_name

setup.py

+2-3
Original file line numberDiff line numberDiff line change
@@ -19,20 +19,19 @@
1919
rqscheduler = rq_scheduler.scripts.rqscheduler:main
2020
''',
2121
package_data={'': ['README.rst']},
22-
install_requires=['crontab>=0.23.0', 'rq>=0.13', 'python-dateutil', 'freezegun'],
22+
install_requires=['crontab>=0.23.0', 'rq>=2', 'python-dateutil', 'freezegun'],
2323
classifiers=[
2424
'Development Status :: 4 - Beta',
2525
'Environment :: Console',
2626
'Intended Audience :: Developers',
2727
'License :: OSI Approved :: MIT License',
2828
'Operating System :: OS Independent',
2929
'Programming Language :: Python :: 3',
30-
'Programming Language :: Python :: 3.6',
31-
'Programming Language :: Python :: 3.7',
3230
'Programming Language :: Python :: 3.8',
3331
'Programming Language :: Python :: 3.9',
3432
'Programming Language :: Python :: 3.10',
3533
'Programming Language :: Python :: 3.11',
34+
'Programming Language :: Python :: 3.12',
3635
'Topic :: Software Development :: Libraries :: Python Modules',
3736
],
3837
)

tests/__init__.py

+2-16
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import unittest
22
from redis import StrictRedis
3-
from rq import push_connection, pop_connection
43

54

65
def find_empty_redis_database():
@@ -27,12 +26,7 @@ class RQTestCase(unittest.TestCase):
2726

2827
@classmethod
2928
def setUpClass(cls):
30-
# Set up connection to Redis
31-
testconn = find_empty_redis_database()
32-
push_connection(testconn)
33-
34-
# Store the connection (for sanity checking)
35-
cls.testconn = testconn
29+
cls.testconn = find_empty_redis_database()
3630

3731
def setUp(self):
3832
# Flush beforewards (we like our hygiene)
@@ -64,12 +58,4 @@ def assertIsInstance(self, obj, cls, msg=None):
6458

6559
@classmethod
6660
def tearDownClass(cls):
67-
68-
# Pop the connection to Redis
69-
testconn = pop_connection()
70-
assert testconn == cls.testconn, 'Wow, something really nasty ' \
71-
'happened to the Redis connection stack. Check your setup.'
72-
73-
# for python < 2.7, which doesn't have setUpClass
74-
if not hasattr(unittest.TestCase, 'setUpClass'):
75-
RQTestCase.setUpClass()
61+
pass

tests/fixtures.py

+1-32
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
from multiprocessing import Process
1616

1717
from redis import Redis
18-
from rq import Connection, get_current_job, get_current_connection, Queue
18+
from rq import get_current_job, Queue
1919
from rq.decorators import job
2020
from rq.worker import HerokuWorker, Worker
2121

@@ -66,17 +66,6 @@ def some_calculation(x, y, z=1):
6666
return x * y / z
6767

6868

69-
def rpush(key, value, append_worker_name=False, sleep=0):
70-
"""Push a value into a list in Redis. Useful for detecting the order in
71-
which jobs were executed."""
72-
if sleep:
73-
time.sleep(sleep)
74-
if append_worker_name:
75-
value += ':' + get_current_job().worker_name
76-
redis = get_current_connection()
77-
redis.rpush(key, value)
78-
79-
8069
def check_dependencies_are_met():
8170
return get_current_job().dependencies_are_met()
8271

@@ -105,11 +94,6 @@ def launch_process_within_worker_and_store_pid(path, timeout):
10594
p.wait()
10695

10796

108-
def access_self():
109-
assert get_current_connection() is not None
110-
assert get_current_job() is not None
111-
112-
11397
def modify_self(meta):
11498
j = get_current_job()
11599
j.meta.update(meta)
@@ -155,12 +139,6 @@ def static_method():
155139
return u"I'm a static method"
156140

157141

158-
with Connection():
159-
@job(queue='default')
160-
def decorated_job(x, y):
161-
return x + y
162-
163-
164142
def black_hole(job, *exc_info):
165143
# Don't fall through to default behaviour (moving to failed queue)
166144
return False
@@ -240,15 +218,6 @@ def start_worker(queue_name, conn_kwargs, worker_name, burst):
240218
w = Worker([queue_name], name=worker_name, connection=Redis(**conn_kwargs))
241219
w.work(burst=burst)
242220

243-
def start_worker_process(queue_name, connection=None, worker_name=None, burst=False):
244-
"""
245-
Use multiprocessing to start a new worker in a separate process.
246-
"""
247-
connection = connection or get_current_connection()
248-
conn_kwargs = connection.connection_pool.connection_kwargs
249-
p = Process(target=start_worker, args=(queue_name, conn_kwargs, worker_name, burst))
250-
p.start()
251-
return p
252221

253222
def burst_two_workers(queue, timeout=2, tries=5, pause=0.1):
254223
"""

tests/test_callbacks.py

+8-9
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
from rq import Queue, Worker
77
from rq.job import Job, JobStatus, UNEVALUATED
8-
from rq.worker import SimpleWorker
8+
from rq.worker import SimpleWorker, Worker
99

1010

1111
class QueueCallbackTestCase(RQTestCase):
@@ -51,7 +51,7 @@ class WorkerCallbackTestCase(RQTestCase):
5151
def test_success_callback(self):
5252
"""Test success callback is executed only when job is successful"""
5353
queue = Queue(connection=self.testconn)
54-
worker = SimpleWorker([queue])
54+
worker = SimpleWorker(['default', 'high'], connection=self.testconn)
5555

5656
job = queue.enqueue(say_hello, on_success=save_result)
5757

@@ -71,7 +71,7 @@ def test_success_callback(self):
7171
def test_erroneous_success_callback(self):
7272
"""Test exception handling when executing success callback"""
7373
queue = Queue(connection=self.testconn)
74-
worker = Worker([queue])
74+
worker = Worker(['default', 'high'], connection=self.testconn)
7575

7676
# If success_callback raises an error, job will is considered as failed
7777
job = queue.enqueue(say_hello, on_success=erroneous_callback)
@@ -81,15 +81,14 @@ def test_erroneous_success_callback(self):
8181
def test_failure_callback(self):
8282
"""Test failure callback is executed only when job a fails"""
8383
queue = Queue(connection=self.testconn)
84-
worker = SimpleWorker([queue])
84+
worker = Worker(['default', 'high'], connection=self.testconn)
8585

8686
job = queue.enqueue(div_by_zero, on_failure=save_exception)
8787

8888
# Callback is executed when job is successfully executed
8989
worker.work(burst=True)
9090
self.assertEqual(job.get_status(), JobStatus.FAILED)
9191
job.refresh()
92-
print(job.exc_info)
9392
self.assertIn('div_by_zero',
9493
self.testconn.get('failure_callback:%s' % job.id).decode())
9594

@@ -103,7 +102,7 @@ class JobCallbackTestCase(RQTestCase):
103102

104103
def test_job_creation_with_success_callback(self):
105104
"""Ensure callbacks are created and persisted properly"""
106-
job = Job.create(say_hello)
105+
job = Job.create(say_hello, connection=self.testconn)
107106
self.assertIsNone(job._success_callback_name)
108107
# _success_callback starts with UNEVALUATED
109108
self.assertEqual(job._success_callback, UNEVALUATED)
@@ -112,7 +111,7 @@ def test_job_creation_with_success_callback(self):
112111
self.assertEqual(job._success_callback, None)
113112

114113
# job.success_callback is assigned properly
115-
job = Job.create(say_hello, on_success=print)
114+
job = Job.create(say_hello, on_success=print, connection=self.testconn)
116115
self.assertIsNotNone(job._success_callback_name)
117116
self.assertEqual(job.success_callback, print)
118117
job.save()
@@ -122,7 +121,7 @@ def test_job_creation_with_success_callback(self):
122121

123122
def test_job_creation_with_failure_callback(self):
124123
"""Ensure failure callbacks are persisted properly"""
125-
job = Job.create(say_hello)
124+
job = Job.create(say_hello, connection=self.testconn)
126125
self.assertIsNone(job._failure_callback_name)
127126
# _failure_callback starts with UNEVALUATED
128127
self.assertEqual(job._failure_callback, UNEVALUATED)
@@ -131,7 +130,7 @@ def test_job_creation_with_failure_callback(self):
131130
self.assertEqual(job._failure_callback, None)
132131

133132
# job.failure_callback is assigned properly
134-
job = Job.create(say_hello, on_failure=print)
133+
job = Job.create(say_hello, on_failure=print, connection=self.testconn)
135134
self.assertIsNotNone(job._failure_callback_name)
136135
self.assertEqual(job.failure_callback, print)
137136
job.save()

tests/test_scheduler.py

+6-6
Original file line numberDiff line numberDiff line change
@@ -381,9 +381,9 @@ def test_enqueue_job(self):
381381
self.assertTrue(job.enqueued_at is not None)
382382
queue = scheduler.get_queue_for_job(job)
383383
self.assertIn(job, queue.jobs)
384-
queue = Queue.from_queue_key('rq:queue:{0}'.format(queue_name))
384+
queue = Queue.from_queue_key('rq:queue:{0}'.format(queue_name), connection=self.testconn)
385385
self.assertIn(job, queue.jobs)
386-
self.assertIn(queue, Queue.all())
386+
self.assertIn(queue, Queue.all(self.testconn))
387387

388388
def test_enqueue_job_with_scheduler_queue(self):
389389
"""
@@ -398,7 +398,7 @@ def test_enqueue_job_with_scheduler_queue(self):
398398
scheduler.enqueue_job(job)
399399
self.assertTrue(job.enqueued_at is not None)
400400
self.assertIn(job, queue.jobs)
401-
self.assertIn(queue, Queue.all())
401+
self.assertIn(queue, Queue.all(self.testconn))
402402

403403
def test_enqueue_job_with_job_queue_name(self):
404404
"""
@@ -413,7 +413,7 @@ def test_enqueue_job_with_job_queue_name(self):
413413
scheduler.enqueue_job(job)
414414
self.assertTrue(job.enqueued_at is not None)
415415
self.assertIn(job, job_queue.jobs)
416-
self.assertIn(job_queue, Queue.all())
416+
self.assertIn(job_queue, Queue.all(self.testconn))
417417

418418
def test_enqueue_at_with_job_queue_name(self):
419419
"""
@@ -428,7 +428,7 @@ def test_enqueue_at_with_job_queue_name(self):
428428
self.scheduler.enqueue_job(job)
429429
self.assertTrue(job.enqueued_at is not None)
430430
self.assertIn(job, job_queue.jobs)
431-
self.assertIn(job_queue, Queue.all())
431+
self.assertIn(job_queue, Queue.all(self.testconn))
432432

433433
def test_job_membership(self):
434434
now = datetime.utcnow()
@@ -797,7 +797,7 @@ def test_scheduler_w_o_explicit_connection(self):
797797
"""
798798
Ensure instantiating Scheduler w/o explicit connection works.
799799
"""
800-
s = Scheduler()
800+
s = Scheduler(connection=self.testconn)
801801
self.assertEqual(s.connection, self.testconn)
802802

803803
def test_small_float_interval(self):

0 commit comments

Comments
 (0)