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).get(self.TIMEOUT)
34 self.stop_proxy(self.monitor)
35 self.subscriber.assert_called_with('test1')
36 self.assertTrue(self.timer.schedule.called)
38 def test_poll_loop_continues_after_failure(self):
39 self.build_monitor(self.MockClientError)
40 self.monitor.subscribe(self.subscriber).get(self.TIMEOUT)
41 self.assertTrue(self.stop_proxy(self.monitor),
42 "poll loop died after error")
43 self.assertTrue(self.timer.schedule.called,
44 "poll loop did not reschedule after error")
45 self.assertFalse(self.subscriber.called,
46 "poll loop notified subscribers after error")
48 def test_late_subscribers_get_responses(self):
49 self.build_monitor(['pre_late_test', 'late_test'])
50 self.monitor.subscribe(lambda response: None).get(self.TIMEOUT)
51 self.monitor.subscribe(self.subscriber)
52 self.monitor.poll().get(self.TIMEOUT)
53 self.stop_proxy(self.monitor)
54 self.subscriber.assert_called_with('late_test')
56 def test_survive_dead_subscriptions(self):
57 self.build_monitor(['survive1', 'survive2'])
58 dead_subscriber = mock.Mock(name='dead_subscriber')
59 dead_subscriber.side_effect = pykka.ActorDeadError
60 self.monitor.subscribe(dead_subscriber)
61 self.monitor.subscribe(self.subscriber)
62 self.monitor.poll().get(self.TIMEOUT)
63 self.assertTrue(self.stop_proxy(self.monitor),
64 "poll loop died from dead subscriber")
65 self.subscriber.assert_called_with('survive2')
67 def test_no_subscriptions_by_key_without_support(self):
68 self.build_monitor([])
69 with self.assertRaises(AttributeError):
70 self.monitor.subscribe_to('key')
73 class RemotePollLoopActorWithKeysTestCase(testutil.RemotePollLoopActorTestMixin,
75 class TestActor(RemotePollLoopActorTestCase.TestActor):
76 def _item_key(self, item):
78 TEST_CLASS = TestActor
81 def build_monitor(self, side_effect, *args, **kwargs):
82 super(RemotePollLoopActorWithKeysTestCase, self).build_monitor(
84 self.client.side_effect = side_effect
86 def test_key_subscription(self):
87 self.build_monitor([[{'key': 1}, {'key': 2}]])
88 self.monitor.subscribe_to(2, self.subscriber).get(self.TIMEOUT)
89 self.stop_proxy(self.monitor)
90 self.subscriber.assert_called_with({'key': 2})
92 def test_survive_dead_key_subscriptions(self):
94 self.build_monitor([[item], [item]])
95 dead_subscriber = mock.Mock(name='dead_subscriber')
96 dead_subscriber.side_effect = pykka.ActorDeadError
97 self.monitor.subscribe_to(3, dead_subscriber)
98 self.monitor.subscribe_to(3, self.subscriber)
99 self.monitor.poll().get(self.TIMEOUT)
100 self.assertTrue(self.stop_proxy(self.monitor),
101 "poll loop died from dead key subscriber")
102 self.subscriber.assert_called_with(item)
104 def test_mixed_subscriptions(self):
106 self.build_monitor([[item], [item]])
107 key_subscriber = mock.Mock(name='key_subscriber')
108 self.monitor.subscribe(self.subscriber)
109 self.monitor.subscribe_to(4, key_subscriber)
110 self.monitor.poll().get(self.TIMEOUT)
111 self.stop_proxy(self.monitor)
112 self.subscriber.assert_called_with([item])
113 key_subscriber.assert_called_with(item)
115 def test_subscription_to_missing_key(self):
116 self.build_monitor([[]])
117 self.monitor.subscribe_to('nonesuch', self.subscriber).get(self.TIMEOUT)
118 self.stop_proxy(self.monitor)
119 self.subscriber.assert_called_with(None)
122 if __name__ == '__main__':