3
3
import unittest
4
4
import sys
5
5
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
10
13
11
14
from google .api_core .exceptions import GoogleAPICallError
12
15
from google .cloud .spanner_v1 import _opentelemetry_tracing
13
16
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
27
18
28
19
def _make_rpc_error (error_cls , trailing_metadata = None ):
29
20
import grpc
@@ -38,102 +29,103 @@ def _make_session():
38
29
39
30
return mock .Mock (autospec = Session , instance = True )
40
31
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 )
41
64
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 ):
129
65
with _opentelemetry_tracing .trace_call (
130
66
"CloudSpanner.Test" , _make_session (), extra_attributes
131
67
) 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 )
0 commit comments