class TestPodLauncher(unittest.TestCase):
    def setUp(self):
        self.mock_kube_client = mock.Mock()
        self.pod_launcher = PodLauncher(kube_client=self.mock_kube_client)

    def test_read_pod_logs_successfully_returns_logs(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.return_value = mock.sentinel.logs
        logs = self.pod_launcher.read_pod_logs(mock.sentinel)
        self.assertEqual(mock.sentinel.logs, logs)

    def test_read_pod_logs_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            BaseHTTPError('Boom'), mock.sentinel.logs
        ]
        logs = self.pod_launcher.read_pod_logs(mock.sentinel)
        self.assertEqual(mock.sentinel.logs, logs)
        self.mock_kube_client.read_namespaced_pod_log.assert_has_calls([
            mock.call(_preload_content=False,
                      container='base',
                      follow=True,
                      name=mock.sentinel.metadata.name,
                      namespace=mock.sentinel.metadata.namespace,
                      tail_lines=10),
            mock.call(_preload_content=False,
                      container='base',
                      follow=True,
                      name=mock.sentinel.metadata.name,
                      namespace=mock.sentinel.metadata.namespace,
                      tail_lines=10)
        ])

    def test_read_pod_logs_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom')
        ]
        self.assertRaises(AirflowException, self.pod_launcher.read_pod_logs,
                          mock.sentinel)

    def test_read_pod_events_successfully_returns_events(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.return_value = mock.sentinel.events
        events = self.pod_launcher.read_pod_events(mock.sentinel)
        self.assertEqual(mock.sentinel.events, events)

    def test_read_pod_events_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.side_effect = [
            BaseHTTPError('Boom'), mock.sentinel.events
        ]
        events = self.pod_launcher.read_pod_events(mock.sentinel)
        self.assertEqual(mock.sentinel.events, events)
        self.mock_kube_client.list_namespaced_event.assert_has_calls([
            mock.call(namespace=mock.sentinel.metadata.namespace,
                      field_selector="involvedObject.name={}".format(
                          mock.sentinel.metadata.name)),
            mock.call(namespace=mock.sentinel.metadata.namespace,
                      field_selector="involvedObject.name={}".format(
                          mock.sentinel.metadata.name))
        ])

    def test_read_pod_events_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom')
        ]
        self.assertRaises(AirflowException, self.pod_launcher.read_pod_events,
                          mock.sentinel)

    def test_read_pod_returns_logs(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.return_value = mock.sentinel.pod_info
        pod_info = self.pod_launcher.read_pod(mock.sentinel)
        self.assertEqual(mock.sentinel.pod_info, pod_info)

    def test_read_pod_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.side_effect = [
            BaseHTTPError('Boom'), mock.sentinel.pod_info
        ]
        pod_info = self.pod_launcher.read_pod(mock.sentinel)
        self.assertEqual(mock.sentinel.pod_info, pod_info)
        self.mock_kube_client.read_namespaced_pod.assert_has_calls([
            mock.call(mock.sentinel.metadata.name,
                      mock.sentinel.metadata.namespace),
            mock.call(mock.sentinel.metadata.name,
                      mock.sentinel.metadata.namespace)
        ])

    def test_read_pod_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom')
        ]
        self.assertRaises(AirflowException, self.pod_launcher.read_pod,
                          mock.sentinel)
