mirror of https://github.com/hashicorp/consul
181 lines
4.9 KiB
Go
181 lines
4.9 KiB
Go
// Copyright (c) HashiCorp, Inc.
|
|
// SPDX-License-Identifier: BUSL-1.1
|
|
|
|
package workloadselector
|
|
|
|
import (
|
|
"context"
|
|
"errors"
|
|
"testing"
|
|
|
|
"github.com/hashicorp/consul/internal/controller"
|
|
"github.com/hashicorp/consul/internal/controller/cache/cachemock"
|
|
"github.com/hashicorp/consul/internal/controller/cache/index"
|
|
"github.com/hashicorp/consul/internal/controller/cache/index/indexmock"
|
|
"github.com/hashicorp/consul/internal/resource"
|
|
"github.com/hashicorp/consul/internal/resource/resourcetest"
|
|
pbcatalog "github.com/hashicorp/consul/proto-public/pbcatalog/v2beta1"
|
|
"github.com/hashicorp/consul/proto-public/pbresource"
|
|
"github.com/hashicorp/consul/proto/private/prototest"
|
|
"github.com/hashicorp/go-hclog"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
var injectedError = errors.New("injected error")
|
|
|
|
func TestMapSelectorToWorkloads(t *testing.T) {
|
|
cache := cachemock.NewReadOnlyCache(t)
|
|
|
|
rt := controller.Runtime{
|
|
Cache: cache,
|
|
}
|
|
|
|
mres := indexmock.NewResourceIterator(t)
|
|
|
|
svc := resourcetest.Resource(pbcatalog.ServiceType, "api").
|
|
WithData(t, &pbcatalog.Service{
|
|
Workloads: &pbcatalog.WorkloadSelector{
|
|
Prefixes: []string{"api-"},
|
|
Names: []string{"foo"},
|
|
},
|
|
}).
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
|
Build()
|
|
|
|
api1 := resourcetest.Resource(pbcatalog.WorkloadType, "api-1").
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
|
Build()
|
|
|
|
api2 := resourcetest.Resource(pbcatalog.WorkloadType, "api-2").
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
|
Build()
|
|
|
|
fooRes := resourcetest.Resource(pbcatalog.WorkloadType, "foo").
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
|
Build()
|
|
|
|
cache.EXPECT().
|
|
ListIterator(pbcatalog.WorkloadType, "id", &pbresource.ID{
|
|
Type: pbcatalog.WorkloadType,
|
|
Name: "api-",
|
|
Tenancy: resource.DefaultNamespacedTenancy(),
|
|
}, index.IndexQueryOptions{Prefix: true}).
|
|
Return(mres, nil).
|
|
Once()
|
|
cache.EXPECT().
|
|
Get(pbcatalog.WorkloadType, "id", &pbresource.ID{
|
|
Type: pbcatalog.WorkloadType,
|
|
Name: "foo",
|
|
Tenancy: resource.DefaultNamespacedTenancy(),
|
|
}).
|
|
Return(fooRes, nil).
|
|
Once()
|
|
|
|
mres.EXPECT().Next().Return(api1).Once()
|
|
mres.EXPECT().Next().Return(api2).Once()
|
|
mres.EXPECT().Next().Return(nil).Once()
|
|
|
|
expected := []controller.Request{
|
|
{ID: fooRes.Id},
|
|
{ID: api1.Id},
|
|
{ID: api2.Id},
|
|
}
|
|
|
|
reqs, err := MapSelectorToWorkloads[*pbcatalog.Service](context.Background(), rt, svc)
|
|
require.NoError(t, err)
|
|
prototest.AssertElementsMatch(t, expected, reqs)
|
|
}
|
|
|
|
func TestMapSelectorToWorkloads_DecodeError(t *testing.T) {
|
|
res := resourcetest.Resource(pbcatalog.ServiceType, "foo").
|
|
WithData(t, &pbcatalog.DNSPolicy{}).
|
|
Build()
|
|
|
|
reqs, err := MapSelectorToWorkloads[*pbcatalog.Service](context.Background(), controller.Runtime{}, res)
|
|
require.Nil(t, reqs)
|
|
require.Error(t, err)
|
|
require.ErrorAs(t, err, &resource.ErrDataParse{})
|
|
}
|
|
|
|
func TestMapSelectorToWorkloads_CacheError(t *testing.T) {
|
|
cache := cachemock.NewReadOnlyCache(t)
|
|
|
|
rt := controller.Runtime{
|
|
Cache: cache,
|
|
}
|
|
|
|
svc := resourcetest.Resource(pbcatalog.ServiceType, "api").
|
|
WithData(t, &pbcatalog.Service{
|
|
Workloads: &pbcatalog.WorkloadSelector{
|
|
Prefixes: []string{"api-"},
|
|
},
|
|
}).
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
|
Build()
|
|
|
|
cache.EXPECT().
|
|
ListIterator(pbcatalog.WorkloadType, "id", &pbresource.ID{
|
|
Type: pbcatalog.WorkloadType,
|
|
Name: "api-",
|
|
Tenancy: resource.DefaultNamespacedTenancy(),
|
|
}, index.IndexQueryOptions{Prefix: true}).
|
|
Return(nil, injectedError).
|
|
Once()
|
|
|
|
reqs, err := MapSelectorToWorkloads[*pbcatalog.Service](context.Background(), rt, svc)
|
|
require.ErrorIs(t, err, injectedError)
|
|
require.Nil(t, reqs)
|
|
}
|
|
|
|
func TestMapWorkloadsToSelectors(t *testing.T) {
|
|
cache := cachemock.NewReadOnlyCache(t)
|
|
rt := controller.Runtime{
|
|
Cache: cache,
|
|
Logger: hclog.NewNullLogger(),
|
|
}
|
|
|
|
dm := MapWorkloadsToSelectors(pbcatalog.ServiceType, "selected-workloads")
|
|
|
|
workload := resourcetest.Resource(pbcatalog.WorkloadType, "api-123").
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
|
Build()
|
|
|
|
svc1 := resourcetest.Resource(pbcatalog.ServiceType, "foo").
|
|
WithData(t, &pbcatalog.Service{
|
|
Workloads: &pbcatalog.WorkloadSelector{
|
|
Prefixes: []string{"api-"},
|
|
},
|
|
}).
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
|
Build()
|
|
|
|
svc2 := resourcetest.Resource(pbcatalog.ServiceType, "bar").
|
|
WithData(t, &pbcatalog.Service{
|
|
Workloads: &pbcatalog.WorkloadSelector{
|
|
Prefixes: []string{"api-"},
|
|
},
|
|
}).
|
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
|
Build()
|
|
|
|
mres := indexmock.NewResourceIterator(t)
|
|
|
|
cache.EXPECT().
|
|
ParentsIterator(pbcatalog.ServiceType, "selected-workloads", workload.Id).
|
|
Return(mres, nil).
|
|
Once()
|
|
|
|
mres.EXPECT().Next().Return(svc1).Once()
|
|
mres.EXPECT().Next().Return(svc2).Once()
|
|
mres.EXPECT().Next().Return(nil).Once()
|
|
|
|
reqs, err := dm(context.Background(), rt, workload)
|
|
require.NoError(t, err)
|
|
expected := []controller.Request{
|
|
{ID: svc1.Id},
|
|
{ID: svc2.Id},
|
|
}
|
|
prototest.AssertElementsMatch(t, expected, reqs)
|
|
|
|
}
|