Files
shadowdaoandClaude Sonnet 5.5 9b74c3adbf Rename module and SDK import paths for Threshold
Fork of hashicorp/boundary-plugin-gcp (MPL-2.0). Module path and Boundary SDK
imports now point at repo.anhonesthost.net/CyberCoveLLC. Adds NOTICE and an
About this fork section to the README.

Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
2026-10-12 10:28:05 -07:00

133 lines
3.7 KiB
Go

// Copyright IBM Corp. 2024, 2026
// SPDX-License-Identifier: MPL-2.0
package host
import (
"context"
"errors"
"testing"
"time"
computepb "cloud.google.com/go/compute/apiv1/computepb"
"repo.anhonesthost.net/CyberCoveLLC/threshold-plugin-gcp/internal/credential"
"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"google.golang.org/api/option"
"google.golang.org/protobuf/types/known/structpb"
)
func TestWithCredentials(t *testing.T) {
cred := &credential.PersistedState{}
opt := withCredentials(cred)
state := &gcpCatalogPersistedState{}
err := opt(state)
require.NoError(t, err)
assert.Equal(t, cred, state.PersistedState)
// Test setting credentials again should return an error
err = opt(state)
assert.Error(t, err)
assert.Equal(t, "gcp credentials already set", err.Error())
}
func TestNewGCPCatalogPersistedState(t *testing.T) {
cred := &credential.PersistedState{}
opt := withCredentials(cred)
state, err := newGCPCatalogPersistedState(opt)
require.NoError(t, err)
assert.Equal(t, cred, state.PersistedState)
}
func TestToProto(t *testing.T) {
lastRotatedTime := time.Now()
state := &gcpCatalogPersistedState{PersistedState: &credential.PersistedState{
CredentialsConfig: &credential.Config{
PrivateKey: "test-private-key",
PrivateKeyId: "test-private-key-id",
ClientEmail: "test@test.com",
},
CredsLastRotatedTime: lastRotatedTime,
},
}
proto, err := state.toProto()
require.NoError(t, err)
expectedData, err := structpb.NewStruct(map[string]any{
"private_key": "test-private-key",
"private_key_id": "test-private-key-id",
"creds_last_rotated_time": lastRotatedTime.Format(time.RFC3339Nano),
})
require.NoError(t, err)
assert.Equal(t, expectedData, proto.Secrets)
}
func TestInstancesClient(t *testing.T) {
ctx := context.Background()
cred := &credential.PersistedState{
CredentialsConfig: &credential.Config{},
}
state := &gcpCatalogPersistedState{PersistedState: cred}
t.Run("GenerateCredentials error", func(t *testing.T) {
_, err := state.InstancesClient(ctx)
assert.Error(t, err)
assert.Contains(t, err.Error(), "error generation GCP credentials")
})
t.Run("NewInstancesRESTClient error", func(t *testing.T) {
state.CredentialsConfig = &credential.Config{
ProjectId: "test-project-id",
PrivateKey: "test-private-key",
ClientEmail: "test@example.com",
}
_, err := state.InstancesClient(ctx, option.WithoutAuthentication())
assert.Error(t, err)
assert.Contains(t, err.Error(), "error creating instances client")
})
}
func TestValidateCredsCallbackFn(t *testing.T) {
ctx := context.Background()
cred := &credential.PersistedState{
CredentialsConfig: &credential.Config{
ProjectId: "test-project-id",
Zone: "test-zone",
},
}
state := &gcpCatalogPersistedState{PersistedState: cred}
t.Run("List instances error", func(t *testing.T) {
state.testInstancesAPIFunc = newTestMockInstances(ctx,
nil,
testMockInstancesWithListInstancesOutput(nil),
testMockInstancesWithListInstancesError(errors.New("error listing instances")),
)
callback := state.ValidateCredsCallbackFn(ctx)
err := callback(&credential.Config{
ProjectId: "test-project-id",
Zone: "test-zone",
})
assert.Error(t, err)
assert.Contains(t, err.Error(), "error listing instances")
})
t.Run("Success", func(t *testing.T) {
state.testInstancesAPIFunc = newTestMockInstances(ctx,
nil,
testMockInstancesWithListInstancesOutput(&computepb.InstanceList{}),
testMockInstancesWithListInstancesError(nil),
)
callback := state.ValidateCredsCallbackFn(ctx)
err := callback(&credential.Config{
ProjectId: "test-project-id",
Zone: "test-zone",
})
assert.NoError(t, err)
})
}