github.com/avahowell/sia@v0.5.1-beta.0.20160524050156-83dcc3d37c94/crypto/hash_test.go (about)

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