mirror of
https://github.com/status-im/consul.git
synced 2025-01-10 22:06:20 +00:00
326c0ecfbe
* Implement In-Process gRPC for use by controller caching/indexing This replaces the pipe base listener implementation we were previously using. The new style CAN avoid cloning resources which our controller caching/indexing is taking advantage of to not duplicate resource objects in memory. To maintain safety for controllers and for them to be able to modify data they get back from the cache and the resource service, the client they are presented in their runtime will be wrapped with an autogenerated client which clones request and response messages as they pass through the client. Another sizable change in this PR is to consolidate how server specific gRPC services get registered and managed. Before this was in a bunch of different methods and it was difficult to track down how gRPC services were registered. Now its all in one place. * Fix race in tests * Ensure the resource service is registered to the multiplexed handler for forwarding from client agents * Expose peer streaming on the internal handler
97 lines
3.7 KiB
Go
97 lines
3.7 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package controllertest
|
|
|
|
import (
|
|
svc "github.com/hashicorp/consul/agent/grpc-external/services/resource"
|
|
svctest "github.com/hashicorp/consul/agent/grpc-external/services/resource/testing"
|
|
"github.com/hashicorp/consul/internal/controller"
|
|
"github.com/hashicorp/consul/internal/resource"
|
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
|
"github.com/hashicorp/consul/sdk/testutil"
|
|
)
|
|
|
|
type Builder struct {
|
|
serviceBuilder *svctest.Builder
|
|
controllerRegisterFns []func(*controller.Manager)
|
|
}
|
|
|
|
// NewControllerTestBuilder starts to build out out the necessary controller testing
|
|
// runtime for lightweight controller integration testing. This will run a single
|
|
// in-memory resource service instance and the controller manager. Usage of this
|
|
// builder is an easy way to ensure that all the right resource gRPC connections/clients
|
|
// get set up appropriately in a manner identical to how they would be on a full
|
|
// running server.
|
|
func NewControllerTestBuilder() *Builder {
|
|
return &Builder{
|
|
// disable cloning because we will enable it after passing the non-cloning variant
|
|
// to the controller manager.
|
|
serviceBuilder: svctest.NewResourceServiceBuilder().WithCloningDisabled(),
|
|
}
|
|
}
|
|
|
|
// WithV2Tenancy tells the internally created resource service to use V2 tenancy.
|
|
func (b *Builder) WithV2Tenancy(useV2Tenancy bool) *Builder {
|
|
b.serviceBuilder = b.serviceBuilder.WithV2Tenancy(useV2Tenancy)
|
|
return b
|
|
}
|
|
|
|
// Registry retrieves the resource registry from the internal im-mem resource service.
|
|
func (b *Builder) Registry() resource.Registry {
|
|
return b.serviceBuilder.Registry()
|
|
}
|
|
|
|
// WithResourceRegisterFns allows configuring functions to be run to register resource
|
|
// types with the internal in-mem resource service for the duration of the test.
|
|
func (b *Builder) WithResourceRegisterFns(registerFns ...func(resource.Registry)) *Builder {
|
|
b.serviceBuilder = b.serviceBuilder.WithRegisterFns(registerFns...)
|
|
return b
|
|
}
|
|
|
|
// WithControllerRegisterFns allows configuring a set of controllers that should be registered
|
|
// with the controller manager and executed during Run.
|
|
func (b *Builder) WithControllerRegisterFns(registerFns ...func(*controller.Manager)) *Builder {
|
|
for _, registerFn := range registerFns {
|
|
b.controllerRegisterFns = append(b.controllerRegisterFns, registerFn)
|
|
}
|
|
return b
|
|
}
|
|
|
|
// WithACLResolver is used to provide an ACLResolver implementation to the internal resource service.
|
|
func (b *Builder) WithACLResolver(aclResolver svc.ACLResolver) *Builder {
|
|
b.serviceBuilder = b.serviceBuilder.WithACLResolver(aclResolver)
|
|
return b
|
|
}
|
|
|
|
// WithTenancies adds additional tenancies if default/default is not sufficient.
|
|
func (b *Builder) WithTenancies(tenancies ...*pbresource.Tenancy) *Builder {
|
|
b.serviceBuilder = b.serviceBuilder.WithTenancies(tenancies...)
|
|
return b
|
|
}
|
|
|
|
// Run executes both the internal resource service and the controller manager.
|
|
// The controller manager gets told it is the Raft leader so all controllers
|
|
// will get executed. The resource service, controller manager and all controllers
|
|
// will be stopped when the test finishes by registering a cleanup method on
|
|
// the test.
|
|
func (b *Builder) Run(t testutil.TestingTB) pbresource.ResourceServiceClient {
|
|
t.Helper()
|
|
|
|
ctx := testutil.TestContext(t)
|
|
|
|
client := b.serviceBuilder.Run(t)
|
|
|
|
mgr := controller.NewManager(client, testutil.Logger(t))
|
|
for _, register := range b.controllerRegisterFns {
|
|
register(mgr)
|
|
}
|
|
|
|
mgr.SetRaftLeader(true)
|
|
go mgr.Run(ctx)
|
|
|
|
// auto-clone messages going through the client so that test
|
|
// code is free to modify objects in place without cloning themselves.
|
|
return pbresource.NewCloningResourceServiceClient(client)
|
|
}
|