Skip to content

Commit 6961132

Browse files
committed
wip
1 parent c901d19 commit 6961132

File tree

9 files changed

+334
-63
lines changed

9 files changed

+334
-63
lines changed

scheduler/tests/test_old_models/__init__.py

Whitespace-only changes.

scheduler/tests/test_cron_task.py renamed to scheduler/tests/test_old_models/test_cron_task.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@
33
from scheduler import settings
44
from scheduler.models import CronTask
55
from scheduler.tools import create_worker
6-
from .test_old_models import BaseTestCases
7-
from .testtools import old_task_factory
8-
from ..queues import get_queue
6+
from scheduler.tests.test_old_models.test_old_models import BaseTestCases
7+
from scheduler.tests.testtools import old_task_factory
8+
from scheduler.queues import get_queue
99

1010

1111
class TestCronTask(BaseTestCases.TestBaseTask):

scheduler/tests/test_old_models.py renamed to scheduler/tests/test_old_models/test_old_models.py

Lines changed: 4 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -10,16 +10,11 @@
1010

1111
from scheduler import settings
1212
from scheduler.models import BaseTask, TaskArg, TaskKwarg, ScheduledTask
13+
from scheduler.queues import get_queue
14+
from scheduler.tests import jobs
15+
from scheduler.tests.testtools import (
16+
old_task_factory, taskarg_factory, _get_job_from_scheduled_registry, SchedulerBaseCase, _get_executions)
1317
from scheduler.tools import run_task, create_worker
14-
from . import jobs
15-
from .testtools import (
16-
old_task_factory,
17-
taskarg_factory,
18-
_get_job_from_scheduled_registry,
19-
SchedulerBaseCase,
20-
_get_executions,
21-
)
22-
from ..queues import get_queue
2318

2419

