Index secret failure locations lazily
This commit is contained in:
@@ -131,6 +131,94 @@ func TestSecretReferenceErrorsAreSafeAndPathSpecific(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestSecretFailureLocationsIndexWideInputOnce(t *testing.T) {
|
||||
type config struct {
|
||||
Secrets map[string]Secret `yaml:"secrets"`
|
||||
DefaultOnly Secret `yaml:"defaultOnly"`
|
||||
Sequence []Secret `yaml:"sequence"`
|
||||
}
|
||||
|
||||
keys := []string{"a/b~c", "12", "ordinary"}
|
||||
for index := 0; index < 128; index++ {
|
||||
keys = append(keys, fmt.Sprintf("wide-%03d", index))
|
||||
}
|
||||
var source strings.Builder
|
||||
source.WriteString("secrets:\n")
|
||||
lookupCounts := make(map[string]int)
|
||||
wantCodes := make(map[string]Code, len(keys)+3)
|
||||
wantLines := make(map[string]int, len(keys)+2)
|
||||
for index, key := range keys {
|
||||
var name string
|
||||
var code Code
|
||||
switch index % 4 {
|
||||
case 0:
|
||||
name, code = "MISSING_SHARED", CodeSecretUnset
|
||||
case 1:
|
||||
name, code = "EMPTY_SHARED", CodeSecretEmpty
|
||||
case 2:
|
||||
name, code = "INVALID-NAME", CodeSecretInvalidName
|
||||
default:
|
||||
name, code = "", CodeSecretInvalidName
|
||||
}
|
||||
line := index + 2
|
||||
fmt.Fprintf(&source, " %q: %q\n", key, name)
|
||||
path := Path{}.Key("secrets").Key(key).String()
|
||||
wantCodes[path] = code
|
||||
wantLines[path] = line
|
||||
}
|
||||
sequenceHeaderLine := len(keys) + 2
|
||||
source.WriteString("sequence:\n - MISSING_SHARED\n - EMPTY_SHARED\n")
|
||||
sequencePaths := []string{Path{}.Key("sequence").Index(0).String(), Path{}.Key("sequence").Index(1).String()}
|
||||
wantCodes[sequencePaths[0]] = CodeSecretUnset
|
||||
wantCodes[sequencePaths[1]] = CodeSecretEmpty
|
||||
wantLines[sequencePaths[0]] = sequenceHeaderLine + 1
|
||||
wantLines[sequencePaths[1]] = sequenceHeaderLine + 2
|
||||
defaultPath := Path{}.Key("defaultOnly").String()
|
||||
wantCodes[defaultPath] = CodeSecretUnset
|
||||
|
||||
_, err := testLoadWithSecretLookup(Bytes("secret-index.yml", []byte(source.String())), func(name string) (string, bool) {
|
||||
lookupCounts[name]++
|
||||
if name == "EMPTY_SHARED" {
|
||||
return "", true
|
||||
}
|
||||
return "", false
|
||||
}, Options[config]{Definition: Definition[config]{Defaults: func() config {
|
||||
return config{DefaultOnly: SecretEnv("MISSING_SHARED")}
|
||||
}}})
|
||||
loadError := requireSecretLoadCode(t, err, CodeSecretUnset)
|
||||
diagnostics := loadError.Diagnostics()
|
||||
if len(diagnostics) != len(wantCodes) {
|
||||
t.Fatalf("diagnostic count = %d, want %d: %#v", len(diagnostics), len(wantCodes), diagnostics)
|
||||
}
|
||||
gotPaths := make(map[string]struct{}, len(diagnostics))
|
||||
for _, diagnostic := range diagnostics {
|
||||
path := diagnostic.Path.String()
|
||||
gotPaths[path] = struct{}{}
|
||||
if code, ok := wantCodes[path]; !ok || diagnostic.Code != code {
|
||||
t.Errorf("diagnostic %q code = %q, want %q", path, diagnostic.Code, code)
|
||||
}
|
||||
if diagnostic.Primary == nil || diagnostic.Primary.SourceID != "source-1" {
|
||||
t.Errorf("diagnostic %q location = %#v, want source source-1", path, diagnostic.Primary)
|
||||
continue
|
||||
}
|
||||
if line, hasExactLine := wantLines[path]; hasExactLine && diagnostic.Primary.Line != line {
|
||||
t.Errorf("diagnostic %q line = %d, want %d", path, diagnostic.Primary.Line, line)
|
||||
}
|
||||
if path == defaultPath && diagnostic.Primary.Line != 1 {
|
||||
t.Errorf("defaults-only diagnostic line = %d, want nearest root line 1", diagnostic.Primary.Line)
|
||||
}
|
||||
}
|
||||
if _, ok := gotPaths["/secrets/a~1b~0c"]; !ok {
|
||||
t.Fatal("escaped mapping key diagnostic path was not preserved")
|
||||
}
|
||||
if _, ok := gotPaths["/secrets/12"]; !ok {
|
||||
t.Fatal("numeric mapping key diagnostic path was not preserved")
|
||||
}
|
||||
if lookupCounts["MISSING_SHARED"] != 1 || lookupCounts["EMPTY_SHARED"] != 1 || len(lookupCounts) != 2 {
|
||||
t.Fatalf("environment lookup counts = %#v, want one lookup per repeated name", lookupCounts)
|
||||
}
|
||||
}
|
||||
|
||||
func TestResolutionSelectsEffectiveSecretNameBeforeLookup(t *testing.T) {
|
||||
type config struct {
|
||||
Name string `yaml:"name"`
|
||||
|
||||
Reference in New Issue
Block a user