...

Source file src/bytes/compare_test.go

Documentation: bytes

		 1  // Copyright 2013 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 bytes_test
		 6  
		 7  import (
		 8  	. "bytes"
		 9  	"internal/testenv"
		10  	"testing"
		11  )
		12  
		13  var compareTests = []struct {
		14  	a, b []byte
		15  	i		int
		16  }{
		17  	{[]byte(""), []byte(""), 0},
		18  	{[]byte("a"), []byte(""), 1},
		19  	{[]byte(""), []byte("a"), -1},
		20  	{[]byte("abc"), []byte("abc"), 0},
		21  	{[]byte("abd"), []byte("abc"), 1},
		22  	{[]byte("abc"), []byte("abd"), -1},
		23  	{[]byte("ab"), []byte("abc"), -1},
		24  	{[]byte("abc"), []byte("ab"), 1},
		25  	{[]byte("x"), []byte("ab"), 1},
		26  	{[]byte("ab"), []byte("x"), -1},
		27  	{[]byte("x"), []byte("a"), 1},
		28  	{[]byte("b"), []byte("x"), -1},
		29  	// test runtime·memeq's chunked implementation
		30  	{[]byte("abcdefgh"), []byte("abcdefgh"), 0},
		31  	{[]byte("abcdefghi"), []byte("abcdefghi"), 0},
		32  	{[]byte("abcdefghi"), []byte("abcdefghj"), -1},
		33  	{[]byte("abcdefghj"), []byte("abcdefghi"), 1},
		34  	// nil tests
		35  	{nil, nil, 0},
		36  	{[]byte(""), nil, 0},
		37  	{nil, []byte(""), 0},
		38  	{[]byte("a"), nil, 1},
		39  	{nil, []byte("a"), -1},
		40  }
		41  
		42  func TestCompare(t *testing.T) {
		43  	for _, tt := range compareTests {
		44  		numShifts := 16
		45  		buffer := make([]byte, len(tt.b)+numShifts)
		46  		// vary the input alignment of tt.b
		47  		for offset := 0; offset <= numShifts; offset++ {
		48  			shiftedB := buffer[offset : len(tt.b)+offset]
		49  			copy(shiftedB, tt.b)
		50  			cmp := Compare(tt.a, shiftedB)
		51  			if cmp != tt.i {
		52  				t.Errorf(`Compare(%q, %q), offset %d = %v; want %v`, tt.a, tt.b, offset, cmp, tt.i)
		53  			}
		54  		}
		55  	}
		56  }
		57  
		58  func TestCompareIdenticalSlice(t *testing.T) {
		59  	var b = []byte("Hello Gophers!")
		60  	if Compare(b, b) != 0 {
		61  		t.Error("b != b")
		62  	}
		63  	if Compare(b, b[:1]) != 1 {
		64  		t.Error("b > b[:1] failed")
		65  	}
		66  }
		67  
		68  func TestCompareBytes(t *testing.T) {
		69  	lengths := make([]int, 0) // lengths to test in ascending order
		70  	for i := 0; i <= 128; i++ {
		71  		lengths = append(lengths, i)
		72  	}
		73  	lengths = append(lengths, 256, 512, 1024, 1333, 4095, 4096, 4097)
		74  
		75  	if !testing.Short() || testenv.Builder() != "" {
		76  		lengths = append(lengths, 65535, 65536, 65537, 99999)
		77  	}
		78  
		79  	n := lengths[len(lengths)-1]
		80  	a := make([]byte, n+1)
		81  	b := make([]byte, n+1)
		82  	for _, len := range lengths {
		83  		// randomish but deterministic data. No 0 or 255.
		84  		for i := 0; i < len; i++ {
		85  			a[i] = byte(1 + 31*i%254)
		86  			b[i] = byte(1 + 31*i%254)
		87  		}
		88  		// data past the end is different
		89  		for i := len; i <= n; i++ {
		90  			a[i] = 8
		91  			b[i] = 9
		92  		}
		93  		cmp := Compare(a[:len], b[:len])
		94  		if cmp != 0 {
		95  			t.Errorf(`CompareIdentical(%d) = %d`, len, cmp)
		96  		}
		97  		if len > 0 {
		98  			cmp = Compare(a[:len-1], b[:len])
		99  			if cmp != -1 {
	 100  				t.Errorf(`CompareAshorter(%d) = %d`, len, cmp)
	 101  			}
	 102  			cmp = Compare(a[:len], b[:len-1])
	 103  			if cmp != 1 {
	 104  				t.Errorf(`CompareBshorter(%d) = %d`, len, cmp)
	 105  			}
	 106  		}
	 107  		for k := 0; k < len; k++ {
	 108  			b[k] = a[k] - 1
	 109  			cmp = Compare(a[:len], b[:len])
	 110  			if cmp != 1 {
	 111  				t.Errorf(`CompareAbigger(%d,%d) = %d`, len, k, cmp)
	 112  			}
	 113  			b[k] = a[k] + 1
	 114  			cmp = Compare(a[:len], b[:len])
	 115  			if cmp != -1 {
	 116  				t.Errorf(`CompareBbigger(%d,%d) = %d`, len, k, cmp)
	 117  			}
	 118  			b[k] = a[k]
	 119  		}
	 120  	}
	 121  }
	 122  
	 123  func TestEndianBaseCompare(t *testing.T) {
	 124  	// This test compares byte slices that are almost identical, except one
	 125  	// difference that for some j, a[j]>b[j] and a[j+1]<b[j+1]. If the implementation
	 126  	// compares large chunks with wrong endianness, it gets wrong result.
	 127  	// no vector register is larger than 512 bytes for now
	 128  	const maxLength = 512
	 129  	a := make([]byte, maxLength)
	 130  	b := make([]byte, maxLength)
	 131  	// randomish but deterministic data. No 0 or 255.
	 132  	for i := 0; i < maxLength; i++ {
	 133  		a[i] = byte(1 + 31*i%254)
	 134  		b[i] = byte(1 + 31*i%254)
	 135  	}
	 136  	for i := 2; i <= maxLength; i <<= 1 {
	 137  		for j := 0; j < i-1; j++ {
	 138  			a[j] = b[j] - 1
	 139  			a[j+1] = b[j+1] + 1
	 140  			cmp := Compare(a[:i], b[:i])
	 141  			if cmp != -1 {
	 142  				t.Errorf(`CompareBbigger(%d,%d) = %d`, i, j, cmp)
	 143  			}
	 144  			a[j] = b[j] + 1
	 145  			a[j+1] = b[j+1] - 1
	 146  			cmp = Compare(a[:i], b[:i])
	 147  			if cmp != 1 {
	 148  				t.Errorf(`CompareAbigger(%d,%d) = %d`, i, j, cmp)
	 149  			}
	 150  			a[j] = b[j]
	 151  			a[j+1] = b[j+1]
	 152  		}
	 153  	}
	 154  }
	 155  
	 156  func BenchmarkCompareBytesEqual(b *testing.B) {
	 157  	b1 := []byte("Hello Gophers!")
	 158  	b2 := []byte("Hello Gophers!")
	 159  	for i := 0; i < b.N; i++ {
	 160  		if Compare(b1, b2) != 0 {
	 161  			b.Fatal("b1 != b2")
	 162  		}
	 163  	}
	 164  }
	 165  
	 166  func BenchmarkCompareBytesToNil(b *testing.B) {
	 167  	b1 := []byte("Hello Gophers!")
	 168  	var b2 []byte
	 169  	for i := 0; i < b.N; i++ {
	 170  		if Compare(b1, b2) != 1 {
	 171  			b.Fatal("b1 > b2 failed")
	 172  		}
	 173  	}
	 174  }
	 175  
	 176  func BenchmarkCompareBytesEmpty(b *testing.B) {
	 177  	b1 := []byte("")
	 178  	b2 := b1
	 179  	for i := 0; i < b.N; i++ {
	 180  		if Compare(b1, b2) != 0 {
	 181  			b.Fatal("b1 != b2")
	 182  		}
	 183  	}
	 184  }
	 185  
	 186  func BenchmarkCompareBytesIdentical(b *testing.B) {
	 187  	b1 := []byte("Hello Gophers!")
	 188  	b2 := b1
	 189  	for i := 0; i < b.N; i++ {
	 190  		if Compare(b1, b2) != 0 {
	 191  			b.Fatal("b1 != b2")
	 192  		}
	 193  	}
	 194  }
	 195  
	 196  func BenchmarkCompareBytesSameLength(b *testing.B) {
	 197  	b1 := []byte("Hello Gophers!")
	 198  	b2 := []byte("Hello, Gophers")
	 199  	for i := 0; i < b.N; i++ {
	 200  		if Compare(b1, b2) != -1 {
	 201  			b.Fatal("b1 < b2 failed")
	 202  		}
	 203  	}
	 204  }
	 205  
	 206  func BenchmarkCompareBytesDifferentLength(b *testing.B) {
	 207  	b1 := []byte("Hello Gophers!")
	 208  	b2 := []byte("Hello, Gophers!")
	 209  	for i := 0; i < b.N; i++ {
	 210  		if Compare(b1, b2) != -1 {
	 211  			b.Fatal("b1 < b2 failed")
	 212  		}
	 213  	}
	 214  }
	 215  
	 216  func BenchmarkCompareBytesBigUnaligned(b *testing.B) {
	 217  	b.StopTimer()
	 218  	b1 := make([]byte, 0, 1<<20)
	 219  	for len(b1) < 1<<20 {
	 220  		b1 = append(b1, "Hello Gophers!"...)
	 221  	}
	 222  	b2 := append([]byte("hello"), b1...)
	 223  	b.StartTimer()
	 224  	for i := 0; i < b.N; i++ {
	 225  		if Compare(b1, b2[len("hello"):]) != 0 {
	 226  			b.Fatal("b1 != b2")
	 227  		}
	 228  	}
	 229  	b.SetBytes(int64(len(b1)))
	 230  }
	 231  
	 232  func BenchmarkCompareBytesBig(b *testing.B) {
	 233  	b.StopTimer()
	 234  	b1 := make([]byte, 0, 1<<20)
	 235  	for len(b1) < 1<<20 {
	 236  		b1 = append(b1, "Hello Gophers!"...)
	 237  	}
	 238  	b2 := append([]byte{}, b1...)
	 239  	b.StartTimer()
	 240  	for i := 0; i < b.N; i++ {
	 241  		if Compare(b1, b2) != 0 {
	 242  			b.Fatal("b1 != b2")
	 243  		}
	 244  	}
	 245  	b.SetBytes(int64(len(b1)))
	 246  }
	 247  
	 248  func BenchmarkCompareBytesBigIdentical(b *testing.B) {
	 249  	b.StopTimer()
	 250  	b1 := make([]byte, 0, 1<<20)
	 251  	for len(b1) < 1<<20 {
	 252  		b1 = append(b1, "Hello Gophers!"...)
	 253  	}
	 254  	b2 := b1
	 255  	b.StartTimer()
	 256  	for i := 0; i < b.N; i++ {
	 257  		if Compare(b1, b2) != 0 {
	 258  			b.Fatal("b1 != b2")
	 259  		}
	 260  	}
	 261  	b.SetBytes(int64(len(b1)))
	 262  }
	 263  

View as plain text