Exemple #2
0
class TestPodLauncher(unittest.TestCase):
    def setUp(self):
        self.mock_kube_client = mock.Mock()
        self.pod_launcher = PodLauncher(kube_client=self.mock_kube_client)

    def test_read_pod_logs_successfully_returns_logs(self):
        self.mock_kube_client.read_namespaced_pod_log.return_value = mock.sentinel.logs
        logs = self.pod_launcher.read_pod_logs(mock.sentinel)
        self.assertEqual(mock.sentinel.logs, logs)

    def test_read_pod_logs_retries_successfully(self):
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            BaseHTTPError('Boom'), mock.sentinel.logs
        ]
        logs = self.pod_launcher.read_pod_logs(mock.sentinel)
        self.assertEqual(mock.sentinel.logs, logs)
        self.mock_kube_client.read_namespaced_pod_log.assert_has_calls([
            mock.call(_preload_content=False,
                      _request_timeout=600,
                      container='base',
                      follow=True,
                      name=mock.sentinel.name,
                      namespace=mock.sentinel.namespace,
                      tail_lines=10),
            mock.call(_preload_content=False,
                      _request_timeout=600,
                      container='base',
                      follow=True,
                      name=mock.sentinel.name,
                      namespace=mock.sentinel.namespace,
                      tail_lines=10)
        ])

    def test_read_pod_logs_retries_fails(self):
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom')
        ]
        self.assertRaises(AirflowException, self.pod_launcher.read_pod_logs,
                          mock.sentinel)

    def test_read_pod_returns_logs(self):
        self.mock_kube_client.read_namespaced_pod.return_value = mock.sentinel.pod_info
        pod_info = self.pod_launcher.read_pod(mock.sentinel)
        self.assertEqual(mock.sentinel.pod_info, pod_info)

    def test_read_pod_retries_successfully(self):
        self.mock_kube_client.read_namespaced_pod.side_effect = [
            BaseHTTPError('Boom'), mock.sentinel.pod_info
        ]
        pod_info = self.pod_launcher.read_pod(mock.sentinel)
        self.assertEqual(mock.sentinel.pod_info, pod_info)
        self.mock_kube_client.read_namespaced_pod.assert_has_calls([
            mock.call(mock.sentinel.name, mock.sentinel.namespace),
            mock.call(mock.sentinel.name, mock.sentinel.namespace)
        ])

    def test_read_pod_retries_fails(self):
        self.mock_kube_client.read_namespaced_pod.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom')
        ]
        self.assertRaises(AirflowException, self.pod_launcher.read_pod,
                          mock.sentinel)
