Skip to content
This repository was archived by the owner on Apr 1, 2026. It is now read-only.

Commit fdc609c

Browse files
committed
improved gemini tests
1 parent 8ff32a5 commit fdc609c

1 file changed

Lines changed: 143 additions & 86 deletions

File tree

tests/unit/data/_metrics/test_opentelemetry_handler.py

Lines changed: 143 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -185,159 +185,216 @@ def test_generate_client_uid(self):
185185
)
186186
assert re.match(expected_pattern, uid)
187187

188-
@pytest.mark.parametrize(
189-
"op_type,is_streaming,first_response_latency_ns,attempts_count",
190-
[
191-
(OperationType.READ_ROWS, True, 12345, 0),
192-
(OperationType.READ_ROWS, True, None, 2),
193-
(OperationType.MUTATE_ROW, False, None, 3),
194-
(
195-
OperationType.SAMPLE_ROW_KEYS,
196-
False,
197-
12345,
198-
1,
199-
), # first_response_latency should be ignored
200-
],
201-
)
202-
def test_on_operation_complete(
203-
self, op_type, is_streaming, first_response_latency_ns, attempts_count
204-
):
205-
mock_instruments = mock.Mock(
206-
operation_latencies=mock.Mock(),
207-
first_response_latencies=mock.Mock(),
208-
retry_count=mock.Mock(),
209-
)
188+
def test_on_operation_complete_operation_latencies(self):
189+
mock_instruments = mock.Mock(operation_latencies=mock.Mock())
210190
handler = self._make_one(
211191
instance_id="inst", table_id="table", instruments=mock_instruments
212192
)
213-
attempts = [mock.Mock() for _ in range(attempts_count)]
214193
op = CompletedOperationMetric(
215-
op_type=op_type,
194+
op_type=OperationType.READ_ROWS,
216195
uuid="test-uuid",
217196
duration_ns=1234567,
218-
completed_attempts=attempts,
197+
completed_attempts=[],
219198
final_status=StatusCode.OK,
220199
cluster_id="cluster",
221200
zone="zone",
222-
is_streaming=is_streaming,
223-
first_response_latency_ns=first_response_latency_ns,
201+
is_streaming=True,
224202
)
225-
226203
handler.on_operation_complete(op)
227-
228204
expected_labels = {
229205
"method": op.op_type.value,
230206
"status": op.final_status.name,
231207
"resource_zone": op.zone,
232208
"resource_cluster": op.cluster_id,
233209
**handler.shared_labels,
234210
}
235-
236-
# check operation_latencies
237211
mock_instruments.operation_latencies.record.assert_called_once_with(
238212
op.duration_ns / 1e6,
239-
{"streaming": str(is_streaming), **expected_labels},
213+
{"streaming": str(op.is_streaming), **expected_labels},
240214
)
241215

242-
# check first_response_latencies
243-
if (
244-
op_type == OperationType.READ_ROWS
245-
and first_response_latency_ns is not None
246-
):
216+
@pytest.mark.parametrize(
217+
"op_type,first_response_latency_ns,should_record",
218+
[
219+
(OperationType.READ_ROWS, 12345, True),
220+
(OperationType.READ_ROWS, None, False),
221+
(OperationType.MUTATE_ROW, 12345, False),
222+
],
223+
)
224+
def test_on_operation_complete_first_response_latencies(
225+
self, op_type, first_response_latency_ns, should_record
226+
):
227+
mock_instruments = mock.Mock(first_response_latencies=mock.Mock())
228+
handler = self._make_one(
229+
instance_id="inst", table_id="table", instruments=mock_instruments
230+
)
231+
op = CompletedOperationMetric(
232+
op_type=op_type,
233+
uuid="test-uuid",
234+
duration_ns=1234567,
235+
completed_attempts=[],
236+
final_status=StatusCode.OK,
237+
cluster_id="cluster",
238+
zone="zone",
239+
is_streaming=True,
240+
first_response_latency_ns=first_response_latency_ns,
241+
)
242+
handler.on_operation_complete(op)
243+
if should_record:
244+
expected_labels = {
245+
"method": op.op_type.value,
246+
"status": op.final_status.name,
247+
"resource_zone": op.zone,
248+
"resource_cluster": op.cluster_id,
249+
**handler.shared_labels,
250+
}
247251
mock_instruments.first_response_latencies.record.assert_called_once_with(
248252
first_response_latency_ns / 1e6, expected_labels
249253
)
250254
else:
251255
mock_instruments.first_response_latencies.record.assert_not_called()
252256

