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

Commit c96b534

Browse files
committed
improved tests
1 parent 7a95c4a commit c96b534

1 file changed

Lines changed: 37 additions & 26 deletions

File tree

tests/system/data/test_metrics.py

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -203,14 +203,10 @@ async def test_resource(get_all_metrics, instance_id, table_id, project_id):
203203
assert resource.labels["instance"] == instance_id
204204
assert resource.labels["table"] == table_id
205205
assert resource.labels["project_id"] == project_id
206-
if 'success' in m.metric.labels["app_profile"]:
207-
# for attempts that succeeded, zone and cluster should be populated
208-
assert resource.labels["zone"] == TEST_ZONE
209-
assert resource.labels["cluster"] == TEST_CLUSTER
210-
else:
211-
# others should fall back to defaults
212-
assert resource.labels["zone"] == "global"
213-
assert resource.labels["cluster"] == "unspecified"
206+
# zone and cluster should use default values for failed attempts
207+
assert resource.labels["zone"] in [TEST_ZONE, 'global']
208+
assert resource.labels["cluster"] in [TEST_CLUSTER, 'unspecified']
209+
214210

215211
@pytest.mark.asyncio
216212
async def test_client_name(get_all_metrics):
@@ -378,7 +374,7 @@ async def test_status_exception(get_all_metrics):
378374
"""
379375
check the subset of rpcs with a single terminal exception
380376
381-
They should have no retries, 1 connectivity errors, a status of NOT_FOUND
377+
They should have no retries, 1+ connectivity errors, a status of NOT_FOUND
382378
Should have default values for cluster and zone
383379
"""
384380
fail_metrics = [m for m in get_all_metrics if m.metric.labels["app_profile"] == "terminal_exception"]
@@ -399,12 +395,16 @@ async def test_status_exception(get_all_metrics):
399395
# check for cluster and zone
400396
assert m.resource.labels["zone"] == 'global'
401397
assert m.resource.labels["cluster"] == 'unspecified'
402-
# ensure connectivity error count is 1
398+
# each rpc should have at least one connectivity error
399+
# ReadRows will have more, since we test point reads and streams
403400
connectivity_error_counts = [m for m in fail_metrics if "connectivity_error_count" in m.metric.type]
404-
assert len(connectivity_error_counts) > 0
405-
for m in connectivity_error_counts:
406-
for pt in m.points:
407-
assert pt.value.int64_value == 1
401+
for error_metric in connectivity_error_counts:
402+
total_points = sum([int(pt.value.int64_value) for pt in error_metric.points])
403+
assert total_points >= 1
404+
# ensure each rpc reported connectivity errors
405+
for prc in OperationType:
406+
assert any(m.metric.labels["method"] == prc.value for m in connectivity_error_counts)
407+
408408

409409
@pytest.mark.asyncio
410410
@pytest.mark.parametrize("app_profile,final_status", [
@@ -435,22 +435,33 @@ async def test_status_retry(get_all_metrics, app_profile, final_status):
435435
server_latencies = [m for m in retry_metrics if "server_latencies" in m.metric.type] # may not be present. only if reached server
436436
first_response_latencies = [m for m in retry_metrics if "first_response_latencies" in m.metric.type] # may not be present
437437

438-
# each retry_count and connectivity_error_count should be 2
439-
for m in retry_counts + connectivity_error_counts:
440-
for pt in m.points:
441-
assert pt.value.int64_value == 2
438+
# should have at least 2 retry attempts
439+
# ReadRows will have more, because it is called multiple times in the test data
440+
for m in retry_counts:
441+
total_errors = sum([int(pt.value.int64_value) for pt in m.points])
442+
assert total_errors >= 2, f"{m} has {total_errors} errors"
443+
# each rpc should have at least one connectivity error
444+
# most will have 2, but will have 1 if status == NOT_FOUND
445+
for m in connectivity_error_counts:
446+
total_errors = sum([int(pt.value.int64_value) for pt in m.points])
447+
assert total_errors >= 1, f"{m} has {total_errors} errors"
442448

443449
# all operation-level status should be final_status
444450
for m in operation_latencies + retry_counts:
445451
assert m.metric.labels["status"] == final_status
446-
# all attempt-level status should have a 2:1 mix of final_status and UNAVAILABLE
447-
status_map = {}
448-
for m in attempt_latencies + server_latencies + first_response_latencies + connectivity_error_counts:
449-
status_map[m.metric.labels["status"]] = status_map.get(m.metric.labels["status"], 0) + 1
450-
assert len(status_map) == 2
451-
assert final_status in status_map
452-
assert "UNAVAILABLE" in status_map
453-
assert len(status_map[final_status]) * 2 == len(status_map["UNAVAILABLE"])
452+
453+
# check attempt statuses
454+
attempt_statuses = set([m.metric.labels["status"] for m in attempt_latencies + server_latencies + first_response_latencies + connectivity_error_counts])
455+
if final_status == "DEADLINE_EXCEEDED":
456+
# operation DEADLINE_EXCEEDED never shows up in attempts
457+
assert len(attempt_statuses) == 1
458+
assert "UNAVAILABLE" in attempt_statuses
459+
else:
460+
# all other attempt-level status should have a mix of final_status and UNAVAILABLE
461+
assert len(attempt_statuses) == 2
462+
assert "UNAVAILABLE" in attempt_statuses
463+
assert final_status in attempt_statuses
464+
454465

455466
@pytest.mark.asyncio
456467
async def test_latency_metric_histogram_buckets(get_all_metrics):

0 commit comments

Comments
 (0)