@@ -1248,7 +1248,41 @@ async def test_mutate_row_failure_grpc(
12481248
12491249 No headers expected
12501250 """
1251- pass
1251+ from google .cloud .bigtable .data .mutations import SetCell
1252+
1253+ row_key = b"row_key_1"
1254+ mutation = SetCell (TEST_FAMILY , b"q" , b"v" )
1255+
1256+ exc = Aborted ("injected" )
1257+ num_retryable = 2
1258+ for i in range (num_retryable ):
1259+ error_injector .push (exc )
1260+ error_injector .push (PermissionDenied ("terminal" ))
1261+ with pytest .raises (PermissionDenied ):
1262+ await table .mutate_row (row_key , [mutation ], retryable_errors = [Aborted ])
1263+ # validate counts
1264+ assert len (handler .completed_operations ) == 1
1265+ assert len (handler .completed_attempts ) == num_retryable + 1
1266+ assert len (handler .cancelled_operations ) == 0
1267+ # validate operation
1268+ operation = handler .completed_operations [0 ]
1269+ assert isinstance (operation , CompletedOperationMetric )
1270+ assert operation .final_status .name == "PERMISSION_DENIED"
1271+ assert operation .op_type .value == "MutateRow"
1272+ assert operation .is_streaming is False
1273+ assert len (operation .completed_attempts ) == num_retryable + 1
1274+ assert operation .cluster_id == "unspecified"
1275+ assert operation .zone == "global"
1276+ # validate attempts
1277+ for i in range (num_retryable ):
1278+ attempt = handler .completed_attempts [i ]
1279+ assert isinstance (attempt , CompletedAttemptMetric )
1280+ assert attempt .end_status .name == "ABORTED"
1281+ assert attempt .gfe_latency_ns is None
1282+ final_attempt = handler .completed_attempts [num_retryable ]
1283+ assert isinstance (final_attempt , CompletedAttemptMetric )
1284+ assert final_attempt .end_status .name == "PERMISSION_DENIED"
1285+ assert final_attempt .gfe_latency_ns is None
12521286
12531287
12541288 @CrossSync .pytest
@@ -1260,7 +1294,31 @@ async def test_mutate_row_failure_timeout(
12601294
12611295 No grpc headers expected
12621296 """
1263- pass
1297+ from google .cloud .bigtable .data .mutations import SetCell
1298+
1299+ row_key = b"row_key_1"
1300+ mutation = SetCell (TEST_FAMILY , b"q" , b"v" )
1301+
1302+ with pytest .raises (GoogleAPICallError ):
1303+ await table .mutate_row (row_key , [mutation ], operation_timeout = 0.001 )
1304+ # validate counts
1305+ assert len (handler .completed_operations ) == 1
1306+ assert len (handler .completed_attempts ) == 1
1307+ assert len (handler .cancelled_operations ) == 0
1308+ # validate operation
1309+ operation = handler .completed_operations [0 ]
1310+ assert isinstance (operation , CompletedOperationMetric )
1311+ assert operation .final_status .name == "DEADLINE_EXCEEDED"
1312+ assert operation .op_type .value == "MutateRow"
1313+ assert operation .is_streaming is False
1314+ assert len (operation .completed_attempts ) == 1
1315+ assert operation .cluster_id == "unspecified"
1316+ assert operation .zone == "global"
1317+ # validate attempt
1318+ attempt = handler .completed_attempts [0 ]
1319+ assert isinstance (attempt , CompletedAttemptMetric )
1320+ assert attempt .end_status .name == "DEADLINE_EXCEEDED"
1321+ assert attempt .gfe_latency_ns is None
12641322
12651323 @CrossSync .pytest
12661324 async def test_mutate_row_failure_unauthorized (
@@ -1269,7 +1327,32 @@ async def test_mutate_row_failure_unauthorized(
12691327 """
12701328 Test failure in backend by accessing an unauthorized family
12711329 """
1272- pass
1330+ from google .cloud .bigtable .data .mutations import SetCell
1331+
1332+ row_key = b"row_key_1"
1333+ mutation = SetCell ("unauthorized" , b"q" , b"v" )
1334+
1335+ with pytest .raises (GoogleAPICallError ) as e :
1336+ await authorized_view .mutate_row (row_key , [mutation ])
1337+ assert e .value .grpc_status_code .name == "PERMISSION_DENIED"
1338+ # validate counts
1339+ assert len (handler .completed_operations ) == 1
1340+ assert len (handler .completed_attempts ) == 1
1341+ assert len (handler .cancelled_operations ) == 0
1342+ # validate operation
1343+ operation = handler .completed_operations [0 ]
1344+ assert isinstance (operation , CompletedOperationMetric )
1345+ assert operation .final_status .name == "PERMISSION_DENIED"
1346+ assert operation .op_type .value == "MutateRow"
1347+ assert operation .is_streaming is False
1348+ assert len (operation .completed_attempts ) == 1
1349+ assert operation .cluster_id == next (iter (cluster_config .keys ()))
1350+ assert operation .zone == cluster_config [operation .cluster_id ].location .split ("/" )[- 1 ]
1351+ # validate attempt
1352+ attempt = handler .completed_attempts [0 ]
1353+ assert isinstance (attempt , CompletedAttemptMetric )
1354+ assert attempt .end_status .name == "PERMISSION_DENIED"
1355+ assert attempt .gfe_latency_ns >= 0 and attempt .gfe_latency_ns < operation .duration_ns
12731356
12741357 @CrossSync .pytest
12751358 async def test_sample_row_keys (self , table , temp_rows , handler , cluster_config ):
0 commit comments