Skip to content

Commit 70a9012

Browse files
committed
bring back support for python2.7
1 parent 2a07883 commit 70a9012

10 files changed

+200
-184
lines changed

google/cloud/spanner_v1/_opentelemetry_tracing.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Copyright 2016 Google LLC All rights reserved.
1+
# Copyright 2020 Google LLC All rights reserved.
22
#
33
# Licensed under the Apache License, Version 2.0 (the "License");
44
# you may not use this file except in compliance with the License.

google/cloud/spanner_v1/session.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -139,9 +139,11 @@ def exists(self):
139139
with trace_call("CloudSpanner.GetSession", self) as span:
140140
try:
141141
api.get_session(self.name, metadata=metadata)
142-
span.set_attribute("session_found", True)
142+
if span:
143+
span.set_attribute("session_found", True)
143144
except NotFound:
144-
span.set_attribute("session_found", False)
145+
if span:
146+
span.set_attribute("session_found", False)
145147
return False
146148

147149
return True

noxfile.py

Lines changed: 12 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -67,10 +67,11 @@ def default(session):
6767
# Install all test dependencies, then install this package in-place.
6868
session.install("mock", "pytest", "pytest-cov")
6969

70-
# Install opentelemetry dependencies
71-
session.install(
72-
"opentelemetry-api", "opentelemetry-sdk", "opentelemetry-instrumentation"
73-
)
70+
# Install opentelemetry dependencies if python3+
71+
if session.python != "2.7":
72+
session.install(
73+
"opentelemetry-api", "opentelemetry-sdk", "opentelemetry-instrumentation"
74+
)
7475

7576
session.install("-e", ".")
7677

@@ -89,13 +90,13 @@ def default(session):
8990
)
9091

9192

92-
@nox.session(python=["3.5", "3.6", "3.7", "3.8"])
93+
@nox.session(python=["2.7", "3.5", "3.6", "3.7", "3.8"])
9394
def unit(session):
9495
"""Run the unit test suite."""
9596
default(session)
9697

9798

98-
@nox.session(python="3.7")
99+
@nox.session(python=["2.7", "3.7"])
99100
def system(session):
100101
"""Run the system test suite."""
101102
system_test_path = os.path.join("tests", "system.py")
@@ -121,10 +122,11 @@ def system(session):
121122
# virtualenv's dist-packages.
122123
session.install("mock", "pytest")
123124

124-
# Install opentelemetry dependencies
125-
session.install(
126-
"opentelemetry-api", "opentelemetry-sdk", "opentelemetry-instrumentation"
127-
)
125+
# Install opentelemetry dependencies if not 2.7
126+
if session.python != "2.7":
127+
session.install(
128+
"opentelemetry-api", "opentelemetry-sdk", "opentelemetry-instrumentation"
129+
)
128130

129131
session.install("-e", ".")
130132
session.install("-e", "test_utils/")

tests/_helpers.py

Lines changed: 33 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,35 +1,47 @@
11
import unittest
2-
from opentelemetry import trace as trace_api
3-
from opentelemetry.trace.status import StatusCanonicalCode
2+
from unittest import mock
43

5-
from opentelemetry.sdk.trace import TracerProvider, export
6-
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
4+
try:
5+
from opentelemetry import trace as trace_api
6+
from opentelemetry.trace.status import StatusCanonicalCode
77

8+
from opentelemetry.sdk.trace import TracerProvider, export
9+
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
10+
11+
HAS_OPENTELEMETRY_INSTALLED = True
12+
except ImportError:
13+
HAS_OPENTELEMETRY_INSTALLED = False
14+
15+
StatusCanonicalCode = mock.Mock()
816

917
class OpenTelemetryBase(unittest.TestCase):
1018
def setUp(self):
11-
self.original_tracer_provider = trace_api.get_tracer_provider()
12-
self.tracer_provider = TracerProvider()
13-
self.memory_exporter = InMemorySpanExporter()
14-
span_processor = export.SimpleExportSpanProcessor(self.memory_exporter)
15-
self.tracer_provider.add_span_processor(span_processor)
16-
trace_api.set_tracer_provider(self.tracer_provider)
19+
if HAS_OPENTELEMETRY_INSTALLED:
20+
self.original_tracer_provider = trace_api.get_tracer_provider()
21+
self.tracer_provider = TracerProvider()
22+
self.memory_exporter = InMemorySpanExporter()
23+
span_processor = export.SimpleExportSpanProcessor(self.memory_exporter)
24+
self.tracer_provider.add_span_processor(span_processor)
25+
trace_api.set_tracer_provider(self.tracer_provider)
1726

