1
+ from time import sleep
1
2
from unittest .mock import MagicMock , call
2
3
3
4
import pytest
@@ -60,6 +61,43 @@ def test_tracks_duration(client: LDClient):
60
61
assert tracker .get_summary ().duration == 100
61
62
62
63
64
+ def test_tracks_duration_of (client : LDClient ):
65
+ context = Context .create ('user-key' )
66
+ tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
67
+ tracker .track_duration_of (lambda : sleep (0.01 ))
68
+
69
+ calls = client .track .mock_calls # type: ignore
70
+
71
+ assert len (calls ) == 1
72
+ assert calls [0 ].args [0 ] == '$ld:ai:duration:total'
73
+ assert calls [0 ].args [1 ] == context
74
+ assert calls [0 ].args [2 ] == {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }
75
+ assert calls [0 ].args [3 ] == pytest .approx (10 , rel = 10 )
76
+
77
+
78
+ def test_tracks_duration_of_with_exception (client : LDClient ):
79
+ context = Context .create ('user-key' )
80
+ tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
81
+
82
+ def sleep_and_throw ():
83
+ sleep (0.01 )
84
+ raise ValueError ("Something went wrong" )
85
+
86
+ try :
87
+ tracker .track_duration_of (sleep_and_throw )
88
+ assert False , "Should have thrown an exception"
89
+ except ValueError :
90
+ pass
91
+
92
+ calls = client .track .mock_calls # type: ignore
93
+
94
+ assert len (calls ) == 1
95
+ assert calls [0 ].args [0 ] == '$ld:ai:duration:total'
96
+ assert calls [0 ].args [1 ] == context
97
+ assert calls [0 ].args [2 ] == {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }
98
+ assert calls [0 ].args [3 ] == pytest .approx (10 , rel = 10 )
99
+
100
+
63
101
def test_tracks_token_usage (client : LDClient ):
64
102
context = Context .create ('user-key' )
65
103
tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
@@ -97,6 +135,7 @@ def test_tracks_bedrock_metrics(client: LDClient):
97
135
98
136
calls = [
99
137
call ('$ld:ai:generation' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
138
+ call ('$ld:ai:generation:success' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
100
139
call ('$ld:ai:duration:total' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 50 ),
101
140
call ('$ld:ai:tokens:total' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 330 ),
102
141
call ('$ld:ai:tokens:input' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 220 ),
@@ -110,6 +149,39 @@ def test_tracks_bedrock_metrics(client: LDClient):
110
149
assert tracker .get_summary ().usage == TokenUsage (330 , 220 , 110 )
111
150
112
151
152
+ def test_tracks_bedrock_metrics_with_error (client : LDClient ):
153
+ context = Context .create ('user-key' )
154
+ tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
155
+
156
+ bedrock_result = {
157
+ '$metadata' : {'httpStatusCode' : 500 },
158
+ 'usage' : {
159
+ 'totalTokens' : 330 ,
160
+ 'inputTokens' : 220 ,
161
+ 'outputTokens' : 110 ,
162
+ },
163
+ 'metrics' : {
164
+ 'latencyMs' : 50 ,
165
+ }
166
+ }
167
+ tracker .track_bedrock_converse_metrics (bedrock_result )
168
+
169
+ calls = [
170
+ call ('$ld:ai:generation' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
171
+ call ('$ld:ai:generation:error' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
172
+ call ('$ld:ai:duration:total' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 50 ),
173
+ call ('$ld:ai:tokens:total' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 330 ),
174
+ call ('$ld:ai:tokens:input' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 220 ),
175
+ call ('$ld:ai:tokens:output' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 110 ),
176
+ ]
177
+
178
+ client .track .assert_has_calls (calls ) # type: ignore
179
+
180
+ assert tracker .get_summary ().success is False
181
+ assert tracker .get_summary ().duration == 50
182
+ assert tracker .get_summary ().usage == TokenUsage (330 , 220 , 110 )
183
+
184
+
113
185
def test_tracks_openai_metrics (client : LDClient ):
114
186
context = Context .create ('user-key' )
115
187
tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
@@ -129,6 +201,8 @@ def to_dict(self):
129
201
tracker .track_openai_metrics (lambda : Result ())
130
202
131
203
calls = [
204
+ call ('$ld:ai:generation' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
205
+ call ('$ld:ai:generation:success' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
132
206
call ('$ld:ai:tokens:total' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 330 ),
133
207
call ('$ld:ai:tokens:input' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 220 ),
134
208
call ('$ld:ai:tokens:output' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 110 ),
@@ -139,6 +213,29 @@ def to_dict(self):
139
213
assert tracker .get_summary ().usage == TokenUsage (330 , 220 , 110 )
140
214
141
215
216
+ def test_tracks_openai_metrics_with_exception (client : LDClient ):
217
+ context = Context .create ('user-key' )
218
+ tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
219
+
220
+ def raise_exception ():
221
+ raise ValueError ("Something went wrong" )
222
+
223
+ try :
224
+ tracker .track_openai_metrics (raise_exception )
225
+ assert False , "Should have thrown an exception"
226
+ except ValueError :
227
+ pass
228
+
229
+ calls = [
230
+ call ('$ld:ai:generation' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
231
+ call ('$ld:ai:generation:error' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
232
+ ]
233
+
234
+ client .track .assert_has_calls (calls , any_order = False ) # type: ignore
235
+
236
+ assert tracker .get_summary ().usage is None
237
+
238
+
142
239
@pytest .mark .parametrize (
143
240
"kind,label" ,
144
241
[
@@ -166,11 +263,44 @@ def test_tracks_success(client: LDClient):
166
263
tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
167
264
tracker .track_success ()
168
265
169
- client . track . assert_called_with ( # type: ignore
170
- '$ld:ai:generation' ,
171
- context ,
172
- { 'variationKey' : 'variation-key' , 'configKey' : 'config-key' },
173
- 1
174
- )
266
+ calls = [
267
+ call ( '$ld:ai:generation' , context , { 'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ) ,
268
+ call ( '$ld:ai:generation:success' , context , { 'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ) ,
269
+ ]
270
+
271
+ client . track . assert_has_calls ( calls ) # type: ignore
175
272
176
273
assert tracker .get_summary ().success is True
274
+
275
+
276
+ def test_tracks_error (client : LDClient ):
277
+ context = Context .create ('user-key' )
278
+ tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
279
+ tracker .track_error ()
280
+
281
+ calls = [
282
+ call ('$ld:ai:generation' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
283
+ call ('$ld:ai:generation:error' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
284
+ ]
285
+
286
+ client .track .assert_has_calls (calls ) # type: ignore
287
+
288
+ assert tracker .get_summary ().success is False
289
+
290
+
291
+ def test_error_overwrites_success (client : LDClient ):
292
+ context = Context .create ('user-key' )
293
+ tracker = LDAIConfigTracker (client , "variation-key" , "config-key" , context )
294
+ tracker .track_success ()
295
+ tracker .track_error ()
296
+
297
+ calls = [
298
+ call ('$ld:ai:generation' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
299
+ call ('$ld:ai:generation:success' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
300
+ call ('$ld:ai:generation' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
301
+ call ('$ld:ai:generation:error' , context , {'variationKey' : 'variation-key' , 'configKey' : 'config-key' }, 1 ),
302
+ ]
303
+
304
+ client .track .assert_has_calls (calls ) # type: ignore
305
+
306
+ assert tracker .get_summary ().success is False
0 commit comments