2520
def assert_response_has_msg(response, message):
Lines changed: 207 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,207 @@
1+
from datetime import timedelta
2+
3+
from django.core.exceptions import ValidationError
4+
from django.test import override_settings
5+
from django.utils import timezone
6+
7+
from scheduler import settings
8+
from scheduler.models import RepeatableTask
9+
from scheduler.tests.test_old_models.test_old_task_model import BaseTestCases
10+
11+
from scheduler.tests.testtools import old_task_factory, _get_job_from_scheduled_registry
12+
13+
14+
class TestRepeatableTask(BaseTestCases.TestSchedulableTask):
15+
TaskModelClass = RepeatableTask
16+
17+
def test_unschedulable_old_job(self):
18+
job = old_task_factory(self.TaskModelClass, scheduled_time=timezone.now() - timedelta(hours=1), repeat=0)
19+
self.assertFalse(job.is_scheduled())
20+
21+
def test_schedulable_old_job_repeat_none(self):
22+
# If repeat is None, the job should be scheduled
23+
job = old_task_factory(self.TaskModelClass, scheduled_time=timezone.now() - timedelta(hours=1), repeat=None)
24+
self.assertTrue(job.is_scheduled())
25+
26+
def test_clean(self):
27+
job = old_task_factory(self.TaskModelClass)
28+
job.queue = list(settings.QUEUES)[0]
29+
job.callable = "scheduler.tests.jobs.test_job"
30+
job.interval = 1
31+
job.result_ttl = -1
32+
self.assertIsNone(job.clean())
33+
34+
def test_clean_seconds(self):
35+
job = old_task_factory(self.TaskModelClass)
36+
job.queue = list(settings.QUEUES)[0]
37+
job.callable = "scheduler.tests.jobs.test_job"
38+
job.interval = 60
39+
job.result_ttl = -1
40+
job.interval_unit = "seconds"
41+
self.assertIsNone(job.clean())
42+
43+
@override_settings(
44+
SCHEDULER_CONFIG={
45+
"SCHEDULER_INTERVAL": 10,
46+
}
47+
)
48+
def test_clean_too_frequent(self):
49+
job = old_task_factory(self.TaskModelClass)
50+
job.queue = list(settings.QUEUES)[0]
51+
job.callable = "scheduler.tests.jobs.test_job"
52+
job.interval = 2 # Smaller than 10
53+
job.result_ttl = -1
54+
job.interval_unit = "seconds"
55+
with self.assertRaises(ValidationError):
56+
job.clean_interval_unit()
57+
58+
def test_clean_not_multiple(self):
59+
job = old_task_factory(self.TaskModelClass)
60+
job.queue = list(settings.QUEUES)[0]
61+
job.callable = "scheduler.tests.jobs.test_job"
62+
job.interval = 121
63+
job.interval_unit = "seconds"
64+
with self.assertRaises(ValidationError):
65+
job.clean_interval_unit()
66+
67+
def test_clean_short_result_ttl(self):
68+
job = old_task_factory(self.TaskModelClass)
69+
job.queue = list(settings.QUEUES)[0]
70+
job.callable = "scheduler.tests.jobs.test_job"
71+
job.interval = 1
72+
job.repeat = 1
73+
job.result_ttl = 3599
74+
job.interval_unit = "hours"
75+
job.repeat = 42
76+
with self.assertRaises(ValidationError):
77+
job.clean_result_ttl()
78+
79+
def test_clean_indefinite_result_ttl(self):
80+
job = old_task_factory(self.TaskModelClass)
81+
job.queue = list(settings.QUEUES)[0]
82+
job.callable = "scheduler.tests.jobs.test_job"
83+
job.interval = 1
84+
job.result_ttl = -1
85+
job.interval_unit = "hours"
86+
job.clean_result_ttl()
87+
88+
def test_clean_undefined_result_ttl(self):
89+
job = old_task_factory(self.TaskModelClass)
90+
job.queue = list(settings.QUEUES)[0]
91+
job.callable = "scheduler.tests.jobs.test_job"
92+
job.interval = 1
93+
job.interval_unit = "hours"
94+
job.clean_result_ttl()
95+
96+
def test_interval_seconds_weeks(self):
97+
job = old_task_factory(self.TaskModelClass, interval=2, interval_unit="weeks")
98+
self.assertEqual(1209600.0, job.interval_seconds())
99+
100+
def test_interval_seconds_days(self):
101+
job = old_task_factory(self.TaskModelClass, interval=2, interval_unit="days")
102+
self.assertEqual(172800.0, job.interval_seconds())
103+
104+
def test_interval_seconds_hours(self):
105+
job = old_task_factory(self.TaskModelClass, interval=2, interval_unit="hours")
106+
self.assertEqual(7200.0, job.interval_seconds())
107+
108+
def test_interval_seconds_minutes(self):
109+
job = old_task_factory(self.TaskModelClass, interval=15, interval_unit="minutes")
110+
self.assertEqual(900.0, job.interval_seconds())
111+
112+
def test_interval_seconds_seconds(self):
113+
job = RepeatableTask(interval=15, interval_unit="seconds")
114+
self.assertEqual(15.0, job.interval_seconds())
115+
116+
def test_interval_display(self):
117+
job = old_task_factory(self.TaskModelClass, interval=15, interval_unit="minutes")
118+
self.assertEqual(job.interval_display(), "15 minutes")
119+
120+
def test_result_interval(self):
121+
job = old_task_factory(
122+
self.TaskModelClass,
123+
)
124+
entry = _get_job_from_scheduled_registry(job)
125+
self.assertEqual(entry.meta["interval"], 3600)
126+
127+
def test_repeat(self):
128+
job = old_task_factory(self.TaskModelClass, repeat=10)
129+
entry = _get_job_from_scheduled_registry(job)
130+
self.assertEqual(entry.meta["repeat"], 10)
131+
132+
def test_repeat_old_job_exhausted(self):
133+
base_time = timezone.now()
134+
job = old_task_factory(self.TaskModelClass, scheduled_time=base_time - timedelta(hours=10), repeat=10)
135+
self.assertEqual(job.is_scheduled(), False)
136+
137+
def test_repeat_old_job_last_iter(self):
138+
base_time = timezone.now()
139+
job = old_task_factory(self.TaskModelClass, scheduled_time=base_time - timedelta(hours=9, minutes=30), repeat=10)
140+
self.assertEqual(job.repeat, 0)
141+
self.assertEqual(job.is_scheduled(), True)
142+
143+
def test_repeat_old_job_remaining(self):
144+
base_time = timezone.now()
145+
job = old_task_factory(self.TaskModelClass, scheduled_time=base_time - timedelta(minutes=30), repeat=5)
146+
self.assertEqual(job.repeat, 4)
147+
self.assertEqual(job.scheduled_time, base_time + timedelta(minutes=30))
148+
self.assertEqual(job.is_scheduled(), True)
149+
150+
def test_repeat_none_interval_2_min(self):
151+
base_time = timezone.now()
152+
job = old_task_factory(self.TaskModelClass, scheduled_time=base_time - timedelta(minutes=29), repeat=None)
153+
job.interval = 120
154+
job.interval_unit = "seconds"
155+
job.schedule()
156+
self.assertTrue(job.scheduled_time > base_time)
157+
self.assertTrue(job.is_scheduled())
158+
159+
def test_check_rescheduled_after_execution(self):
160+
task = old_task_factory(self.TaskModelClass, scheduled_time=timezone.now() + timedelta(seconds=1), repeat=10)
161+
queue = task.rqueue
162+
first_run_id = task.job_id
163+
entry = queue.fetch_job(first_run_id)
164+
queue.run_sync(entry)
165+
task.refresh_from_db()
166+
self.assertEqual(task.failed_runs, 0)
167+
self.assertIsNone(task.last_failed_run)
168+
self.assertEqual(task.successful_runs, 1)
169+
self.assertIsNotNone(task.last_successful_run)
170+
self.assertTrue(task.is_scheduled())
171+
self.assertNotEqual(task.job_id, first_run_id)
172+
173+
def test_check_rescheduled_after_execution_failed_job(self):
174+
task = old_task_factory(
175+
self.TaskModelClass,
176+
callable_name="scheduler.tests.jobs.failing_job",
177+
scheduled_time=timezone.now() + timedelta(seconds=1),
178+
repeat=10,
179+
)
180+
queue = task.rqueue
181+
first_run_id = task.job_id
182+
entry = queue.fetch_job(first_run_id)
183+
queue.run_sync(entry)
184+
task.refresh_from_db()
185+
self.assertEqual(task.failed_runs, 1)
186+
self.assertIsNotNone(task.last_failed_run)
187+
self.assertEqual(task.successful_runs, 0)
188+
self.assertIsNone(task.last_successful_run)
189+
self.assertTrue(task.is_scheduled())
190+
self.assertNotEqual(task.job_id, first_run_id)
191+
192+
def test_check_not_rescheduled_after_last_repeat(self):
193+
task = old_task_factory(
194+
self.TaskModelClass,
195+
scheduled_time=timezone.now() + timedelta(seconds=1),
196+
repeat=1,
197+
)
198+
queue = task.rqueue
199+
first_run_id = task.job_id
200+
entry = queue.fetch_job(first_run_id)
201+
queue.run_sync(entry)
202+
task.refresh_from_db()
203+
self.assertEqual(task.failed_runs, 0)
204+
self.assertIsNone(task.last_failed_run)
205+
self.assertEqual(task.successful_runs, 1)
206+
self.assertIsNotNone(task.last_successful_run)
207+
self.assertNotEqual(task.job_id, first_run_id)

