def test_follow_logs_streams_to_logging(self, mock_log, mock_get_namespace, mock_client): mock_get_namespace.return_value = 'logging-ns' mock_read = mock_client.CoreV1Api.return_value.read_namespaced_pod_log mock_read.return_value.stream.return_value = [b'line1\n', b'line2\n'] mock_pod = self.make_mock_pod('logging-pod-123') kc = KubernetesClient() kc._set_pod(mock_pod) mock_log.reset_mock( ) # log will have other calls before calling follow_logs() kc.follow_logs() self.assertTrue(mock_read.called) self.assertEqual( mock_read.call_args, call('logging-pod-123', 'logging-ns', follow=True, _preload_content=False)) self.assertEqual( mock_log.debug.mock_calls, [call('[logging-pod-123] line1'), call('[logging-pod-123] line2')]) self.assertEqual(mock_log.info.mock_calls, [ call('[logging-pod-123] follow_logs start'), call('[logging-pod-123] follow_logs end') ])
def test_raises_on_set_second_pod(self, mock_get_namespace, mock_client): kc = KubernetesClient() kc._set_pod(Mock()) with self.assertRaises(CalrissianJobException) as context: kc._set_pod(Mock()) self.assertIn('This client is already observing pod', str(context.exception))
def test_wait_raises_exception_when_state_is_unexpected( self, mock_watch, mock_get_namespace, mock_client): mock_pod = create_autospec(V1Pod) mock_pod.status.container_statuses[0].state = Mock(running=None, waiting=None, terminated=None) self.setup_mock_watch(mock_watch, [mock_pod]) kc = KubernetesClient() kc._set_pod(Mock()) with self.assertRaisesRegex(CalrissianJobException, 'Unexpected pod container status'): kc.wait_for_completion()
def test_wait_skips_pod_when_status_is_none(self, mock_watch, mock_get_namespace, mock_client): mock_pod = Mock(status=Mock(container_statuses=None)) self.setup_mock_watch(mock_watch, [mock_pod]) kc = KubernetesClient() kc._set_pod(Mock()) kc.wait_for_completion() self.assertFalse(mock_watch.Watch.return_value.stop.called) self.assertFalse( mock_client.CoreV1Api.return_value.delete_namespaced_pod.called) self.assertIsNotNone(kc.pod)
def test_wait_calls_watch_pod_with_pod_name_field_selector( self, mock_watch, mock_get_namespace, mock_client): self.setup_mock_watch(mock_watch) mock_pod = self.make_mock_pod('test123') kc = KubernetesClient() kc._set_pod(mock_pod) kc.wait_for_completion() mock_stream = mock_watch.Watch.return_value.stream self.assertEqual( mock_stream.call_args, call(kc.core_api_instance.list_namespaced_pod, kc.namespace, field_selector='metadata.name=test123'))
def test_wait_skips_pod_when_state_is_waiting(self, mock_watch, mock_get_namespace, mock_client): mock_pod = create_autospec(V1Pod) mock_pod.status.container_statuses[0].state = Mock(running=None, waiting=True, terminated=None) self.setup_mock_watch(mock_watch, [mock_pod]) kc = KubernetesClient() kc._set_pod(Mock()) kc.wait_for_completion() self.assertFalse(mock_watch.Watch.return_value.stop.called) self.assertFalse( mock_client.CoreV1Api.return_value.delete_namespaced_pod.called) self.assertIsNotNone(kc.pod)
def test_wait_checks_should_delete_when_pod_state_is_terminated( self, mock_cpu_memory, mock_should_delete_pod, mock_watch, mock_get_namespace, mock_client): mock_pod = create_autospec(V1Pod) mock_pod.status.container_statuses[0].state = Mock( running=None, waiting=None, terminated=Mock(exit_code=123)) mock_cpu_memory.return_value = ('1', '1Mi') mock_should_delete_pod.return_value = False self.setup_mock_watch(mock_watch, [mock_pod]) kc = KubernetesClient() kc._set_pod(Mock()) completion_result = kc.wait_for_completion() self.assertEqual(completion_result.exit_code, 123) self.assertEqual(completion_result.memory, '1Mi') self.assertEqual(completion_result.cpus, '1') self.assertTrue(mock_watch.Watch.return_value.stop.called) self.assertFalse( mock_client.CoreV1Api.return_value.delete_namespaced_pod.called) self.assertIsNone(kc.pod)
def test_wait_finishes_when_pod_state_is_terminated( self, mock_cpu_memory, mock_podmonitor, mock_watch, mock_get_namespace, mock_client): mock_pod = create_autospec(V1Pod) mock_pod.status.container_statuses[0].state = Mock( running=None, waiting=None, terminated=Mock(exit_code=123)) mock_cpu_memory.return_value = ('1', '1Mi') self.setup_mock_watch(mock_watch, [mock_pod]) kc = KubernetesClient() kc._set_pod(Mock()) completion_result = kc.wait_for_completion() self.assertEqual(completion_result.exit_code, 123) self.assertTrue(mock_watch.Watch.return_value.stop.called) self.assertTrue( mock_client.CoreV1Api.return_value.delete_namespaced_pod.called) self.assertIsNone(kc.pod) # This is to inspect `with PodMonitor() as monitor`: self.assertTrue( mock_podmonitor.return_value.__enter__.return_value.remove.called)
def test_raises_on_set_second_pod(self, mock_get_namespace, mock_client): kc = KubernetesClient() kc._set_pod(Mock()) with self.assertRaisesRegex(CalrissianJobException, 'This client is already observing pod'): kc._set_pod(Mock())