253-
# check retry_count
257+
@pytest.mark.parametrize("attempts_count", [0, 1, 5])
258+
def test_on_operation_complete_retry_count(self, attempts_count):
259+
mock_instruments = mock.Mock(retry_count=mock.Mock())
260+
handler = self._make_one(
261+
instance_id="inst", table_id="table", instruments=mock_instruments
262+
)
263+
attempts = [mock.Mock()] * attempts_count
264+
op = CompletedOperationMetric(
265+
op_type=OperationType.READ_ROWS,
266+
uuid="test-uuid",
267+
duration_ns=1234567,
268+
completed_attempts=attempts,
269+
final_status=StatusCode.OK,
270+
cluster_id="cluster",
271+
zone="zone",
272+
is_streaming=True,
273+
)
274+
handler.on_operation_complete(op)
254275
if attempts:
276+
expected_labels = {
277+
"method": op.op_type.value,
278+
"status": op.final_status.name,
279+
"resource_zone": op.zone,
280+
"resource_cluster": op.cluster_id,
281+
**handler.shared_labels,
282+
}
255283
mock_instruments.retry_count.add.assert_called_once_with(
256284
len(attempts) - 1, expected_labels
257285
)
258286
else:
259287
mock_instruments.retry_count.add.assert_not_called()
260288

