def setUp(self): super(TestEtcdWatcher, self).setUp() self.m_client = Mock() etcdv3._client = self.m_client self.watcher = EtcdWatcher("/calico") self.m_dispatcher = Mock(spec=PathDispatcher) self.watcher.dispatcher = self.m_dispatcher
def setUp(self): super(TestEtcdWatcher, self).setUp() self.reconnect_patch = patch( "networking_calico.etcdutils.EtcdWatcher.reconnect") self.m_reconnect = self.reconnect_patch.start() self.watcher = EtcdWatcher(["foobar:4001"], "/calico") self.m_client = Mock() self.watcher.client = self.m_client self.m_dispatcher = Mock(spec=PathDispatcher) self.watcher.dispatcher = self.m_dispatcher
def setUp(self): super(TestEtcdWatcher, self).setUp() self.reconnect_patch = patch( "networking_calico.etcdutils.EtcdWatcher.reconnect" ) self.m_reconnect = self.reconnect_patch.start() self.watcher = EtcdWatcher(["foobar:4001"], "/calico") self.m_client = Mock() self.watcher.client = self.m_client self.m_dispatcher = Mock(spec=PathDispatcher) self.watcher.dispatcher = self.m_dispatcher
class TestEtcdWatcher(unittest.TestCase): def setUp(self): super(TestEtcdWatcher, self).setUp() self.reconnect_patch = patch( "networking_calico.etcdutils.EtcdWatcher.reconnect") self.m_reconnect = self.reconnect_patch.start() self.watcher = EtcdWatcher(["foobar:4001"], "/calico") self.m_client = Mock() self.watcher.client = self.m_client self.m_dispatcher = Mock(spec=PathDispatcher) self.watcher.dispatcher = self.m_dispatcher @patch("time.sleep", autospec=True) def test_mainline(self, m_sleep): m_snap_response = Mock() m_snap_response.etcd_index = 1 m_poll_response = Mock() m_poll_response.modifiedIndex = 2 responses = [ m_snap_response, m_poll_response, ResyncRequired(), # Loop 1 EtcdException(), # Loop 2 ExpectedException(), # Loop 3, Break out of loop. ] self.m_client.read.side_effect = iter(responses) with patch.object(self.watcher, "_on_pre_resync", autospec=True) as m_pre_r: with patch.object(self.watcher, "_on_snapshot_loaded", autospec=True) as m_snap_load: self.assertRaises(ExpectedException, self.watcher.loop) # _on_pre_resync() called once per loop. self.assertEqual(m_pre_r.mock_calls, [call(), call(), call()]) # The snapshot only loads successfully the first time. self.assertEqual(m_snap_load.mock_calls, [call(m_snap_response)]) self.assertEqual(self.m_dispatcher.handle_event.mock_calls, [call(m_poll_response)]) # Should sleep after exception. m_sleep.assert_called_once_with(1) def test_loop_stopped(self): self.watcher._stopped = True with patch.object(self.watcher, "_on_pre_resync", autospec=True) as m_pre_r: self.watcher.loop() self.assertFalse(m_pre_r.called) def test_register(self): self.watcher.register_path("key", foo="bar") self.assertEqual(self.m_dispatcher.register.mock_calls, [call("key", foo="bar")]) @patch("time.sleep", autospec=True) def test_wait_for_ready(self, m_sleep): m_resp_1 = Mock() m_resp_1.value = "false" m_resp_2 = Mock() m_resp_2.value = "true" responses = [ etcd.EtcdException(), etcd.EtcdKeyNotFound(), m_resp_1, m_resp_2, ] self.m_client.read.side_effect = iter(responses) self.watcher.wait_for_ready(1) self.assertEqual(m_sleep.mock_calls, [call(1)] * 3) def test_load_initial_dump(self): m_response = Mock(spec=etcd.EtcdResult) m_response.etcd_index = 10000 self.m_client.read.side_effect = [etcd.EtcdKeyNotFound(), m_response] with patch("time.sleep") as m_sleep: self.assertEqual(self.watcher.load_initial_dump(), m_response) m_sleep.assert_called_once_with(1) self.m_client.read.assert_has_calls([ call("/calico", recursive=True), call("/calico", recursive=True), ]) self.assertEqual(self.watcher.next_etcd_index, 10001) def test_load_initial_dump_stopped(self): self.watcher.stop() self.m_client.read.side_effect = etcd.EtcdKeyNotFound() self.assertRaises(etcd.EtcdKeyNotFound, self.watcher.load_initial_dump) def test_resync_set(self): self.watcher.next_etcd_index = 1 self.watcher.resync_after_current_poll = True self.assertRaises(ResyncRequired, self.watcher.wait_for_etcd_event) self.assertFalse(self.watcher.resync_after_current_poll) @patch("time.sleep", autospec=True) def test_wait_for_etcd_event_conn_failed(self, m_sleep): self.watcher.next_etcd_index = 1 m_resp = Mock() m_resp.modifiedIndex = 123 read_timeout = etcd.EtcdConnectionFailed() read_timeout.cause = ReadTimeoutError(Mock(), "", "") other_error = etcd.EtcdConnectionFailed() other_error.cause = ExpectedException() responses = [ read_timeout, other_error, m_resp, ] self.m_client.read.side_effect = iter(responses) event = self.watcher.wait_for_etcd_event() self.assertEqual(event, m_resp) self.assertEqual(m_sleep.mock_calls, [call(1)]) def test_wait_for_etcd_event_cluster_id_changed(self): self.watcher.next_etcd_index = 1 responses = [ etcd.EtcdClusterIdChanged(), ] self.m_client.read.side_effect = iter(responses) self.assertRaises(ResyncRequired, self.watcher.wait_for_etcd_event) def test_wait_for_etcd_event_index_cleared(self): self.watcher.next_etcd_index = 1 responses = [ etcd.EtcdEventIndexCleared(), ] self.m_client.read.side_effect = iter(responses) self.assertRaises(ResyncRequired, self.watcher.wait_for_etcd_event) @patch("time.sleep", autospec=True) def test_wait_for_etcd_event_unexpected_error(self, m_sleep): self.watcher.next_etcd_index = 1 responses = [ etcd.EtcdException(), ] self.m_client.read.side_effect = iter(responses) self.assertRaises(ResyncRequired, self.watcher.wait_for_etcd_event) self.assertEqual(m_sleep.mock_calls, [call(1)]) def test_coverage(self): # These methods are no-ops. self.watcher._on_pre_resync() self.watcher._on_snapshot_loaded(Mock()) def tearDown(self): self.reconnect_patch.stop() super(TestEtcdWatcher, self).tearDown()
class TestEtcdWatcher(unittest.TestCase): def setUp(self): super(TestEtcdWatcher, self).setUp() self.reconnect_patch = patch( "networking_calico.etcdutils.EtcdWatcher.reconnect" ) self.m_reconnect = self.reconnect_patch.start() self.watcher = EtcdWatcher(["foobar:4001"], "/calico") self.m_client = Mock() self.watcher.client = self.m_client self.m_dispatcher = Mock(spec=PathDispatcher) self.watcher.dispatcher = self.m_dispatcher @patch("time.sleep", autospec=True) def test_mainline(self, m_sleep): m_snap_response = Mock() m_snap_response.etcd_index = 1 m_poll_response = Mock() m_poll_response.modifiedIndex = 2 responses = [ m_snap_response, m_poll_response, ResyncRequired(), # Loop 1 EtcdException(), # Loop 2 ExpectedException(), # Loop 3, Break out of loop. ] self.m_client.read.side_effect = iter(responses) with patch.object(self.watcher, "_on_pre_resync", autospec=True) as m_pre_r: with patch.object(self.watcher, "_on_snapshot_loaded", autospec=True) as m_snap_load: self.assertRaises(ExpectedException, self.watcher.loop) # _on_pre_resync() called once per loop. self.assertEqual(m_pre_r.mock_calls, [call(), call(), call()]) # The snapshot only loads successfully the first time. self.assertEqual(m_snap_load.mock_calls, [call(m_snap_response)]) self.assertEqual(self.m_dispatcher.handle_event.mock_calls, [call(m_poll_response)]) # Should sleep after exception. m_sleep.assert_called_once_with(1) def test_loop_stopped(self): self.watcher._stopped = True with patch.object(self.watcher, "_on_pre_resync", autospec=True) as m_pre_r: self.watcher.loop() self.assertFalse(m_pre_r.called) def test_register(self): self.watcher.register_path("key", foo="bar") self.assertEqual(self.m_dispatcher.register.mock_calls, [call("key", foo="bar")]) @patch("time.sleep", autospec=True) def test_wait_for_ready(self, m_sleep): m_resp_1 = Mock() m_resp_1.value = "false" m_resp_2 = Mock() m_resp_2.value = "true" responses = [ etcd.EtcdException(), etcd.EtcdKeyNotFound(), m_resp_1, m_resp_2, ] self.m_client.read.side_effect = iter(responses) self.watcher.wait_for_ready(1) self.assertEqual(m_sleep.mock_calls, [call(1)] * 3) def test_load_initial_dump(self): m_response = Mock(spec=etcd.EtcdResult) m_response.etcd_index = 10000 self.m_client.read.side_effect = [ etcd.EtcdKeyNotFound(), m_response ] with patch("time.sleep") as m_sleep: self.assertEqual(self.watcher.load_initial_dump(), m_response) m_sleep.assert_called_once_with(1) self.m_client.read.assert_has_calls([ call("/calico", recursive=True), call("/calico", recursive=True), ]) self.assertEqual(self.watcher.next_etcd_index, 10001) def test_load_initial_dump_stopped(self): self.watcher.stop() self.m_client.read.side_effect = etcd.EtcdKeyNotFound() self.assertRaises(etcd.EtcdKeyNotFound, self.watcher.load_initial_dump) def test_resync_set(self): self.watcher.next_etcd_index = 1 self.watcher.resync_after_current_poll = True self.assertRaises(ResyncRequired, self.watcher.wait_for_etcd_event) self.assertFalse(self.watcher.resync_after_current_poll) @patch("time.sleep", autospec=True) def test_wait_for_etcd_event_conn_failed(self, m_sleep): self.watcher.next_etcd_index = 1 m_resp = Mock() m_resp.modifiedIndex = 123 read_timeout = etcd.EtcdConnectionFailed() read_timeout.cause = ReadTimeoutError(Mock(), "", "") other_error = etcd.EtcdConnectionFailed() other_error.cause = ExpectedException() responses = [ read_timeout, other_error, m_resp, ] self.m_client.read.side_effect = iter(responses) event = self.watcher.wait_for_etcd_event() self.assertEqual(event, m_resp) self.assertEqual(m_sleep.mock_calls, [call(1)]) def test_wait_for_etcd_event_cluster_id_changed(self): self.watcher.next_etcd_index = 1 responses = [ etcd.EtcdClusterIdChanged(), ] self.m_client.read.side_effect = iter(responses) self.assertRaises(ResyncRequired, self.watcher.wait_for_etcd_event) def test_wait_for_etcd_event_index_cleared(self): self.watcher.next_etcd_index = 1 responses = [ etcd.EtcdEventIndexCleared(), ] self.m_client.read.side_effect = iter(responses) self.assertRaises(ResyncRequired, self.watcher.wait_for_etcd_event) @patch("time.sleep", autospec=True) def test_wait_for_etcd_event_unexpected_error(self, m_sleep): self.watcher.next_etcd_index = 1 responses = [ etcd.EtcdException(), ] self.m_client.read.side_effect = iter(responses) self.assertRaises(ResyncRequired, self.watcher.wait_for_etcd_event) self.assertEqual(m_sleep.mock_calls, [call(1)]) def test_coverage(self): # These methods are no-ops. self.watcher._on_pre_resync() self.watcher._on_snapshot_loaded(Mock()) def tearDown(self): self.reconnect_patch.stop() super(TestEtcdWatcher, self).tearDown()
class TestEtcdWatcher(unittest.TestCase): def setUp(self): super(TestEtcdWatcher, self).setUp() self.m_client = Mock() etcdv3._client = self.m_client self.watcher = EtcdWatcher("/calico") self.m_dispatcher = Mock(spec=PathDispatcher) self.watcher.dispatcher = self.m_dispatcher def test_mainline(self): # Set up 3 iterations through the watcher's main loop. # # 1. No data for snapshot. Watch throws exception. # # 2. Data for snapshot. Watch throws exception. # # 3. Throw ExpectedException(), to exit. status = {'header': {'cluster_id': '1234', 'revision': '10'}} self.m_client.status.side_effect = iter([ # Iteration 1. status, # Iteration 2. status, # Iteration 3. status, ]) rsp1 = Response(action='set', key='foo', value='bar', mod_revision='12') self.m_client.get.side_effect = iter([[], [_rsp_to_tuple(rsp1)], ExpectedException()]) self.m_client.watch_prefix.side_effect = etcdv3.KeyNotFound() with patch.object(self.watcher, "_pre_snapshot_hook", autospec=True) as m_pre: m_pre.return_value = None with patch.object(self.watcher, "_post_snapshot_hook", autospec=True) as m_post: self.assertRaises(ExpectedException, self.watcher.start) # _pre_snapshot_hook() called 3 times. self.assertEqual(m_pre.mock_calls, [call(), call(), call()]) # _post_snapshot_hook() called twice. self.assertEqual(m_post.mock_calls, [call(None), call(None)]) # watch_prefix called twice. self.assertEqual(self.m_client.watch_prefix.mock_calls, [ call('/calico', start_revision='11'), call('/calico', start_revision='11') ]) # Snapshot event dispatched once. self.assertEqual(self.m_dispatcher.handle_event.mock_calls, [call(rsp1)]) def test_register(self): self.watcher.register_path("key", foo="bar") self.assertEqual(self.m_dispatcher.register.mock_calls, [call("key", foo="bar")])