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  }