...

Source file src/github.com/theupdateframework/go-tuf/util/util_test.go

Documentation: github.com/theupdateframework/go-tuf/util

     1  package util
     2  
     3  import (
     4  	"bytes"
     5  	"crypto/sha256"
     6  	"crypto/sha512"
     7  	"encoding/hex"
     8  	"hash"
     9  	"testing"
    10  
    11  	"github.com/theupdateframework/go-tuf/data"
    12  	. "gopkg.in/check.v1"
    13  )
    14  
    15  // Hook up gocheck into the "go test" runner.
    16  func Test(t *testing.T) { TestingT(t) }
    17  
    18  type UtilSuite struct{}
    19  
    20  var _ = Suite(&UtilSuite{})
    21  
    22  func (UtilSuite) TestGenerateTargetFileMetaDefault(c *C) {
    23  	// default is sha512
    24  	r := bytes.NewReader([]byte("foo"))
    25  	meta, err := GenerateTargetFileMeta(r)
    26  	c.Assert(err, IsNil)
    27  	c.Assert(meta.Length, Equals, int64(3))
    28  	hashes := meta.Hashes
    29  	c.Assert(hashes, HasLen, 1)
    30  	hash, ok := hashes["sha512"]
    31  	if !ok {
    32  		c.Fatal("missing sha512 hash")
    33  	}
    34  	c.Assert(hash.String(), DeepEquals, "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7")
    35  }
    36  
    37  func (UtilSuite) TestGenerateTargetFileMetaExplicit(c *C) {
    38  	r := bytes.NewReader([]byte("foo"))
    39  	meta, err := GenerateTargetFileMeta(r, "sha256", "sha512")
    40  	c.Assert(err, IsNil)
    41  	c.Assert(meta.Length, Equals, int64(3))
    42  	hashes := meta.Hashes
    43  	c.Assert(hashes, HasLen, 2)
    44  	for name, val := range map[string]string{
    45  		"sha256": "2c26b46b68ffc68ff99b453c1d30413413422d706483bfa0f98a5e886266e7ae",
    46  		"sha512": "f7fbba6e0636f890e56fbbf3283e524c6fa3204ae298382d624741d0dc6638326e282c41be5e4254d8820772c5518a2c5a8c0c7f7eda19594a7eb539453e1ed7",
    47  	} {
    48  		hash, ok := hashes[name]
    49  		if !ok {
    50  			c.Fatalf("missing %s hash", name)
    51  		}
    52  		c.Assert(hash.String(), DeepEquals, val)
    53  	}
    54  }
    55  
    56  func makeHashes(c *C, hashes map[string]string) data.Hashes {
    57  	h := make(map[string]data.HexBytes, len(hashes))
    58  	for typ, hash := range hashes {
    59  		v, err := hex.DecodeString(hash)
    60  		c.Assert(err, IsNil)
    61  		h[typ] = v
    62  	}
    63  	return h
    64  }
    65  
    66  type testMetaFile struct {
    67  	name     string
    68  	actual   data.FileMeta
    69  	expected data.FileMeta
    70  	err      func(testMetaFile) error
    71  }
    72  
    73  func testMetaFileCases(c *C) []testMetaFile {
    74  	fileMeta := func(c *C, length int64, hashes map[string]string) data.FileMeta {
    75  		return data.FileMeta{
    76  			Length: length,
    77  			Hashes: makeHashes(c, hashes),
    78  		}
    79  	}
    80  
    81  	return []testMetaFile{
    82  		{
    83  			name:     "wrong length",
    84  			actual:   data.FileMeta{Length: 1},
    85  			expected: data.FileMeta{Length: 2},
    86  			err:      func(testMetaFile) error { return ErrWrongLength{Actual: 1, Expected: 2} },
    87  		},
    88  		{
    89  			name:     "wrong sha512 hash",
    90  			actual:   fileMeta(c, 10, map[string]string{"sha512": "111111"}),
    91  			expected: fileMeta(c, 10, map[string]string{"sha512": "222222"}),
    92  			err: func(t testMetaFile) error {
    93  				return ErrWrongHash{"sha512", t.expected.Hashes["sha512"], t.actual.Hashes["sha512"]}
    94  			},
    95  		},
    96  		{
    97  			name:     "intersecting hashes",
    98  			actual:   fileMeta(c, 10, map[string]string{"sha512": "111111", "md5": "222222"}),
    99  			expected: fileMeta(c, 10, map[string]string{"sha512": "111111", "sha256": "333333"}),
   100  			err:      func(testMetaFile) error { return nil },
   101  		},
   102  		{
   103  			name:     "no common hashes",
   104  			actual:   fileMeta(c, 10, map[string]string{"sha512": "111111"}),
   105  			expected: fileMeta(c, 10, map[string]string{"sha256": "222222", "md5": "333333"}),
   106  			err:      func(t testMetaFile) error { return ErrNoCommonHash{t.expected.Hashes, t.actual.Hashes} },
   107  		},
   108  	}
   109  }
   110  
   111  func (UtilSuite) TestSnapshotFileMetaEqual(c *C) {
   112  	type test struct {
   113  		name     string
   114  		actual   data.SnapshotFileMeta
   115  		expected data.SnapshotFileMeta
   116  		err      func(test) error
   117  	}
   118  
   119  	fileMeta := func(version int64, length int64, hashes map[string]string) data.SnapshotFileMeta {
   120  		return data.SnapshotFileMeta{
   121  			Length:  length,
   122  			Hashes:  makeHashes(c, hashes),
   123  			Version: version,
   124  		}
   125  	}
   126  
   127  	tests := []test{
   128  		{
   129  			name:     "same version",
   130  			actual:   fileMeta(1, 10, map[string]string{"sha512": "111111"}),
   131  			expected: fileMeta(1, 10, map[string]string{"sha512": "111111"}),
   132  			err:      func(test) error { return nil },
   133  		},
   134  		{
   135  			name:     "wrong version",
   136  			actual:   fileMeta(0, 10, map[string]string{"sha512": "111111"}),
   137  			expected: fileMeta(1, 10, map[string]string{"sha512": "111111"}),
   138  			err:      func(test) error { return ErrWrongVersion{Expected: 1, Actual: 0} },
   139  		},
   140  		{
   141  			name:     "wrong version",
   142  			actual:   fileMeta(1, 10, map[string]string{"sha512": "111111"}),
   143  			expected: fileMeta(0, 10, map[string]string{"sha512": "111111"}),
   144  			err:      func(test) error { return ErrWrongVersion{Expected: 0, Actual: 1} },
   145  		},
   146  		{
   147  			name:     "wrong version",
   148  			actual:   fileMeta(1, 10, map[string]string{"sha512": "111111"}),
   149  			expected: fileMeta(2, 10, map[string]string{"sha512": "111111"}),
   150  			err:      func(test) error { return ErrWrongVersion{Expected: 2, Actual: 1} },
   151  		},
   152  	}
   153  
   154  	for _, t := range tests {
   155  		c.Assert(SnapshotFileMetaEqual(t.actual, t.expected), DeepEquals, t.err(t), Commentf("name = %s", t.name))
   156  	}
   157  
   158  	for _, t := range testMetaFileCases(c) {
   159  		actual := data.SnapshotFileMeta{Length: t.actual.Length, Hashes: t.actual.Hashes}
   160  		expected := data.SnapshotFileMeta{Length: t.expected.Length, Hashes: t.expected.Hashes}
   161  		c.Assert(SnapshotFileMetaEqual(actual, expected), DeepEquals, t.err(t), Commentf("name = %s %d %d", t.name, t.actual.Length, t.expected.Length))
   162  		c.Assert(FileMetaEqual(t.actual, t.expected), DeepEquals, t.err(t), Commentf("name = %s", t.name))
   163  	}
   164  }
   165  
   166  func (UtilSuite) TestNormalizeTarget(c *C) {
   167  	for before, after := range map[string]string{
   168  		"":                    "",
   169  		"foo.txt":             "foo.txt",
   170  		"/bar.txt":            "bar.txt",
   171  		"foo//bar.txt":        "foo/bar.txt",
   172  		"/with/./a/dot":       "with/a/dot",
   173  		"/with/double/../dot": "with/dot",
   174  	} {
   175  		c.Assert(NormalizeTarget(before), Equals, after)
   176  	}
   177  }
   178  
   179  func (UtilSuite) TestHashedPaths(c *C) {
   180  	hexBytes := func(s string) data.HexBytes {
   181  		v, err := hex.DecodeString(s)
   182  		c.Assert(err, IsNil)
   183  		return v
   184  	}
   185  	hashes := data.Hashes{
   186  		"sha512": hexBytes("abc123"),
   187  		"sha256": hexBytes("def456"),
   188  	}
   189  	paths := HashedPaths("foo/bar.txt", hashes)
   190  	// cannot use DeepEquals as the returned order is non-deterministic
   191  	c.Assert(paths, HasLen, 2)
   192  	expected := map[string]struct{}{"foo/abc123.bar.txt": {}, "foo/def456.bar.txt": {}}
   193  	for _, path := range paths {
   194  		if _, ok := expected[path]; !ok {
   195  			c.Fatalf("unexpected path: %s", path)
   196  		}
   197  		delete(expected, path)
   198  	}
   199  }
   200  
   201  func (UtilSuite) TestVersionEqual(c *C) {
   202  	c.Assert(VersionEqual(1, 1), IsNil)
   203  	c.Assert(VersionEqual(1, 3), Equals, ErrWrongVersion{3, 1})
   204  }
   205  
   206  func makeHash(b []byte, alg string) []byte {
   207  	var h hash.Hash
   208  
   209  	switch alg {
   210  	case "sha256":
   211  		h = sha256.New()
   212  	case "sha512":
   213  		h = sha512.New()
   214  	}
   215  	h.Write(b)
   216  	return h.Sum(nil)
   217  }
   218  
   219  func (UtilSuite) TestBytesMatchLenAndHashes(c *C) {
   220  	type test struct {
   221  		name   string
   222  		bytes  []byte
   223  		length int64
   224  		hashes data.Hashes
   225  		err    func(test) error
   226  	}
   227  
   228  	b := []byte{82, 253, 252, 7, 33, 130, 101, 79, 22, 63, 95, 15, 154, 98, 29, 114}
   229  	bhashes := data.Hashes{
   230  		"sha512": makeHash(b, "sha512"),
   231  		"sha256": makeHash(b, "sha256"),
   232  	}
   233  
   234  	tests := []test{
   235  		{
   236  			name:   "correct len and hashes",
   237  			bytes:  b,
   238  			length: 16,
   239  			hashes: bhashes,
   240  			err:    func(test) error { return nil },
   241  		},
   242  		{
   243  			name:   "incorrect len",
   244  			bytes:  b,
   245  			length: 32,
   246  			hashes: bhashes,
   247  			err:    func(test) error { return ErrWrongLength{32, 16} },
   248  		},
   249  		{
   250  			name:   "incorrect hashes sha512",
   251  			bytes:  b,
   252  			length: 16,
   253  			hashes: data.Hashes{
   254  				"sha512": makeHash(b, "sha256"),
   255  			},
   256  			err: func(test) error { return ErrWrongHash{"sha512", bhashes["sha256"], bhashes["sha512"]} },
   257  		},
   258  		{
   259  			name:   "incorrect hashes sha256",
   260  			bytes:  b,
   261  			length: 16,
   262  			hashes: data.Hashes{
   263  				"sha256": makeHash(b, "sha512"),
   264  			},
   265  			err: func(test) error { return ErrWrongHash{"sha256", bhashes["sha512"], bhashes["sha256"]} },
   266  		},
   267  		{
   268  			name:   "incorrect len and hashes",
   269  			bytes:  b,
   270  			length: 32,
   271  			hashes: data.Hashes{
   272  				"sha512": makeHash(b, "sha256"),
   273  				"sha256": makeHash(b, "sha512"),
   274  			},
   275  			err: func(test) error { return ErrWrongLength{32, 16} },
   276  		},
   277  	}
   278  
   279  	for _, t := range tests {
   280  		c.Assert(BytesMatchLenAndHashes(t.bytes, t.length, t.hashes), DeepEquals, t.err(t), Commentf("name = %s", t.name))
   281  	}
   282  }
   283  

View as plain text