Remove unread private transport members
This commit is contained in:
@@ -548,6 +548,14 @@ Focused check: `go test .` and `go test ./examples/consumers`.
|
|||||||
Finding: completes **F06**, following its schema-path subset in Stage 1.
|
Finding: completes **F06**, following its schema-path subset in Stage 1.
|
||||||
Owners: the exact records/files listed in [audit F06](audit.md#f06-trim-unread-private-result-and-transport-members).
|
Owners: the exact records/files listed in [audit F06](audit.md#f06-trim-unread-private-result-and-transport-members).
|
||||||
|
|
||||||
|
Status: **complete** (F06). Prior completed commits: `2736ddf`, `deb9aa5`,
|
||||||
|
`ae3408a`, `ea27f17`, `08a8c25`, `877c497`, `8aba43d`, `7bf2f0c`,
|
||||||
|
`0f9ecf1`, `119b42c`, `247a12b`, `4fcff5f`, `12d350a`, `08f2a8f`,
|
||||||
|
`826062a`, `e4a5ecb`. Validation passed:
|
||||||
|
`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test ./internal/engine`,
|
||||||
|
`env GOTOOLCHAIN=local GOPROXY=off GOTELEMETRY=off go test .`, and
|
||||||
|
`git diff --check`.
|
||||||
|
|
||||||
Remove `collectionPolicyResolution`'s four named unread fields; `inputPresence.null`;
|
Remove `collectionPolicyResolution`'s four named unread fields; `inputPresence.null`;
|
||||||
directive extraction's two presence flags; `importSelection.outcome`;
|
directive extraction's two presence flags; `importSelection.outcome`;
|
||||||
`importDeclarationSpec.excludeSet`; `selectedOverlayRequest.filesystem`;
|
`importDeclarationSpec.excludeSet`; `selectedOverlayRequest.filesystem`;
|
||||||
|
|||||||
@@ -14,11 +14,7 @@ type collectionPolicy struct {
|
|||||||
type collectionPolicyResolution struct {
|
type collectionPolicyResolution struct {
|
||||||
policy collectionPolicy
|
policy collectionPolicy
|
||||||
operation sequenceMode
|
operation sequenceMode
|
||||||
declarations []sequenceDeclarationSpec
|
|
||||||
declarationsPresent bool
|
|
||||||
identityDeclarationPresent bool
|
|
||||||
modeDeclarationPresent bool
|
modeDeclarationPresent bool
|
||||||
applicationIdentityFields []string
|
|
||||||
applicationIdentityPresent bool
|
applicationIdentityPresent bool
|
||||||
effectiveIdentityFields []string
|
effectiveIdentityFields []string
|
||||||
}
|
}
|
||||||
@@ -60,9 +56,6 @@ func resolveCollectionPolicy(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
result := collectionPolicyResolution{
|
result := collectionPolicyResolution{
|
||||||
declarations: normalizedDeclarations,
|
|
||||||
declarationsPresent: len(normalizedDeclarations) != 0,
|
|
||||||
applicationIdentityFields: normalizedApplicationIdentityFields,
|
|
||||||
applicationIdentityPresent: len(normalizedApplicationIdentityFields) != 0,
|
applicationIdentityPresent: len(normalizedApplicationIdentityFields) != 0,
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -73,7 +66,6 @@ func resolveCollectionPolicy(
|
|||||||
var declaredModeLocation *Location
|
var declaredModeLocation *Location
|
||||||
for _, declaration := range normalizedDeclarations {
|
for _, declaration := range normalizedDeclarations {
|
||||||
if declaration.identityPresent {
|
if declaration.identityPresent {
|
||||||
result.identityDeclarationPresent = true
|
|
||||||
if declaredIdentityFields == nil {
|
if declaredIdentityFields == nil {
|
||||||
declaredIdentityFields = cloneStrings(declaration.identityFields)
|
declaredIdentityFields = cloneStrings(declaration.identityFields)
|
||||||
declaredIdentityLocation = collectionDeclarationLocation(declaration.identityLocation, declaration.location)
|
declaredIdentityLocation = collectionDeclarationLocation(declaration.identityLocation, declaration.location)
|
||||||
|
|||||||
@@ -21,8 +21,8 @@ func TestResolveCollectionPolicyReconcilesDeclarationsBeforeComposition(t *testi
|
|||||||
if len(diagnostics) != 0 {
|
if len(diagnostics) != 0 {
|
||||||
t.Fatalf("policy diagnostics = %#v", diagnostics)
|
t.Fatalf("policy diagnostics = %#v", diagnostics)
|
||||||
}
|
}
|
||||||
if !resolved.declarationsPresent || !resolved.identityDeclarationPresent || !resolved.modeDeclarationPresent {
|
if !resolved.modeDeclarationPresent {
|
||||||
t.Fatalf("declaration presence was lost: %#v", resolved)
|
t.Fatalf("mode declaration was lost: %#v", resolved)
|
||||||
}
|
}
|
||||||
wantFields := []string{"id", "namespace"}
|
wantFields := []string{"id", "namespace"}
|
||||||
if !reflect.DeepEqual(resolved.policy.identityFields, wantFields) || !reflect.DeepEqual(resolved.effectiveIdentityFields, wantFields) {
|
if !reflect.DeepEqual(resolved.policy.identityFields, wantFields) || !reflect.DeepEqual(resolved.effectiveIdentityFields, wantFields) {
|
||||||
@@ -31,9 +31,6 @@ func TestResolveCollectionPolicyReconcilesDeclarationsBeforeComposition(t *testi
|
|||||||
if !resolved.policy.identityPresent || !resolved.policy.explicitModePresent || resolved.policy.explicitMode != sequenceModeAppend || resolved.operation != sequenceModeAppend {
|
if !resolved.policy.identityPresent || !resolved.policy.explicitModePresent || resolved.policy.explicitMode != sequenceModeAppend || resolved.operation != sequenceModeAppend {
|
||||||
t.Fatalf("resolved explicit policy = %#v, operation %d", resolved.policy, resolved.operation)
|
t.Fatalf("resolved explicit policy = %#v, operation %d", resolved.policy, resolved.operation)
|
||||||
}
|
}
|
||||||
if len(resolved.declarations) != 3 || resolved.declarations[0].identityLocation == nil || resolved.declarations[2].location.Line == 0 {
|
|
||||||
t.Fatalf("declaration locations were not retained: %#v", resolved.declarations)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestResolveCollectionPolicyRejectsConflictingPeersAtBothSites(t *testing.T) {
|
func TestResolveCollectionPolicyRejectsConflictingPeersAtBothSites(t *testing.T) {
|
||||||
|
|||||||
@@ -22,7 +22,6 @@ type decodeIssue struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type inputPresence struct {
|
type inputPresence struct {
|
||||||
null bool
|
|
||||||
location document.Location
|
location document.Location
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -434,7 +433,7 @@ func fieldForDecode(root reflect.Value, index []int, allocate bool) (reflect.Val
|
|||||||
}
|
}
|
||||||
|
|
||||||
func collectPresence(node *document.Node, path Path, presence map[string]inputPresence) {
|
func collectPresence(node *document.Node, path Path, presence map[string]inputPresence) {
|
||||||
presence[path.String()] = inputPresence{null: node.Kind == document.Null, location: node.Location}
|
presence[path.String()] = inputPresence{location: node.Location}
|
||||||
switch node.Kind {
|
switch node.Kind {
|
||||||
case document.Mapping:
|
case document.Mapping:
|
||||||
for _, entry := range node.Mapping {
|
for _, entry := range node.Mapping {
|
||||||
|
|||||||
@@ -19,11 +19,9 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type rootDirectiveExtraction struct {
|
type rootDirectiveExtraction struct {
|
||||||
body *document.Node
|
body *document.Node
|
||||||
imports []importDeclarationSpec
|
imports []importDeclarationSpec
|
||||||
sequences []sequenceDeclarationSpec
|
sequences []sequenceDeclarationSpec
|
||||||
importsPresent bool
|
|
||||||
sequencesPresent bool
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func splitImportDirectives(root *document.Node) (*document.Node, []importDeclarationSpec, []Diagnostic) {
|
func splitImportDirectives(root *document.Node) (*document.Node, []importDeclarationSpec, []Diagnostic) {
|
||||||
@@ -74,7 +72,6 @@ func parseRootDirectiveBlock(node *document.Node, directivePath Path, context ro
|
|||||||
fieldPath := directivePath.Key(entry.Key)
|
fieldPath := directivePath.Key(entry.Key)
|
||||||
switch entry.Key {
|
switch entry.Key {
|
||||||
case "imports":
|
case "imports":
|
||||||
extracted.importsPresent = true
|
|
||||||
if context == rootDirectiveContextOverlay {
|
if context == rootDirectiveContextOverlay {
|
||||||
diagnostics = append(diagnostics, nodeImportDiagnostic(CodeOverlayDirective, fieldPath, "overlays cannot contain imports", entry.Value))
|
diagnostics = append(diagnostics, nodeImportDiagnostic(CodeOverlayDirective, fieldPath, "overlays cannot contain imports", entry.Value))
|
||||||
continue
|
continue
|
||||||
@@ -87,7 +84,6 @@ func parseRootDirectiveBlock(node *document.Node, directivePath Path, context ro
|
|||||||
extracted.imports = append(extracted.imports, parsed...)
|
extracted.imports = append(extracted.imports, parsed...)
|
||||||
diagnostics = append(diagnostics, issues...)
|
diagnostics = append(diagnostics, issues...)
|
||||||
case "sequences":
|
case "sequences":
|
||||||
extracted.sequencesPresent = true
|
|
||||||
if context == rootDirectiveContextImportsOnly {
|
if context == rootDirectiveContextImportsOnly {
|
||||||
diagnostics = append(diagnostics, sequenceDeclarationDiagnostic(fieldPath, "sequence declarations are not enabled in this extraction context", entry.Value))
|
diagnostics = append(diagnostics, sequenceDeclarationDiagnostic(fieldPath, "sequence declarations are not enabled in this extraction context", entry.Value))
|
||||||
continue
|
continue
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ func TestSelectShallowDirectoriesUnionsRootsAndPatterns(t *testing.T) {
|
|||||||
if len(diagnostics) != 0 {
|
if len(diagnostics) != 0 {
|
||||||
t.Fatalf("selection diagnostics = %#v", diagnostics)
|
t.Fatalf("selection diagnostics = %#v", diagnostics)
|
||||||
}
|
}
|
||||||
if selection.outcome != importSelectionHasCandidates || len(selection.candidates) != 3 {
|
if len(selection.candidates) != 3 {
|
||||||
t.Fatalf("selection = %#v, want three unioned matches", selection)
|
t.Fatalf("selection = %#v, want three unioned matches", selection)
|
||||||
}
|
}
|
||||||
if selection.candidates[0].path != "one/README" || selection.candidates[1].path != "one/a.yaml" || selection.candidates[2].path != "two/a.yaml" {
|
if selection.candidates[0].path != "one/README" || selection.candidates[1].path != "one/a.yaml" || selection.candidates[2].path != "two/a.yaml" {
|
||||||
@@ -353,7 +353,7 @@ func TestSelectDirectoriesRetainsEmptySearchAndDirectoryVisitLimits(t *testing.T
|
|||||||
}
|
}
|
||||||
accounting := &importAccounting{}
|
accounting := &importAccounting{}
|
||||||
selection, diagnostics := selectDirectoryImportCandidates(access, root, specs[0], policy, defaultImportLimits(), accounting)
|
selection, diagnostics := selectDirectoryImportCandidates(access, root, specs[0], policy, defaultImportLimits(), accounting)
|
||||||
if len(diagnostics) != 0 || selection.outcome != importSelectionNone || len(selection.candidates) != 0 {
|
if len(diagnostics) != 0 || len(selection.candidates) != 0 {
|
||||||
t.Fatalf("empty recursive selection, diagnostics = %#v, %#v", selection, diagnostics)
|
t.Fatalf("empty recursive selection, diagnostics = %#v, %#v", selection, diagnostics)
|
||||||
}
|
}
|
||||||
if accounting.entries != 5 {
|
if accounting.entries != 5 {
|
||||||
|
|||||||
@@ -120,9 +120,6 @@ func selectGlobImportCandidates(access *filesystemAccess, basePath string, spec
|
|||||||
// Source allowance is charged by source admission, after this filtered set
|
// Source allowance is charged by source admission, after this filtered set
|
||||||
// reaches the traversal; that preserves repeated-source diagnostics first.
|
// reaches the traversal; that preserves repeated-source diagnostics first.
|
||||||
selection := importSelection{candidates: selected}
|
selection := importSelection{candidates: selected}
|
||||||
if len(selected) != 0 {
|
|
||||||
selection.outcome = importSelectionHasCandidates
|
|
||||||
}
|
|
||||||
return selection, nil
|
return selection, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ type selectedImportCandidate struct {
|
|||||||
// importSelection contains lexical candidates only; admission assigns source identity later.
|
// importSelection contains lexical candidates only; admission assigns source identity later.
|
||||||
type importSelection struct {
|
type importSelection struct {
|
||||||
candidates []selectedImportCandidate
|
candidates []selectedImportCandidate
|
||||||
outcome importSelectionOutcome
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func selectNamedImportCandidates(access *filesystemAccess, basePath string, spec importDeclarationSpec, policy resolvedImportPolicy) (importSelection, []Diagnostic) {
|
func selectNamedImportCandidates(access *filesystemAccess, basePath string, spec importDeclarationSpec, policy resolvedImportPolicy) (importSelection, []Diagnostic) {
|
||||||
@@ -68,9 +67,6 @@ func selectNamedImportCandidates(access *filesystemAccess, basePath string, spec
|
|||||||
candidates = append(candidates, candidate)
|
candidates = append(candidates, candidate)
|
||||||
}
|
}
|
||||||
selection := importSelection{candidates: candidates}
|
selection := importSelection{candidates: candidates}
|
||||||
if len(candidates) != 0 {
|
|
||||||
selection.outcome = importSelectionHasCandidates
|
|
||||||
}
|
|
||||||
return selection, nil
|
return selection, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -174,9 +170,6 @@ func selectDirectoryImportCandidates(access *filesystemAccess, basePath string,
|
|||||||
return importSelection{}, []Diagnostic{*importSelectionDiagnostic(spec.fieldSites["dir"], CodeImportMissing, "required directory import selected no files")}
|
return importSelection{}, []Diagnostic{*importSelectionDiagnostic(spec.fieldSites["dir"], CodeImportMissing, "required directory import selected no files")}
|
||||||
}
|
}
|
||||||
selection := importSelection{candidates: selected}
|
selection := importSelection{candidates: selected}
|
||||||
if len(selected) != 0 {
|
|
||||||
selection.outcome = importSelectionHasCandidates
|
|
||||||
}
|
|
||||||
return selection, nil
|
return selection, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ func TestSelectNamedImportsHandlesPartialAndEmptySelections(t *testing.T) {
|
|||||||
if len(diagnostics) != 0 {
|
if len(diagnostics) != 0 {
|
||||||
t.Fatalf("optional partial selection diagnostics = %#v", diagnostics)
|
t.Fatalf("optional partial selection diagnostics = %#v", diagnostics)
|
||||||
}
|
}
|
||||||
if selection.outcome != importSelectionHasCandidates || len(selection.candidates) != 1 || filepath.Base(selection.candidates[0].path) != "present.yaml" {
|
if len(selection.candidates) != 1 || filepath.Base(selection.candidates[0].path) != "present.yaml" {
|
||||||
t.Fatalf("partial selection = %#v", selection)
|
t.Fatalf("partial selection = %#v", selection)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ func TestSelectNamedImportsHandlesPartialAndEmptySelections(t *testing.T) {
|
|||||||
t.Fatal(diagnostics)
|
t.Fatal(diagnostics)
|
||||||
}
|
}
|
||||||
empty, diagnostics := selectNamedImportCandidates(access, root, emptySpecs[0], resolvedImportPolicy{required: true})
|
empty, diagnostics := selectNamedImportCandidates(access, root, emptySpecs[0], resolvedImportPolicy{required: true})
|
||||||
if len(diagnostics) != 0 || empty.outcome != importSelectionNone || len(empty.candidates) != 0 {
|
if len(diagnostics) != 0 || len(empty.candidates) != 0 {
|
||||||
t.Fatalf("required empty path selection, diagnostics = %#v, %#v", empty, diagnostics)
|
t.Fatalf("required empty path selection, diagnostics = %#v, %#v", empty, diagnostics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -123,7 +123,7 @@ func TestSelectNamedImportsDoesNotOpenExcludedContentOrApplySearchControls(t *te
|
|||||||
t.Fatal(diagnostics)
|
t.Fatal(diagnostics)
|
||||||
}
|
}
|
||||||
selection, diagnostics := selectNamedImportCandidates(access, ".", specs[0], policy)
|
selection, diagnostics := selectNamedImportCandidates(access, ".", specs[0], policy)
|
||||||
if len(diagnostics) != 0 || selection.outcome != importSelectionNone {
|
if len(diagnostics) != 0 || len(selection.candidates) != 0 {
|
||||||
t.Fatalf("excluded selection, diagnostics = %#v, %#v", selection, diagnostics)
|
t.Fatalf("excluded selection, diagnostics = %#v, %#v", selection, diagnostics)
|
||||||
}
|
}
|
||||||
if filesystem.openCalls != 0 || filesystem.statCalls == 0 {
|
if filesystem.openCalls != 0 || filesystem.statCalls == 0 {
|
||||||
|
|||||||
@@ -35,7 +35,6 @@ type importDeclarationSpec struct {
|
|||||||
pattern []string
|
pattern []string
|
||||||
patternSet bool
|
patternSet bool
|
||||||
exclude []string
|
exclude []string
|
||||||
excludeSet bool
|
|
||||||
depth int
|
depth int
|
||||||
depthSet bool
|
depthSet bool
|
||||||
destination Path
|
destination Path
|
||||||
@@ -327,7 +326,7 @@ func parseImportWildcardAssignment(spec *importDeclarationSpec, field string, no
|
|||||||
case "pattern":
|
case "pattern":
|
||||||
spec.pattern, spec.patternSet = values, true
|
spec.pattern, spec.patternSet = values, true
|
||||||
case "exclude":
|
case "exclude":
|
||||||
spec.exclude, spec.excludeSet = values, true
|
spec.exclude = values
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ func TestParseImportDeclarationSpecNormalizesPresenceAndPlacement(t *testing.T)
|
|||||||
t.Fatalf("stored paths = declaration %q, required %q", first.path.String(), first.fieldSites["required"].path.String())
|
t.Fatalf("stored paths = declaration %q, required %q", first.path.String(), first.fieldSites["required"].path.String())
|
||||||
}
|
}
|
||||||
second := specs[1]
|
second := specs[1]
|
||||||
if second.selector != importSelectorDirectory || second.paths == nil || len(second.paths) != 0 || !second.patternSet || second.pattern == nil || len(second.pattern) != 0 || !second.excludeSet || second.exclude == nil {
|
if second.selector != importSelectorDirectory || second.paths == nil || len(second.paths) != 0 || !second.patternSet || second.pattern == nil || len(second.pattern) != 0 || second.exclude == nil {
|
||||||
t.Fatalf("empty list presence was lost: %#v", second)
|
t.Fatalf("empty list presence was lost: %#v", second)
|
||||||
}
|
}
|
||||||
third := specs[2]
|
third := specs[2]
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ func applyInputLayers(source Source, filesystem *FilesystemContext, overlay stri
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
request := selectedOverlayRequest{
|
request := selectedOverlayRequest{
|
||||||
name: overlay, filesystem: resolved, protectionRule: protectionRule,
|
name: overlay, protectionRule: protectionRule,
|
||||||
sequencePolicy: policy, limits: defaultImportLimits(), versionState: input.versionState,
|
sequencePolicy: policy, limits: defaultImportLimits(), versionState: input.versionState,
|
||||||
}
|
}
|
||||||
access, diagnostic := openSelectedOverlayAccess(resolved)
|
access, diagnostic := openSelectedOverlayAccess(resolved)
|
||||||
|
|||||||
@@ -207,7 +207,7 @@ func assembleLayeredInput[T any](request loadRequest[T], input assembledInput, p
|
|||||||
return input, append(versionDiagnostics, *diagnostic)
|
return input, append(versionDiagnostics, *diagnostic)
|
||||||
}
|
}
|
||||||
overlayRequest := selectedOverlayRequest{
|
overlayRequest := selectedOverlayRequest{
|
||||||
name: request.overlay, filesystem: resolved, protectionRule: request.protectionVersion(),
|
name: request.overlay, protectionRule: request.protectionVersion(),
|
||||||
sequencePolicy: policy.sequencePolicy, limits: defaultImportLimits(), versionState: input.versionState,
|
sequencePolicy: policy.sequencePolicy, limits: defaultImportLimits(), versionState: input.versionState,
|
||||||
}
|
}
|
||||||
var diagnostics []Diagnostic
|
var diagnostics []Diagnostic
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ type postDecodeOverrideContext struct {
|
|||||||
decoded decodedConfiguration
|
decoded decodedConfiguration
|
||||||
metadata Metadata
|
metadata Metadata
|
||||||
resolution resolutionInput
|
resolution resolutionInput
|
||||||
sources []SourceInfo
|
|
||||||
applications []historyApplication
|
applications []historyApplication
|
||||||
postDecodeApps []historyApplication
|
postDecodeApps []historyApplication
|
||||||
referenceInput *document.Node
|
referenceInput *document.Node
|
||||||
@@ -76,7 +75,6 @@ func preparePostDecodeOverrideContext(input assembledInput, before decodedConfig
|
|||||||
decoded: after,
|
decoded: after,
|
||||||
metadata: metadata,
|
metadata: metadata,
|
||||||
resolution: resolution,
|
resolution: resolution,
|
||||||
sources: sources,
|
|
||||||
applications: applications,
|
applications: applications,
|
||||||
postDecodeApps: postDecodeApps,
|
postDecodeApps: postDecodeApps,
|
||||||
referenceInput: documentWithMetadataLocations(assigned.final, metadata, input.document),
|
referenceInput: documentWithMetadataLocations(assigned.final, metadata, input.document),
|
||||||
|
|||||||
@@ -72,9 +72,6 @@ func TestPostDecodeOverrideContextOrdersDecodeCLIAndResolutionEvidence(t *testin
|
|||||||
if len(prepared.applications) != 1 || len(prepared.postDecodeApps) != len(batch.overrides) || len(prepared.historyApplications()) != 1+len(batch.overrides) {
|
if len(prepared.applications) != 1 || len(prepared.postDecodeApps) != len(batch.overrides) || len(prepared.historyApplications()) != 1+len(batch.overrides) {
|
||||||
t.Fatalf("history applications = structural:%d CLI:%d all:%d", len(prepared.applications), len(prepared.postDecodeApps), len(prepared.historyApplications()))
|
t.Fatalf("history applications = structural:%d CLI:%d all:%d", len(prepared.applications), len(prepared.postDecodeApps), len(prepared.historyApplications()))
|
||||||
}
|
}
|
||||||
if len(prepared.sources) != len(sources)+len(batch.overrides) || prepared.sources[len(prepared.sources)-1].Layer != LayerCLI {
|
|
||||||
t.Fatalf("prepared source order = %#v", prepared.sources)
|
|
||||||
}
|
|
||||||
if prepared.resolution.contexts["source-1"].BaseDir != "/config" {
|
if prepared.resolution.contexts["source-1"].BaseDir != "/config" {
|
||||||
t.Fatalf("resolution source contexts = %#v", prepared.resolution.contexts)
|
t.Fatalf("resolution source contexts = %#v", prepared.resolution.contexts)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,7 +30,6 @@ func validOverlayName(name string) bool {
|
|||||||
|
|
||||||
type selectedOverlayRequest struct {
|
type selectedOverlayRequest struct {
|
||||||
name string
|
name string
|
||||||
filesystem resolvedFilesystemContext
|
|
||||||
protectionRule *VersionRule
|
protectionRule *VersionRule
|
||||||
sequencePolicy sequencePolicy
|
sequencePolicy sequencePolicy
|
||||||
limits importLimits
|
limits importLimits
|
||||||
|
|||||||
@@ -590,7 +590,7 @@ func TestLoadOverlayCountsAgainstAggregateBudgets(t *testing.T) {
|
|||||||
t.Fatal(diagnostic)
|
t.Fatal(diagnostic)
|
||||||
}
|
}
|
||||||
request := selectedOverlayRequest{
|
request := selectedOverlayRequest{
|
||||||
name: "testing", filesystem: resolved, limits: test.limits(main, len(overlayData)),
|
name: "testing", limits: test.limits(main, len(overlayData)),
|
||||||
}
|
}
|
||||||
if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil {
|
if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil {
|
||||||
t.Fatal(diagnostic)
|
t.Fatal(diagnostic)
|
||||||
|
|||||||
@@ -11,16 +11,15 @@ const (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type sequenceDeclarationSpec struct {
|
type sequenceDeclarationSpec struct {
|
||||||
path Path
|
path Path
|
||||||
location Location
|
location Location
|
||||||
destination Path
|
destination Path
|
||||||
destinationLocation Location
|
identityFields []string
|
||||||
identityFields []string
|
identityPresent bool
|
||||||
identityPresent bool
|
identityLocation *Location
|
||||||
identityLocation *Location
|
mode sequenceMode
|
||||||
mode sequenceMode
|
modePresent bool
|
||||||
modePresent bool
|
modeLocation *Location
|
||||||
modeLocation *Location
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSequenceDeclarationDirective(node *document.Node, directivePath Path) ([]sequenceDeclarationSpec, []Diagnostic) {
|
func parseSequenceDeclarationDirective(node *document.Node, directivePath Path) ([]sequenceDeclarationSpec, []Diagnostic) {
|
||||||
@@ -60,7 +59,6 @@ func parseSequenceDeclarationSpec(node *document.Node, declarationPath Path) (se
|
|||||||
return sequenceDeclarationSpec{}, []Diagnostic{*diagnostic}
|
return sequenceDeclarationSpec{}, []Diagnostic{*diagnostic}
|
||||||
}
|
}
|
||||||
declaration.destination = destination
|
declaration.destination = destination
|
||||||
declaration.destinationLocation = publicLocation(entry.Value.Location)
|
|
||||||
case "key":
|
case "key":
|
||||||
fields, locations, errIndex, valid := parseSequenceIdentityFieldSet(entry.Value)
|
fields, locations, errIndex, valid := parseSequenceIdentityFieldSet(entry.Value)
|
||||||
if !valid {
|
if !valid {
|
||||||
|
|||||||
@@ -24,14 +24,14 @@ func TestParseSequenceDeclarationPresenceAndRelativeDestination(t *testing.T) {
|
|||||||
for _, test := range tests {
|
for _, test := range tests {
|
||||||
t.Run(test.name, func(t *testing.T) {
|
t.Run(test.name, func(t *testing.T) {
|
||||||
extracted := extractSequenceDeclarationsYAML(t, "configkit:\n sequences:\n - "+test.declaration+"\n", rootDirectiveContextSource)
|
extracted := extractSequenceDeclarationsYAML(t, "configkit:\n sequences:\n - "+test.declaration+"\n", rootDirectiveContextSource)
|
||||||
if !extracted.sequencesPresent || len(extracted.sequences) != 1 {
|
if len(extracted.sequences) != 1 {
|
||||||
t.Fatalf("extraction = %#v", extracted)
|
t.Fatalf("extraction = %#v", extracted)
|
||||||
}
|
}
|
||||||
declaration := extracted.sequences[0]
|
declaration := extracted.sequences[0]
|
||||||
if declaration.destination.String() != "/prompts" || declaration.path.String() != "/configkit/sequences/0" {
|
if declaration.destination.String() != "/prompts" || declaration.path.String() != "/configkit/sequences/0" {
|
||||||
t.Fatalf("relative destination or declaration path changed: %#v", declaration)
|
t.Fatalf("relative destination or declaration path changed: %#v", declaration)
|
||||||
}
|
}
|
||||||
if declaration.location.SourceID != "sequence-declarations" || declaration.location.Line == 0 || declaration.destinationLocation.SourceID != "sequence-declarations" || declaration.destinationLocation.Line == 0 {
|
if declaration.location.SourceID != "sequence-declarations" || declaration.location.Line == 0 {
|
||||||
t.Fatalf("declaration source locations were not retained: %#v", declaration)
|
t.Fatalf("declaration source locations were not retained: %#v", declaration)
|
||||||
}
|
}
|
||||||
if declaration.identityPresent != test.wantIdentity || declaration.modePresent != test.wantMode {
|
if declaration.identityPresent != test.wantIdentity || declaration.modePresent != test.wantMode {
|
||||||
@@ -63,13 +63,13 @@ func TestParseSequenceDeclarationNormalizesEquivalentFieldSets(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestExtractRootDirectivesCombinesImportsAndSequencesWithPresence(t *testing.T) {
|
func TestExtractRootDirectivesCombinesAndRemovesImportsAndSequences(t *testing.T) {
|
||||||
extracted := extractSequenceDeclarationsYAML(t, `configkit:
|
extracted := extractSequenceDeclarationsYAML(t, `configkit:
|
||||||
imports: [{path: fragments/base.yaml}]
|
imports: [{path: fragments/base.yaml}]
|
||||||
sequences: []
|
sequences: []
|
||||||
value: true
|
value: true
|
||||||
`, rootDirectiveContextSource)
|
`, rootDirectiveContextSource)
|
||||||
if !extracted.importsPresent || len(extracted.imports) != 1 || !extracted.sequencesPresent || len(extracted.sequences) != 0 {
|
if len(extracted.imports) != 1 || len(extracted.sequences) != 0 {
|
||||||
t.Fatalf("mixed extraction = %#v", extracted)
|
t.Fatalf("mixed extraction = %#v", extracted)
|
||||||
}
|
}
|
||||||
if extracted.body == nil || extracted.body.Kind != document.Mapping || len(extracted.body.Mapping) != 1 || extracted.body.Mapping[0].Key != "value" {
|
if extracted.body == nil || extracted.body.Kind != document.Mapping || len(extracted.body.Mapping) != 1 || extracted.body.Mapping[0].Key != "value" {
|
||||||
@@ -89,7 +89,7 @@ func TestExtractRootDirectivesAllowsSequencesButRejectsOverlayImports(t *testing
|
|||||||
extracted, diagnostics := extractRootDirectives(parseRootDirectiveDocument(t, `configkit:
|
extracted, diagnostics := extractRootDirectives(parseRootDirectiveDocument(t, `configkit:
|
||||||
sequences: [{destination: [prompts], key: id}]
|
sequences: [{destination: [prompts], key: id}]
|
||||||
`), rootDirectiveContextOverlay)
|
`), rootDirectiveContextOverlay)
|
||||||
if len(diagnostics) != 0 || !extracted.sequencesPresent || len(extracted.sequences) != 1 {
|
if len(diagnostics) != 0 || len(extracted.sequences) != 1 {
|
||||||
t.Fatalf("overlay sequence extraction = %#v, %#v", extracted, diagnostics)
|
t.Fatalf("overlay sequence extraction = %#v, %#v", extracted, diagnostics)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -26,7 +26,6 @@ const (
|
|||||||
|
|
||||||
type sourceVersionAncestor struct {
|
type sourceVersionAncestor struct {
|
||||||
path Path
|
path Path
|
||||||
kind document.Kind
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type sourceVersionEvidence struct {
|
type sourceVersionEvidence struct {
|
||||||
@@ -38,8 +37,6 @@ type sourceVersionEvidence struct {
|
|||||||
version Version
|
version Version
|
||||||
location *Location
|
location *Location
|
||||||
ancestors []sourceVersionAncestor
|
ancestors []sourceVersionAncestor
|
||||||
absence sourceVersionPathAbsence
|
|
||||||
checked bool
|
|
||||||
redacted bool
|
redacted bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,7 +236,6 @@ func processSourceVersionWithDirectiveContext(root *document.Node, rule *Version
|
|||||||
evidence := &sourceVersionEvidence{
|
evidence := &sourceVersionEvidence{
|
||||||
path: rule.Path.clone(), resolvedPath: resolved.resolvedPath,
|
path: rule.Path.clone(), resolvedPath: resolved.resolvedPath,
|
||||||
destination: destination.clone(), ancestors: resolved.ancestors,
|
destination: destination.clone(), ancestors: resolved.ancestors,
|
||||||
absence: resolved.absence,
|
|
||||||
}
|
}
|
||||||
location := resolved.nearest
|
location := resolved.nearest
|
||||||
if resolved.present {
|
if resolved.present {
|
||||||
@@ -277,7 +273,6 @@ func processSourceVersionWithDirectiveContext(root *document.Node, rule *Version
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
evidence.checked = true
|
|
||||||
result.diagnostics = canonicalDiagnostics(reportVersion(rule, interpreted.version, root))
|
result.diagnostics = canonicalDiagnostics(reportVersion(rule, interpreted.version, root))
|
||||||
if hasErrors(result.diagnostics) {
|
if hasErrors(result.diagnostics) {
|
||||||
evidence.redactText()
|
evidence.redactText()
|
||||||
@@ -334,7 +329,7 @@ func resolveSourceVersionPath(root *document.Node, path Path) sourceVersionPath
|
|||||||
}
|
}
|
||||||
current := root
|
current := root
|
||||||
resolved.nearest = current.Location
|
resolved.nearest = current.Location
|
||||||
resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{kind: current.Kind})
|
resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{})
|
||||||
for position, segment := range path.segments {
|
for position, segment := range path.segments {
|
||||||
switch current.Kind {
|
switch current.Kind {
|
||||||
case document.Mapping:
|
case document.Mapping:
|
||||||
@@ -373,7 +368,7 @@ func resolveSourceVersionPath(root *document.Node, path Path) sourceVersionPath
|
|||||||
}
|
}
|
||||||
resolved.nearest = current.Location
|
resolved.nearest = current.Location
|
||||||
resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{
|
resolved.ancestors = append(resolved.ancestors, sourceVersionAncestor{
|
||||||
path: Path{segments: clonePathSegments(resolved.resolvedPath.segments[:position+1], 0)}, kind: current.Kind,
|
path: Path{segments: clonePathSegments(resolved.resolvedPath.segments[:position+1], 0)},
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
resolved.node = current
|
resolved.node = current
|
||||||
|
|||||||
@@ -217,7 +217,7 @@ func TestSourceVersionExtractionPreservesVersionVocabulary(t *testing.T) {
|
|||||||
return nil
|
return nil
|
||||||
}}
|
}}
|
||||||
result := processSourceVersion(root, rule, sourceVersionContribution, Keys("collections", "weather"), sourceVersionModeIfPresent)
|
result := processSourceVersion(root, rule, sourceVersionContribution, Keys("collections", "weather"), sourceVersionModeIfPresent)
|
||||||
if len(result.diagnostics) != 0 || !result.evidence.checked || result.evidence.version != test.want || checked != test.want {
|
if len(result.diagnostics) != 0 || result.evidence.version != test.want || checked != test.want {
|
||||||
t.Fatalf("result = %#v, checked = %#v", result, checked)
|
t.Fatalf("result = %#v, checked = %#v", result, checked)
|
||||||
}
|
}
|
||||||
if _, found := documentAtPath(result.payload, rule.Path); found {
|
if _, found := documentAtPath(result.payload, rule.Path); found {
|
||||||
@@ -245,35 +245,34 @@ func TestSourceVersionExtractionHandlesMissingAndMalformedValues(t *testing.T) {
|
|||||||
wantCode Code
|
wantCode Code
|
||||||
wantPresent bool
|
wantPresent bool
|
||||||
wantCallback bool
|
wantCallback bool
|
||||||
wantAbsence sourceVersionPathAbsence
|
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "missing mapping member is optional absence", input: "settings: {}\n",
|
name: "missing mapping member is optional absence", input: "settings: {}\n",
|
||||||
path: Keys("settings", "version"), mode: sourceVersionModeIfPresent,
|
path: Keys("settings", "version"), mode: sourceVersionModeIfPresent,
|
||||||
role: sourceVersionContribution, wantPresent: false, wantAbsence: sourceVersionMemberMissing,
|
role: sourceVersionContribution, wantPresent: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "missing below scalar is optional absence", input: "settings: scalar\n",
|
name: "missing below scalar is optional absence", input: "settings: scalar\n",
|
||||||
path: Keys("settings", "version"), mode: sourceVersionModeIfPresent,
|
path: Keys("settings", "version"), mode: sourceVersionModeIfPresent,
|
||||||
role: sourceVersionContribution, wantPresent: false, wantAbsence: sourceVersionPathObstructed,
|
role: sourceVersionContribution, wantPresent: false,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "required absence reports nearest location", input: "settings: scalar\n",
|
name: "required absence reports nearest location", input: "settings: scalar\n",
|
||||||
path: Keys("settings", "version"), mode: sourceVersionModeRequired,
|
path: Keys("settings", "version"), mode: sourceVersionModeRequired,
|
||||||
role: sourceVersionContribution, wantCode: CodeVersionError, wantAbsence: sourceVersionPathObstructed,
|
role: sourceVersionContribution, wantCode: CodeVersionError,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unavailable sequence index is absence", input: "versions: [1]\n",
|
name: "unavailable sequence index is absence", input: "versions: [1]\n",
|
||||||
path: Keys("versions").Index(3), mode: sourceVersionModeRequired,
|
path: Keys("versions").Index(3), mode: sourceVersionModeRequired,
|
||||||
role: sourceVersionContribution, wantCode: CodeVersionError, wantAbsence: sourceVersionIndexUnavailable,
|
role: sourceVersionContribution, wantCode: CodeVersionError,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "required actual main absence", input: "name: demo\n", path: Keys("version"),
|
name: "required actual main absence", input: "name: demo\n", path: Keys("version"),
|
||||||
mode: sourceVersionModeRequired, role: sourceVersionMain, wantCode: CodeVersionError, wantAbsence: sourceVersionMemberMissing,
|
mode: sourceVersionModeRequired, role: sourceVersionMain, wantCode: CodeVersionError,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "main optional absence invokes checker", input: "name: demo\n", path: Keys("version"),
|
name: "main optional absence invokes checker", input: "name: demo\n", path: Keys("version"),
|
||||||
mode: sourceVersionModeIfPresent, role: sourceVersionMain, wantCallback: true, wantAbsence: sourceVersionMemberMissing,
|
mode: sourceVersionModeIfPresent, role: sourceVersionMain, wantCallback: true,
|
||||||
},
|
},
|
||||||
{name: "boolean", input: "version: true\n", path: Keys("version"), mode: sourceVersionModeIfPresent, role: sourceVersionContribution, wantCode: CodeVersionType, wantPresent: true},
|
{name: "boolean", input: "version: true\n", path: Keys("version"), mode: sourceVersionModeIfPresent, role: sourceVersionContribution, wantCode: CodeVersionType, wantPresent: true},
|
||||||
{name: "fraction", input: "version: 4.5\n", path: Keys("version"), mode: sourceVersionModeIfPresent, role: sourceVersionContribution, wantCode: CodeVersionType, wantPresent: true},
|
{name: "fraction", input: "version: 4.5\n", path: Keys("version"), mode: sourceVersionModeIfPresent, role: sourceVersionContribution, wantCode: CodeVersionType, wantPresent: true},
|
||||||
@@ -307,15 +306,9 @@ func TestSourceVersionExtractionHandlesMissingAndMalformedValues(t *testing.T) {
|
|||||||
if result.evidence == nil || result.evidence.version.Present != test.wantPresent {
|
if result.evidence == nil || result.evidence.version.Present != test.wantPresent {
|
||||||
t.Fatalf("evidence = %#v", result.evidence)
|
t.Fatalf("evidence = %#v", result.evidence)
|
||||||
}
|
}
|
||||||
if result.evidence.absence != test.wantAbsence {
|
|
||||||
t.Fatalf("absence cause = %v, want %v", result.evidence.absence, test.wantAbsence)
|
|
||||||
}
|
|
||||||
if test.wantCode == CodeVersionType && (!result.evidence.redacted || result.evidence.version.Text != "") {
|
if test.wantCode == CodeVersionType && (!result.evidence.redacted || result.evidence.version.Text != "") {
|
||||||
t.Fatalf("malformed value was retained: %#v", result.evidence)
|
t.Fatalf("malformed value was retained: %#v", result.evidence)
|
||||||
}
|
}
|
||||||
if !test.wantCallback && result.evidence.checked {
|
|
||||||
t.Fatalf("evidence incorrectly records a callback: %#v", result.evidence)
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,7 +332,7 @@ func TestSourceVersionExtractionConsumesOnlySelectedNodes(t *testing.T) {
|
|||||||
if original, found := documentAtPath(root, Keys("settings", "version")); !found || original.Text != "8" {
|
if original, found := documentAtPath(root, Keys("settings", "version")); !found || original.Text != "8" {
|
||||||
t.Fatalf("original source changed: %#v, found %v", original, found)
|
t.Fatalf("original source changed: %#v, found %v", original, found)
|
||||||
}
|
}
|
||||||
if len(result.evidence.ancestors) != 3 || result.evidence.ancestors[1].kind != document.Mapping {
|
if len(result.evidence.ancestors) != 3 || result.evidence.ancestors[1].path.String() != "/settings" || result.evidence.ancestors[2].path.String() != "/settings/version" {
|
||||||
t.Fatalf("ancestor shape = %#v", result.evidence.ancestors)
|
t.Fatalf("ancestor shape = %#v", result.evidence.ancestors)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1492,7 +1485,7 @@ func TestSourceVersionOverlayProtectsMountedMainAndPreservesSequenceCoordinates(
|
|||||||
t.Fatalf("resolve overlay context: %#v", diagnostic)
|
t.Fatalf("resolve overlay context: %#v", diagnostic)
|
||||||
}
|
}
|
||||||
request := selectedOverlayRequest{
|
request := selectedOverlayRequest{
|
||||||
name: "testing", filesystem: resolved, protectionRule: effectiveRule,
|
name: "testing", protectionRule: effectiveRule,
|
||||||
limits: defaultImportLimits(), versionState: state,
|
limits: defaultImportLimits(), versionState: state,
|
||||||
}
|
}
|
||||||
if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil {
|
if diagnostic := validateResolvedFilesystemDirectories(resolved); diagnostic != nil {
|
||||||
@@ -1544,7 +1537,7 @@ func TestSourceVersionImportAccountingIncludesConsumedHeaderNodes(t *testing.T)
|
|||||||
if len(foundDiagnostics) != 0 || composed == nil || len(sources) != 2 || accounting.nodes != wantNodes || accounting.bytes != wantBytes {
|
if len(foundDiagnostics) != 0 || composed == nil || len(sources) != 2 || accounting.nodes != wantNodes || accounting.bytes != wantBytes {
|
||||||
t.Fatalf("exact raw byte/node accounting = %#v, %d/%d, want %d/%d, %#v", composed, accounting.bytes, accounting.nodes, wantBytes, wantNodes, foundDiagnostics)
|
t.Fatalf("exact raw byte/node accounting = %#v, %d/%d, want %d/%d, %#v", composed, accounting.bytes, accounting.nodes, wantBytes, wantNodes, foundDiagnostics)
|
||||||
}
|
}
|
||||||
if len(state.evidence) != 1 || state.evidence[0].sourceID != "source-2" || !state.evidence[0].checked || state.evidence[0].version.Text != "accepted" {
|
if len(state.evidence) != 1 || state.evidence[0].sourceID != "source-2" || state.evidence[0].version.Text != "accepted" {
|
||||||
t.Fatalf("acquired child evidence = %#v", state.evidence)
|
t.Fatalf("acquired child evidence = %#v", state.evidence)
|
||||||
}
|
}
|
||||||
if _, present := documentAtPath(composed.root, Keys("version")); present {
|
if _, present := documentAtPath(composed.root, Keys("version")); present {
|
||||||
|
|||||||
Reference in New Issue
Block a user