Ejemplo n.º 1
0
 def setUp(self):
     super(TestEtcdWatcher, self).setUp()
     self.reconnect_patch = patch("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
Ejemplo n.º 2
0
 def setUp(self):
     super(TestEtcdWatcher, self).setUp()
     self.reconnect_patch = patch("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
Ejemplo n.º 3
0
class TestEtcdWatcher(BaseTestCase):
    def setUp(self):
        super(TestEtcdWatcher, self).setUp()
        with patch("calico.etcdutils.EtcdWatcher.reconnect") as m_reconnect:
            self.watcher = EtcdWatcher("foobar:4001", "/calico")
        self.m_client = Mock()
        self.watcher.client = self.m_client

    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)
Ejemplo n.º 4
0
class TestEtcdWatcher(BaseTestCase):
    def setUp(self):
        super(TestEtcdWatcher, self).setUp()
        with patch("calico.etcdutils.EtcdWatcher.reconnect") as m_reconnect:
            self.watcher = EtcdWatcher("foobar:4001", "/calico")
        self.m_client = Mock()
        self.watcher.client = self.m_client

    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)
Ejemplo n.º 5
0
class TestEtcdWatcher(BaseTestCase):
    def setUp(self):
        super(TestEtcdWatcher, self).setUp()
        self.reconnect_patch = patch("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()
Ejemplo n.º 6
0
 def setUp(self):
     super(TestEtcdWatcher, self).setUp()
     with patch("calico.etcdutils.EtcdWatcher.reconnect") as m_reconnect:
         self.watcher = EtcdWatcher("foobar:4001", "/calico")
     self.m_client = Mock()
     self.watcher.client = self.m_client
Ejemplo n.º 7
0
 def setUp(self):
     super(TestEtcdWatcher, self).setUp()
     with patch("calico.etcdutils.EtcdWatcher.reconnect") as m_reconnect:
         self.watcher = EtcdWatcher("foobar:4001", "/calico")
     self.m_client = Mock()
     self.watcher.client = self.m_client
Ejemplo n.º 8
0
class TestEtcdWatcher(BaseTestCase):
    def setUp(self):
        super(TestEtcdWatcher, self).setUp()
        self.reconnect_patch = patch("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()