72 lines
2.5 KiB
Go
72 lines
2.5 KiB
Go
package gcp
|
|
|
|
import (
|
|
"errors"
|
|
"fmt"
|
|
"testing"
|
|
|
|
"google.golang.org/api/googleapi"
|
|
|
|
"gitea.home.hrajfrisbee.cz/kacerr/egress-proxies-operator/internal/provider"
|
|
)
|
|
|
|
func gerr(code int, reasons ...string) error {
|
|
e := &googleapi.Error{Code: code, Message: "boom"}
|
|
for _, r := range reasons {
|
|
e.Errors = append(e.Errors, googleapi.ErrorItem{Reason: r})
|
|
}
|
|
return e
|
|
}
|
|
|
|
func TestClassify(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
err error
|
|
want error
|
|
}{
|
|
{name: "404 is NotFound", err: gerr(404), want: provider.ErrNotFound},
|
|
{name: "429 is Quota", err: gerr(429), want: provider.ErrQuotaExceeded},
|
|
{name: "403 quotaExceeded is Quota", err: gerr(403, "quotaExceeded"), want: provider.ErrQuotaExceeded},
|
|
{name: "403 rateLimitExceeded is Quota", err: gerr(403, "rateLimitExceeded"), want: provider.ErrQuotaExceeded},
|
|
{name: "403 plain is Permanent", err: gerr(403, "forbidden"), want: provider.ErrPermanent},
|
|
{name: "400 is Permanent", err: gerr(400), want: provider.ErrPermanent},
|
|
{name: "401 is Permanent", err: gerr(401), want: provider.ErrPermanent},
|
|
{name: "408 is Transient", err: gerr(408), want: provider.ErrTransient},
|
|
{name: "500 is Transient", err: gerr(500), want: provider.ErrTransient},
|
|
{name: "503 is Transient", err: gerr(503), want: provider.ErrTransient},
|
|
{name: "409 is Transient (alreadyExists is handled before classify)", err: gerr(409), want: provider.ErrTransient},
|
|
{name: "plain network error is Transient", err: errors.New("connection reset"), want: provider.ErrTransient},
|
|
{name: "wrapped googleapi error still classifies", err: fmt.Errorf("calling api: %w", gerr(404)), want: provider.ErrNotFound},
|
|
}
|
|
|
|
for _, tc := range tests {
|
|
t.Run(tc.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
if got := classify(tc.err); got != tc.want {
|
|
t.Errorf("classify() = %v, want %v", got, tc.want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
// The wrapped error must satisfy both halves of the taxonomy contract:
|
|
// errors.Is against the sentinel AND errors.As back to the SDK error.
|
|
func TestWrapErr_isAndAsBothWork(t *testing.T) {
|
|
t.Parallel()
|
|
p := &Provider{name: "gcp-eu"}
|
|
wrapped := p.wrapErr("get", "zones/z/instances/i", gerr(404))
|
|
|
|
if !errors.Is(wrapped, provider.ErrNotFound) {
|
|
t.Error("errors.Is(wrapped, ErrNotFound) = false")
|
|
}
|
|
var ge *googleapi.Error
|
|
if !errors.As(wrapped, &ge) || ge.Code != 404 {
|
|
t.Error("errors.As back to *googleapi.Error failed")
|
|
}
|
|
if provider.Class(wrapped) != provider.ErrNotFound {
|
|
t.Errorf("Class() = %v, want ErrNotFound", provider.Class(wrapped))
|
|
}
|
|
}
|