Source file src/internal/zstd/xxhash_test.go

     1  // Copyright 2023 The Go Authors. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package zstd
     6  
     7  import (
     8  	"bytes"
     9  	"os"
    10  	"os/exec"
    11  	"strconv"
    12  	"testing"
    13  )
    14  
    15  var xxHashTests = []struct {
    16  	data string
    17  	hash uint64
    18  }{
    19  	{
    20  		"hello, world",
    21  		0xb33a384e6d1b1242,
    22  	},
    23  	{
    24  		"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789$",
    25  		0x1032d841e824f998,
    26  	},
    27  }
    28  
    29  func TestXXHash(t *testing.T) {
    30  	var xh xxhash64
    31  	for i, test := range xxHashTests {
    32  		xh.reset()
    33  		xh.update([]byte(test.data))
    34  		if got := xh.digest(); got != test.hash {
    35  			t.Errorf("#%d: got %#x want %#x", i, got, test.hash)
    36  		}
    37  	}
    38  }
    39  
    40  func TestLargeXXHash(t *testing.T) {
    41  	if testing.Short() {
    42  		t.Skip("skipping expensive test in short mode")
    43  	}
    44  
    45  	data, err := os.ReadFile("../../testdata/Isaac.Newton-Opticks.txt")
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  
    50  	var xh xxhash64
    51  	xh.reset()
    52  	i := 0
    53  	for i < len(data) {
    54  		// Write varying amounts to test buffering.
    55  		c := i%4094 + 1
    56  		if i+c > len(data) {
    57  			c = len(data) - i
    58  		}
    59  		xh.update(data[i : i+c])
    60  		i += c
    61  	}
    62  
    63  	got := xh.digest()
    64  	want := uint64(0xf0dd39fd7e063f82)
    65  	if got != want {
    66  		t.Errorf("got %#x want %#x", got, want)
    67  	}
    68  }
    69  
    70  func findXxhsum(t testing.TB) string {
    71  	xxhsum, err := exec.LookPath("xxhsum")
    72  	if err != nil {
    73  		t.Skip("skipping because xxhsum not found")
    74  	}
    75  	return xxhsum
    76  }
    77  
    78  func FuzzXXHash(f *testing.F) {
    79  	xxhsum := findXxhsum(f)
    80  
    81  	for _, test := range xxHashTests {
    82  		f.Add([]byte(test.data))
    83  	}
    84  	f.Add(bytes.Repeat([]byte("abcdefghijklmnop"), 256))
    85  	var buf bytes.Buffer
    86  	for i := 0; i < 256; i++ {
    87  		buf.WriteByte(byte(i))
    88  	}
    89  	f.Add(bytes.Repeat(buf.Bytes(), 64))
    90  	f.Add(bigData(f))
    91  
    92  	f.Fuzz(func(t *testing.T, b []byte) {
    93  		cmd := exec.Command(xxhsum, "-H64")
    94  		cmd.Stdin = bytes.NewReader(b)
    95  		var hhsumHash bytes.Buffer
    96  		cmd.Stdout = &hhsumHash
    97  		if err := cmd.Run(); err != nil {
    98  			t.Fatalf("running hhsum failed: %v", err)
    99  		}
   100  		hhHashBytes := bytes.Fields(bytes.TrimSpace(hhsumHash.Bytes()))[0]
   101  		hhHash, err := strconv.ParseUint(string(hhHashBytes), 16, 64)
   102  		if err != nil {
   103  			t.Fatalf("could not parse hash %q: %v", hhHashBytes, err)
   104  		}
   105  
   106  		var xh xxhash64
   107  		xh.reset()
   108  		xh.update(b)
   109  		goHash := xh.digest()
   110  
   111  		if goHash != hhHash {
   112  			t.Errorf("Go hash %#x != xxhsum hash %#x", goHash, hhHash)
   113  		}
   114  	})
   115  }
   116  

View as plain text