2014-05-05 08:49:29 +00:00
|
|
|
# -*- coding: utf-8 -*-
|
2012-02-15 20:55:06 +00:00
|
|
|
"""
|
|
|
|
This file contains all jobs that are used in tests. Each of these test
|
|
|
|
fixtures has a slighty different characteristics.
|
|
|
|
"""
|
2014-05-05 08:49:29 +00:00
|
|
|
from __future__ import (absolute_import, division, print_function,
|
|
|
|
unicode_literals)
|
|
|
|
|
2014-09-08 10:31:05 +00:00
|
|
|
import os
|
2012-02-22 17:01:14 +00:00
|
|
|
import time
|
2020-01-04 03:14:52 +00:00
|
|
|
import signal
|
2016-07-25 11:04:47 +00:00
|
|
|
import sys
|
2014-05-05 08:49:29 +00:00
|
|
|
|
2016-06-04 14:15:27 +00:00
|
|
|
from rq import Connection, get_current_job, get_current_connection, Queue
|
2012-07-23 06:25:31 +00:00
|
|
|
from rq.decorators import job
|
2018-10-26 13:27:36 +00:00
|
|
|
from rq.compat import PY2, text_type
|
2016-06-04 14:15:27 +00:00
|
|
|
from rq.worker import HerokuWorker
|
2012-07-23 06:25:31 +00:00
|
|
|
|
2014-09-08 18:29:24 +00:00
|
|
|
|
2014-09-08 10:31:05 +00:00
|
|
|
def say_pid():
|
|
|
|
return os.getpid()
|
2012-02-22 16:39:14 +00:00
|
|
|
|
2014-09-08 18:29:24 +00:00
|
|
|
|
2012-02-15 20:55:06 +00:00
|
|
|
def say_hello(name=None):
|
|
|
|
"""A job with a single argument and a return value."""
|
|
|
|
if name is None:
|
|
|
|
name = 'Stranger'
|
|
|
|
return 'Hi there, %s!' % (name,)
|
|
|
|
|
2012-02-22 16:39:14 +00:00
|
|
|
|
2017-04-19 04:16:24 +00:00
|
|
|
def say_hello_unicode(name=None):
|
|
|
|
"""A job with a single argument and a return value."""
|
2018-10-26 13:27:36 +00:00
|
|
|
return text_type(say_hello(name)) # noqa
|
2017-04-19 04:16:24 +00:00
|
|
|
|
|
|
|
|
2012-02-15 20:55:06 +00:00
|
|
|
def do_nothing():
|
|
|
|
"""The best job in the world."""
|
|
|
|
pass
|
|
|
|
|
2012-02-22 16:39:14 +00:00
|
|
|
|
2012-02-15 20:55:06 +00:00
|
|
|
def div_by_zero(x):
|
|
|
|
"""Prepare for a division-by-zero exception."""
|
|
|
|
return x / 0
|
|
|
|
|
2012-02-22 16:39:14 +00:00
|
|
|
|
2012-02-15 20:55:06 +00:00
|
|
|
def some_calculation(x, y, z=1):
|
|
|
|
"""Some arbitrary calculation with three numbers. Choose z smartly if you
|
|
|
|
want a division by zero exception.
|
|
|
|
"""
|
|
|
|
return x * y / z
|
|
|
|
|
2012-02-22 16:39:14 +00:00
|
|
|
|
2012-02-15 20:55:06 +00:00
|
|
|
def create_file(path):
|
|
|
|
"""Creates a file at the given path. Actually, leaves evidence that the
|
|
|
|
job ran."""
|
|
|
|
with open(path, 'w') as f:
|
|
|
|
f.write('Just a sentinel.')
|
2012-02-22 17:01:14 +00:00
|
|
|
|
|
|
|
|
|
|
|
def create_file_after_timeout(path, timeout):
|
|
|
|
time.sleep(timeout)
|
|
|
|
create_file(path)
|
2012-07-17 10:48:41 +00:00
|
|
|
|
|
|
|
|
2012-09-02 20:34:11 +00:00
|
|
|
def access_self():
|
2016-01-09 15:43:44 +00:00
|
|
|
assert get_current_connection() is not None
|
2015-04-12 09:15:55 +00:00
|
|
|
assert get_current_job() is not None
|
2012-09-02 20:34:11 +00:00
|
|
|
|
|
|
|
|
2017-01-09 16:49:36 +00:00
|
|
|
def modify_self(meta):
|
|
|
|
j = get_current_job()
|
|
|
|
j.meta.update(meta)
|
|
|
|
j.save()
|
|
|
|
|
|
|
|
|
2017-01-09 17:06:57 +00:00
|
|
|
def modify_self_and_error(meta):
|
|
|
|
j = get_current_job()
|
|
|
|
j.meta.update(meta)
|
|
|
|
j.save()
|
|
|
|
return 1 / 0
|
|
|
|
|
|
|
|
|
2014-04-11 09:47:31 +00:00
|
|
|
def echo(*args, **kwargs):
|
2017-09-08 09:28:10 +00:00
|
|
|
return args, kwargs
|
2014-04-11 09:47:31 +00:00
|
|
|
|
|
|
|
|
2013-04-19 19:18:23 +00:00
|
|
|
class Number(object):
|
|
|
|
def __init__(self, value):
|
|
|
|
self.value = value
|
2012-07-17 10:48:41 +00:00
|
|
|
|
2013-04-19 19:18:23 +00:00
|
|
|
@classmethod
|
|
|
|
def divide(cls, x, y):
|
|
|
|
return x * y
|
|
|
|
|
|
|
|
def div(self, y):
|
|
|
|
return self.value / y
|
2012-07-23 06:25:31 +00:00
|
|
|
|
2012-07-24 10:33:22 +00:00
|
|
|
|
2014-07-26 07:33:58 +00:00
|
|
|
class CallableObject(object):
|
|
|
|
def __call__(self):
|
|
|
|
return u"I'm callable"
|
|
|
|
|
|
|
|
|
2015-05-28 21:15:18 +00:00
|
|
|
class UnicodeStringObject(object):
|
|
|
|
def __repr__(self):
|
2015-05-28 21:23:04 +00:00
|
|
|
if PY2:
|
|
|
|
return u'é'.encode('utf-8')
|
|
|
|
else:
|
|
|
|
return u'é'
|
2015-05-28 21:15:18 +00:00
|
|
|
|
|
|
|
|
2012-07-24 10:33:22 +00:00
|
|
|
with Connection():
|
|
|
|
@job(queue='default')
|
|
|
|
def decorated_job(x, y):
|
|
|
|
return x + y
|
2012-07-26 02:36:50 +00:00
|
|
|
|
|
|
|
|
2014-11-12 14:04:40 +00:00
|
|
|
def black_hole(job, *exc_info):
|
|
|
|
# Don't fall through to default behaviour (moving to failed queue)
|
|
|
|
return False
|
2015-07-03 10:06:20 +00:00
|
|
|
|
|
|
|
|
2019-03-30 02:13:56 +00:00
|
|
|
def add_meta(job, *exc_info):
|
|
|
|
job.meta = {'foo': 1}
|
|
|
|
job.save()
|
|
|
|
return True
|
|
|
|
|
|
|
|
|
2018-10-20 04:49:14 +00:00
|
|
|
def save_key_ttl(key):
|
|
|
|
# Stores key ttl in meta
|
|
|
|
job = get_current_job()
|
|
|
|
ttl = job.connection.ttl(key)
|
|
|
|
job.meta = {'ttl': ttl}
|
|
|
|
job.save_meta()
|
|
|
|
|
|
|
|
|
2015-01-29 13:19:50 +00:00
|
|
|
def long_running_job(timeout=10):
|
|
|
|
time.sleep(timeout)
|
|
|
|
return 'Done sleeping...'
|
2016-06-04 14:15:27 +00:00
|
|
|
|
|
|
|
|
|
|
|
def run_dummy_heroku_worker(sandbox, _imminent_shutdown_delay):
|
|
|
|
"""
|
2016-06-04 15:05:52 +00:00
|
|
|
Run the work horse for a simplified heroku worker where perform_job just
|
|
|
|
creates two sentinel files 2 seconds apart.
|
2016-06-04 14:15:27 +00:00
|
|
|
:param sandbox: directory to create files in
|
2016-06-04 15:05:52 +00:00
|
|
|
:param _imminent_shutdown_delay: delay to use for HerokuWorker
|
2016-06-04 14:15:27 +00:00
|
|
|
"""
|
2016-07-25 11:04:47 +00:00
|
|
|
sys.stderr = open(os.path.join(sandbox, 'stderr.log'), 'w')
|
|
|
|
|
2016-06-04 14:15:27 +00:00
|
|
|
class TestHerokuWorker(HerokuWorker):
|
|
|
|
imminent_shutdown_delay = _imminent_shutdown_delay
|
|
|
|
|
|
|
|
def perform_job(self, job, queue):
|
|
|
|
create_file(os.path.join(sandbox, 'started'))
|
2016-06-04 15:05:52 +00:00
|
|
|
# have to loop here rather than one sleep to avoid holding the GIL
|
|
|
|
# and preventing signals being received
|
2016-06-04 14:15:27 +00:00
|
|
|
for i in range(20):
|
|
|
|
time.sleep(0.1)
|
|
|
|
create_file(os.path.join(sandbox, 'finished'))
|
|
|
|
|
|
|
|
w = TestHerokuWorker(Queue('dummy'))
|
|
|
|
w.main_work_horse(None, None)
|
2017-08-31 11:23:17 +00:00
|
|
|
|
|
|
|
|
|
|
|
class DummyQueue(object):
|
|
|
|
pass
|
2020-01-04 03:14:52 +00:00
|
|
|
|
|
|
|
|
|
|
|
def kill_worker(pid, double_kill, interval=0.5):
|
|
|
|
# wait for the worker to be started over on the main process
|
|
|
|
time.sleep(interval)
|
|
|
|
os.kill(pid, signal.SIGTERM)
|
|
|
|
if double_kill:
|
|
|
|
# give the worker time to switch signal handler
|
|
|
|
time.sleep(interval)
|
|
|
|
os.kill(pid, signal.SIGTERM)
|
2020-04-16 12:53:48 +00:00
|
|
|
|
|
|
|
|
|
|
|
class Serializer(object):
|
|
|
|
def loads(self): pass
|
|
|
|
|
|
|
|
def dumps(self): pass
|
|
|
|
|