open-consul/agent/consul/state/config_entry_oss_test.go
freddygv 073c9e3a91 Update assumptions around exported-service config
Given that the exported-services config entry can use wildcards, the
precedence for wildcards is handled as with intentions. The most exact
match is the match that applies for any given service. We do not take
the union of all that apply.

Another update that was made was to reflect that only one
exported-services config entry applies to any given service in a
partition. This is a pre-existing constraint that gets enforced by
the Normalize() method on that config entry type.
2022-06-01 17:03:51 -06:00

164 lines
3.4 KiB
Go

//go:build !consulent
// +build !consulent
package state
import (
"testing"
"github.com/hashicorp/consul/acl"
"github.com/hashicorp/consul/agent/configentry"
"github.com/hashicorp/consul/agent/structs"
"github.com/stretchr/testify/require"
)
func testIndexerTableConfigEntries() map[string]indexerTestCase {
return map[string]indexerTestCase{
indexID: {
read: indexValue{
source: configentry.KindName{
Kind: "Proxy-Defaults",
Name: "NaMe",
},
expected: []byte("proxy-defaults\x00name\x00"),
},
write: indexValue{
source: &structs.ProxyConfigEntry{Name: "NaMe"},
expected: []byte("proxy-defaults\x00name\x00"),
},
prefix: []indexValue{
{
source: acl.EnterpriseMeta{},
expected: nil,
},
{
source: ConfigEntryKindQuery{Kind: "Proxy-Defaults"},
expected: []byte("proxy-defaults\x00"),
},
},
},
}
}
func TestStore_peersForService(t *testing.T) {
queryName := "foo"
type testCase struct {
name string
write structs.ConfigEntry
expect []string
}
cases := []testCase{
{
name: "empty everything",
expect: nil,
},
{
name: "service is not exported",
write: &structs.ExportedServicesConfigEntry{
Name: "default",
Services: []structs.ExportedService{
{
Name: "not-" + queryName,
Consumers: []structs.ServiceConsumer{
{
PeerName: "zip",
},
},
},
},
},
expect: nil,
},
{
name: "wildcard name matches",
write: &structs.ExportedServicesConfigEntry{
Name: "default",
Services: []structs.ExportedService{
{
Name: "not-" + queryName,
Consumers: []structs.ServiceConsumer{
{
PeerName: "zip",
},
},
},
{
Name: structs.WildcardSpecifier,
Consumers: []structs.ServiceConsumer{
{
PeerName: "bar",
},
{
PeerName: "baz",
},
},
},
},
},
expect: []string{"bar", "baz"},
},
{
name: "exact name takes precedence over wildcard",
write: &structs.ExportedServicesConfigEntry{
Name: "default",
Services: []structs.ExportedService{
{
Name: queryName,
Consumers: []structs.ServiceConsumer{
{
PeerName: "baz",
},
},
},
{
Name: structs.WildcardSpecifier,
Consumers: []structs.ServiceConsumer{
{
PeerName: "zip",
},
},
},
},
},
expect: []string{"baz"},
},
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
s := testStateStore(t)
var lastIdx uint64
// Write the entry.
if tc.write != nil {
require.NoError(t, tc.write.Normalize())
require.NoError(t, tc.write.Validate())
lastIdx++
require.NoError(t, s.EnsureConfigEntry(lastIdx, tc.write))
}
// Read the entries back.
tx := s.db.ReadTxn()
defer tx.Abort()
idx, peers, err := peersForServiceTxn(tx, nil, queryName, acl.DefaultEnterpriseMeta())
require.NoError(t, err)
// This is a little weird, but when there are no results, the index returned should be the max index for the
// config entries table so that the caller can watch for changes to it
if len(peers) == 0 {
require.Equal(t, maxIndexTxn(tx, tableConfigEntries), idx)
} else {
require.Equal(t, lastIdx, idx)
}
// Verify the result.
require.Len(t, peers, len(tc.expect))
require.Equal(t, tc.expect, peers)
})
}
}