gitlab.com/SiaPrime/SiaPrime@v1.4.1/crypto/hash_test.go (about)

     1  package crypto
     2  
     3  import (
     4  	"bytes"
     5  	"encoding/json"
     6  	"sort"
     7  	"strings"
     8  	"testing"
     9  
    10  	"gitlab.com/NebulousLabs/fastrand"
    11  )
    12  
    13  type (
    14  	// TestObject is a struct that's used for testing HashAll and HashObject. The
    15  	// fields have to be exported so the encoder can read them.
    16  	TestObject struct {
    17  		A int
    18  		B byte
    19  		C bool
    20  		D string
    21  	}
    22  )
    23  
    24  // TestHashing uses each of the functions in hash.go and verifies that the
    25  // results are as expected.
    26  func TestHashing(t *testing.T) {
    27  	// Create a test object.
    28  	to := TestObject{
    29  		A: 12345,
    30  		B: 5,
    31  		C: true,
    32  		D: "testing",
    33  	}
    34  
    35  	// Call HashObject on the object.
    36  	var emptyHash Hash
    37  	h0 := HashObject(to)
    38  	if h0 == emptyHash {
    39  		t.Error("HashObject returned the zero hash!")
    40  	}
    41  
    42  	// Call HashAll on the test object and some other fields.
    43  	h1 := HashAll(
    44  		int(122),
    45  		byte(115),
    46  		string("test"),
    47  		to,
    48  	)
    49  	if h1 == emptyHash {
    50  		t.Error("HashObject returned the zero hash!")
    51  	}
    52  
    53  	// Call HashBytes on a random byte slice.
    54  	h2 := HashBytes(fastrand.Bytes(435))
    55  	if h2 == emptyHash {
    56  		t.Error("HashObject returned the zero hash!")
    57  	}
    58  }
    59  
    60  // TestHashSorting takes a set of hashses and checks that they can be sorted.
    61  func TestHashSorting(t *testing.T) {
    62  	// Created an unsorted list of hashes.
    63  	hashes := make([]Hash, 5)
    64  	hashes[0][0] = 12
    65  	hashes[1][0] = 7
    66  	hashes[2][0] = 13
    67  	hashes[3][0] = 14
    68  	hashes[4][0] = 1
    69  
    70  	// Sort the hashes.
    71  	sort.Sort(HashSlice(hashes))
    72  	if hashes[0][0] != 1 {
    73  		t.Error("bad sort")
    74  	}
    75  	if hashes[1][0] != 7 {
    76  		t.Error("bad sort")
    77  	}
    78  	if hashes[2][0] != 12 {
    79  		t.Error("bad sort")
    80  	}
    81  	if hashes[3][0] != 13 {
    82  		t.Error("bad sort")
    83  	}
    84  	if hashes[4][0] != 14 {
    85  		t.Error("bad sort")
    86  	}
    87  }
    88  
    89  // TestUnitHashMarshalJSON tests that Hashes are correctly marshalled to JSON.
    90  func TestUnitHashMarshalJSON(t *testing.T) {
    91  	h := HashObject("an object")
    92  	jsonBytes, err := h.MarshalJSON()
    93  	if err != nil {
    94  		t.Fatal(err)
    95  	}
    96  	if !bytes.Equal(jsonBytes, []byte(`"`+h.String()+`"`)) {
    97  		t.Errorf("hash %s encoded incorrectly: got %s\n", h, jsonBytes)
    98  	}
    99  }
   100  
   101  // TestUnitHashUnmarshalJSON tests that unmarshalling invalid JSON will result
   102  // in an error.
   103  func TestUnitHashUnmarshalJSON(t *testing.T) {
   104  	// Test unmarshalling invalid data.
   105  	invalidJSONBytes := [][]byte{
   106  		// Invalid JSON.
   107  		nil,
   108  		{},
   109  		[]byte("\""),
   110  		// JSON of wrong length.
   111  		[]byte(""),
   112  		[]byte(`"` + strings.Repeat("a", HashSize*2-1) + `"`),
   113  		[]byte(`"` + strings.Repeat("a", HashSize*2+1) + `"`),
   114  		// JSON of right length but invalid Hashes.
   115  		[]byte(`"` + strings.Repeat("z", HashSize*2) + `"`),
   116  		[]byte(`"` + strings.Repeat(".", HashSize*2) + `"`),
   117  		[]byte(`"` + strings.Repeat("\n", HashSize*2) + `"`),
   118  	}
   119  
   120  	for _, jsonBytes := range invalidJSONBytes {
   121  		var h Hash
   122  		err := h.UnmarshalJSON(jsonBytes)
   123  		if err == nil {
   124  			t.Errorf("expected unmarshall to fail on the invalid JSON: %q\n", jsonBytes)
   125  		}
   126  	}
   127  
   128  	// Test unmarshalling valid data.
   129  	expectedH := HashObject("an object")
   130  	jsonBytes := []byte(`"` + expectedH.String() + `"`)
   131  
   132  	var h Hash
   133  	err := h.UnmarshalJSON(jsonBytes)
   134  	if err != nil {
   135  		t.Fatal(err)
   136  	}
   137  	if !bytes.Equal(h[:], expectedH[:]) {
   138  		t.Errorf("Hash %s marshalled incorrectly: got %s\n", expectedH, h)
   139  	}
   140  }
   141  
   142  // TestHashMarshalling checks that the marshalling of the hash type works as
   143  // expected.
   144  func TestHashMarshalling(t *testing.T) {
   145  	h := HashObject("an object")
   146  	hBytes, err := json.Marshal(h)
   147  	if err != nil {
   148  		t.Fatal(err)
   149  	}
   150  
   151  	var uMarH Hash
   152  	err = uMarH.UnmarshalJSON(hBytes)
   153  	if err != nil {
   154  		t.Fatal(err)
   155  	}
   156  
   157  	if h != uMarH {
   158  		t.Error("encoded and decoded hash do not match!")
   159  	}
   160  }
   161  
   162  // TestHashLoadString checks that the LoadString method of the hash function is
   163  // working properly.
   164  func TestHashLoadString(t *testing.T) {
   165  	h1 := Hash{}
   166  	h2 := HashObject("tame")
   167  	h1e := h1.String()
   168  	h2e := h2.String()
   169  
   170  	var h1d, h2d Hash
   171  	err := h1d.LoadString(h1e)
   172  	if err != nil {
   173  		t.Fatal(err)
   174  	}
   175  	err = h2d.LoadString(h2e)
   176  	if err != nil {
   177  		t.Fatal(err)
   178  	}
   179  	if h1d != h1 {
   180  		t.Error("decoding h1 failed")
   181  	}
   182  	if h2d != h2 {
   183  		t.Error("decoding h2 failed")
   184  	}
   185  
   186  	// Try some bogus strings.
   187  	h1e = h1e + "a"
   188  	err = h1.LoadString(h1e)
   189  	if err == nil {
   190  		t.Fatal("expecting error when decoding hash of too large length")
   191  	}
   192  	h1e = h1e[:60]
   193  	err = h1.LoadString(h1e)
   194  	if err == nil {
   195  		t.Fatal("expecting error when decoding hash of too small length")
   196  	}
   197  }