Skip to content

Commit 049fc3e

Browse files
CagriYoncapvital
authored andcommitted
unittests(pubsub): added unittests of pubsub otel instrumentation
1 parent 7576c42 commit 049fc3e

File tree

2 files changed

+76
-68
lines changed

2 files changed

+76
-68
lines changed

tests/clients/test_google-cloud-pubsub.py

Lines changed: 76 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -4,30 +4,33 @@
44
import os
55
import threading
66
import time
7-
import six
8-
import unittest
7+
from typing import Generator
98

10-
from google.cloud.pubsub_v1 import PublisherClient, SubscriberClient
9+
import pytest
10+
import six
1111
from google.api_core.exceptions import AlreadyExists
12+
from google.cloud.pubsub_v1 import PublisherClient, SubscriberClient
1213
from google.cloud.pubsub_v1.publisher import exceptions
14+
from opentelemetry.trace import SpanKind
15+
1316
from instana.singletons import agent, tracer
17+
from instana.span.span import get_current_span
1418
from tests.test_utils import _TraceContextMixin
1519

1620
# Use PubSub Emulator exposed at :8085
1721
os.environ["PUBSUB_EMULATOR_HOST"] = "localhost:8085"
1822

1923

20-
class TestPubSubPublish(unittest.TestCase, _TraceContextMixin):
21-
@classmethod
22-
def setUpClass(cls):
23-
cls.publisher = PublisherClient()
24+
class TestPubSubPublish(_TraceContextMixin):
25+
publisher = PublisherClient()
2426

25-
def setUp(self):
26-
self.recorder = tracer.recorder
27+
@pytest.fixture(autouse=True)
28+
def _resource(self) -> Generator[None, None, None]:
29+
self.recorder = tracer.span_processor
2730
self.recorder.clear_spans()
2831

29-
self.project_id = 'test-project'
30-
self.topic_name = 'test-topic'
32+
self.project_id = "test-project"
33+
self.topic_name = "test-topic"
3134

3235
# setup topic_path & topic
3336
self.topic_path = self.publisher.topic_path(self.project_id, self.topic_name)
@@ -36,89 +39,91 @@ def setUp(self):
3639
except AlreadyExists:
3740
self.publisher.delete_topic(request={"topic": self.topic_path})
3841
self.publisher.create_topic(request={"name": self.topic_path})
39-
40-
def tearDown(self):
42+
yield
4143
self.publisher.delete_topic(request={"topic": self.topic_path})
4244
agent.options.allow_exit_as_root = False
4345

44-
def test_publish(self):
46+
def test_publish(self) -> None:
4547
# publish a single message
46-
with tracer.start_active_span('test'):
47-
future = self.publisher.publish(self.topic_path,
48-
b'Test Message',
49-
origin="instana")
48+
with tracer.start_as_current_span("test"):
49+
future = self.publisher.publish(
50+
self.topic_path, b"Test Message", origin="instana"
51+
)
5052
time.sleep(2.0) # for sanity
5153
result = future.result()
52-
self.assertIsInstance(result, six.string_types)
54+
assert isinstance(result, six.string_types)
5355

5456
spans = self.recorder.queued_spans()
5557
gcps_span, test_span = spans[0], spans[1]
5658

57-
self.assertEqual(2, len(spans))
58-
self.assertIsNone(tracer.active_span)
59-
self.assertEqual('gcps', gcps_span.n)
60-
self.assertEqual(2, gcps_span.k) # EXIT
59+
assert len(spans) == 2
60+
61+
current_span = get_current_span()
62+
assert not current_span.is_recording()
63+
assert gcps_span.n == "gcps"
64+
assert gcps_span.k is SpanKind.CLIENT
6165

62-
self.assertEqual('publish', gcps_span.data['gcps']['op'])
63-
self.assertEqual(self.topic_name, gcps_span.data['gcps']['top'])
66+
assert gcps_span.data["gcps"]["op"] == "publish"
67+
assert self.topic_name == gcps_span.data["gcps"]["top"]
6468

6569
# Trace Context Propagation
6670
self.assertTraceContextPropagated(test_span, gcps_span)
6771

6872
# Error logging
6973
self.assertErrorLogging(spans)
7074

71-
def test_publish_as_root_exit_span(self):
75+
def test_publish_as_root_exit_span(self) -> None:
7276
agent.options.allow_exit_as_root = True
7377
# publish a single message
74-
future = self.publisher.publish(self.topic_path,
75-
b'Test Message',
76-
origin="instana")
78+
future = self.publisher.publish(
79+
self.topic_path, b"Test Message", origin="instana"
80+
)
7781
time.sleep(2.0) # for sanity
7882
result = future.result()
79-
self.assertIsInstance(result, six.string_types)
83+
assert isinstance(result, six.string_types)
8084

8185
spans = self.recorder.queued_spans()
82-
self.assertEqual(1, len(spans))
86+
assert len(spans) == 1
8387
gcps_span = spans[0]
8488

85-
self.assertIsNone(tracer.active_span)
86-
self.assertEqual('gcps', gcps_span.n)
87-
self.assertEqual(2, gcps_span.k) # EXIT
89+
current_span = get_current_span()
90+
assert not current_span.is_recording()
91+
assert gcps_span.n == "gcps"
92+
assert gcps_span.k is SpanKind.CLIENT
8893

