|
14 | 14 |
|
15 | 15 | # pylint: disable=no-name-in-module
|
16 | 16 |
|
17 |
| -from unittest import TestCase |
| 17 | +from unittest.mock import patch |
| 18 | + |
| 19 | +from opentelemetry.semconv.trace import SpanAttributes, MessagingDestinationKindValues |
| 20 | +from opentelemetry.test.test_base import TestBase |
| 21 | +from .utils import MockConsumer, MockedMessage |
18 | 22 |
|
19 | 23 | from confluent_kafka import Consumer, Producer
|
20 | 24 |
|
|
29 | 33 | )
|
30 | 34 |
|
31 | 35 |
|
32 |
| -class TestConfluentKafka(TestCase): |
| 36 | +class TestConfluentKafka(TestBase): |
33 | 37 | def test_instrument_api(self) -> None:
|
34 | 38 | instrumentation = ConfluentKafkaInstrumentor()
|
35 | 39 |
|
@@ -104,3 +108,160 @@ def test_context_getter(self) -> None:
|
104 | 108 | context_setter.set(carrier_list, "key1", "val1")
|
105 | 109 | self.assertEqual(context_getter.get(carrier_list, "key1"), ["val1"])
|
106 | 110 | self.assertEqual(["key1"], context_getter.keys(carrier_list))
|
| 111 | + |
| 112 | + def test_poll(self) -> None: |
| 113 | + instrumentation = ConfluentKafkaInstrumentor() |
| 114 | + mocked_messages = [ |
| 115 | + MockedMessage("topic-10", 0, 0, []), |
| 116 | + MockedMessage("topic-20", 2, 4, []), |
| 117 | + MockedMessage("topic-30", 1, 3, []), |
| 118 | + ] |
| 119 | + expected_spans= [ |
| 120 | + { |
| 121 | + "name": "recv", |
| 122 | + "attributes": {} |
| 123 | + }, |
| 124 | + { |
| 125 | + "name": "topic-10 process", |
| 126 | + "attributes": { |
| 127 | + SpanAttributes.MESSAGING_OPERATION: "process", |
| 128 | + SpanAttributes.MESSAGING_KAFKA_PARTITION: 0, |
| 129 | + SpanAttributes.MESSAGING_SYSTEM: "kafka", |
| 130 | + SpanAttributes.MESSAGING_DESTINATION: "topic-10", |
| 131 | + SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value, |
| 132 | + SpanAttributes.MESSAGING_MESSAGE_ID: "topic-10.0.0", |
| 133 | + } |
| 134 | + }, |
| 135 | + { |
| 136 | + "name": "recv", |
| 137 | + "attributes": {} |
| 138 | + }, |
| 139 | + { |
| 140 | + "name": "topic-20 process", |
| 141 | + "attributes": { |
| 142 | + SpanAttributes.MESSAGING_OPERATION: "process", |
| 143 | + SpanAttributes.MESSAGING_KAFKA_PARTITION: 2, |
| 144 | + SpanAttributes.MESSAGING_SYSTEM: "kafka", |
| 145 | + SpanAttributes.MESSAGING_DESTINATION: "topic-20", |
| 146 | + SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value, |
| 147 | + SpanAttributes.MESSAGING_MESSAGE_ID: "topic-20.2.4", |
| 148 | + } |
| 149 | + }, |
| 150 | + { |
| 151 | + "name": "recv", |
| 152 | + "attributes": {} |
| 153 | + }, |
| 154 | + { |
| 155 | + "name": "topic-30 process", |
| 156 | + "attributes": { |
| 157 | + SpanAttributes.MESSAGING_OPERATION: "process", |
| 158 | + SpanAttributes.MESSAGING_KAFKA_PARTITION: 1, |
| 159 | + SpanAttributes.MESSAGING_SYSTEM: "kafka", |
| 160 | + SpanAttributes.MESSAGING_DESTINATION: "topic-30", |
| 161 | + SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value, |
| 162 | + SpanAttributes.MESSAGING_MESSAGE_ID: "topic-30.1.3", |
| 163 | + } |
| 164 | + }, |
| 165 | + { |
| 166 | + "name": "recv", |
| 167 | + "attributes": {} |
| 168 | + }, |
| 169 | + ] |
| 170 | + |
| 171 | + consumer = MockConsumer( |
| 172 | + mocked_messages, |
| 173 | + { |
| 174 | + "bootstrap.servers": "localhost:29092", |
| 175 | + "group.id": "mygroup", |
| 176 | + "auto.offset.reset": "earliest", |
| 177 | + } |
| 178 | + ) |
| 179 | + span_list = self.memory_exporter.clear() |
| 180 | + consumer = instrumentation.instrument_consumer(consumer) |
| 181 | + consumer.poll(1) |
| 182 | + consumer.poll(1) |
| 183 | + consumer.poll(1) |
| 184 | + consumer.poll(1) |
| 185 | + |
| 186 | + span_list = self.memory_exporter.get_finished_spans() |
| 187 | + self._compare_spans(span_list, expected_spans) |
| 188 | + |
| 189 | + def test_consume(self) -> None: |
| 190 | + instrumentation = ConfluentKafkaInstrumentor() |
| 191 | + mocked_messages = [ |
| 192 | + MockedMessage("topic-1", 0, 0, []), |
| 193 | + MockedMessage("topic-1", 2, 1, []), |
| 194 | + MockedMessage("topic-1", 3, 2, []), |
| 195 | + MockedMessage("topic-2", 0, 0, []), |
| 196 | + MockedMessage("topic-3", 0, 3, []), |
| 197 | + MockedMessage("topic-2", 0, 1, []), |
| 198 | + ] |
| 199 | + expected_spans= [ |
| 200 | + { |
| 201 | + "name": "recv", |
| 202 | + "attributes": {} |
| 203 | + }, |
| 204 | + { |
| 205 | + "name": "topic-1 process", |
| 206 | + "attributes": { |
| 207 | + SpanAttributes.MESSAGING_OPERATION: "process", |
| 208 | + SpanAttributes.MESSAGING_SYSTEM: "kafka", |
| 209 | + SpanAttributes.MESSAGING_DESTINATION: "topic-1", |
| 210 | + SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value, |
| 211 | + } |
| 212 | + }, |
| 213 | + { |
| 214 | + "name": "recv", |
| 215 | + "attributes": {} |
| 216 | + }, |
| 217 | + { |
| 218 | + "name": "topic-2 process", |
| 219 | + "attributes": { |
| 220 | + SpanAttributes.MESSAGING_OPERATION: "process", |
| 221 | + SpanAttributes.MESSAGING_SYSTEM: "kafka", |
| 222 | + SpanAttributes.MESSAGING_DESTINATION: "topic-2", |
| 223 | + SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value, |
| 224 | + } |
| 225 | + }, |
| 226 | + { |
| 227 | + "name": "recv", |
| 228 | + "attributes": {} |
| 229 | + }, |
| 230 | + { |
| 231 | + "name": "topic-3 process", |
| 232 | + "attributes": { |
| 233 | + SpanAttributes.MESSAGING_OPERATION: "process", |
| 234 | + SpanAttributes.MESSAGING_SYSTEM: "kafka", |
| 235 | + SpanAttributes.MESSAGING_DESTINATION: "topic-3", |
| 236 | + SpanAttributes.MESSAGING_DESTINATION_KIND: MessagingDestinationKindValues.QUEUE.value, |
| 237 | + } |
| 238 | + }, |
| 239 | + { |
| 240 | + "name": "recv", |
| 241 | + "attributes": {} |
| 242 | + }, |
| 243 | + ] |
| 244 | + |
| 245 | + consumer = MockConsumer( |
| 246 | + mocked_messages, |
| 247 | + { |
| 248 | + "bootstrap.servers": "localhost:29092", |
| 249 | + "group.id": "mygroup", |
| 250 | + "auto.offset.reset": "earliest", |
| 251 | + } |
| 252 | + ) |
| 253 | + |
| 254 | + span_list = self.memory_exporter.clear() |
| 255 | + consumer = instrumentation.instrument_consumer(consumer) |
| 256 | + consumer.consume(3) |
| 257 | + consumer.consume(1) |
| 258 | + consumer.consume(2) |
| 259 | + consumer.consume(1) |
| 260 | + span_list = self.memory_exporter.get_finished_spans() |
| 261 | + self._compare_spans(span_list, expected_spans) |
| 262 | + |
| 263 | + def _compare_spans(self, spans, expected_spans): |
| 264 | + for (span, expected_span) in zip(spans, expected_spans): |
| 265 | + self.assertEqual(expected_span['name'], span.name) |
| 266 | + for attribute_key, expected_attribute_value in expected_span['attributes'].items(): |
| 267 | + self.assertEqual(expected_attribute_value, span.attributes[attribute_key]) |
0 commit comments