Project version protections through item placement
This commit is contained in:
@@ -37,6 +37,40 @@ func TestSourceVersionAbsentPathKeepsUnresolvedSegmentIntent(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestFragmentVersionClaimUsesAssignedSequenceProjection(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
fragment := sourceVersionTestDocument(t, "items: [{version: v1}]\n")
|
||||
rangeForPeer := []sequenceRange{{sourceIndex: 1, path: Keys("items"), start: 1, end: 2}}
|
||||
if node := fragmentVersionClaimProjected(fragment, &VersionRule{Path: Keys("items").Index(0).Key("version")}, 1, rangeForPeer); node != nil {
|
||||
t.Fatalf("peer append claimed main index 0: %#v", node)
|
||||
}
|
||||
if node := fragmentVersionClaimProjected(fragment, &VersionRule{Path: Keys("items").Index(1).Key("version")}, 1, rangeForPeer); node == nil || node.Text != "v1" {
|
||||
t.Fatalf("assigned peer index 1 claim = %#v, want its version node", node)
|
||||
}
|
||||
nested := sourceVersionTestDocument(t, "items: [{nested: [{version: nested-v}]}]\n")
|
||||
nestedRanges := []sequenceRange{
|
||||
{sourceIndex: 1, path: Keys("items"), start: 1, end: 2},
|
||||
{sourceIndex: 1, path: Keys("items").Index(0).Key("nested"), start: 2, end: 3},
|
||||
}
|
||||
if node := fragmentVersionClaimProjected(nested, &VersionRule{Path: Keys("items").Index(1).Key("nested").Index(2).Key("version")}, 1, nestedRanges); node == nil || node.Text != "nested-v" {
|
||||
t.Fatalf("nested assigned claim = %#v, want nested version", node)
|
||||
}
|
||||
ancestor := sourceVersionTestDocument(t, "items: {version: replacement}\n")
|
||||
if node := fragmentVersionClaim(ancestor, &VersionRule{Path: Keys("items").Index(0).Key("version")}); node == nil || node.Kind != document.Mapping {
|
||||
t.Fatalf("destructive sequence ancestor claim = %#v, want mapping node", node)
|
||||
}
|
||||
|
||||
effective := effectiveSourceVersionRuleForPlacement(&VersionRule{Path: Keys("version")}, Keys("catalog", "entries"), sourceVersionModeRequired, placementModeSequenceItem)
|
||||
if got, want := effective.Path.String(), "/catalog/entries/0/version"; got != want {
|
||||
t.Fatalf("item effective version path = %q, want %q", got, want)
|
||||
}
|
||||
defaultRule := effectiveSourceVersionRuleForPlacement(&VersionRule{Path: Keys("version")}, Keys("catalog", "entries"), sourceVersionModeDefault, placementModeSequenceItem)
|
||||
if got, want := defaultRule.Path.String(), "/version"; got != want {
|
||||
t.Fatalf("default effective version path = %q, want %q", got, want)
|
||||
}
|
||||
}
|
||||
|
||||
type sourceVersionMountedService struct {
|
||||
Version string `yaml:"version"`
|
||||
}
|
||||
@@ -473,6 +507,83 @@ func TestSourceVersionLoadChecksMountedMainLocallyAndProtectsEffectivePath(t *te
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceVersionItemPlacementKeepsLocalChecksAndProtectsProjectedPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
for _, test := range []struct {
|
||||
name string
|
||||
load func(Definition[map[string]any]) error
|
||||
}{
|
||||
{
|
||||
name: "ordinary",
|
||||
load: func(definition Definition[map[string]any]) error {
|
||||
_, err := Load(Mapping("main", map[string]any{"version": "v1", "name": "ordinary"}), testSecretBinding(), Options[map[string]any]{
|
||||
Definition: definition, SourceVersionMode: sourceVersionModeRequired,
|
||||
destination: Keys("catalog", "entries"), placementMode: placementModeSequenceItem,
|
||||
Overrides: []Override{{Path: Keys("catalog", "entries"), Value: []any{}, Flag: "--entries"}},
|
||||
})
|
||||
return err
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "layered",
|
||||
load: func(definition Definition[map[string]any]) error {
|
||||
_, err := LoadLayered(Input{Source: Mapping("main", map[string]any{"version": "v1", "name": "layered"}), Destination: Keys("catalog", "entries"), placementMode: placementModeSequenceItem}, testSecretBinding(), LayeredOptions[map[string]any]{
|
||||
Definition: definition, SourceVersionMode: sourceVersionModeRequired,
|
||||
Overrides: []Override{{Path: Keys("catalog", "entries"), Value: []any{}, Flag: "--entries"}},
|
||||
})
|
||||
return err
|
||||
},
|
||||
},
|
||||
} {
|
||||
t.Run(test.name, func(t *testing.T) {
|
||||
t.Parallel()
|
||||
checks := 0
|
||||
definition := Definition[map[string]any]{Version: &VersionRule{
|
||||
Path: Keys("version"),
|
||||
Check: func(version Version, _ *Validation) error {
|
||||
checks++
|
||||
if !version.Present || version.Text != "v1" {
|
||||
t.Errorf("source-local version = %#v, want v1", version)
|
||||
}
|
||||
return nil
|
||||
},
|
||||
}}
|
||||
err := test.load(definition)
|
||||
var loadErr *LoadError
|
||||
if !errors.As(err, &loadErr) {
|
||||
t.Fatalf("item placement override error = %T %v, want *LoadError", err, err)
|
||||
}
|
||||
requireSourceVersionDiagnostic(t, loadErr.Diagnostics(), CodeOverrideVersion, "/catalog/entries")
|
||||
if checks != 1 {
|
||||
t.Fatalf("source-version checker called %d times, want once", checks)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceVersionItemEvidenceUsesProjectedSensitivityPath(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
const canary = "PROJECTED-VERSION-EVIDENCE-CANARY"
|
||||
secretPath := Keys("catalog", "entries").Index(0).Key("version")
|
||||
loaded, err := Load(Mapping("main", map[string]any{"version": canary}), testSecretBinding(), Options[map[string]any]{
|
||||
Definition: Definition[map[string]any]{
|
||||
Version: &VersionRule{Path: Keys("version"), Check: func(Version, *Validation) error { return nil }},
|
||||
Secret: func(path Path) bool { return path.String() == secretPath.String() },
|
||||
},
|
||||
SourceVersionMode: sourceVersionModeRequired,
|
||||
destination: Keys("catalog", "entries"), placementMode: placementModeSequenceItem,
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("item source-version load: %v", err)
|
||||
}
|
||||
sources := loaded.Inspection.Sources()
|
||||
if len(sources) != 1 || sources[0].VersionCheck == nil || !sources[0].VersionCheck.Redacted || sources[0].VersionCheck.Version.Text != "" {
|
||||
t.Fatalf("projected source-version evidence was not redacted: %#v", sources)
|
||||
}
|
||||
}
|
||||
|
||||
func TestSourceVersionLoadChecksNullAndNoSourceMain(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user