1827
def tearDown(self):
19-
trace_api.set_tracer_provider(self.original_tracer_provider)
28+
if HAS_OPENTELEMETRY_INSTALLED:
29+
trace_api.set_tracer_provider(self.original_tracer_provider)
2030

2131
def assertNoSpans(self):
22-
span_list = self.memory_exporter.get_finished_spans()
23-
self.assertEqual(len(span_list), 0)
32+
if HAS_OPENTELEMETRY_INSTALLED:
33+
span_list = self.memory_exporter.get_finished_spans()
34+
self.assertEqual(len(span_list), 0)
2435

2536
def assertSpanAttributes(
2637
self, name, status=StatusCanonicalCode.OK, attributes=None, span=None
2738
):
28-
if not span:
29-
span_list = self.memory_exporter.get_finished_spans()
30-
self.assertEqual(len(span_list), 1)
31-
span = span_list[0]
32-
print(status, attributes, span.status, span.attributes)
33-
self.assertEqual(span.name, name)
34-
self.assertEqual(span.status.canonical_code, status)
35-
self.assertEqual(span.attributes, attributes)
39+
if HAS_OPENTELEMETRY_INSTALLED:
40+
if not span:
41+
span_list = self.memory_exporter.get_finished_spans()
42+
self.assertEqual(len(span_list), 1)
43+
span = span_list[0]
44+
45+
self.assertEqual(span.name, name)
46+
self.assertEqual(span.status.canonical_code, status)
47+
self.assertEqual(span.attributes, attributes)

tests/system/test_system.py

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,8 +1332,10 @@ def test_transaction_batch_update_wo_statements(self):
13321332
transaction.batch_update([])
13331333

13341334
def test_transaction_batch_update_w_parent_span(self):
1335-
import sys
1336-
from opentelemetry import trace
1335+
try:
1336+
from opentelemetry import trace
1337+
except ImportError:
1338+
return
13371339

13381340
tracer = trace.get_tracer(__name__)
13391341

tests/unit/test__opentelemetry_tracing.py

Lines changed: 104 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -3,27 +3,18 @@
33
import unittest
44
import sys
55

6-
from opentelemetry import trace as trace_api
7-
from opentelemetry.trace.status import StatusCanonicalCode
8-
from opentelemetry.sdk.trace import TracerProvider, export
9-
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
6+
try:
7+
from opentelemetry import trace as trace_api
8+
from opentelemetry.trace.status import StatusCanonicalCode
9+
from opentelemetry.sdk.trace import TracerProvider, export
10+
from opentelemetry.sdk.trace.export.in_memory_span_exporter import InMemorySpanExporter
11+
except ImportError:
12+
pass
1013

1114
from google.api_core.exceptions import GoogleAPICallError
1215
from google.cloud.spanner_v1 import _opentelemetry_tracing
1316

14-
15-
class OpenTelemetryBase(unittest.TestCase):
16-
def setUp(self):
17-
self.original_tracer_provider = trace_api.get_tracer_provider()
18-
self.tracer_provider = TracerProvider()
19-
self.memory_exporter = InMemorySpanExporter()
20-
span_processor = export.SimpleExportSpanProcessor(self.memory_exporter)
21-
self.tracer_provider.add_span_processor(span_processor)
22-
trace_api.set_tracer_provider(self.tracer_provider)
23-
24-
def tearDown(self):
25-
trace_api.set_tracer_provider(self.original_tracer_provider)
26-
17+
from tests._helpers import OpenTelemetryBase, HAS_OPENTELEMETRY_INSTALLED
2718

2819
def _make_rpc_error(error_cls, trailing_metadata=None):
2920
import grpc
@@ -38,102 +29,103 @@ def _make_session():
3829

3930
return mock.Mock(autospec=Session, instance=True)
4031