scheduler/tests/test_old_task_model.py renamed to scheduler/tests/test_old_models/test_old_task_model.py

Lines changed: 6 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -11,15 +11,10 @@
1111
from scheduler import settings
1212
from scheduler.models import BaseTask, TaskArg, TaskKwarg, ScheduledTask
1313
from scheduler.tools import run_task, create_worker
14-
from . import jobs
15-
from .testtools import (
16-
old_task_factory,
17-
taskarg_factory,
18-
_get_job_from_scheduled_registry,
19-
SchedulerBaseCase,
20-
_get_executions,
21-
)
22-
from ..queues import get_queue
14+
from scheduler.tests import jobs
15+
from scheduler.tests.testtools import old_task_factory, taskarg_factory, _get_job_from_scheduled_registry, \
16+
SchedulerBaseCase, _get_executions
17+
from scheduler.queues import get_queue
2318

2419

2520
def assert_response_has_msg(response, message):
@@ -512,7 +507,7 @@ def test_admin_delete_selected(self):
512507
scheduled_jobs = queue.scheduled_job_registry.get_job_ids()
513508
self.assertNotIn(job_id, scheduled_jobs)
514509

515-
class TestSchedulableJob(TestBaseTask):
510+
class TestSchedulableTask(TestBaseTask):
516511
# Currently ScheduledJob and RepeatableJob
517512
TaskModelClass = ScheduledTask
518513