289+
def test_on_attempt_complete_attempt_latencies(self):
290+
mock_instruments = mock.Mock(attempt_latencies=mock.Mock())
291+
handler = self._make_one(
292+
instance_id="inst", table_id="table", instruments=mock_instruments
293+
)
294+
attempt = CompletedAttemptMetric(duration_ns=1234567, end_status=StatusCode.OK)
295+
op = ActiveOperationMetric(
296+
op_type=OperationType.READ_ROWS,
297+
zone="zone",
298+
cluster_id="cluster",
299+
is_streaming=True,
300+
)
301+
handler.on_attempt_complete(attempt, op)
302+
expected_labels = {
303+
"method": op.op_type.value,
304+
"resource_zone": op.zone,
305+
"resource_cluster": op.cluster_id,
306+
**handler.shared_labels,
307+
}
308+
mock_instruments.attempt_latencies.record.assert_called_once_with(
309+
attempt.duration_ns / 1e6,
310+
{
311+
"streaming": str(op.is_streaming),
312+
"status": attempt.end_status.name,
313+
**expected_labels,
314+
},
315+
)
316+
261317
@pytest.mark.parametrize(
262-
"zone,cluster,gfe_latency_ns,is_first_attempt,flow_throttling_ns",
263-
[
264-
("zone", "cluster", 12345, True, 54321),
265-
(None, None, None, False, 0),
266-
("zone", "cluster", 0, True, 0), # gfe_latency_ns is 0
267-
],
318+
"is_first_attempt,flow_throttling_ns",
319+
[(True, 54321), (False, 0), (True, 0)],
268320
)
269-
def test_on_attempt_complete(
270-
self, zone, cluster, gfe_latency_ns, is_first_attempt, flow_throttling_ns
321+
def test_on_attempt_complete_throttling_latencies(
322+
self, is_first_attempt, flow_throttling_ns
271323
):
272-
mock_instruments = mock.Mock(
273-
attempt_latencies=mock.Mock(),
274-
throttling_latencies=mock.Mock(),
275-
application_latencies=mock.Mock(),
276-
server_latencies=mock.Mock(),
277-
connectivity_error_count=mock.Mock(),
278-
)
324+
mock_instruments = mock.Mock(throttling_latencies=mock.Mock())
279325
handler = self._make_one(
280326
instance_id="inst", table_id="table", instruments=mock_instruments
281327
)
282328
attempt = CompletedAttemptMetric(
283329
duration_ns=1234567,
284330
end_status=StatusCode.OK,
285-
gfe_latency_ns=gfe_latency_ns,
286-
application_blocking_time_ns=234567,
287-
backoff_before_attempt_ns=345678,
288331
grpc_throttling_time_ns=456789,
289332
)
290333
op = ActiveOperationMetric(
291334
op_type=OperationType.READ_ROWS,
292-
zone=zone,
293-
cluster_id=cluster,
294-
is_streaming=True,
295335
flow_throttling_time_ns=flow_throttling_ns,
296336
)
297337
if not is_first_attempt:
298338
op.completed_attempts.append(mock.Mock())
299-
300339
handler.on_attempt_complete(attempt, op)
301-
302-
expected_labels = {
303-
"method": op.op_type.value,
304-
"resource_zone": zone or DEFAULT_ZONE,
305-
"resource_cluster": cluster or DEFAULT_CLUSTER_ID,
306-
**handler.shared_labels,
307-
}
308-
status = attempt.end_status.name
309-
is_streaming = str(op.is_streaming)
310-
311-
# check attempt_latencies
312-
mock_instruments.attempt_latencies.record.assert_called_once_with(
313-
attempt.duration_ns / 1e6,
314-
{"streaming": is_streaming, "status": status, **expected_labels},
315-
)
316-
317-
# check throttling_latencies
318340
expected_throttling = attempt.grpc_throttling_time_ns / 1e6
319341
if is_first_attempt:
320342
expected_throttling += flow_throttling_ns / 1e6
321343
mock_instruments.throttling_latencies.record.assert_called_once_with(
322-
pytest.approx(expected_throttling), expected_labels
344+
pytest.approx(expected_throttling), mock.ANY
323345
)
324346

325-
# check application_latencies
347+
def test_on_attempt_complete_application_latencies(self):
348+
mock_instruments = mock.Mock(application_latencies=mock.Mock())
349+
handler = self._make_one(
350+
instance_id="inst", table_id="table", instruments=mock_instruments
351+
)
352+
attempt = CompletedAttemptMetric(
353+
duration_ns=1234567,
354+
end_status=StatusCode.OK,
355+
application_blocking_time_ns=234567,
356+
backoff_before_attempt_ns=345678,
357+
)
358+
op = ActiveOperationMetric(op_type=OperationType.READ_ROWS)
359+
handler.on_attempt_complete(attempt, op)
326360
mock_instruments.application_latencies.record.assert_called_once_with(
327361
(attempt.application_blocking_time_ns + attempt.backoff_before_attempt_ns)
328362
/ 1e6,
329-
expected_labels,
363+
mock.ANY,
330364
)
331365

332-
# check server_latencies or connectivity_error_count
333-
if gfe_latency_ns is not None:
366+
@pytest.mark.parametrize(
367+
"gfe_latency_ns,should_record_server_latency",
368+
[(12345, True), (None, False), (0, True)],
369+
)
370+
def test_on_attempt_complete_server_latencies_and_connectivity_error(
371+
self, gfe_latency_ns, should_record_server_latency
372+
):
373+
mock_instruments = mock.Mock(
374+
server_latencies=mock.Mock(), connectivity_error_count=mock.Mock()
375+
)
376+
handler = self._make_one(
377+
instance_id="inst", table_id="table", instruments=mock_instruments
378+
)
379+
attempt = CompletedAttemptMetric(
380+
duration_ns=1234567,
381+
end_status=StatusCode.OK,
382+
gfe_latency_ns=gfe_latency_ns,
383+
)
384+
op = ActiveOperationMetric(
385+
op_type=OperationType.READ_ROWS,
386+
zone="zone",
387+
cluster_id="cluster",
388+
is_streaming=True,
389+
)
390+
handler.on_attempt_complete(attempt, op)
391+
if should_record_server_latency:
334392
mock_instruments.server_latencies.record.assert_called_once_with(
335-
gfe_latency_ns / 1e6,
336-
{"streaming": is_streaming, "status": status, **expected_labels},
393+
gfe_latency_ns / 1e6, mock.ANY
337394
)
338395
mock_instruments.connectivity_error_count.add.assert_not_called()
339396
else:
340397
mock_instruments.server_latencies.record.assert_not_called()
341398
mock_instruments.connectivity_error_count.add.assert_called_once_with(
342-
1, {"status": status, **expected_labels}
343-
)
399+
1, mock.ANY
400+
)

0 commit comments

Comments
 (0)