Exemple #3
0
class TestPodLauncher(unittest.TestCase):
    def setUp(self):
        self.mock_kube_client = mock.Mock()
        self.pod_launcher = PodLauncher(kube_client=self.mock_kube_client)

    def test_read_pod_logs_successfully_returns_logs(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.return_value = mock.sentinel.logs
        logs = self.pod_launcher.read_pod_logs(mock.sentinel)
        assert mock.sentinel.logs == logs

    def test_read_pod_logs_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            BaseHTTPError('Boom'),
            mock.sentinel.logs,
        ]
        logs = self.pod_launcher.read_pod_logs(mock.sentinel)
        assert mock.sentinel.logs == logs
        self.mock_kube_client.read_namespaced_pod_log.assert_has_calls([
            mock.call(
                _preload_content=False,
                container='base',
                follow=True,
                timestamps=False,
                name=mock.sentinel.metadata.name,
                namespace=mock.sentinel.metadata.namespace,
            ),
            mock.call(
                _preload_content=False,
                container='base',
                follow=True,
                timestamps=False,
                name=mock.sentinel.metadata.name,
                namespace=mock.sentinel.metadata.namespace,
            ),
        ])

    def test_read_pod_logs_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
        ]
        with pytest.raises(AirflowException):
            self.pod_launcher.read_pod_logs(mock.sentinel)

    def test_read_pod_logs_successfully_with_tail_lines(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            mock.sentinel.logs
        ]
        logs = self.pod_launcher.read_pod_logs(mock.sentinel, tail_lines=100)
        assert mock.sentinel.logs == logs
        self.mock_kube_client.read_namespaced_pod_log.assert_has_calls([
            mock.call(
                _preload_content=False,
                container='base',
                follow=True,
                timestamps=False,
                name=mock.sentinel.metadata.name,
                namespace=mock.sentinel.metadata.namespace,
                tail_lines=100,
            ),
        ])

    def test_read_pod_logs_successfully_with_since_seconds(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            mock.sentinel.logs
        ]
        logs = self.pod_launcher.read_pod_logs(mock.sentinel, since_seconds=2)
        assert mock.sentinel.logs == logs
        self.mock_kube_client.read_namespaced_pod_log.assert_has_calls([
            mock.call(
                _preload_content=False,
                container='base',
                follow=True,
                timestamps=False,
                name=mock.sentinel.metadata.name,
                namespace=mock.sentinel.metadata.namespace,
                since_seconds=2,
            ),
        ])

    def test_read_pod_events_successfully_returns_events(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.return_value = mock.sentinel.events
        events = self.pod_launcher.read_pod_events(mock.sentinel)
        assert mock.sentinel.events == events

    def test_read_pod_events_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.side_effect = [
            BaseHTTPError('Boom'),
            mock.sentinel.events,
        ]
        events = self.pod_launcher.read_pod_events(mock.sentinel)
        assert mock.sentinel.events == events
        self.mock_kube_client.list_namespaced_event.assert_has_calls([
            mock.call(
                namespace=mock.sentinel.metadata.namespace,
                field_selector=
                f"involvedObject.name={mock.sentinel.metadata.name}",
            ),
            mock.call(
                namespace=mock.sentinel.metadata.namespace,
                field_selector=
                f"involvedObject.name={mock.sentinel.metadata.name}",
            ),
        ])

    def test_read_pod_events_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
        ]
        with pytest.raises(AirflowException):
            self.pod_launcher.read_pod_events(mock.sentinel)

    def test_read_pod_returns_logs(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.return_value = mock.sentinel.pod_info
        pod_info = self.pod_launcher.read_pod(mock.sentinel)
        assert mock.sentinel.pod_info == pod_info

    def test_read_pod_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.side_effect = [
            BaseHTTPError('Boom'),
            mock.sentinel.pod_info,
        ]
        pod_info = self.pod_launcher.read_pod(mock.sentinel)
        assert mock.sentinel.pod_info == pod_info
        self.mock_kube_client.read_namespaced_pod.assert_has_calls([
            mock.call(mock.sentinel.metadata.name,
                      mock.sentinel.metadata.namespace),
            mock.call(mock.sentinel.metadata.name,
                      mock.sentinel.metadata.namespace),
        ])

    def test_read_pod_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
        ]
        with pytest.raises(AirflowException):
            self.pod_launcher.read_pod(mock.sentinel)

    def test_parse_log_line(self):
        timestamp, message = self.pod_launcher.parse_log_line(
            '2020-10-08T14:16:17.793417674Z Valid message\n')

        assert timestamp == '2020-10-08T14:16:17.793417674Z'
        assert message == 'Valid message'

        with pytest.raises(Exception):
            self.pod_launcher.parse_log_line(
                '2020-10-08T14:16:17.793417674ZInvalidmessage\n')
