Skip to content
This repository was archived by the owner on Feb 8, 2024. It is now read-only.

Commit 61fa779

Browse files
committed
More elegant test utilities for examining crosstown tasks in a django view.
1 parent e185a25 commit 61fa779

File tree

5 files changed

+42
-30
lines changed

5 files changed

+42
-30
lines changed

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -14,3 +14,4 @@ _trial_temp*
1414
ignore*
1515
*.log
1616
*.log.*
17+
.idea

hendrix/experience/crosstown_traffic.py

+4-5
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,11 @@
33

44
class ModuleCaller(object):
55

6+
decorator = None
7+
68
def __init__(self, decorator=None):
7-
if not decorator:
8-
from hendrix.mechanics.async.decorators import ThroughToYou
9-
self.decorator = ThroughToYou
10-
else:
11-
self.decorator = decorator
9+
from hendrix.mechanics.async.decorators import ThroughToYou
10+
self.decorator = decorator or self.decorator or ThroughToYou
1211

1312
super(ModuleCaller, self).__init__()
1413

hendrix/mechanics/async/decorators.py

+10-5
Original file line numberDiff line numberDiff line change
@@ -36,13 +36,18 @@ def __call__(self, crosstown_task=None):
3636
if not self.no_go:
3737
self.response.crosstown_tasks.append(self)
3838
except ThreadHasNoResponse:
39-
if self.fail_without_response:
40-
raise
41-
else:
42-
self.log.info("thread %s has no response; running crosstown task now. To supress this behavior, set fail_without_response == True." % threading.current_thread())
43-
self.run()
39+
self.responseless_fallback(crosstown_task)
4440
return self.run
4541

42+
def responseless_fallback(self, crosstown_task=None):
43+
self.crosstown_task = crosstown_task or self.crosstown_task
44+
45+
if self.fail_without_response:
46+
raise ThreadHasNoResponse("This crosstown decorator cannot proceed without a response. To run the crosstown_task at this time, set fail_without_response = False.")
47+
else:
48+
self.log.info("thread %s has no response; running crosstown task now. To supress this behavior, set fail_without_response == True." % threading.current_thread())
49+
self.run()
50+
4651
def run(self, threadpool=None):
4752
if self.no_go:
4853
return

hendrix/test/test_testing_utils.py

+17-2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
from hendrix.experience import crosstown_traffic
2-
from hendrix.utils.test_utils import AsyncTestMixin
2+
from hendrix.utils.test_utils import AsyncTestMixin, crosstownTaskListDecoratorFactory
33
from twisted.trial.unittest import TestCase
44

55

@@ -48,4 +48,19 @@ def some_task():
4848
same_task = a_mixin.next_task()
4949

5050
# That will be the only (and thus last) task.
51-
self.assertRaises(StopIteration, a_mixin.next_task)
51+
self.assertRaises(StopIteration, a_mixin.next_task)
52+
53+
54+
class TestRecordTasksAsList(TestCase):
55+
56+
def test_record_task_to_list(self):
57+
task_list = []
58+
crosstown_traffic.decorator = crosstownTaskListDecoratorFactory(task_list)
59+
60+
self.assertEqual(len(task_list), 0)
61+
62+
@crosstown_traffic()
63+
def add_to_task_list():
64+
print "this will be in the task list"
65+
66+
self.assertEqual(len(task_list), 1)

hendrix/utils/test_utils/__init__.py

+10-18
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,18 @@
33
from hendrix.mechanics.async.decorators import ThroughToYou
44

55

6-
class MockThroughToYou(ThroughToYou):
6+
def crosstownTaskListDecoratorFactory(list_to_populate):
77

8-
log = Logger()
9-
warned_strange_overuse = False
8+
class TaskListThroughToYou(ThroughToYou):
109

11-
def __call__(self, crosstown_task):
12-
try:
13-
crosstown_traffic.recorded_tasks.append(crosstown_task)
14-
except AttributeError:
15-
raise TypeError('This is a MockThroughToYou object; it must be used with AsyncTestMixin or another compatible ThroughToYou object. If this is happening in production, this is a big deal.')
10+
def __init__(self, *args, **kwargs):
11+
self.crosstown_task_list = list_to_populate
12+
super(TaskListThroughToYou, self).__init__(*args, **kwargs)
1613

17-
if len(crosstown_traffic.recorded_tasks) > 10 and not self.warned_strange_overuse:
18-
self.log.warning("More than 10 tasks have been recorded in a pattern meant for tests. If this app is in production, something is wrong.")
19-
self.warned_strange_overuse = True
14+
def responseless_fallback(self, crosstown_task):
15+
self.crosstown_task_list.append(crosstown_task)
2016

21-
super(MockThroughToYou, self).__call__(crosstown_task)
17+
return TaskListThroughToYou
2218

2319

2420
class AsyncTestMixin(object):
@@ -28,14 +24,10 @@ def setUp(self):
2824
return super(AsyncTestMixin, self).setUp()
2925

3026
def sub_setUp(self):
31-
crosstown_traffic.decorator = MockThroughToYou
27+
self.recorded_tasks = []
28+
crosstown_traffic.decorator = crosstownTaskListDecoratorFactory(self.recorded_tasks)
3229
crosstown_traffic()
3330
self.archived_tasks = []
34-
self.recorded_tasks = crosstown_traffic.recorded_tasks = []
35-
36-
def tearDown(self):
37-
crosstown_traffic.__call__ = self.old_call
38-
return super(AsyncTestMixin, self).tearDown()
3931

4032
def next_task(self):
4133
for task in self.recorded_tasks:

0 commit comments

Comments
 (0)