3 from __future__ import absolute_import, print_function
10 import arvnodeman.clientactor as clientactor
11 from . import testutil
13 class RemotePollLoopActorTestCase(testutil.RemotePollLoopActorTestMixin,
15 class MockClientError(Exception):
18 class TestActor(clientactor.RemotePollLoopActor):
19 LOGGER_NAME = 'arvnodeman.testpoll'
21 def _send_request(self):
23 TestActor.CLIENT_ERRORS = (MockClientError,)
24 TEST_CLASS = TestActor
27 def build_monitor(self, side_effect, *args, **kwargs):
28 super(RemotePollLoopActorTestCase, self).build_monitor(*args, **kwargs)
29 self.client.side_effect = side_effect
31 def test_poll_loop_starts_after_subscription(self):
32 self.build_monitor(['test1'])
33 self.monitor.subscribe(self.subscriber)
34 self.wait_for_call(self.subscriber)
35 self.subscriber.assert_called_with('test1')
36 self.wait_for_call(self.timer.schedule)
38 def test_poll_loop_continues_after_failure(self):
39 self.build_monitor(self.MockClientError)
40 self.monitor.subscribe(self.subscriber)
41 self.wait_for_call(self.timer.schedule)
42 self.assertTrue(self.monitor.actor_ref.is_alive(),
43 "poll loop died after error")
44 self.assertFalse(self.subscriber.called,
45 "poll loop notified subscribers after error")
47 def test_late_subscribers_get_responses(self):
48 self.build_monitor(['late_test'])
49 self.monitor.subscribe(lambda response: None)
50 self.monitor.subscribe(self.subscriber)
52 self.wait_for_call(self.subscriber)
53 self.subscriber.assert_called_with('late_test')
55 def test_survive_dead_subscriptions(self):
56 self.build_monitor(['survive1', 'survive2'])
57 dead_subscriber = mock.Mock(name='dead_subscriber')
58 dead_subscriber.side_effect = pykka.ActorDeadError
59 self.monitor.subscribe(dead_subscriber)
60 self.wait_for_call(dead_subscriber)
61 self.monitor.subscribe(self.subscriber)
63 self.wait_for_call(self.subscriber)
64 self.subscriber.assert_called_with('survive2')
65 self.assertTrue(self.monitor.actor_ref.is_alive(),
66 "poll loop died from dead subscriber")
68 def test_no_subscriptions_by_key_without_support(self):
69 self.build_monitor([])
70 with self.assertRaises(AttributeError):
71 self.monitor.subscribe_to('key')
74 class RemotePollLoopActorWithKeysTestCase(testutil.RemotePollLoopActorTestMixin,
76 class TestActor(RemotePollLoopActorTestCase.TestActor):
77 def _item_key(self, item):
79 TEST_CLASS = TestActor
82 def build_monitor(self, side_effect, *args, **kwargs):
83 super(RemotePollLoopActorWithKeysTestCase, self).build_monitor(
85 self.client.side_effect = side_effect
87 def test_key_subscription(self):
88 self.build_monitor([[{'key': 1}, {'key': 2}]])
89 self.monitor.subscribe_to(2, self.subscriber)
90 self.wait_for_call(self.subscriber)
91 self.subscriber.assert_called_with({'key': 2})
93 def test_survive_dead_key_subscriptions(self):
95 self.build_monitor([[item], [item]])
96 dead_subscriber = mock.Mock(name='dead_subscriber')
97 dead_subscriber.side_effect = pykka.ActorDeadError
98 self.monitor.subscribe_to(3, dead_subscriber)
99 self.wait_for_call(dead_subscriber)
100 self.monitor.subscribe_to(3, self.subscriber)
102 self.wait_for_call(self.subscriber)
103 self.subscriber.assert_called_with(item)
104 self.assertTrue(self.monitor.actor_ref.is_alive(),
105 "poll loop died from dead key subscriber")
107 def test_mixed_subscriptions(self):
109 self.build_monitor([[item], [item]])
110 key_subscriber = mock.Mock(name='key_subscriber')
111 self.monitor.subscribe(self.subscriber)
112 self.monitor.subscribe_to(4, key_subscriber)
114 self.wait_for_call(self.subscriber)
115 self.subscriber.assert_called_with([item])
116 key_subscriber.assert_called_with(item)
118 def test_subscription_to_missing_key(self):
119 self.build_monitor([[]])
120 self.monitor.subscribe_to('nonesuch', self.subscriber)
121 self.wait_for_call(self.subscriber)
122 self.subscriber.assert_called_with(None)
125 if __name__ == '__main__':