github.com/rclone/rclone@v1.66.1-0.20240517100346-7b89735ae726/fs/hash/hash_test.go (about) 1 package hash_test 2 3 import ( 4 "bytes" 5 "io" 6 "log" 7 "testing" 8 9 "github.com/rclone/rclone/fs/hash" 10 "github.com/spf13/pflag" 11 "github.com/stretchr/testify/assert" 12 "github.com/stretchr/testify/require" 13 ) 14 15 // Check it satisfies the interface 16 var _ pflag.Value = (*hash.Type)(nil) 17 18 func TestHashSet(t *testing.T) { 19 var h hash.Set 20 21 assert.Equal(t, 0, h.Count()) 22 23 a := h.Array() 24 assert.Len(t, a, 0) 25 26 h = h.Add(hash.MD5) 27 log.Println(h) 28 assert.Equal(t, 1, h.Count()) 29 assert.Equal(t, hash.MD5, h.GetOne()) 30 a = h.Array() 31 assert.Len(t, a, 1) 32 assert.Equal(t, a[0], hash.MD5) 33 34 // Test overlap, with all hashes 35 h = h.Overlap(hash.Supported()) 36 assert.Equal(t, 1, h.Count()) 37 assert.Equal(t, hash.MD5, h.GetOne()) 38 assert.True(t, h.SubsetOf(hash.Supported())) 39 assert.True(t, h.SubsetOf(hash.NewHashSet(hash.MD5))) 40 41 h = h.Add(hash.SHA1) 42 assert.Equal(t, 2, h.Count()) 43 one := h.GetOne() 44 if !(one == hash.MD5 || one == hash.SHA1) { 45 t.Fatalf("expected to be either MD5 or SHA1, got %v", one) 46 } 47 assert.True(t, h.SubsetOf(hash.Supported())) 48 assert.False(t, h.SubsetOf(hash.NewHashSet(hash.MD5))) 49 assert.False(t, h.SubsetOf(hash.NewHashSet(hash.SHA1))) 50 assert.True(t, h.SubsetOf(hash.NewHashSet(hash.MD5, hash.SHA1))) 51 a = h.Array() 52 assert.Len(t, a, 2) 53 54 ol := h.Overlap(hash.NewHashSet(hash.MD5)) 55 assert.Equal(t, 1, ol.Count()) 56 assert.True(t, ol.Contains(hash.MD5)) 57 assert.False(t, ol.Contains(hash.SHA1)) 58 59 ol = h.Overlap(hash.NewHashSet(hash.MD5, hash.SHA1)) 60 assert.Equal(t, 2, ol.Count()) 61 assert.True(t, ol.Contains(hash.MD5)) 62 assert.True(t, ol.Contains(hash.SHA1)) 63 } 64 65 type hashTest struct { 66 input []byte 67 output map[hash.Type]string 68 } 69 70 var hashTestSet = []hashTest{ 71 { 72 input: []byte{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 73 output: map[hash.Type]string{ 74 hash.MD5: "bf13fc19e5151ac57d4252e0e0f87abe", 75 hash.SHA1: "3ab6543c08a75f292a5ecedac87ec41642d12166", 76 hash.Whirlpool: "eddf52133d4566d763f716e853d6e4efbabd29e2c2e63f56747b1596172851d34c2df9944beb6640dbdbe3d9b4eb61180720a79e3d15baff31c91e43d63869a4", 77 hash.CRC32: "a6041d7e", 78 hash.SHA256: "c839e57675862af5c21bd0a15413c3ec579e0d5522dab600bc6c3489b05b8f54", 79 }, 80 }, 81 // Empty data set 82 { 83 input: []byte{}, 84 output: map[hash.Type]string{ 85 hash.MD5: "d41d8cd98f00b204e9800998ecf8427e", 86 hash.SHA1: "da39a3ee5e6b4b0d3255bfef95601890afd80709", 87 hash.Whirlpool: "19fa61d75522a4669b44e39c1d2e1726c530232130d407f89afee0964997f7a73e83be698b288febcf88e3e03c4f0757ea8964e59b63d93708b138cc42a66eb3", 88 hash.CRC32: "00000000", 89 hash.SHA256: "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855", 90 }, 91 }, 92 } 93 94 func TestMultiHasher(t *testing.T) { 95 for _, test := range hashTestSet { 96 mh := hash.NewMultiHasher() 97 n, err := io.Copy(mh, bytes.NewBuffer(test.input)) 98 require.NoError(t, err) 99 assert.Len(t, test.input, int(n)) 100 sums := mh.Sums() 101 for k, v := range sums { 102 expect, ok := test.output[k] 103 require.True(t, ok, "test output for hash not found") 104 assert.Equal(t, expect, v) 105 } 106 // Test that all are present 107 for k, v := range test.output { 108 expect, ok := sums[k] 109 require.True(t, ok, "test output for hash not found") 110 assert.Equal(t, expect, v) 111 } 112 } 113 } 114 115 func TestMultiHasherTypes(t *testing.T) { 116 h := hash.SHA1 117 for _, test := range hashTestSet { 118 mh, err := hash.NewMultiHasherTypes(hash.NewHashSet(h)) 119 if err != nil { 120 t.Fatal(err) 121 } 122 n, err := io.Copy(mh, bytes.NewBuffer(test.input)) 123 require.NoError(t, err) 124 assert.Len(t, test.input, int(n)) 125 sums := mh.Sums() 126 assert.Len(t, sums, 1) 127 assert.Equal(t, sums[h], test.output[h]) 128 } 129 } 130 131 func TestHashStream(t *testing.T) { 132 for _, test := range hashTestSet { 133 sums, err := hash.Stream(bytes.NewBuffer(test.input)) 134 require.NoError(t, err) 135 for k, v := range sums { 136 expect, ok := test.output[k] 137 require.True(t, ok) 138 assert.Equal(t, v, expect) 139 } 140 // Test that all are present 141 for k, v := range test.output { 142 expect, ok := sums[k] 143 require.True(t, ok) 144 assert.Equal(t, v, expect) 145 } 146 } 147 } 148 149 func TestHashStreamTypes(t *testing.T) { 150 h := hash.SHA1 151 for _, test := range hashTestSet { 152 sums, err := hash.StreamTypes(bytes.NewBuffer(test.input), hash.NewHashSet(h)) 153 require.NoError(t, err) 154 assert.Len(t, sums, 1) 155 assert.Equal(t, sums[h], test.output[h]) 156 } 157 } 158 159 func TestHashSetStringer(t *testing.T) { 160 h := hash.NewHashSet(hash.SHA1, hash.MD5) 161 assert.Equal(t, "[md5, sha1]", h.String()) 162 h = hash.NewHashSet(hash.SHA1) 163 assert.Equal(t, "[sha1]", h.String()) 164 h = hash.NewHashSet() 165 assert.Equal(t, "[]", h.String()) 166 } 167 168 func TestHashStringer(t *testing.T) { 169 h := hash.MD5 170 assert.Equal(t, "md5", h.String()) 171 h = hash.SHA1 172 assert.Equal(t, "sha1", h.String()) 173 h = hash.None 174 assert.Equal(t, "none", h.String()) 175 } 176 177 func TestHashSetter(t *testing.T) { 178 var ht hash.Type 179 180 assert.NoError(t, ht.Set("none")) 181 assert.Equal(t, hash.None, ht) 182 assert.NoError(t, ht.Set("None")) 183 assert.Equal(t, hash.None, ht) 184 185 assert.NoError(t, ht.Set("md5")) 186 assert.Equal(t, hash.MD5, ht) 187 assert.NoError(t, ht.Set("MD5")) 188 assert.Equal(t, hash.MD5, ht) 189 190 assert.NoError(t, ht.Set("sha1")) 191 assert.Equal(t, hash.SHA1, ht) 192 assert.NoError(t, ht.Set("SHA-1")) 193 assert.Equal(t, hash.SHA1, ht) 194 195 assert.NoError(t, ht.Set("SHA1")) 196 assert.Equal(t, hash.SHA1, ht) 197 assert.NoError(t, ht.Set("Sha1")) 198 assert.Equal(t, hash.SHA1, ht) 199 assert.Error(t, ht.Set("Sha-1")) 200 } 201 202 func TestHashTypeStability(t *testing.T) { 203 assert.Equal(t, hash.Type(0), hash.None) 204 assert.Equal(t, hash.Type(1), hash.MD5) 205 assert.Equal(t, hash.Type(2), hash.SHA1) 206 207 assert.True(t, hash.Supported().Contains(hash.MD5)) 208 assert.True(t, hash.Supported().Contains(hash.SHA1)) 209 assert.False(t, hash.Supported().Contains(hash.None)) 210 }