32+
# Skip all of these tests if we don't have OpenTelemetry
33+
if HAS_OPENTELEMETRY_INSTALLED:
34+
class TestNoTracing(unittest.TestCase):
35+
def setUp(self):
36+
self._temp_opentelemetry = sys.modules["opentelemetry"]
37+
38+
sys.modules["opentelemetry"] = None
39+
importlib.reload(_opentelemetry_tracing)
40+
41+
def tearDown(self):
42+
sys.modules["opentelemetry"] = self._temp_opentelemetry
43+
importlib.reload(_opentelemetry_tracing)
44+
45+
def test_no_trace_call(self):
46+
with _opentelemetry_tracing.trace_call("Test", _make_session()) as no_span:
47+
self.assertIsNone(no_span)
48+
49+
50+
class TestTracing(OpenTelemetryBase):
51+
def test_trace_call(self):
52+
extra_attributes = {
53+
"attribute1": "value1",
54+
# Since our database is mocked, we have to override the db.instance parameter so it is a string
55+
"db.instance": "database_name",
56+
}
57+
58+
expected_attributes = {
59+
"db.type": "spanner",
60+
"db.url": "spanner.googleapis.com:443",
61+
"net.host.name": "spanner.googleapis.com:443",
62+
}
63+
expected_attributes.update(extra_attributes)
4164

