consul/agent/grpc-external/services/resource/testing/testing.go

125 lines
4.1 KiB
Go
Raw Normal View History

[COMPLIANCE] License changes (#18443) * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Adding explicit MPL license for sub-package This directory and its subdirectories (packages) contain files licensed with the MPLv2 `LICENSE` file in this directory and are intentionally licensed separately from the BSL `LICENSE` file at the root of this repository. * Updating the license from MPL to Business Source License Going forward, this project will be licensed under the Business Source License v1.1. Please see our blog post for more details at <Blog URL>, FAQ at www.hashicorp.com/licensing-faq, and details of the license at www.hashicorp.com/bsl. * add missing license headers * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 * Update copyright file headers to BUSL-1.1 --------- Co-authored-by: hashicorp-copywrite[bot] <110428419+hashicorp-copywrite[bot]@users.noreply.github.com>
2023-08-11 13:12:13 +00:00
// Copyright (c) HashiCorp, Inc.
// SPDX-License-Identifier: BUSL-1.1
package testing
import (
"context"
"testing"
"github.com/stretchr/testify/mock"
"github.com/stretchr/testify/require"
"google.golang.org/grpc"
"google.golang.org/grpc/credentials/insecure"
"github.com/hashicorp/go-uuid"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/acl/resolver"
svc "github.com/hashicorp/consul/agent/grpc-external/services/resource"
"github.com/hashicorp/consul/agent/grpc-external/testutils"
internal "github.com/hashicorp/consul/agent/grpc-internal"
"github.com/hashicorp/consul/agent/structs"
"github.com/hashicorp/consul/internal/resource"
"github.com/hashicorp/consul/internal/storage/inmem"
"github.com/hashicorp/consul/proto-public/pbresource"
"github.com/hashicorp/consul/sdk/testutil"
)
func randomACLIdentity(t *testing.T) structs.ACLIdentity {
id, err := uuid.GenerateUUID()
require.NoError(t, err)
return &structs.ACLToken{AccessorID: id}
}
func AuthorizerFrom(t *testing.T, policyStrs ...string) resolver.Result {
policies := []*acl.Policy{}
for _, policyStr := range policyStrs {
policy, err := acl.NewPolicyFromSource(policyStr, nil, nil)
require.NoError(t, err)
policies = append(policies, policy)
}
authz, err := acl.NewPolicyAuthorizerWithDefaults(acl.DenyAll(), policies, nil)
require.NoError(t, err)
return resolver.Result{
Authorizer: authz,
ACLIdentity: randomACLIdentity(t),
}
}
// RunResourceService runs a Resource Service for the duration of the test and
// returns a client to interact with it. ACLs will be disabled and only the
// default partition and namespace are available.
func RunResourceService(t *testing.T, registerFns ...func(resource.Registry)) pbresource.ResourceServiceClient {
// Provide a resolver which will default partition and namespace when not provided. This is similar to user
// initiated requests.
//
// Controllers under test should be providing full tenancy since they will run with the DANGER_NO_AUTH.
mockACLResolver := &svc.MockACLResolver{}
mockACLResolver.On("ResolveTokenAndDefaultMeta", mock.Anything, mock.Anything, mock.Anything).
Return(testutils.ACLsDisabled(t), nil).
Run(func(args mock.Arguments) {
// Caller expecting passed in tokenEntMeta and authorizerContext to be filled in.
tokenEntMeta := args.Get(1).(*acl.EnterpriseMeta)
if tokenEntMeta != nil {
FillEntMeta(tokenEntMeta)
}
authzContext := args.Get(2).(*acl.AuthorizerContext)
if authzContext != nil {
FillAuthorizerContext(authzContext)
}
})
return RunResourceServiceWithACL(t, mockACLResolver, registerFns...)
}
func RunResourceServiceWithACL(t *testing.T, aclResolver svc.ACLResolver, registerFns ...func(resource.Registry)) pbresource.ResourceServiceClient {
t.Helper()
backend, err := inmem.NewBackend()
require.NoError(t, err)
ctx, cancel := context.WithCancel(context.Background())
t.Cleanup(cancel)
go backend.Run(ctx)
registry := resource.NewRegistry()
for _, fn := range registerFns {
fn(registry)
}
server := grpc.NewServer()
mockTenancyBridge := &svc.MockTenancyBridge{}
mockTenancyBridge.On("PartitionExists", resource.DefaultPartitionName).Return(true, nil)
mockTenancyBridge.On("NamespaceExists", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(true, nil)
mockTenancyBridge.On("IsPartitionMarkedForDeletion", resource.DefaultPartitionName).Return(false, nil)
mockTenancyBridge.On("IsNamespaceMarkedForDeletion", resource.DefaultPartitionName, resource.DefaultNamespaceName).Return(false, nil)
svc.NewServer(svc.Config{
Backend: backend,
Registry: registry,
Logger: testutil.Logger(t),
ACLResolver: aclResolver,
V1TenancyBridge: mockTenancyBridge,
}).Register(server)
pipe := internal.NewPipeListener()
go server.Serve(pipe)
t.Cleanup(server.Stop)
conn, err := grpc.Dial("",
grpc.WithTransportCredentials(insecure.NewCredentials()),
grpc.WithContextDialer(pipe.DialContext),
grpc.WithBlock(),
)
require.NoError(t, err)
t.Cleanup(func() { _ = conn.Close() })
return pbresource.NewResourceServiceClient(conn)
}