Skip to content

Commit

Permalink
duplication is not an error
Browse files Browse the repository at this point in the history
  • Loading branch information
letFunny committed Aug 5, 2024
1 parent f41c82b commit 48d58ee
Show file tree
Hide file tree
Showing 2 changed files with 119 additions and 106 deletions.
7 changes: 3 additions & 4 deletions internal/manifest/manifest.go
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,6 @@ func Validate(manifest *Manifest) (err error) {
return err
}

// TODO duplicated should not be a problem, here an in delete below.
pathToSlices := map[string][]string{}
err = manifest.IterateContents("", func(content Content) error {
if !sliceExist[content.Slice] {
Expand All @@ -145,6 +144,7 @@ func Validate(manifest *Manifest) (err error) {
return err
}

done := map[string]bool{}
err = manifest.IteratePaths("", func(path Path) error {
pathSlices, ok := pathToSlices[path.Path]
if !ok {
Expand All @@ -155,15 +155,14 @@ func Validate(manifest *Manifest) (err error) {
if !slices.Equal(pathSlices, path.Slices) {
return fmt.Errorf(`path %s and content have diverging slices: %q != %q`, path.Path, path.Slices, pathSlices)
}
// TODO This disallows duplicates.
delete(pathToSlices, path.Path)
done[path.Path] = true
return nil
})
if err != nil {
return err
}

if len(pathToSlices) > 0 {
if len(done) != len(pathToSlices) {
for path := range pathToSlices {
return fmt.Errorf(`content path %s has no matching entry in paths`, path)
}
Expand Down
218 changes: 116 additions & 102 deletions internal/manifest/manifest_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,108 +22,120 @@ type manifestContents struct {
var manifestTests = []struct {
summary string
input string
mfest manifestContents
mfest *manifestContents
valError string
readError string
}{
{
summary: "All types",
input: `
{"jsonwall":"1.0","schema":"1.0","count":13}
{"kind":"content","slice":"pkg1_manifest","path":"/manifest/manifest.wall"}
{"kind":"content","slice":"pkg1_myslice","path":"/dir/file"}
{"kind":"content","slice":"pkg1_myslice","path":"/dir/foo/bar/"}
{"kind":"content","slice":"pkg1_myslice","path":"/dir/link/file"}
{"kind":"content","slice":"pkg2_myotherslice","path":"/dir/foo/bar/"}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
{"kind":"package","name":"pkg2","version":"v2","sha256":"hash2","arch":"arch2"}
{"kind":"path","path":"/dir/file","mode":"0644","slices":["pkg1_myslice"],"sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","final_sha256":"8067926c032c090867013d14fb0eb21ae858344f62ad07086fd32375845c91a6","size":21}
{"kind":"path","path":"/dir/foo/bar/","mode":"01777","slices":["pkg2_myotherslice","pkg1_myslice"]}
{"kind":"path","path":"/dir/link/file","mode":"0644","slices":["pkg1_myslice"],"link":"/dir/file"}
{"kind":"path","path":"/manifest/manifest.wall","mode":"0644","slices":["pkg1_manifest"]}
{"kind":"slice","name":"pkg1_manifest"}
{"kind":"slice","name":"pkg1_myslice"}
{"kind":"slice","name":"pkg2_myotherslice"}
`,
mfest: manifestContents{
Paths: []manifest.Path{
{Kind: "path", Path: "/dir/file", Mode: "0644", Slices: []string{"pkg1_myslice"}, Hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", FinalHash: "8067926c032c090867013d14fb0eb21ae858344f62ad07086fd32375845c91a6", Size: 0x15, Link: ""},
{Kind: "path", Path: "/dir/foo/bar/", Mode: "01777", Slices: []string{"pkg2_myotherslice", "pkg1_myslice"}, Hash: "", FinalHash: "", Size: 0x0, Link: ""},
{Kind: "path", Path: "/dir/link/file", Mode: "0644", Slices: []string{"pkg1_myslice"}, Hash: "", FinalHash: "", Size: 0x0, Link: "/dir/file"},
{Kind: "path", Path: "/manifest/manifest.wall", Mode: "0644", Slices: []string{"pkg1_manifest"}, Hash: "", FinalHash: "", Size: 0x0, Link: ""},
},
Packages: []manifest.Package{
{Kind: "package", Name: "pkg1", Version: "v1", Digest: "hash1", Arch: "arch1"},
{Kind: "package", Name: "pkg2", Version: "v2", Digest: "hash2", Arch: "arch2"},
},
Slices: []manifest.Slice{
{Kind: "slice", Name: "pkg1_manifest"},
{Kind: "slice", Name: "pkg1_myslice"},
{Kind: "slice", Name: "pkg2_myotherslice"},
},
Contents: []manifest.Content{
{Kind: "content", Slice: "pkg1_manifest", Path: "/manifest/manifest.wall"},
{Kind: "content", Slice: "pkg1_myslice", Path: "/dir/file"},
{Kind: "content", Slice: "pkg1_myslice", Path: "/dir/foo/bar/"},
{Kind: "content", Slice: "pkg1_myslice", Path: "/dir/link/file"},
{Kind: "content", Slice: "pkg2_myotherslice", Path: "/dir/foo/bar/"},
},
}{{
summary: "All types",
input: `
{"jsonwall":"1.0","schema":"1.0","count":13}
{"kind":"content","slice":"pkg1_manifest","path":"/manifest/manifest.wall"}
{"kind":"content","slice":"pkg1_myslice","path":"/dir/file"}
{"kind":"content","slice":"pkg1_myslice","path":"/dir/foo/bar/"}
{"kind":"content","slice":"pkg1_myslice","path":"/dir/link/file"}
{"kind":"content","slice":"pkg2_myotherslice","path":"/dir/foo/bar/"}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
{"kind":"package","name":"pkg2","version":"v2","sha256":"hash2","arch":"arch2"}
{"kind":"path","path":"/dir/file","mode":"0644","slices":["pkg1_myslice"],"sha256":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","final_sha256":"8067926c032c090867013d14fb0eb21ae858344f62ad07086fd32375845c91a6","size":21}
{"kind":"path","path":"/dir/foo/bar/","mode":"01777","slices":["pkg2_myotherslice","pkg1_myslice"]}
{"kind":"path","path":"/dir/link/file","mode":"0644","slices":["pkg1_myslice"],"link":"/dir/file"}
{"kind":"path","path":"/manifest/manifest.wall","mode":"0644","slices":["pkg1_manifest"]}
{"kind":"slice","name":"pkg1_manifest"}
{"kind":"slice","name":"pkg1_myslice"}
{"kind":"slice","name":"pkg2_myotherslice"}
`,
mfest: &manifestContents{
Paths: []manifest.Path{
{Kind: "path", Path: "/dir/file", Mode: "0644", Slices: []string{"pkg1_myslice"}, Hash: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", FinalHash: "8067926c032c090867013d14fb0eb21ae858344f62ad07086fd32375845c91a6", Size: 0x15, Link: ""},
{Kind: "path", Path: "/dir/foo/bar/", Mode: "01777", Slices: []string{"pkg2_myotherslice", "pkg1_myslice"}, Hash: "", FinalHash: "", Size: 0x0, Link: ""},
{Kind: "path", Path: "/dir/link/file", Mode: "0644", Slices: []string{"pkg1_myslice"}, Hash: "", FinalHash: "", Size: 0x0, Link: "/dir/file"},
{Kind: "path", Path: "/manifest/manifest.wall", Mode: "0644", Slices: []string{"pkg1_manifest"}, Hash: "", FinalHash: "", Size: 0x0, Link: ""},
},
}, {
summary: "Slice not found",
input: `
{"jsonwall":"1.0","schema":"1.0","count":1}
{"kind":"content","slice":"pkg1_manifest","path":"/manifest/manifest.wall"}
`,
valError: `invalid manifest: slice pkg1_manifest not found in slices`,
}, {
summary: "Package not found",
input: `
{"jsonwall":"1.0","schema":"1.0","count":1}
{"kind":"slice","name":"pkg1_manifest"}
`,
valError: `invalid manifest: package "pkg1" not found in packages`,
}, {
summary: "Path not found in contents",
input: `
{"jsonwall":"1.0","schema":"1.0","count":1}
{"kind":"path","path":"/dir/","mode":"01777","slices":["pkg1_myslice"]}
`,
valError: `invalid manifest: path /dir/ has no matching entry in contents`,
}, {
summary: "Content and path have different slices",
input: `
{"jsonwall":"1.0","schema":"1.0","count":3}
{"kind":"content","slice":"pkg1_myotherslice","path":"/dir/"}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
{"kind":"path","path":"/dir/","mode":"01777","slices":["pkg1_myslice"]}
{"kind":"slice","name":"pkg1_myotherslice"}
`,
valError: `invalid manifest: path /dir/ and content have diverging slices: \["pkg1_myslice"\] != \["pkg1_myotherslice"\]`,
}, {
summary: "Content not found in paths",
input: `
{"jsonwall":"1.0","schema":"1.0","count":3}
{"kind":"content","slice":"pkg1_myslice","path":"/dir/"}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
{"kind":"slice","name":"pkg1_myslice"}
`,
valError: `invalid manifest: content path /dir/ has no matching entry in paths`,
}, {
summary: "Malformed jsonwall",
input: `
{"jsonwall":"1.0","schema":"1.0","count":1}
{"kind":"content", "not valid json"
`,
valError: `invalid manifest: cannot read manifest: unexpected end of JSON input`,
}, {
summary: "Unknown schema",
input: `
{"jsonwall":"1.0","schema":"2.0","count":1}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
`,
readError: `cannot read manifest: unknown schema version "2.0"`,
}}
Packages: []manifest.Package{
{Kind: "package", Name: "pkg1", Version: "v1", Digest: "hash1", Arch: "arch1"},
{Kind: "package", Name: "pkg2", Version: "v2", Digest: "hash2", Arch: "arch2"},
},
Slices: []manifest.Slice{
{Kind: "slice", Name: "pkg1_manifest"},
{Kind: "slice", Name: "pkg1_myslice"},
{Kind: "slice", Name: "pkg2_myotherslice"},
},
Contents: []manifest.Content{
{Kind: "content", Slice: "pkg1_manifest", Path: "/manifest/manifest.wall"},
{Kind: "content", Slice: "pkg1_myslice", Path: "/dir/file"},
{Kind: "content", Slice: "pkg1_myslice", Path: "/dir/foo/bar/"},
{Kind: "content", Slice: "pkg1_myslice", Path: "/dir/link/file"},
{Kind: "content", Slice: "pkg2_myotherslice", Path: "/dir/foo/bar/"},
},
},
}, {
summary: "Slice not found",
input: `
{"jsonwall":"1.0","schema":"1.0","count":1}
{"kind":"content","slice":"pkg1_manifest","path":"/manifest/manifest.wall"}
`,
valError: `invalid manifest: slice pkg1_manifest not found in slices`,
}, {
summary: "Package not found",
input: `
{"jsonwall":"1.0","schema":"1.0","count":1}
{"kind":"slice","name":"pkg1_manifest"}
`,
valError: `invalid manifest: package "pkg1" not found in packages`,
}, {
summary: "Path not found in contents",
input: `
{"jsonwall":"1.0","schema":"1.0","count":1}
{"kind":"path","path":"/dir/","mode":"01777","slices":["pkg1_myslice"]}
`,
valError: `invalid manifest: path /dir/ has no matching entry in contents`,
}, {
summary: "Content and path have different slices",
input: `
{"jsonwall":"1.0","schema":"1.0","count":3}
{"kind":"content","slice":"pkg1_myotherslice","path":"/dir/"}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
{"kind":"path","path":"/dir/","mode":"01777","slices":["pkg1_myslice"]}
{"kind":"slice","name":"pkg1_myotherslice"}
`,
valError: `invalid manifest: path /dir/ and content have diverging slices: \["pkg1_myslice"\] != \["pkg1_myotherslice"\]`,
}, {
summary: "Content not found in paths",
input: `
{"jsonwall":"1.0","schema":"1.0","count":3}
{"kind":"content","slice":"pkg1_myslice","path":"/dir/"}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
{"kind":"slice","name":"pkg1_myslice"}
`,
valError: `invalid manifest: content path /dir/ has no matching entry in paths`,
}, {
summary: "Malformed jsonwall",
input: `
{"jsonwall":"1.0","schema":"1.0","count":1}
{"kind":"content", "not valid json"
`,
valError: `invalid manifest: cannot read manifest: unexpected end of JSON input`,
}, {
summary: "Unknown schema",
input: `
{"jsonwall":"1.0","schema":"2.0","count":1}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
`,
readError: `cannot read manifest: unknown schema version "2.0"`,
}, {
summary: "Duplication is not an error",
input: `
{"jsonwall":"1.0","schema":"1.0","count":8}
{"kind":"content","slice":"pkg1_manifest","path":"/manifest/manifest.wall"}
{"kind":"content","slice":"pkg1_manifest","path":"/manifest/manifest.wall"}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
{"kind":"package","name":"pkg1","version":"v1","sha256":"hash1","arch":"arch1"}
{"kind":"path","path":"/manifest/manifest.wall","mode":"0644","slices":["pkg1_manifest"]}
{"kind":"path","path":"/manifest/manifest.wall","mode":"0644","slices":["pkg1_manifest"]}
{"kind":"slice","name":"pkg1_manifest"}
{"kind":"slice","name":"pkg1_manifest"}
`,
}}

func (s *S) TestRun(c *C) {
for _, test := range manifestTests {
Expand Down Expand Up @@ -164,11 +176,13 @@ func (s *S) TestRun(c *C) {
continue
}
c.Assert(err, IsNil)
c.Assert(dumpManifestContents(c, mfest), DeepEquals, test.mfest)
if test.mfest != nil {
c.Assert(dumpManifestContents(c, mfest), DeepEquals, test.mfest)
}
}
}

func dumpManifestContents(c *C, mfest *manifest.Manifest) manifestContents {
func dumpManifestContents(c *C, mfest *manifest.Manifest) *manifestContents {
var slices []manifest.Slice
err := mfest.IterateSlices("", func(slice manifest.Slice) error {
slices = append(slices, slice)
Expand Down Expand Up @@ -203,5 +217,5 @@ func dumpManifestContents(c *C, mfest *manifest.Manifest) manifestContents {
Slices: slices,
Contents: contents,
}
return mc
return &mc
}

0 comments on commit 48d58ee

Please sign in to comment.