@@ -899,36 +899,123 @@ async def test_read_modify_write(self, table, temp_rows, handler, cluster_config
899899 assert attempt .grpc_throttling_time_ns == 0 # TODO: confirm
900900
901901 @CrossSync .pytest
902- async def test_read_modify_write_row_failure_grpc (
902+ async def test_read_modify_write_failure_grpc (
903903 self , table , temp_rows , handler , error_injector
904904 ):
905905 """
906906 Test failure in grpc layer by injecting an error into an interceptor
907907
908908 No headers expected
909909 """
910- pass
910+ from google .cloud .bigtable .data .read_modify_write_rules import IncrementRule
911+
912+ row_key = b"test-row-key"
913+ family = TEST_FAMILY
914+ qualifier = b"test-qualifier"
915+ await temp_rows .add_row (
916+ row_key , value = 0 , family = family , qualifier = qualifier
917+ )
918+ rule = IncrementRule (family , qualifier , 1 )
919+
920+ # trigger an exception
921+ exc = RuntimeError ("injected" )
922+ error_injector .push (exc )
923+ with pytest .raises (RuntimeError ):
924+ await table .read_modify_write_row (row_key , rule )
925+
926+ # validate counts
927+ assert len (handler .completed_operations ) == 1
928+ assert len (handler .completed_attempts ) == 1
929+ assert len (handler .cancelled_operations ) == 0
930+ # validate operation
931+ operation = handler .completed_operations [0 ]
932+ assert isinstance (operation , CompletedOperationMetric )
933+ assert operation .final_status .name == "UNKNOWN"
934+ assert operation .is_streaming is False
935+ assert operation .op_type .value == "ReadModifyWriteRow"
936+ assert len (operation .completed_attempts ) == len (handler .completed_attempts )
937+ assert operation .completed_attempts == handler .completed_attempts
938+ assert operation .cluster_id == "unspecified"
939+ assert operation .zone == "global"
940+ assert operation .duration_ns > 0 and operation .duration_ns < 1e9
941+ assert (
942+ operation .first_response_latency_ns is None
943+ ) # populated for read_rows only
944+ assert operation .flow_throttling_time_ns == 0
945+ # validate attempt
946+ attempt = handler .completed_attempts [0 ]
947+ assert isinstance (attempt , CompletedAttemptMetric )
948+ assert attempt .duration_ns > 0
949+ assert attempt .end_status .name == "UNKNOWN"
950+ assert attempt .backoff_before_attempt_ns == 0
951+ assert attempt .gfe_latency_ns is None
952+ assert attempt .application_blocking_time_ns == 0
953+ assert attempt .grpc_throttling_time_ns == 0 # TODO: confirm
911954
912955
913956 @CrossSync .pytest
914- async def test_read_modify_write_row_failure_timeout (
957+ async def test_read_modify_write_failure_timeout (
915958 self , table , temp_rows , handler
916959 ):
917960 """
918961 Test failure in gapic layer by passing very low timeout
919962
920963 No grpc headers expected
921964 """
922- pass
965+ from google .cloud .bigtable .data .read_modify_write_rules import IncrementRule
966+
967+ row_key = b"test-row-key"
968+ family = TEST_FAMILY
969+ qualifier = b"test-qualifier"
970+ await temp_rows .add_row (
971+ row_key , value = 0 , family = family , qualifier = qualifier
972+ )
973+ rule = IncrementRule (family , qualifier , 1 )
974+ with pytest .raises (GoogleAPICallError ):
975+ await table .read_modify_write_row (row_key , rule , operation_timeout = 0.001 )
976+ # validate counts
977+ assert len (handler .completed_operations ) == 1
978+ assert len (handler .completed_attempts ) == 1
979+ assert len (handler .cancelled_operations ) == 0
980+ # validate operation
981+ operation = handler .completed_operations [0 ]
982+ assert isinstance (operation , CompletedOperationMetric )
983+ assert operation .final_status .name == "DEADLINE_EXCEEDED"
984+ assert operation .op_type .value == "ReadModifyWriteRow"
985+ assert operation .cluster_id == "unspecified"
986+ assert operation .zone == "global"
987+ # validate attempt
988+ attempt = handler .completed_attempts [0 ]
989+ assert attempt .gfe_latency_ns is None
923990
924991 @CrossSync .pytest
925- async def test_read_modify_write_row_failure_unauthorized (
992+ async def test_read_modify_write_failure_unauthorized (
926993 self , handler , authorized_view , cluster_config
927994 ):
928995 """
929996 Test failure in backend by accessing an unauthorized family
930997 """
931- pass
998+ from google .cloud .bigtable .data .read_modify_write_rules import IncrementRule
999+
1000+ row_key = b"test-row-key"
1001+ qualifier = b"test-qualifier"
1002+ rule = IncrementRule ("unauthorized" , qualifier , 1 )
1003+ with pytest .raises (GoogleAPICallError ):
1004+ await authorized_view .read_modify_write_row (row_key , rule )
1005+ # validate counts
1006+ assert len (handler .completed_operations ) == 1
1007+ assert len (handler .completed_attempts ) == 1
1008+ assert len (handler .cancelled_operations ) == 0
1009+ # validate operation
1010+ operation = handler .completed_operations [0 ]
1011+ assert isinstance (operation , CompletedOperationMetric )
1012+ assert operation .final_status .name == "PERMISSION_DENIED"
1013+ assert operation .op_type .value == "ReadModifyWriteRow"
1014+ assert operation .cluster_id == next (iter (cluster_config .keys ()))
1015+ assert operation .zone == cluster_config [operation .cluster_id ].location .split ("/" )[- 1 ]
1016+ # validate attempt
1017+ attempt = handler .completed_attempts [0 ]
1018+ assert attempt .gfe_latency_ns >= 0 and attempt .gfe_latency_ns < operation .duration_ns
9321019
9331020
9341021 @CrossSync .pytest
0 commit comments