89-
self.assertEqual('publish', gcps_span.data['gcps']['op'])
90-
self.assertEqual(self.topic_name, gcps_span.data['gcps']['top'])
94+
assert gcps_span.data["gcps"]["op"] == "publish"
95+
assert self.topic_name == gcps_span.data["gcps"]["top"]
9196

9297
# Error logging
9398
self.assertErrorLogging(spans)
9499

95100

96101
class AckCallback(object):
97-
def __init__(self):
102+
def __init__(self) -> None:
98103
self.calls = 0
99104
self.lock = threading.Lock()
100105

101-
def __call__(self, message):
106+
def __call__(self, message) -> None:
102107
message.ack()
103108
# Only increment the number of calls **after** finishing.
104109
with self.lock:
105110
self.calls += 1
106111

107112

108-
class TestPubSubSubscribe(unittest.TestCase, _TraceContextMixin):
113+
class TestPubSubSubscribe(_TraceContextMixin):
109114
@classmethod
110-
def setUpClass(cls):
115+
def setup_class(cls) -> None:
111116
cls.publisher = PublisherClient()
112117
cls.subscriber = SubscriberClient()
113118

114-
def setUp(self):
115-
116-
self.recorder = tracer.recorder
119+
@pytest.fixture(autouse=True)
120+
def _resource(self) -> Generator[None, None, None]:
121+
self.recorder = tracer.span_processor
117122
self.recorder.clear_spans()
118123

119-
self.project_id = 'test-project'
120-
self.topic_name = 'test-topic'
121-
self.subscription_name = 'test-subscription'
124+
self.project_id = "test-project"
125+
self.topic_name = "test-topic"
126+
self.subscription_name = "test-subscription"
122127

123128
# setup topic_path & topic
124129
self.topic_path = self.publisher.topic_path(self.project_id, self.topic_name)
@@ -130,29 +135,33 @@ def setUp(self):
130135

131136
# setup subscription path & attach subscription
132137
self.subscription_path = self.subscriber.subscription_path(
133-
self.project_id, self.subscription_name)
138+
self.project_id,
139+
self.subscription_name,
140+
)
134141
try:
135142
self.subscriber.create_subscription(
136143
request={"name": self.subscription_path, "topic": self.topic_path}
137144
)
138145
except AlreadyExists:
139-
self.subscriber.delete_subscription(request={"subscription": self.subscription_path})
146+
self.subscriber.delete_subscription(
147+
request={"subscription": self.subscription_path}
148+
)
140149
self.subscriber.create_subscription(
141150
request={"name": self.subscription_path, "topic": self.topic_path}
142151
)
143-
144-
def tearDown(self):
152+
yield
145153
self.publisher.delete_topic(request={"topic": self.topic_path})
146-
self.subscriber.delete_subscription(request={"subscription": self.subscription_path})
147-
148-
def test_subscribe(self):
154+
self.subscriber.delete_subscription(
155+
request={"subscription": self.subscription_path}
156+
)
149157

150-
with tracer.start_active_span('test'):
158+
def test_subscribe(self) -> None:
159+
with tracer.start_as_current_span("test"):
151160
# Publish a message
152-
future = self.publisher.publish(self.topic_path,
153-
b"Test Message to PubSub",
154-
origin="instana")
155-
self.assertIsInstance(future.result(), six.string_types)
161+
future = self.publisher.publish(
162+
self.topic_path, b"Test Message to PubSub", origin="instana"
163+
)
164+
assert isinstance(future.result(), six.string_types)
156165

157166
time.sleep(2.0) # for sanity
158167

@@ -171,15 +180,16 @@ def test_subscribe(self):
171180
consumer_span = spans[1]
172181
test_span = spans[2]
173182

174-
self.assertEqual(3, len(spans))
175-
self.assertIsNone(tracer.active_span)
176-
self.assertEqual('publish', producer_span.data['gcps']['op'])
177-
self.assertEqual('consume', consumer_span.data['gcps']['op'])
178-
self.assertEqual(self.topic_name, producer_span.data['gcps']['top'])
179-
self.assertEqual(self.subscription_name, consumer_span.data['gcps']['sub'])
183+
assert len(spans) == 3
184+
current_span = get_current_span()
185+
assert not current_span.is_recording()
186+
assert producer_span.data["gcps"]["op"] == "publish"
187+
assert consumer_span.data["gcps"]["op"] == "consume"
188+
assert self.topic_name == producer_span.data["gcps"]["top"]
189+
assert self.subscription_name == consumer_span.data["gcps"]["sub"]
180190

181-
self.assertEqual(2, producer_span.k) # EXIT
182-
self.assertEqual(1, consumer_span.k) # ENTRY
191+
assert producer_span.k is SpanKind.CLIENT
192+
assert consumer_span.k is SpanKind.SERVER
183193

184194
# Trace Context Propagation
185195
self.assertTraceContextPropagated(producer_span, consumer_span)

tests/conftest.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,8 +29,6 @@
2929

3030
# TODO: remove the following entries as the migration of the instrumentation
3131
# codes are finalised.
32-
collect_ignore_glob.append("*clients/test_google*")
33-
3432
collect_ignore_glob.append("*frameworks/test_gevent*")
3533

3634
# # Cassandra and gevent tests are run in dedicated jobs on CircleCI and will

0 commit comments

Comments
 (0)