-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathtest_tracing.py
More file actions
196 lines (151 loc) · 5.79 KB
/
test_tracing.py
File metadata and controls
196 lines (151 loc) · 5.79 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
import asyncio
from unittest.mock import MagicMock, call, patch
import pytest
from common.tracing import trace_function
@pytest.fixture
def mock_tracer():
"""
Fixture to mock the OpenTelemetry tracer and span.
"""
mock_tracer = MagicMock()
mock_span = MagicMock()
mock_tracer.start_as_current_span.return_value.__enter__.return_value = mock_span
with (
patch("opentelemetry.trace.get_tracer", return_value=mock_tracer),
patch("common.tracing.tracer", mock_tracer),
):
yield mock_tracer, mock_span
def test_sync_function_default_params(mock_tracer):
"""
Test a synchronous function with default decorator parameters.
"""
mock_tracer, mock_span = mock_tracer
# Define a sync function to wrap with the decorator
@trace_function()
def add_nums(a, b):
return a + b
# Call the function
result = add_nums(2, 3)
# Assertions
assert result == 5
mock_tracer.start_as_current_span.assert_called_once_with("add_nums")
mock_span.set_attribute.assert_any_call("function.args", "(2, 3)")
mock_span.set_attribute.assert_any_call("function.result", "5")
async def test_async_function_default_params(mock_tracer):
"""
Test an asynchronous function with default decorator parameters.
"""
mock_tracer, mock_span = mock_tracer
# Define an async function to wrap with the decorator
@trace_function()
async def async_func(a, b):
await asyncio.sleep(0.1)
return a * b
# Run the async function
result = await async_func(4, 5)
# Assertions
assert result == 20
mock_tracer.start_as_current_span.assert_called_once_with("async_func")
mock_span.set_attribute.assert_any_call("function.args", "(4, 5)")
mock_span.set_attribute.assert_any_call("function.result", "20")
def test_disable_function_attributes_sync(mock_tracer):
"""
Test a synchronous function with `add_function_attributes` set to False.
"""
mock_tracer, mock_span = mock_tracer
# Define a sync function with attributes disabled
@trace_function(trace_attributes=False)
def sync_func(a, b):
return a - b
# Call the function
result = sync_func(10, 6)
# Assertions
assert result == 4
mock_tracer.start_as_current_span.assert_called_once_with("sync_func")
mock_span.set_attribute.assert_any_call("function.result", "4")
assert call("function.args", "(10, 6)") not in mock_span.set_attribute.call_args_list
async def test_disable_function_attributes_async(mock_tracer):
"""
Test an asynchronous function with `add_function_attributes` set to False.
"""
mock_tracer, mock_span = mock_tracer
# Define a sync function with attributes disabled
@trace_function(trace_attributes=False)
async def async_func(a, b):
return a - b
# Call the function
result = await async_func(10, 6)
# Assertions
assert result == 4
mock_tracer.start_as_current_span.assert_called_once_with("async_func")
mock_span.set_attribute.assert_any_call("function.result", "4")
assert call("function.args", "(10, 6)") not in mock_span.set_attribute.call_args_list
def test_disable_result_in_span_sync(mock_tracer):
"""
Test an asynchronous function with `add_result_to_span` set to False.
"""
mock_tracer, mock_span = mock_tracer
# Define an async function with result disabled
@trace_function(trace_result=False)
def sync_func(a, b):
return a / b
# Run the async function
result = sync_func(10, 2)
# Assertions
assert result == 5.0
mock_tracer.start_as_current_span.assert_called_once_with("sync_func")
mock_span.set_attribute.assert_any_call("function.args", "(10, 2)")
assert call("function.result") not in mock_span.set_attribute.call_args_list
async def test_disable_result_in_span(mock_tracer):
"""
Test an asynchronous function with `add_result_to_span` set to False.
"""
mock_tracer, mock_span = mock_tracer
# Define an async function with result disabled
@trace_function(trace_result=False)
async def async_func(a, b):
await asyncio.sleep(0.1)
return a / b
# Run the async function
result = await async_func(10, 2)
# Assertions
assert result == 5.0
mock_tracer.start_as_current_span.assert_called_once_with("async_func")
mock_span.set_attribute.assert_any_call("function.args", "(10, 2)")
assert call("function.result") not in mock_span.set_attribute.call_args_list
def test_exception_in_function_sync(mock_tracer):
"""
Test behavior when the function raises an exception.
"""
mock_tracer, mock_span = mock_tracer
# Define a failing function
@trace_function()
def failing_func(a, b):
if b == 0:
raise ValueError("Division by zero!")
return a / b
# Use pytest to assert the exception is raised
with pytest.raises(ValueError, match="Division by zero!"):
failing_func(10, 0)
# Assertions
mock_tracer.start_as_current_span.assert_called_once_with("failing_func")
mock_span.record_exception.assert_called_once()
mock_span.set_status.assert_called_once()
async def test_exception_in_function_async(mock_tracer):
"""
Test behavior when the function raises an exception.
"""
mock_tracer, mock_span = mock_tracer
# Define a failing function
@trace_function()
async def failing_func(a, b):
if b == 0:
raise ValueError("Division by zero!")
return a / b
# Use pytest to assert the exception is raised
with pytest.raises(ValueError, match="Division by zero!"):
await failing_func(10, 0)
# Assertions
mock_tracer.start_as_current_span.assert_called_once_with("failing_func")
mock_span.record_exception.assert_called_once()
mock_span.set_status.assert_called_once()