package engine import ( "context" "os" "os/exec" "reflect" "testing" "time" ) type sliceBudgetConfig struct { Values []string `yaml:"values"` } type arrayBudgetConfig struct { Values [1]string `yaml:"values"` } type mapBudgetConfig struct { Values map[string]string `yaml:"values"` } type inlineBudgetFields struct { Name string `yaml:"name"` } type inlineStructBudgetConfig struct { Fields inlineBudgetFields `yaml:",inline"` } type inlineMapBudgetConfig struct { Fields map[string]string `yaml:",inline"` } type hugeZeroBudgetConfig struct { Values []struct{} `yaml:"values"` } func TestProjectionChecksMinimumContainerNodes(t *testing.T) { tests := []struct { name string typeOf reflect.Type value any exact int }{ {name: "slice", typeOf: reflect.TypeFor[sliceBudgetConfig](), value: sliceBudgetConfig{Values: []string{"x"}}, exact: 4}, {name: "array", typeOf: reflect.TypeFor[arrayBudgetConfig](), value: arrayBudgetConfig{Values: [1]string{"x"}}, exact: 4}, {name: "map", typeOf: reflect.TypeFor[mapBudgetConfig](), value: mapBudgetConfig{Values: map[string]string{"x": "y"}}, exact: 5}, {name: "inline struct", typeOf: reflect.TypeFor[inlineStructBudgetConfig](), value: inlineStructBudgetConfig{Fields: inlineBudgetFields{Name: "x"}}, exact: 3}, {name: "inline map", typeOf: reflect.TypeFor[inlineMapBudgetConfig](), value: inlineMapBudgetConfig{Fields: map[string]string{"x": "y"}}, exact: 3}, } for _, test := range tests { t.Run(test.name, func(t *testing.T) { schema, issue := buildSchema(test.typeOf, testSecretBinding()) if issue != nil { t.Fatal(issue.message) } for _, limits := range []struct { name string nodes int fail bool }{{name: "exact", nodes: test.exact}, {name: "insufficient", nodes: test.exact - 1, fail: true}} { t.Run(limits.name, func(t *testing.T) { _, projectionIssue := projectConfiguration(schema, reflect.ValueOf(test.value), projectionLimits{depth: maxDocumentDepth, nodes: limits.nodes}) if limits.fail { if projectionIssue == nil || projectionIssue.code != CodeSchemaProjectionLimit { t.Fatalf("projection issue = %#v, want limit failure", projectionIssue) } } else if projectionIssue != nil { t.Fatalf("exact-budget projection issue = %#v", projectionIssue) } }) } }) } } func TestProjectionRejectsMaximumZeroSizedSliceBeforeAllocation(t *testing.T) { if os.Getenv("CONFIGKIT_HUGE_ZERO_SLICE_TEST") != "" { schema := mustSchemaFor[hugeZeroBudgetConfig](t) value := hugeZeroBudgetConfig{Values: make([]struct{}, int(^uint(0)>>1))} _, issue := projectConfiguration(schema, reflect.ValueOf(value), defaultProjectionLimits()) if issue == nil || issue.code != CodeSchemaProjectionLimit { t.Fatalf("projection issue = %#v, want a safe limit failure", issue) } return } ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) defer cancel() command := exec.CommandContext(ctx, os.Args[0], "-test.run=^TestProjectionRejectsMaximumZeroSizedSliceBeforeAllocation$") command.Env = append(os.Environ(), "CONFIGKIT_HUGE_ZERO_SLICE_TEST=1") output, err := command.CombinedOutput() if ctx.Err() != nil { t.Fatalf("maximum-length zero-sized slice projection did not terminate: %s", output) } if err != nil { t.Fatalf("maximum-length zero-sized slice projection failed: %v, %s", err, output) } }