summaryrefslogtreecommitdiffstats
path: root/util/util_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'util/util_test.go')
-rw-r--r--util/util_test.go282
1 files changed, 282 insertions, 0 deletions
diff --git a/util/util_test.go b/util/util_test.go
new file mode 100644
index 0000000..ca691ef
--- /dev/null
+++ b/util/util_test.go
@@ -0,0 +1,282 @@
+package util
+
+import (
+ "bytes"
+ "crypto/sha256"
+ "crypto/sha512"
+ "encoding/hex"
+ "hash"
+ "testing"
+
+ "github.com/theupdateframework/go-tuf/data"
+ . "gopkg.in/check.v1"
+)
+
+// Hook up gocheck into the "go test" runner.
+func Test(t *testing.T) { TestingT(t) }
+
+type UtilSuite struct{}
+
+var _ = Suite(&UtilSuite{})
+
+func (UtilSuite) TestGenerateTargetFileMetaDefault(c *C) {
+ // default is sha512
+ r := bytes.NewReader([]byte("foo"))
+ meta, err := GenerateTargetFileMeta(r)
+ c.Assert(err, IsNil)
+ c.Assert(meta.Length, Equals, int64(3))
+ hashes := meta.Hashes
+ c.Assert(hashes, HasLen, 1)
+ hash, ok := hashes["sha512"]
+ if !ok {
+ c.Fatal("missing sha512 hash")
+ }
+ c.Assert(hash.String(), DeepEquals, "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
+}
+
+func (UtilSuite) TestGenerateTargetFileMetaExplicit(c *C) {
+ r := bytes.NewReader([]byte("foo"))
+ meta, err := GenerateTargetFileMeta(r, "sha256", "sha512")
+ c.Assert(err, IsNil)
+ c.Assert(meta.Length, Equals, int64(3))
+ hashes := meta.Hashes
+ c.Assert(hashes, HasLen, 2)
+ for name, val := range map[string]string{
+ "sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
+ "sha512": "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7",
+ } {
+ hash, ok := hashes[name]
+ if !ok {
+ c.Fatalf("missing %s hash", name)
+ }
+ c.Assert(hash.String(), DeepEquals, val)
+ }
+}
+
+func makeHashes(c *C, hashes map[string]string) data.Hashes {
+ h := make(map[string]data.HexBytes, len(hashes))
+ for typ, hash := range hashes {
+ v, err := hex.DecodeString(hash)
+ c.Assert(err, IsNil)
+ h[typ] = v
+ }
+ return h
+}
+
+type testMetaFile struct {
+ name string
+ actual data.FileMeta
+ expected data.FileMeta
+ err func(testMetaFile) error
+}
+
+func testMetaFileCases(c *C) []testMetaFile {
+ fileMeta := func(c *C, length int64, hashes map[string]string) data.FileMeta {
+ return data.FileMeta{
+ Length: length,
+ Hashes: makeHashes(c, hashes),
+ }
+ }
+
+ return []testMetaFile{
+ {
+ name: "wrong length",
+ actual: data.FileMeta{Length: 1},
+ expected: data.FileMeta{Length: 2},
+ err: func(testMetaFile) error { return ErrWrongLength{Actual: 1, Expected: 2} },
+ },
+ {
+ name: "wrong sha512 hash",
+ actual: fileMeta(c, 10, map[string]string{"sha512": "111111"}),
+ expected: fileMeta(c, 10, map[string]string{"sha512": "222222"}),
+ err: func(t testMetaFile) error {
+ return ErrWrongHash{"sha512", t.expected.Hashes["sha512"], t.actual.Hashes["sha512"]}
+ },
+ },
+ {
+ name: "intersecting hashes",
+ actual: fileMeta(c, 10, map[string]string{"sha512": "111111", "md5": "222222"}),
+ expected: fileMeta(c, 10, map[string]string{"sha512": "111111", "sha256": "333333"}),
+ err: func(testMetaFile) error { return nil },
+ },
+ {
+ name: "no common hashes",
+ actual: fileMeta(c, 10, map[string]string{"sha512": "111111"}),
+ expected: fileMeta(c, 10, map[string]string{"sha256": "222222", "md5": "333333"}),
+ err: func(t testMetaFile) error { return ErrNoCommonHash{t.expected.Hashes, t.actual.Hashes} },
+ },
+ }
+}
+
+func (UtilSuite) TestSnapshotFileMetaEqual(c *C) {
+ type test struct {
+ name string
+ actual data.SnapshotFileMeta
+ expected data.SnapshotFileMeta
+ err func(test) error
+ }
+
+ fileMeta := func(version int64, length int64, hashes map[string]string) data.SnapshotFileMeta {
+ return data.SnapshotFileMeta{
+ Length: length,
+ Hashes: makeHashes(c, hashes),
+ Version: version,
+ }
+ }
+
+ tests := []test{
+ {
+ name: "same version",
+ actual: fileMeta(1, 10, map[string]string{"sha512": "111111"}),
+ expected: fileMeta(1, 10, map[string]string{"sha512": "111111"}),
+ err: func(test) error { return nil },
+ },
+ {
+ name: "wrong version",
+ actual: fileMeta(0, 10, map[string]string{"sha512": "111111"}),
+ expected: fileMeta(1, 10, map[string]string{"sha512": "111111"}),
+ err: func(test) error { return ErrWrongVersion{Expected: 1, Actual: 0} },
+ },
+ {
+ name: "wrong version",
+ actual: fileMeta(1, 10, map[string]string{"sha512": "111111"}),
+ expected: fileMeta(0, 10, map[string]string{"sha512": "111111"}),
+ err: func(test) error { return ErrWrongVersion{Expected: 0, Actual: 1} },
+ },
+ {
+ name: "wrong version",
+ actual: fileMeta(1, 10, map[string]string{"sha512": "111111"}),
+ expected: fileMeta(2, 10, map[string]string{"sha512": "111111"}),
+ err: func(test) error { return ErrWrongVersion{Expected: 2, Actual: 1} },
+ },
+ }
+
+ for _, t := range tests {
+ c.Assert(SnapshotFileMetaEqual(t.actual, t.expected), DeepEquals, t.err(t), Commentf("name = %s", t.name))
+ }
+
+ for _, t := range testMetaFileCases(c) {
+ actual := data.SnapshotFileMeta{Length: t.actual.Length, Hashes: t.actual.Hashes}
+ expected := data.SnapshotFileMeta{Length: t.expected.Length, Hashes: t.expected.Hashes}
+ c.Assert(SnapshotFileMetaEqual(actual, expected), DeepEquals, t.err(t), Commentf("name = %s %d %d", t.name, t.actual.Length, t.expected.Length))
+ c.Assert(FileMetaEqual(t.actual, t.expected), DeepEquals, t.err(t), Commentf("name = %s", t.name))
+ }
+}
+
+func (UtilSuite) TestNormalizeTarget(c *C) {
+ for before, after := range map[string]string{
+ "": "",
+ "foo.txt": "foo.txt",
+ "/bar.txt": "bar.txt",
+ "foo//bar.txt": "foo/bar.txt",
+ "/with/./a/dot": "with/a/dot",
+ "/with/double/../dot": "with/dot",
+ } {
+ c.Assert(NormalizeTarget(before), Equals, after)
+ }
+}
+
+func (UtilSuite) TestHashedPaths(c *C) {
+ hexBytes := func(s string) data.HexBytes {
+ v, err := hex.DecodeString(s)
+ c.Assert(err, IsNil)
+ return v
+ }
+ hashes := data.Hashes{
+ "sha512": hexBytes("abc123"),
+ "sha256": hexBytes("def456"),
+ }
+ paths := HashedPaths("foo/bar.txt", hashes)
+ // cannot use DeepEquals as the returned order is non-deterministic
+ c.Assert(paths, HasLen, 2)
+ expected := map[string]struct{}{"foo/abc123.bar.txt": {}, "foo/def456.bar.txt": {}}
+ for _, path := range paths {
+ if _, ok := expected[path]; !ok {
+ c.Fatalf("unexpected path: %s", path)
+ }
+ delete(expected, path)
+ }
+}
+
+func (UtilSuite) TestVersionEqual(c *C) {
+ c.Assert(VersionEqual(1, 1), IsNil)
+ c.Assert(VersionEqual(1, 3), Equals, ErrWrongVersion{3, 1})
+}
+
+func makeHash(b []byte, alg string) []byte {
+ var h hash.Hash
+
+ switch alg {
+ case "sha256":
+ h = sha256.New()
+ case "sha512":
+ h = sha512.New()
+ }
+ h.Write(b)
+ return h.Sum(nil)
+}
+
+func (UtilSuite) TestBytesMatchLenAndHashes(c *C) {
+ type test struct {
+ name string
+ bytes []byte
+ length int64
+ hashes data.Hashes
+ err func(test) error
+ }
+
+ b := []byte{82, 253, 252, 7, 33, 130, 101, 79, 22, 63, 95, 15, 154, 98, 29, 114}
+ bhashes := data.Hashes{
+ "sha512": makeHash(b, "sha512"),
+ "sha256": makeHash(b, "sha256"),
+ }
+
+ tests := []test{
+ {
+ name: "correct len and hashes",
+ bytes: b,
+ length: 16,
+ hashes: bhashes,
+ err: func(test) error { return nil },
+ },
+ {
+ name: "incorrect len",
+ bytes: b,
+ length: 32,
+ hashes: bhashes,
+ err: func(test) error { return ErrWrongLength{32, 16} },
+ },
+ {
+ name: "incorrect hashes sha512",
+ bytes: b,
+ length: 16,
+ hashes: data.Hashes{
+ "sha512": makeHash(b, "sha256"),
+ },
+ err: func(test) error { return ErrWrongHash{"sha512", bhashes["sha256"], bhashes["sha512"]} },
+ },
+ {
+ name: "incorrect hashes sha256",
+ bytes: b,
+ length: 16,
+ hashes: data.Hashes{
+ "sha256": makeHash(b, "sha512"),
+ },
+ err: func(test) error { return ErrWrongHash{"sha256", bhashes["sha512"], bhashes["sha256"]} },
+ },
+ {
+ name: "incorrect len and hashes",
+ bytes: b,
+ length: 32,
+ hashes: data.Hashes{
+ "sha512": makeHash(b, "sha256"),
+ "sha256": makeHash(b, "sha512"),
+ },
+ err: func(test) error { return ErrWrongLength{32, 16} },
+ },
+ }
+
+ for _, t := range tests {
+ c.Assert(BytesMatchLenAndHashes(t.bytes, t.length, t.hashes), DeepEquals, t.err(t), Commentf("name = %s", t.name))
+ }
+}