42-
class TestNoTracing(unittest.TestCase):
43-
def setUp(self):
44-
self._temp_opentelemetry = sys.modules["opentelemetry"]
45-
46-
sys.modules["opentelemetry"] = None
47-
importlib.reload(_opentelemetry_tracing)
48-
49-
def tearDown(self):
50-
sys.modules["opentelemetry"] = self._temp_opentelemetry
51-
importlib.reload(_opentelemetry_tracing)
52-
53-
def test_no_trace_call(self):
54-
with _opentelemetry_tracing.trace_call("Test", _make_session()) as no_span:
55-
self.assertIsNone(no_span)
56-
57-
58-
class TestTracing(OpenTelemetryBase):
59-
def test_trace_call(self):
60-
extra_attributes = {
61-
"attribute1": "value1",
62-
# Since our database is mocked, we have to override the db.instance parameter so it is a string
63-
"db.instance": "database_name",
64-
}
65-
66-
expected_attributes = {
67-
"db.type": "spanner",
68-
"db.url": "spanner.googleapis.com:443",
69-
"net.host.name": "spanner.googleapis.com:443",
70-
}
71-
expected_attributes.update(extra_attributes)
72-
73-
with _opentelemetry_tracing.trace_call(
74-
"CloudSpanner.Test", _make_session(), extra_attributes
75-
) as span:
76-
span.set_attribute("after_setup_attribute", 1)
77-
78-
expected_attributes["after_setup_attribute"] = 1
79-
80-
span_list = self.memory_exporter.get_finished_spans()
81-
self.assertEqual(len(span_list), 1)
82-
span = span_list[0]
83-
self.assertEqual(span.kind, trace_api.SpanKind.CLIENT)
84-
self.assertEqual(span.attributes, expected_attributes)
85-
self.assertEqual(span.name, "CloudSpanner.Test")
86-
self.assertEqual(
87-
span.status.canonical_code, trace_api.status.StatusCanonicalCode.OK
88-
)
89-
90-
def test_trace_error(self):
91-
extra_attributes = {"db.instance": "database_name"}
92-
93-
expected_attributes = {
94-
"db.type": "spanner",
95-
"db.url": "spanner.googleapis.com:443",
96-
"net.host.name": "spanner.googleapis.com:443",
97-
}
98-
expected_attributes.update(extra_attributes)
99-
100-
with self.assertRaises(GoogleAPICallError):
101-
with _opentelemetry_tracing.trace_call(
102-
"CloudSpanner.Test", _make_session(), extra_attributes
103-
) as span:
104-
from google.api_core.exceptions import InvalidArgument
105-
106-
raise _make_rpc_error(InvalidArgument)
107-
108-
span_list = self.memory_exporter.get_finished_spans()
109-
self.assertEqual(len(span_list), 1)
110-
span = span_list[0]
111-
self.assertEqual(span.kind, trace_api.SpanKind.CLIENT)
112-
self.assertEqual(span.attributes, expected_attributes)
113-
self.assertEqual(span.name, "CloudSpanner.Test")
114-
self.assertEqual(
115-
span.status.canonical_code, StatusCanonicalCode.INVALID_ARGUMENT
116-
)
117-
118-
def test_trace_grpc_error(self):
119-
extra_attributes = {"db.instance": "database_name"}
120-
121-
expected_attributes = {
122-
"db.type": "spanner",
123-
"db.url": "spanner.googleapis.com:443",
124-
"net.host.name": "spanner.googleapis.com:443",
125-
}
126-
expected_attributes.update(extra_attributes)
127-
128-
with self.assertRaises(GoogleAPICallError):
12965
with _opentelemetry_tracing.trace_call(
13066
"CloudSpanner.Test", _make_session(), extra_attributes
13167
) as span:
132-
from google.api_core.exceptions import DataLoss
133-
134-
raise _make_rpc_error(DataLoss)
135-
136-
span_list = self.memory_exporter.get_finished_spans()
137-
self.assertEqual(len(span_list), 1)
138-
span = span_list[0]
139-
self.assertEqual(span.status.canonical_code, StatusCanonicalCode.DATA_LOSS)
68+
span.set_attribute("after_setup_attribute", 1)
69+
70+
expected_attributes["after_setup_attribute"] = 1
71+
72+
span_list = self.memory_exporter.get_finished_spans()
73+
self.assertEqual(len(span_list), 1)
74+
span = span_list[0]
75+
self.assertEqual(span.kind, trace_api.SpanKind.CLIENT)
76+
self.assertEqual(span.attributes, expected_attributes)
77+
self.assertEqual(span.name, "CloudSpanner.Test")
78+
self.assertEqual(
79+
span.status.canonical_code, trace_api.status.StatusCanonicalCode.OK
80+
)
81+
82+
def test_trace_error(self):
83+
extra_attributes = {"db.instance": "database_name"}
84+
85+
expected_attributes = {
86+
"db.type": "spanner",
87+
"db.url": "spanner.googleapis.com:443",
88+
"net.host.name": "spanner.googleapis.com:443",
89+
}
90+
expected_attributes.update(extra_attributes)
91+
92+
with self.assertRaises(GoogleAPICallError):
93+
with _opentelemetry_tracing.trace_call(
94+
"CloudSpanner.Test", _make_session(), extra_attributes
95+
) as span:
96+
from google.api_core.exceptions import InvalidArgument
97+
98+
raise _make_rpc_error(InvalidArgument)
99+
100+
span_list = self.memory_exporter.get_finished_spans()
101+
self.assertEqual(len(span_list), 1)
102+
span = span_list[0]
103+
self.assertEqual(span.kind, trace_api.SpanKind.CLIENT)
104+
self.assertEqual(span.attributes, expected_attributes)
105+
self.assertEqual(span.name, "CloudSpanner.Test")
106+
self.assertEqual(
107+
span.status.canonical_code, StatusCanonicalCode.INVALID_ARGUMENT
108+
)
109+
110+
def test_trace_grpc_error(self):
111+
extra_attributes = {"db.instance": "database_name"}
112+
113+
expected_attributes = {
114+
"db.type": "spanner",
115+
"db.url": "spanner.googleapis.com:443",
116+
"net.host.name": "spanner.googleapis.com:443",
117+
}
118+
expected_attributes.update(extra_attributes)
119+
120+
with self.assertRaises(GoogleAPICallError):
121+
with _opentelemetry_tracing.trace_call(
122+
"CloudSpanner.Test", _make_session(), extra_attributes
123+
) as span:
124+
from google.api_core.exceptions import DataLoss
125+
126+
raise _make_rpc_error(DataLoss)
127+
128+
span_list = self.memory_exporter.get_finished_spans()
129+
self.assertEqual(len(span_list), 1)
130+
span = span_list[0]
131+
self.assertEqual(span.status.canonical_code, StatusCanonicalCode.DATA_LOSS)

tests/unit/test_batch.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,7 @@
1414

1515

1616
import unittest
17-
from tests._helpers import OpenTelemetryBase
18-
from opentelemetry.trace.status import StatusCanonicalCode
17+
from tests._helpers import OpenTelemetryBase, StatusCanonicalCode
1918

2019
TABLE_NAME = "citizens"
2120
COLUMNS = ["email", "first_name", "last_name", "age"]

0 commit comments

Comments
 (0)