mirror of https://github.com/hashicorp/consul
152 lines
5.1 KiB
Go
152 lines
5.1 KiB
Go
|
// Copyright (c) HashiCorp, Inc.
|
||
|
// SPDX-License-Identifier: BUSL-1.1
|
||
|
|
||
|
package workloadselector_test
|
||
|
|
||
|
import (
|
||
|
"context"
|
||
|
"testing"
|
||
|
|
||
|
"github.com/hashicorp/consul/internal/catalog/workloadselector"
|
||
|
"github.com/hashicorp/consul/internal/controller"
|
||
|
"github.com/hashicorp/consul/internal/controller/cache"
|
||
|
"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/private/prototest"
|
||
|
"github.com/hashicorp/consul/sdk/testutil"
|
||
|
"github.com/stretchr/testify/require"
|
||
|
)
|
||
|
|
||
|
func TestWorkloadSelectorCacheIntegration(t *testing.T) {
|
||
|
c := cache.New()
|
||
|
i := workloadselector.Index[*pbcatalog.Service]("selected-workloads")
|
||
|
c.AddType(pbcatalog.WorkloadType)
|
||
|
c.AddIndex(pbcatalog.ServiceType, i)
|
||
|
|
||
|
rt := controller.Runtime{
|
||
|
Cache: c,
|
||
|
Logger: testutil.Logger(t),
|
||
|
}
|
||
|
|
||
|
svcFoo := resourcetest.Resource(pbcatalog.ServiceType, "foo").
|
||
|
WithData(t, &pbcatalog.Service{
|
||
|
Workloads: &pbcatalog.WorkloadSelector{
|
||
|
Names: []string{"foo"},
|
||
|
Prefixes: []string{"api-", "other-"},
|
||
|
},
|
||
|
}).
|
||
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
||
|
Build()
|
||
|
|
||
|
svcBar := resourcetest.Resource(pbcatalog.ServiceType, "bar").
|
||
|
WithData(t, &pbcatalog.Service{
|
||
|
Workloads: &pbcatalog.WorkloadSelector{
|
||
|
Names: []string{"bar"},
|
||
|
Prefixes: []string{"api-1", "something-else-"},
|
||
|
},
|
||
|
}).
|
||
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
||
|
Build()
|
||
|
|
||
|
workloadBar := resourcetest.Resource(pbcatalog.WorkloadType, "bar").
|
||
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
||
|
Build()
|
||
|
|
||
|
workloadAPIFoo := resourcetest.Resource(pbcatalog.WorkloadType, "api-foo").
|
||
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
||
|
Build()
|
||
|
|
||
|
workloadAPI12 := resourcetest.Resource(pbcatalog.WorkloadType, "api-1").
|
||
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
||
|
Build()
|
||
|
|
||
|
workloadFoo := resourcetest.Resource(pbcatalog.WorkloadType, "foo").
|
||
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
||
|
Build()
|
||
|
|
||
|
workloadSomethingElse12 := resourcetest.Resource(pbcatalog.WorkloadType, "something-else-12").
|
||
|
WithTenancy(resource.DefaultNamespacedTenancy()).
|
||
|
Build()
|
||
|
|
||
|
// prime the cache with all of our services and workloads
|
||
|
require.NoError(t, c.Insert(svcFoo))
|
||
|
require.NoError(t, c.Insert(svcBar))
|
||
|
require.NoError(t, c.Insert(workloadAPIFoo))
|
||
|
require.NoError(t, c.Insert(workloadAPI12))
|
||
|
require.NoError(t, c.Insert(workloadFoo))
|
||
|
require.NoError(t, c.Insert(workloadSomethingElse12))
|
||
|
|
||
|
// check that mapping a selecting resource to the list of currently selected workloads works as expected
|
||
|
reqs, err := workloadselector.MapSelectorToWorkloads[*pbcatalog.Service](context.Background(), rt, svcFoo)
|
||
|
require.NoError(t, err)
|
||
|
// in particular workloadSomethingElse12 should not show up here
|
||
|
expected := []controller.Request{
|
||
|
{ID: workloadFoo.Id},
|
||
|
{ID: workloadAPI12.Id},
|
||
|
{ID: workloadAPIFoo.Id},
|
||
|
}
|
||
|
prototest.AssertElementsMatch(t, expected, reqs)
|
||
|
|
||
|
reqs, err = workloadselector.MapSelectorToWorkloads[*pbcatalog.Service](context.Background(), rt, svcBar)
|
||
|
require.NoError(t, err)
|
||
|
// workloadFoo and workloadAPIFoo should not show up here as they don't meet the selection critiera
|
||
|
// workloadBar should not show up here because it hasn't been inserted into the cache yet.
|
||
|
expected = []controller.Request{
|
||
|
{ID: workloadSomethingElse12.Id},
|
||
|
{ID: workloadAPI12.Id},
|
||
|
}
|
||
|
prototest.AssertElementsMatch(t, expected, reqs)
|
||
|
|
||
|
// insert workloadBar into the cache so that future calls to MapSelectorToWorkloads for svcBar show
|
||
|
// the workload in the output
|
||
|
require.NoError(t, c.Insert(workloadBar))
|
||
|
|
||
|
// now validate that workloadBar shows up in the svcBar mapping
|
||
|
reqs, err = workloadselector.MapSelectorToWorkloads[*pbcatalog.Service](context.Background(), rt, svcBar)
|
||
|
require.NoError(t, err)
|
||
|
expected = []controller.Request{
|
||
|
{ID: workloadSomethingElse12.Id},
|
||
|
{ID: workloadAPI12.Id},
|
||
|
{ID: workloadBar.Id},
|
||
|
}
|
||
|
prototest.AssertElementsMatch(t, expected, reqs)
|
||
|
|
||
|
// create the mapper to verify that finding services that select workloads functions correctly
|
||
|
mapper := workloadselector.MapWorkloadsToSelectors(pbcatalog.ServiceType, i.Name())
|
||
|
|
||
|
// check that workloadAPIFoo only returns a request for serviceFoo
|
||
|
reqs, err = mapper(context.Background(), rt, workloadAPIFoo)
|
||
|
require.NoError(t, err)
|
||
|
expected = []controller.Request{
|
||
|
{ID: svcFoo.Id},
|
||
|
}
|
||
|
prototest.AssertElementsMatch(t, expected, reqs)
|
||
|
|
||
|
// check that workloadAPI12 returns both services
|
||
|
reqs, err = mapper(context.Background(), rt, workloadAPI12)
|
||
|
require.NoError(t, err)
|
||
|
expected = []controller.Request{
|
||
|
{ID: svcFoo.Id},
|
||
|
{ID: svcBar.Id},
|
||
|
}
|
||
|
prototest.AssertElementsMatch(t, expected, reqs)
|
||
|
|
||
|
// check that workloadSomethingElse12 returns only svcBar
|
||
|
reqs, err = mapper(context.Background(), rt, workloadSomethingElse12)
|
||
|
require.NoError(t, err)
|
||
|
expected = []controller.Request{
|
||
|
{ID: svcBar.Id},
|
||
|
}
|
||
|
prototest.AssertElementsMatch(t, expected, reqs)
|
||
|
|
||
|
// check that workloadFoo returns only svcFoo
|
||
|
reqs, err = mapper(context.Background(), rt, workloadFoo)
|
||
|
require.NoError(t, err)
|
||
|
expected = []controller.Request{
|
||
|
{ID: svcFoo.Id},
|
||
|
}
|
||
|
prototest.AssertElementsMatch(t, expected, reqs)
|
||
|
|
||
|
}
|