Beispiel #1
0
class TestEtcdReporting(BaseTestCase):
    def setUp(self):
        super(TestEtcdReporting, self).setUp()
        self.m_config = Mock()
        self.m_config.IFACE_PREFIX = "tap"
        self.m_config.ETCD_ADDR = "localhost:4001"
        self.m_config.HOSTNAME = "hostname"
        self.m_config.RESYNC_INTERVAL = 0
        self.m_config.REPORTING_INTERVAL_SECS = 1
        self.m_config.REPORTING_TTL_SECS = 10
        self.m_hosts_ipset = Mock(spec=IpsetActor)
        with patch("gevent.spawn", autospec=True):
            with patch("calico.felix.fetcd._FelixEtcdWatcher", autospec=True):
                with patch("calico.felix.fetcd.monotonic_time",
                           return_value=100):
                    self.api = EtcdAPI(self.m_config, self.m_hosts_ipset)
        self.api._watcher.configured = Mock()

    @patch("gevent.sleep", autospec=True)
    def test_reporting_loop_mainline(self, m_sleep):
        """
        Test the mainline function of the status reporting loop.

        It should repeatedly call the _update_felix_status method,
        retrying on various exceptions.
        """
        with patch.object(self.api, "_update_felix_status") as m_update:
            m_update.side_effect = [EtcdException, None, RuntimeError]
            self.assertRaises(RuntimeError,
                              self.api._periodically_report_status)
        self.assertEqual(m_update.mock_calls, [call(10)] * 3)

        retry_call, jittered_call = m_sleep.mock_calls
        self.assertEqual(retry_call, call(5))
        _, (delay, ), _ = jittered_call
        self.assertTrue(delay >= 1)
        self.assertTrue(delay <= 1.1005)

    def test_reporting_loop_disabled(self):
        self.m_config.REPORTING_INTERVAL_SECS = 0
        with patch.object(self.api, "_update_felix_status") as m_update:
            m_update.side_effect = RuntimeError
            self.api._periodically_report_status()

    @patch("calico.felix.futils.datetime", autospec=True)
    @patch("calico.felix.fetcd.monotonic_time", return_value=200)
    def test_update_felix_status(self, m_monotime, m_datetime):
        m_datetime.utcnow.return_value = datetime(2015, 9, 10, 2, 1, 53, 1234)
        with patch.object(self.api.client, "set") as m_set:
            self.api._update_felix_status(10)
            self.api._update_felix_status(10)
        # Should write two keys into etcd, one with a TTL and another with
        # richer status.
        self.assertEqual(m_set.mock_calls, [
            call(
                "/calico/felix/v1/host/hostname/last_reported_status",
                JSONString({
                    "uptime": 100,
                    "time": "2015-09-10T02:01:53Z",
                    "first_update": True
                })),
            call("/calico/felix/v1/host/hostname/status",
                 JSONString({
                     "uptime": 100,
                     "time": "2015-09-10T02:01:53Z",
                     "first_update": True
                 }),
                 ttl=10),
            call(
                "/calico/felix/v1/host/hostname/last_reported_status",
                JSONString({
                    "uptime": 100,
                    "time": "2015-09-10T02:01:53Z",
                    "first_update": False
                })),
            call("/calico/felix/v1/host/hostname/status",
                 JSONString({
                     "uptime": 100,
                     "time": "2015-09-10T02:01:53Z",
                     "first_update": False
                 }),
                 ttl=10),
        ])
Beispiel #2
0
class TestEtcdReporting(BaseTestCase):
    def setUp(self):
        super(TestEtcdReporting, self).setUp()
        self.m_config = Mock()
        self.m_config.IFACE_PREFIX = "tap"
        self.m_config.ETCD_ADDR = "localhost:4001"
        self.m_config.HOSTNAME = "hostname"
        self.m_config.RESYNC_INTERVAL = 0
        self.m_config.REPORTING_INTERVAL_SECS = 1
        self.m_config.REPORTING_TTL_SECS = 10
        self.m_hosts_ipset = Mock(spec=IpsetActor)
        with patch("gevent.spawn", autospec=True):
            with patch("calico.felix.fetcd._FelixEtcdWatcher", autospec=True):
                with patch("calico.felix.fetcd.monotonic_time",
                           return_value=100):
                    self.api = EtcdAPI(self.m_config, self.m_hosts_ipset)
        self.api._watcher.configured = Mock()

    @patch("gevent.sleep", autospec=True)
    def test_reporting_loop_mainline(self, m_sleep):
        """
        Test the mainline function of the status reporting loop.

        It should repeatedly call the _update_felix_status method,
        retrying on various exceptions.
        """
        with patch.object(self.api, "_update_felix_status") as m_update:
            m_update.side_effect = [EtcdException, None, RuntimeError]
            self.assertRaises(RuntimeError,
                              self.api._periodically_report_status)
        self.assertEqual(m_update.mock_calls,
                         [call(10)] * 3)

        retry_call, jittered_call = m_sleep.mock_calls
        self.assertEqual(retry_call, call(5))
        _, (delay,), _ = jittered_call
        self.assertTrue(delay >= 1)
        self.assertTrue(delay <= 1.1005)

    def test_reporting_loop_disabled(self):
        self.m_config.REPORTING_INTERVAL_SECS = 0
        with patch.object(self.api, "_update_felix_status") as m_update:
            m_update.side_effect = RuntimeError
            self.api._periodically_report_status()

    @patch("calico.felix.futils.datetime", autospec=True)
    @patch("calico.felix.fetcd.monotonic_time", return_value=200)
    def test_update_felix_status(self, m_monotime, m_datetime):
        m_datetime.utcnow.return_value = datetime(2015, 9, 10, 2, 1, 53, 1234)
        with patch.object(self.api.client, "set") as m_set:
            self.api._update_felix_status(10)
            self.api._update_felix_status(10)
        # Should write two keys into etcd, one with a TTL and another with
        # richer status.
        self.assertEqual(m_set.mock_calls, [
            call("/calico/felix/v1/host/hostname/last_reported_status",
                 JSONString({"uptime": 100,
                             "time": "2015-09-10T02:01:53Z",
                             "first_update": True})),
            call("/calico/felix/v1/host/hostname/status",
                 JSONString({"uptime": 100,
                             "time": "2015-09-10T02:01:53Z",
                             "first_update": True}), ttl=10),
            call("/calico/felix/v1/host/hostname/last_reported_status",
                 JSONString({"uptime": 100,
                             "time": "2015-09-10T02:01:53Z",
                             "first_update": False})),
            call("/calico/felix/v1/host/hostname/status",
                 JSONString({"uptime": 100,
                             "time": "2015-09-10T02:01:53Z",
                             "first_update": False}), ttl=10),
        ])