| // Copyright 2020 The Go Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style |
| // license that can be found in the LICENSE file. |
| |
| package secret |
| |
| import ( |
| "context" |
| "fmt" |
| "testing" |
| |
| gax "github.com/googleapis/gax-go/v2" |
| secretmanagerpb "google.golang.org/genproto/googleapis/cloud/secretmanager/v1" |
| "google.golang.org/grpc/codes" |
| "google.golang.org/grpc/status" |
| ) |
| |
| type fakeSecretClient struct { |
| accessReturnError error |
| accessSecretMap map[string]string // map[path] = secret |
| |
| closeReturnError error |
| } |
| |
| func (fsc *fakeSecretClient) AccessSecretVersion(ctx context.Context, req *secretmanagerpb.AccessSecretVersionRequest, opts ...gax.CallOption) (*secretmanagerpb.AccessSecretVersionResponse, error) { |
| if ctx == nil || req == nil { |
| return nil, status.Error(codes.InvalidArgument, "ctx or req are nil") |
| } |
| if secret, ok := fsc.accessSecretMap[req.GetName()]; ok { |
| return &secretmanagerpb.AccessSecretVersionResponse{ |
| Payload: &secretmanagerpb.SecretPayload{ |
| Data: []byte(secret), |
| }, |
| }, nil |
| } |
| return nil, status.Error(codes.NotFound, "secret not found") |
| } |
| |
| func (fsc *fakeSecretClient) Close() error { |
| return fsc.closeReturnError |
| } |
| |
| func TestRetrieve(t *testing.T) { |
| testCases := []struct { |
| desc string |
| fakeClient secretClient |
| ctx context.Context |
| name string |
| projectID string |
| wantSecret string |
| wantErrorCode codes.Code |
| }{ |
| { |
| desc: "nil-params", |
| fakeClient: &fakeSecretClient{}, |
| ctx: nil, |
| name: "x", |
| projectID: "y", |
| wantSecret: "", |
| wantErrorCode: codes.InvalidArgument, |
| }, |
| { |
| desc: "secret-not-found", |
| fakeClient: &fakeSecretClient{}, |
| ctx: context.Background(), |
| name: "x", |
| projectID: "y", |
| wantSecret: "", |
| wantErrorCode: codes.NotFound, |
| }, |
| { |
| desc: "secret-found", |
| fakeClient: &fakeSecretClient{ |
| accessReturnError: nil, |
| accessSecretMap: map[string]string{ |
| buildNamePath("projecto", "nombre", "latest"): "secreto", |
| }, |
| }, |
| ctx: context.Background(), |
| name: "nombre", |
| projectID: "projecto", |
| wantSecret: "secreto", |
| wantErrorCode: codes.OK, |
| }, |
| } |
| for _, tc := range testCases { |
| t.Run(tc.desc, func(t *testing.T) { |
| c := &Client{ |
| client: tc.fakeClient, |
| projectID: tc.projectID, |
| } |
| gotSecret, gotErr := c.Retrieve(tc.ctx, tc.name) |
| gotErrStatus, _ := status.FromError(gotErr) |
| if gotErrStatus.Code() != tc.wantErrorCode || gotSecret != tc.wantSecret { |
| t.Errorf("Retrieve(%v, %q) = %q, %v, wanted %q, %v", tc.ctx, tc.name, gotSecret, gotErr, tc.wantSecret, tc.wantErrorCode) |
| } |
| }) |
| } |
| } |
| |
| func TestClose(t *testing.T) { |
| randomErr := fmt.Errorf("close error") |
| |
| testCases := []struct { |
| desc string |
| fakeClient secretClient |
| wantError error |
| }{ |
| { |
| desc: "no-error", |
| fakeClient: &fakeSecretClient{}, |
| wantError: nil, |
| }, |
| { |
| desc: "error", |
| fakeClient: &fakeSecretClient{ |
| closeReturnError: randomErr, |
| }, |
| wantError: randomErr, |
| }, |
| } |
| for _, tc := range testCases { |
| t.Run(tc.desc, func(t *testing.T) { |
| c := &Client{ |
| client: tc.fakeClient, |
| } |
| if gotErr := c.Close(); gotErr != tc.wantError { |
| t.Errorf("Close() = %v, wanted %v", gotErr, tc.wantError) |
| } |
| }) |
| } |
| } |
| |
| func TestBuildNamePath(t *testing.T) { |
| want := "projects/x/secrets/y/versions/z" |
| got := buildNamePath("x", "y", "z") |
| if got != want { |
| t.Errorf("BuildVersionNumber(%s, %s, %s) = %q; want=%q", "x", "y", "z", got, want) |
| } |
| } |