| 
									
										
										
										
											2021-02-06 09:42:05 -08:00
										 |  |  | from gometa.ingestion.sink.datahub_kafka import DatahubKafkaSink, KafkaCallback | 
					
						
							| 
									
										
										
										
											2021-02-09 15:58:26 -08:00
										 |  |  | from gometa.ingestion.api.sink import WriteCallback, SinkReport | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | import unittest | 
					
						
							|  |  |  | from unittest.mock import patch, MagicMock | 
					
						
							| 
									
										
										
										
											2021-02-11 21:59:54 -08:00
										 |  |  | from gometa.ingestion.api.common import RecordEnvelope | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  | class KafkaSinkTest(unittest.TestCase): | 
					
						
							| 
									
										
										
										
											2021-02-06 09:42:05 -08:00
										 |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.PipelineContext") | 
					
						
							|  |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.SerializingProducer") | 
					
						
							|  |  |  |     def test_kafka_sink_config(self, mock_producer, mock_context): | 
					
						
							| 
									
										
										
										
											2021-02-11 22:48:08 -08:00
										 |  |  |         kafka_sink = DatahubKafkaSink.create( | 
					
						
							|  |  |  |             {"connection": {"bootstrap": "foobar:9092"}}, mock_context | 
					
						
							|  |  |  |         ) | 
					
						
							|  |  |  |         kafka_sink.close() | 
					
						
							| 
									
										
										
										
											2021-02-11 16:00:29 -08:00
										 |  |  |         assert mock_producer.call_count == 1  # constructor should be called | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  | 
 | 
					
						
							|  |  |  |     def validate_kafka_callback(self, mock_k_callback, record_envelope, write_callback): | 
					
						
							|  |  |  |         assert mock_k_callback.call_count == 1  # KafkaCallback constructed | 
					
						
							|  |  |  |         constructor_args, constructor_kwargs = mock_k_callback.call_args | 
					
						
							| 
									
										
										
										
											2021-02-09 15:58:26 -08:00
										 |  |  |         assert constructor_args[1] == record_envelope | 
					
						
							|  |  |  |         assert constructor_args[2] == write_callback | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-06 09:42:05 -08:00
										 |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.PipelineContext") | 
					
						
							|  |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.SerializingProducer") | 
					
						
							|  |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.KafkaCallback") | 
					
						
							|  |  |  |     def test_kafka_sink_write(self, mock_k_callback, mock_producer, mock_context): | 
					
						
							| 
									
										
										
										
											2021-02-11 16:00:29 -08:00
										 |  |  |         mock_producer_instance = mock_producer.return_value | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  |         mock_k_callback_instance = mock_k_callback.return_value | 
					
						
							|  |  |  |         callback = MagicMock(spec=WriteCallback) | 
					
						
							| 
									
										
										
										
											2021-02-11 22:48:08 -08:00
										 |  |  |         kafka_sink = DatahubKafkaSink.create( | 
					
						
							|  |  |  |             {"connection": {"bootstrap": "foobar:9092"}}, mock_context | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  |         re = RecordEnvelope(record="test", metadata={}) | 
					
						
							|  |  |  |         kafka_sink.write_record_async(re, callback) | 
					
						
							| 
									
										
										
										
											2021-02-11 16:00:29 -08:00
										 |  |  |         assert mock_producer_instance.poll.call_count == 1  # poll() called once | 
					
						
							|  |  |  |         self.validate_kafka_callback( | 
					
						
							|  |  |  |             mock_k_callback, re, callback | 
					
						
							|  |  |  |         )  # validate kafka callback was constructed appropriately | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  |         # validate that confluent_kafka.Producer.produce was called with the right arguments | 
					
						
							|  |  |  |         args, kwargs = mock_producer_instance.produce.call_args | 
					
						
							| 
									
										
										
										
											2021-02-06 09:42:05 -08:00
										 |  |  |         created_callback = kwargs["on_delivery"] | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  |         assert created_callback == mock_k_callback_instance.kafka_callback | 
					
						
							| 
									
										
										
										
											2021-02-11 16:00:29 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-11 22:48:08 -08:00
										 |  |  |     # TODO: Test that kafka producer is configured correctly | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-06 09:42:05 -08:00
										 |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.PipelineContext") | 
					
						
							|  |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.SerializingProducer") | 
					
						
							|  |  |  |     def test_kafka_sink_close(self, mock_producer, mock_context): | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  |         mock_producer_instance = mock_producer.return_value | 
					
						
							| 
									
										
										
										
											2021-02-06 09:42:05 -08:00
										 |  |  |         kafka_sink = DatahubKafkaSink.create({}, mock_context) | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  |         kafka_sink.close() | 
					
						
							|  |  |  |         mock_producer_instance.flush.assert_called_once() | 
					
						
							| 
									
										
										
										
											2021-02-11 16:00:29 -08:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-02-06 09:42:05 -08:00
										 |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.RecordEnvelope") | 
					
						
							|  |  |  |     @patch("gometa.ingestion.sink.datahub_kafka.WriteCallback") | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  |     def test_kafka_callback_class(self, mock_w_callback, mock_re): | 
					
						
							| 
									
										
										
										
											2021-02-11 22:48:08 -08:00
										 |  |  |         callback = KafkaCallback( | 
					
						
							|  |  |  |             SinkReport(), record_envelope=mock_re, write_callback=mock_w_callback | 
					
						
							|  |  |  |         ) | 
					
						
							| 
									
										
										
										
											2021-01-31 22:40:30 -08:00
										 |  |  |         mock_error = MagicMock() | 
					
						
							|  |  |  |         mock_message = MagicMock() | 
					
						
							|  |  |  |         callback.kafka_callback(mock_error, mock_message) | 
					
						
							|  |  |  |         assert mock_w_callback.on_failure.call_count == 1 | 
					
						
							|  |  |  |         mock_w_callback.on_failure.called_with(mock_re, None, {"error", mock_error}) | 
					
						
							|  |  |  |         callback.kafka_callback(None, mock_message) | 
					
						
							|  |  |  |         mock_w_callback.on_success.called_once_with(mock_re, {"msg", mock_message}) |