github.com/metacurrency/holochain@v0.1.0-alpha-26.0.20200915073418-5c83169c9b5b/hash/hash_test.go (about) 1 package hash 2 3 import ( 4 "bytes" 5 "fmt" 6 peer "github.com/libp2p/go-libp2p-peer" 7 mh "github.com/multiformats/go-multihash" 8 . "github.com/smartystreets/goconvey/convey" 9 "math/big" 10 "testing" 11 ) 12 13 func TestHash(t *testing.T) { 14 15 Convey("Hash string representation", t, func() { 16 var h Hash 17 var err error 18 multih, err := mh.Sum([]byte("test data"), mh.SHA2_256, -1) 19 h = Hash(multih) 20 So(fmt.Sprintf("%v", []byte(h)), ShouldEqual, "[18 32 145 111 0 39 165 117 7 76 231 42 51 23 119 195 71 141 101 19 247 134 165 145 189 137 45 161 165 119 191 35 53 249]") 21 So(h.String(), ShouldEqual, "QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 22 h, err = NewHash("QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 23 So(err, ShouldBeNil) 24 So(h.String(), ShouldEqual, "QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 25 s := fmt.Sprintf("%v", h) 26 So(s, ShouldEqual, "QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 27 }) 28 } 29 30 func TestHashSum(t *testing.T) { 31 var hs = HashSpec{mh.SHA2_256, -1} 32 b := []byte("test data") 33 Convey("it should make a hash of binary data", t, func() { 34 h, err := Sum(hs, b) 35 So(err, ShouldBeNil) 36 So(h.String(), ShouldEqual, "QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 37 }) 38 } 39 40 func TestNullHash(t *testing.T) { 41 Convey("There should be a null hash", t, func() { 42 h := NullHash() 43 So(fmt.Sprintf("%v", h), ShouldEqual, "") 44 So(h.IsNullHash(), ShouldBeTrue) 45 }) 46 47 } 48 49 func TestHashFromBytes(t *testing.T) { 50 h1, _ := NewHash("QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 51 52 Convey("it should make a hash from valid bytes", t, func() { 53 h, err := HashFromBytes([]byte(h1)) 54 So(err, ShouldBeNil) 55 So(h.Equal(h1), ShouldBeTrue) 56 }) 57 } 58 59 func TestPeerIDFromHash(t *testing.T) { 60 b58 := "QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2" 61 h, _ := NewHash(b58) 62 63 Convey("it should make a peerID from a Hash", t, func() { 64 peer := PeerIDFromHash(h) 65 So(peer.Pretty(), ShouldEqual, b58) 66 }) 67 } 68 69 func TestHashFromPeerID(t *testing.T) { 70 b58 := "QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2" 71 peer, _ := peer.IDB58Decode(b58) 72 73 Convey("it should make a hash from a peer ID", t, func() { 74 h := HashFromPeerID(peer) 75 So(h.String(), ShouldEqual, b58) 76 }) 77 } 78 79 func TestHashEqual(t *testing.T) { 80 h1, _ := NewHash("QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 81 h2, _ := NewHash("QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 82 83 nh1 := NullHash() 84 nh2 := NullHash() 85 Convey("similar hashes should equal", t, func() { 86 So(h1.Equal(h2), ShouldBeTrue) 87 88 So(nh1.Equal(nh2), ShouldBeTrue) 89 }) 90 91 h3, _ := NewHash("QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh3") 92 93 Convey("dissimilar hashes should not", t, func() { 94 So(h1.Equal(h3), ShouldBeFalse) 95 So(h1.Equal(nh2), ShouldBeFalse) 96 }) 97 98 } 99 100 func TestMarshalHash(t *testing.T) { 101 Convey("should be able to marshal and unmarshal a hash", t, func() { 102 hash, _ := NewHash("QmY8Mzg9F69e5P9AoQPYat655HEhc1TVGs11tmfNSzkqh2") 103 var b bytes.Buffer 104 err := hash.MarshalHash(&b) 105 So(err, ShouldBeNil) 106 var hash2 Hash 107 hash2, err = UnmarshalHash(&b) 108 So(err, ShouldBeNil) 109 So(hash.Equal(hash2), ShouldBeTrue) 110 }) 111 Convey("should be able to marshal and unmarshal a Null Hash", t, func() { 112 hash := NullHash() 113 var b bytes.Buffer 114 err := hash.MarshalHash(&b) 115 So(err, ShouldBeNil) 116 var hash2 Hash 117 hash2, err = UnmarshalHash(&b) 118 So(err, ShouldBeNil) 119 So(hash.Equal(hash2), ShouldBeTrue) 120 }) 121 } 122 123 func TestZeroPrefixLen(t *testing.T) { 124 cases := [][]byte{ 125 {0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00}, 126 {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}, 127 {0x00, 0x58, 0xFF, 0x80, 0x00, 0x00, 0xF0}, 128 } 129 lens := []int{24, 56, 9} 130 131 Convey("it should calculate prefix lengths", t, func() { 132 for i, c := range cases { 133 r := ZeroPrefixLen(c) 134 So(r, ShouldEqual, lens[i]) 135 } 136 }) 137 } 138 139 func TestHashXORDistance(t *testing.T) { 140 h0, _ := HashFromBytes( 141 []byte{0x12, 0x20, 0x91, 0x6f, 0x00, 0x27, 0xa5, 0x75, 0x07, 0x4c, 0xe7, 0x2a, 0x33, 0x17, 0x77, 0xc3, 0x47, 0x8d, 0x65, 0x13, 0xf7, 0x86, 0xa5, 0x91, 0xbd, 0x89, 0x2d, 0xa1, 0xa5, 0x77, 0xbf, 0x23, 0x36, 0x00}) 142 h1, _ := HashFromBytes( 143 []byte{0x12, 0x20, 0x91, 0x6f, 0x00, 0x27, 0xa5, 0x75, 0x07, 0x4c, 0xe7, 0x2a, 0x33, 0x17, 0x77, 0xc3, 0x47, 0x8d, 0x65, 0x13, 0xf7, 0x86, 0xa5, 0x91, 0xbd, 0x89, 0x2d, 0xa1, 0xa5, 0x77, 0xbf, 0x23, 0x36, 0x01}) 144 h2, _ := HashFromBytes( 145 []byte{0x12, 0x20, 0x91, 0x6f, 0x00, 0x27, 0xa5, 0x75, 0x07, 0x4c, 0xe7, 0x2a, 0x33, 0x17, 0x77, 0xc3, 0x47, 0x8d, 0x65, 0x13, 0xf7, 0x86, 0xa5, 0x91, 0xbd, 0x89, 0x2d, 0xa1, 0xa5, 0x77, 0xbf, 0x23, 0x36, 0xff}) 146 Convey("the same hash should be at distance 0 from itself", t, func() { 147 var d big.Int 148 So(d.Cmp(HashXORDistance(h0, h0)), ShouldEqual, 0) 149 }) 150 Convey("it should calculate distance", t, func() { 151 So(fmt.Sprintf("%v", HashXORDistance(h0, h1)), ShouldEqual, "1") 152 So(fmt.Sprintf("%v", HashXORDistance(h0, h2)), ShouldEqual, "255") 153 }) 154 155 } 156 157 func TestHashDistancesAndCenterSorting(t *testing.T) { 158 159 hashes := makeTestHashes() 160 161 cmp := func(a int64, b *big.Int) int { 162 return big.NewInt(a).Cmp(b) 163 } 164 165 Convey("the same hash should be at distance 0 from itself", t, func() { 166 So(cmp(0, HashXORDistance(hashes[2], hashes[3])), ShouldEqual, 0) 167 }) 168 Convey("it should cmp if less", t, func() { 169 So(cmp(1, HashXORDistance(hashes[2], hashes[4])), ShouldEqual, 0) 170 }) 171 /* 172 d1 := HashXORDistance(hashes[2], hashes[5]) 173 d2 := u.XOR(keys[2].Bytes, keys[5].Bytes) 174 d2 = d2[len(keys[2].Bytes)-len(d1.Bytes()):] // skip empty space for big 175 if !bytes.Equal(d1.Bytes(), d2) { 176 t.Errorf("bytes should be the same. %v == %v", d1.Bytes(), d2) 177 }*/ 178 /* 179 if -1 != cmp(2<<32, keys[2].Distance(keys[5])) { 180 t.Errorf("2<<32 should be smaller") 181 } 182 */ 183 184 Convey("sort function should order by XOR distance", t, func() { 185 hashes2 := SortByDistance(hashes[2], hashes) 186 order := []int{2, 3, 4, 5, 1, 0} 187 for i, o := range order { 188 So(hashes[o].Equal(hashes2[i]), ShouldBeTrue) 189 } 190 }) 191 } 192 193 func makeTestHashes() []Hash { 194 adjs := [][]byte{ 195 {0x12, 0x20, 173, 149, 19, 27, 192, 183, 153, 192, 177, 175, 71, 127, 177, 79, 207, 38, 166, 169, 247, 96, 121, 228, 139, 240, 144, 172, 183, 232, 54, 123, 253, 14}, 196 {0x12, 0x20, 223, 63, 97, 152, 4, 169, 47, 219, 64, 87, 25, 45, 196, 61, 215, 72, 234, 119, 138, 220, 82, 188, 73, 140, 232, 5, 36, 192, 20, 184, 17, 25}, 197 {0x12, 0x20, 73, 176, 221, 176, 149, 143, 22, 42, 129, 124, 213, 114, 232, 95, 189, 154, 18, 3, 122, 132, 32, 199, 53, 185, 58, 157, 117, 78, 52, 146, 157, 127}, 198 {0x12, 0x20, 73, 176, 221, 176, 149, 143, 22, 42, 129, 124, 213, 114, 232, 95, 189, 154, 18, 3, 122, 132, 32, 199, 53, 185, 58, 157, 117, 78, 52, 146, 157, 127}, 199 {0x12, 0x20, 73, 176, 221, 176, 149, 143, 22, 42, 129, 124, 213, 114, 232, 95, 189, 154, 18, 3, 122, 132, 32, 199, 53, 185, 58, 157, 117, 78, 52, 146, 157, 126}, 200 {0x12, 0x20, 73, 0, 221, 176, 149, 143, 22, 42, 129, 124, 213, 114, 232, 95, 189, 154, 18, 3, 122, 132, 32, 199, 53, 185, 58, 157, 117, 78, 52, 146, 157, 127}, 201 } 202 203 hashes := make([]Hash, len(adjs)) 204 var err error 205 for i, a := range adjs { 206 hashes[i], err = HashFromBytes(a) 207 if err != nil { 208 panic(err) 209 } 210 } 211 return hashes 212 }