Exemple #4
0
class TestPodLauncher(unittest.TestCase):
    def setUp(self):
        self.mock_kube_client = mock.Mock()
        self.pod_launcher = PodLauncher(kube_client=self.mock_kube_client)

    def test_read_pod_logs_successfully_returns_logs(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.return_value = mock.sentinel.logs
        logs = self.pod_launcher.read_pod_logs(mock.sentinel)
        self.assertEqual(mock.sentinel.logs, logs)

    def test_read_pod_logs_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            BaseHTTPError('Boom'), mock.sentinel.logs
        ]
        logs = self.pod_launcher.read_pod_logs(mock.sentinel)
        self.assertEqual(mock.sentinel.logs, logs)
        self.mock_kube_client.read_namespaced_pod_log.assert_has_calls([
            mock.call(_preload_content=False,
                      container='base',
                      follow=True,
                      timestamps=False,
                      name=mock.sentinel.metadata.name,
                      namespace=mock.sentinel.metadata.namespace),
            mock.call(_preload_content=False,
                      container='base',
                      follow=True,
                      timestamps=False,
                      name=mock.sentinel.metadata.name,
                      namespace=mock.sentinel.metadata.namespace)
        ])

    def test_read_pod_logs_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom')
        ]
        self.assertRaises(AirflowException, self.pod_launcher.read_pod_logs,
                          mock.sentinel)

    def test_read_pod_logs_successfully_with_tail_lines(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            mock.sentinel.logs
        ]
        logs = self.pod_launcher.read_pod_logs(mock.sentinel, tail_lines=100)
        self.assertEqual(mock.sentinel.logs, logs)
        self.mock_kube_client.read_namespaced_pod_log.assert_has_calls([
            mock.call(_preload_content=False,
                      container='base',
                      follow=True,
                      timestamps=False,
                      name=mock.sentinel.metadata.name,
                      namespace=mock.sentinel.metadata.namespace,
                      tail_lines=100),
        ])

    def test_read_pod_logs_successfully_with_since_seconds(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod_log.side_effect = [
            mock.sentinel.logs
        ]
        logs = self.pod_launcher.read_pod_logs(mock.sentinel, since_seconds=2)
        self.assertEqual(mock.sentinel.logs, logs)
        self.mock_kube_client.read_namespaced_pod_log.assert_has_calls([
            mock.call(_preload_content=False,
                      container='base',
                      follow=True,
                      timestamps=False,
                      name=mock.sentinel.metadata.name,
                      namespace=mock.sentinel.metadata.namespace,
                      since_seconds=2),
        ])

    def test_read_pod_events_successfully_returns_events(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.return_value = mock.sentinel.events
        events = self.pod_launcher.read_pod_events(mock.sentinel)
        self.assertEqual(mock.sentinel.events, events)

    def test_read_pod_events_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.side_effect = [
            BaseHTTPError('Boom'), mock.sentinel.events
        ]
        events = self.pod_launcher.read_pod_events(mock.sentinel)
        self.assertEqual(mock.sentinel.events, events)
        self.mock_kube_client.list_namespaced_event.assert_has_calls([
            mock.call(namespace=mock.sentinel.metadata.namespace,
                      field_selector="involvedObject.name={}".format(
                          mock.sentinel.metadata.name)),
            mock.call(namespace=mock.sentinel.metadata.namespace,
                      field_selector="involvedObject.name={}".format(
                          mock.sentinel.metadata.name))
        ])

    def test_read_pod_events_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.list_namespaced_event.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom')
        ]
        self.assertRaises(AirflowException, self.pod_launcher.read_pod_events,
                          mock.sentinel)

    def test_read_pod_returns_logs(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.return_value = mock.sentinel.pod_info
        pod_info = self.pod_launcher.read_pod(mock.sentinel)
        self.assertEqual(mock.sentinel.pod_info, pod_info)

    def test_read_pod_retries_successfully(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.side_effect = [
            BaseHTTPError('Boom'), mock.sentinel.pod_info
        ]
        pod_info = self.pod_launcher.read_pod(mock.sentinel)
        self.assertEqual(mock.sentinel.pod_info, pod_info)
        self.mock_kube_client.read_namespaced_pod.assert_has_calls([
            mock.call(mock.sentinel.metadata.name,
                      mock.sentinel.metadata.namespace),
            mock.call(mock.sentinel.metadata.name,
                      mock.sentinel.metadata.namespace)
        ])

    def test_read_pod_retries_fails(self):
        mock.sentinel.metadata = mock.MagicMock()
        self.mock_kube_client.read_namespaced_pod.side_effect = [
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom'),
            BaseHTTPError('Boom')
        ]
        self.assertRaises(AirflowException, self.pod_launcher.read_pod,
                          mock.sentinel)

    def test_parse_log_line(self):
        timestamp, message = \
            self.pod_launcher.parse_log_line('2020-10-08T14:16:17.793417674Z Valid message\n')

        self.assertEqual(timestamp, '2020-10-08T14:16:17.793417674Z')
        self.assertEqual(message, 'Valid message')

        self.assertRaises(
            Exception,
            self.pod_launcher.parse_log_line(
                '2020-10-08T14:16:17.793417674ZInvalid message\n'),
        )