@@ -537,7 +532,7 @@ def test_result_ttl_passthrough(self):
537532
self.assertEqual(entry.result_ttl, 500)
538533

539534

540-
class TestScheduledJob(BaseTestCases.TestSchedulableJob):
535+
class TestScheduledJob(BaseTestCases.TestSchedulableTask):
541536
TaskModelClass = ScheduledTask
542537

543538
def test_clean(self):

scheduler/tests/test_task_types/__init__.py

Whitespace-only changes.
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from django.core.exceptions import ValidationError
2+
3+
from scheduler import settings
4+
from scheduler.queues import get_queue
5+
from scheduler.tests.test_task_types.test_task_model import BaseTestCases
6+
from scheduler.tests.testtools import task_factory
7+
from scheduler.tools import create_worker, TaskType
8+
9+
10+
class TestCronTask(BaseTestCases.TestBaseTask):
11+
task_type = TaskType.CRON
12+
13+
def test_clean(self):
14+
task = task_factory(self.task_type)
15+
task.cron_string = "* * * * *"
16+
task.queue = list(settings.QUEUES)[0]
17+
task.callable = "scheduler.tests.jobs.test_job"
18+
self.assertIsNone(task.clean())
19+
20+
def test_clean_cron_string_invalid(self):
21+
task = task_factory(self.task_type)
22+
task.cron_string = "not-a-cron-string"
23+
task.queue = list(settings.QUEUES)[0]
24+
task.callable = "scheduler.tests.jobs.test_job"
25+
with self.assertRaises(ValidationError):
26+
task.clean_cron_string()
27+
28+
def test_check_rescheduled_after_execution(self):
29+
task = task_factory(self.task_type)
30+
queue = task.rqueue
31+
first_run_id = task.job_id
32+
entry = queue.fetch_job(first_run_id)
33+
queue.run_sync(entry)
34+
task.refresh_from_db()
35+
self.assertEqual(task.failed_runs, 0)
36+
self.assertIsNone(task.last_failed_run)
37+
self.assertEqual(task.successful_runs, 1)
38+
self.assertIsNotNone(task.last_successful_run)
39+
self.assertTrue(task.is_scheduled())
40+
self.assertNotEqual(task.job_id, first_run_id)
41+
42+
def test_check_rescheduled_after_failed_execution(self):
43+
task = task_factory(
44+
self.task_type,
45+
callable_name="scheduler.tests.jobs.scheduler.tests.jobs.test_job",
46+
)
47+
queue = task.rqueue
48+
first_run_id = task.job_id
49+
entry = queue.fetch_job(first_run_id)
50+
queue.run_sync(entry)
51+
task.refresh_from_db()
52+
self.assertEqual(task.failed_runs, 1)
53+
self.assertIsNotNone(task.last_failed_run)
54+
self.assertEqual(task.successful_runs, 0)
55+
self.assertIsNone(task.last_successful_run)
56+
self.assertTrue(task.is_scheduled())
57+
self.assertNotEqual(task.job_id, first_run_id)
58+
59+
def test_cron_task_enqueuing_jobs(self):
60+
queue = get_queue()
61+
prev_queued = len(queue.scheduled_job_registry)
62+
prev_finished = len(queue.finished_job_registry)
63+
task = task_factory(self.task_type, callable_name="scheduler.tests.jobs.enqueue_jobs")
64+
self.assertEqual(prev_queued + 1, len(queue.scheduled_job_registry))
65+
first_run_id = task.job_id
66+
entry = queue.fetch_job(first_run_id)
67+
queue.run_sync(entry)
68+
self.assertEqual(20, len(queue))
69+
self.assertEqual(prev_finished + 1, len(queue.finished_job_registry))
70+
worker = create_worker(
71+
"default",
72+
fork_job_execution=False,
73+
)
74+
worker.work(burst=True)
75+
self.assertEqual(prev_finished + 21, len(queue.finished_job_registry))
76+
worker.refresh()
77+
self.assertEqual(20, worker.successful_job_count)
78+
self.assertEqual(0, worker.failed_job_count)

0 commit comments

Comments
 (0)