mirror of https://github.com/hashicorp/consul
Browse Source
To allow the index to be refactored without accidental changes. To update the expected value run: 'go test ./agent/consul/state -update'pull/9420/head
Daniel Nephin
4 years ago
4 changed files with 317 additions and 5 deletions
@ -0,0 +1,5 @@
|
||||
// +build !consulent
|
||||
|
||||
package state |
||||
|
||||
var stateStoreSchemaExpected = "TestStateStoreSchema.golden" |
@ -1,17 +1,100 @@
|
||||
package state |
||||
|
||||
import ( |
||||
"bytes" |
||||
"fmt" |
||||
"reflect" |
||||
"runtime" |
||||
"sort" |
||||
"testing" |
||||
|
||||
"github.com/hashicorp/go-memdb" |
||||
"github.com/stretchr/testify/require" |
||||
|
||||
"github.com/hashicorp/consul/internal/testing/golden" |
||||
) |
||||
|
||||
func TestStateStore_Schema(t *testing.T) { |
||||
// First call the schema creation
|
||||
func TestStateStoreSchema(t *testing.T) { |
||||
schema := stateStoreSchema() |
||||
require.NoError(t, schema.Validate()) |
||||
|
||||
_, err := memdb.NewMemDB(schema) |
||||
require.NoError(t, err) |
||||
|
||||
actual, err := repr(schema) |
||||
require.NoError(t, err) |
||||
|
||||
expected := golden.Get(t, actual, stateStoreSchemaExpected) |
||||
require.Equal(t, expected, actual) |
||||
} |
||||
|
||||
func repr(schema *memdb.DBSchema) (string, error) { |
||||
tables := make([]string, 0, len(schema.Tables)) |
||||
for name := range schema.Tables { |
||||
tables = append(tables, name) |
||||
} |
||||
sort.Strings(tables) |
||||
|
||||
buf := new(bytes.Buffer) |
||||
for _, name := range tables { |
||||
fmt.Fprintf(buf, "table=%v\n", name) |
||||
|
||||
// Try to initialize a new memdb using the schema
|
||||
if _, err := memdb.NewMemDB(schema); err != nil { |
||||
t.Fatalf("err: %s", err) |
||||
indexes := indexNames(schema.Tables[name]) |
||||
for _, i := range indexes { |
||||
index := schema.Tables[name].Indexes[i] |
||||
fmt.Fprintf(buf, " index=%v", i) |
||||
if index.Unique { |
||||
buf.WriteString(" unique") |
||||
} |
||||
if index.AllowMissing { |
||||
buf.WriteString(" allow-missing") |
||||
} |
||||
buf.WriteString("\n") |
||||
buf.WriteString(" indexer=") |
||||
formatIndexer(buf, index.Indexer) |
||||
buf.WriteString("\n") |
||||
} |
||||
buf.WriteString("\n") |
||||
} |
||||
|
||||
return buf.String(), nil |
||||
} |
||||
|
||||
func formatIndexer(buf *bytes.Buffer, indexer memdb.Indexer) { |
||||
v := reflect.Indirect(reflect.ValueOf(indexer)) |
||||
typ := v.Type() |
||||
buf.WriteString(typ.PkgPath() + "." + typ.Name()) |
||||
for i := 0; i < typ.NumField(); i++ { |
||||
fmt.Fprintf(buf, " %v=", typ.Field(i).Name) |
||||
|
||||
field := v.Field(i) |
||||
switch typ.Field(i).Type.Kind() { |
||||
case reflect.Slice: |
||||
buf.WriteString("[") |
||||
for j := 0; j < field.Len(); j++ { |
||||
if j != 0 { |
||||
buf.WriteString(", ") |
||||
} |
||||
// TODO: handle other types of slices
|
||||
formatIndexer(buf, v.Field(i).Index(j).Interface().(memdb.Indexer)) |
||||
} |
||||
buf.WriteString("]") |
||||
case reflect.Func: |
||||
// Functions are printed as pointer addresses, which change frequently.
|
||||
// Instead use the name.
|
||||
buf.WriteString(runtime.FuncForPC(field.Pointer()).Name()) |
||||
default: |
||||
fmt.Fprintf(buf, "%v", field) |
||||
} |
||||
} |
||||
} |
||||
|
||||
func indexNames(table *memdb.TableSchema) []string { |
||||
indexes := make([]string, 0, len(table.Indexes)) |
||||
for name := range table.Indexes { |
||||
indexes = append(indexes, name) |
||||
} |
||||
|
||||
sort.Strings(indexes) |
||||
return indexes |
||||
} |
||||
|
@ -0,0 +1,188 @@
|
||||
table=acl-auth-methods |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Name Lowercase=true |
||||
|
||||
table=acl-binding-rules |
||||
index=authmethod |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=AuthMethod Lowercase=true |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=ID |
||||
|
||||
table=acl-policies |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=ID |
||||
index=name unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Name Lowercase=true |
||||
|
||||
table=acl-roles |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=ID |
||||
index=name unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Name Lowercase=true |
||||
index=policies allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.RolePoliciesIndex |
||||
|
||||
table=acl-tokens |
||||
index=accessor unique allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=AccessorID |
||||
index=authmethod allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=AuthMethod Lowercase=false |
||||
index=expires-global allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.TokenExpirationIndex LocalFilter=false |
||||
index=expires-local allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.TokenExpirationIndex LocalFilter=true |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=SecretID Lowercase=false |
||||
index=local |
||||
indexer=github.com/hashicorp/go-memdb.ConditionalIndex Conditional=github.com/hashicorp/consul/agent/consul/state.tokensTableSchema.func1 |
||||
index=needs-upgrade |
||||
indexer=github.com/hashicorp/go-memdb.ConditionalIndex Conditional=github.com/hashicorp/consul/agent/consul/state.tokensTableSchema.func2 |
||||
index=policies allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.TokenPoliciesIndex |
||||
index=roles allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.TokenRolesIndex |
||||
|
||||
table=autopilot-config |
||||
index=id unique allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.ConditionalIndex Conditional=github.com/hashicorp/consul/agent/consul/state.autopilotConfigTableSchema.func1 |
||||
|
||||
table=checks |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=CheckID Lowercase=true] AllowMissing=false |
||||
index=node allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true |
||||
index=node_service allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=ServiceID Lowercase=true] AllowMissing=false |
||||
index=node_service_check allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/go-memdb.FieldSetIndex Field=ServiceID] AllowMissing=false |
||||
index=service allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=ServiceName Lowercase=true |
||||
index=status |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Status Lowercase=false |
||||
|
||||
table=config-entries |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Kind Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=Name Lowercase=true] AllowMissing=false |
||||
index=intention-legacy-id unique allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.ServiceIntentionLegacyIDIndex uuidFieldIndex={} |
||||
index=intention-source allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.ServiceIntentionSourceIndex |
||||
index=kind |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Kind Lowercase=true |
||||
index=link allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.ConfigEntryLinkIndex |
||||
|
||||
table=connect-ca-builtin |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=ID Lowercase=false |
||||
|
||||
table=connect-ca-config |
||||
index=id unique allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.ConditionalIndex Conditional=github.com/hashicorp/consul/agent/consul/state.caConfigTableSchema.func1 |
||||
|
||||
table=connect-ca-roots |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=ID Lowercase=false |
||||
|
||||
table=connect-intentions |
||||
index=destination allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=DestinationNS Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=DestinationName Lowercase=true] AllowMissing=false |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=ID |
||||
index=source allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=SourceNS Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=SourceName Lowercase=true] AllowMissing=false |
||||
index=source_destination unique allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=SourceNS Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=SourceName Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=DestinationNS Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=DestinationName Lowercase=true] AllowMissing=false |
||||
|
||||
table=coordinates |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=Segment Lowercase=true] AllowMissing=true |
||||
index=node |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true |
||||
|
||||
table=federation-states |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Datacenter Lowercase=true |
||||
|
||||
table=gateway-services |
||||
index=gateway |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.ServiceNameIndex Field=Gateway |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/consul/agent/consul/state.ServiceNameIndex Field=Gateway, github.com/hashicorp/consul/agent/consul/state.ServiceNameIndex Field=Service, github.com/hashicorp/go-memdb.IntFieldIndex Field=Port] AllowMissing=false |
||||
index=service allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.ServiceNameIndex Field=Service |
||||
|
||||
table=index |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Key Lowercase=true |
||||
|
||||
table=kvs |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Key Lowercase=false |
||||
index=session allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=Session |
||||
|
||||
table=mesh-topology |
||||
index=downstream |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.ServiceNameIndex Field=Downstream |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/consul/agent/consul/state.ServiceNameIndex Field=Upstream, github.com/hashicorp/consul/agent/consul/state.ServiceNameIndex Field=Downstream] AllowMissing=false |
||||
index=upstream allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.ServiceNameIndex Field=Upstream |
||||
|
||||
table=nodes |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true |
||||
index=meta allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.StringMapFieldIndex Field=Meta Lowercase=false |
||||
index=uuid unique allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=ID |
||||
|
||||
table=prepared-queries |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=ID |
||||
index=name unique allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Name Lowercase=true |
||||
index=session allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=Session |
||||
index=template unique allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.PreparedQueryIndex |
||||
|
||||
table=services |
||||
index=connect allow-missing |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.IndexConnectService |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/go-memdb.StringFieldIndex Field=ServiceID Lowercase=true] AllowMissing=false |
||||
index=kind |
||||
indexer=github.com/hashicorp/consul/agent/consul/state.IndexServiceKind |
||||
index=node |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true |
||||
index=service allow-missing |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=ServiceName Lowercase=true |
||||
|
||||
table=session_checks |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/consul/agent/consul/state.CheckIDIndex, github.com/hashicorp/go-memdb.UUIDFieldIndex Field=Session] AllowMissing=false |
||||
index=node_check |
||||
indexer=github.com/hashicorp/go-memdb.CompoundIndex Indexes=[github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true, github.com/hashicorp/consul/agent/consul/state.CheckIDIndex] AllowMissing=false |
||||
index=session |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=Session |
||||
|
||||
table=sessions |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.UUIDFieldIndex Field=ID |
||||
index=node |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Node Lowercase=true |
||||
|
||||
table=system-metadata |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Key Lowercase=true |
||||
|
||||
table=tombstones |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=Key Lowercase=false |
||||
|
||||
table=usage |
||||
index=id unique |
||||
indexer=github.com/hashicorp/go-memdb.StringFieldIndex Field=ID Lowercase=true |
||||
|
@ -0,0 +1,36 @@
|
||||
package golden |
||||
|
||||
import ( |
||||
"flag" |
||||
"io/ioutil" |
||||
"os" |
||||
"path/filepath" |
||||
"testing" |
||||
|
||||
"github.com/stretchr/testify/require" |
||||
) |
||||
|
||||
// update allows golden files to be updated based on the current output.
|
||||
var update = flag.Bool("update", false, "update golden files") |
||||
|
||||
// Get reads the expected value from the file at filename and returns the value.
|
||||
// filename is relative to the ./testdata directory.
|
||||
//
|
||||
// If the `-update` flag is used with `go test`, the golden file will be updated
|
||||
// to the value of actual.
|
||||
func Get(t *testing.T, actual, filename string) string { |
||||
t.Helper() |
||||
|
||||
path := filepath.Join("testdata", filename) |
||||
if *update { |
||||
if dir := filepath.Dir(path); dir != "." { |
||||
require.NoError(t, os.MkdirAll(dir, 0755)) |
||||
} |
||||
err := ioutil.WriteFile(path, []byte(actual), 0644) |
||||
require.NoError(t, err) |
||||
} |
||||
|
||||
expected, err := ioutil.ReadFile(path) |
||||
require.NoError(t, err) |
||||
return string(expected) |
||||
} |
Loading…
Reference in new issue