blob: 42057efd3d66e5f15b3c44ad0cbb3d7d0b8dc837 [file] [log] [blame]
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: MPL-2.0
package transport
import (
"strconv"
"testing"
"google.golang.org/api/googleapi"
"google.golang.org/genproto/googleapis/rpc/errdetails"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
"google.golang.org/protobuf/types/known/durationpb"
)
func TestIsAppEngineRetryableError_operationInProgress(t *testing.T) {
err := googleapi.Error{
Code: 409,
Body: "Operation is already in progress",
}
isRetryable, _ := IsAppEngineRetryableError(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
func TestIsAppEngineRetryableError_p4saPropagation(t *testing.T) {
err := googleapi.Error{
Code: 404,
Body: "Unable to retrieve P4SA: [service-111111111111@gcp-gae-service.iam.gserviceaccount.com] from GAIA. Could be GAIA propagation delay or request from deleted apps.",
}
isRetryable, _ := IsAppEngineRetryableError(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
func TestIsAppEngineRetryableError_missingPage(t *testing.T) {
err := googleapi.Error{
Code: 404,
Body: "Missing page",
}
isRetryable, _ := IsAppEngineRetryableError(&err)
if isRetryable {
t.Errorf("Error incorrectly detected as retryable")
}
}
func TestIsAppEngineRetryableError_serverError(t *testing.T) {
err := googleapi.Error{
Code: 500,
Body: "Unable to retrieve P4SA because of a bad thing happening",
}
isRetryable, _ := IsAppEngineRetryableError(&err)
if isRetryable {
t.Errorf("Error incorrectly detected as retryable")
}
}
func TestIsCommonRetryableErrorCode_retryableErrorCode(t *testing.T) {
codes := []int{429, 500, 502, 503}
for _, code := range codes {
code := code
t.Run(strconv.Itoa(code), func(t *testing.T) {
err := googleapi.Error{
Code: code,
Body: "some text describing error",
}
isRetryable, _ := isCommonRetryableErrorCode(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
})
}
}
func TestIsCommonRetryableErrorCode_otherError(t *testing.T) {
err := googleapi.Error{
Code: 404,
Body: "Some unretryable issue",
}
isRetryable, _ := isCommonRetryableErrorCode(&err)
if isRetryable {
t.Errorf("Error incorrectly detected as retryable")
}
}
func TestIsOperationReadQuotaError_quotaExceeded(t *testing.T) {
err := googleapi.Error{
Code: 403,
Body: "Quota exceeded for quota metric 'OperationReadGroup' and limit 'Operation read requests per minute' of service 'compute.googleapis.com' for consumer 'project_number:11111111'.",
}
isRetryable, _ := is403QuotaExceededPerMinuteError(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
func TestIs403QuotaExceededPerMinuteError_perMinuteQuotaExceeded(t *testing.T) {
err := googleapi.Error{
Code: 403,
Body: "Quota exceeded for quota metric 'Queries' and limit 'Queries per minute' of service 'compute.googleapis.com' for consumer 'project_number:11111111'.",
}
isRetryable, _ := is403QuotaExceededPerMinuteError(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
func TestIs403QuotaExceededPerMinuteError_perDayQuotaExceededNotRetryable(t *testing.T) {
err := googleapi.Error{
Code: 403,
Body: "Quota exceeded for quota metric 'Queries' and limit 'Queries per day' of service 'compute.googleapis.com' for consumer 'project_number:11111111'.",
}
isRetryable, _ := is403QuotaExceededPerMinuteError(&err)
if isRetryable {
t.Errorf("Error incorrectly detected as retryable")
}
}
// An error with retry info is retryable.
func TestBigtableError_retryable(t *testing.T) {
retryInfo := &errdetails.RetryInfo{
RetryDelay: &durationpb.Duration{Seconds: 10, Nanos: 10},
}
status, _ := status.New(codes.FailedPrecondition, "is retryable").WithDetails(retryInfo)
isRetryable, _ := IsBigTableRetryableError(status.Err())
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
// An error without retry info is not retryable.
func TestBigtableError_withoutRetryInfoNotRetryable(t *testing.T) {
status := status.New(codes.FailedPrecondition, "is not retryable")
isRetryable, _ := IsBigTableRetryableError(status.Err())
if isRetryable {
t.Errorf("Error incorrectly detected as retryable")
}
}
// An OK status with retry info is not retryable.
func TestBigtableError_okIsNotRetryable(t *testing.T) {
retryInfo := &errdetails.RetryInfo{
RetryDelay: &durationpb.Duration{Seconds: 10, Nanos: 10},
}
status, _ := status.New(codes.OK, "is not retryable").WithDetails(retryInfo)
isRetryable, _ := IsBigTableRetryableError(status.Err())
if isRetryable {
t.Errorf("Error incorrectly detected as retryable")
}
}
func TestIsSwgAutogenRouterRetryableError_otherError(t *testing.T) {
err := googleapi.Error{
Code: 400,
Body: "another error.",
}
isRetryable, _ := IsSwgAutogenRouterRetryable(&err)
if isRetryable {
t.Errorf("Error incorrectly detected as retryable")
}
}
func TestIsSwgAutogenRouterRetryableError_notReady(t *testing.T) {
err := googleapi.Error{
Code: 400,
Body: "The resource 'projects/project123/regions/us-central1/routers/swg-autogen-router-123456789' is not ready",
}
isRetryable, _ := IsSwgAutogenRouterRetryable(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
func TestFirestoreField409_retryUnderlyingDataChanged(t *testing.T) {
err := googleapi.Error{
Code: 409,
Body: "Please retry, underlying data changed",
}
isRetryable, _ := FirestoreField409RetryUnderlyingDataChanged(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
func TestFirestoreIndex409_crossTransactionContetion(t *testing.T) {
err := googleapi.Error{
Code: 409,
Body: "Aborted due to cross-transaction contention",
}
isRetryable, _ := FirestoreIndex409Retry(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
func TestFirestoreIndex409_retryUnderlyingDataChanged(t *testing.T) {
err := googleapi.Error{
Code: 409,
Body: "Please retry, underlying data changed",
}
isRetryable, _ := FirestoreIndex409Retry(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}
func TestExternalIpServiceNotActive(t *testing.T) {
err := googleapi.Error{
Code: 400,
Body: "External IP address network service is not active in the provided network policy",
}
isRetryable, _ := ExternalIpServiceNotActive(&err)
if !isRetryable {
t.Errorf("Error not detected as retryable")
}
}