Source file src/internal/fuzz/mutators_byteslice_test.go

     1  // Copyright 2021 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 fuzz
     6  
     7  import (
     8  	"bytes"
     9  	"testing"
    10  )
    11  
    12  type mockRand struct {
    13  	values  []int
    14  	counter int
    15  	b       bool
    16  }
    17  
    18  func (mr *mockRand) uint32() uint32 {
    19  	c := mr.values[mr.counter]
    20  	mr.counter++
    21  	return uint32(c)
    22  }
    23  
    24  func (mr *mockRand) intn(n int) int {
    25  	c := mr.values[mr.counter]
    26  	mr.counter++
    27  	return c % n
    28  }
    29  
    30  func (mr *mockRand) uint32n(n uint32) uint32 {
    31  	c := mr.values[mr.counter]
    32  	mr.counter++
    33  	return uint32(c) % n
    34  }
    35  
    36  func (mr *mockRand) exp2() int {
    37  	c := mr.values[mr.counter]
    38  	mr.counter++
    39  	return c
    40  }
    41  
    42  func (mr *mockRand) bool() bool {
    43  	b := mr.b
    44  	mr.b = !mr.b
    45  	return b
    46  }
    47  
    48  func (mr *mockRand) save(*uint64, *uint64) {
    49  	panic("unimplemented")
    50  }
    51  
    52  func (mr *mockRand) restore(uint64, uint64) {
    53  	panic("unimplemented")
    54  }
    55  
    56  func TestByteSliceMutators(t *testing.T) {
    57  	for _, tc := range []struct {
    58  		name     string
    59  		mutator  func(*mutator, []byte) []byte
    60  		randVals []int
    61  		input    []byte
    62  		expected []byte
    63  	}{
    64  		{
    65  			name:     "byteSliceRemoveBytes",
    66  			mutator:  byteSliceRemoveBytes,
    67  			input:    []byte{1, 2, 3, 4},
    68  			expected: []byte{4},
    69  		},
    70  		{
    71  			name:     "byteSliceInsertRandomBytes",
    72  			mutator:  byteSliceInsertRandomBytes,
    73  			input:    make([]byte, 4, 8),
    74  			expected: []byte{3, 4, 5, 0, 0, 0, 0},
    75  		},
    76  		{
    77  			name:     "byteSliceDuplicateBytes",
    78  			mutator:  byteSliceDuplicateBytes,
    79  			input:    append(make([]byte, 0, 13), []byte{1, 2, 3, 4}...),
    80  			expected: []byte{1, 1, 2, 3, 4, 2, 3, 4},
    81  		},
    82  		{
    83  			name:     "byteSliceOverwriteBytes",
    84  			mutator:  byteSliceOverwriteBytes,
    85  			input:    []byte{1, 2, 3, 4},
    86  			expected: []byte{1, 1, 3, 4},
    87  		},
    88  		{
    89  			name:     "byteSliceBitFlip",
    90  			mutator:  byteSliceBitFlip,
    91  			input:    []byte{1, 2, 3, 4},
    92  			expected: []byte{3, 2, 3, 4},
    93  		},
    94  		{
    95  			name:     "byteSliceXORByte",
    96  			mutator:  byteSliceXORByte,
    97  			input:    []byte{1, 2, 3, 4},
    98  			expected: []byte{3, 2, 3, 4},
    99  		},
   100  		{
   101  			name:     "byteSliceSwapByte",
   102  			mutator:  byteSliceSwapByte,
   103  			input:    []byte{1, 2, 3, 4},
   104  			expected: []byte{2, 1, 3, 4},
   105  		},
   106  		{
   107  			name:     "byteSliceArithmeticUint8",
   108  			mutator:  byteSliceArithmeticUint8,
   109  			input:    []byte{1, 2, 3, 4},
   110  			expected: []byte{255, 2, 3, 4},
   111  		},
   112  		{
   113  			name:     "byteSliceArithmeticUint16",
   114  			mutator:  byteSliceArithmeticUint16,
   115  			input:    []byte{1, 2, 3, 4},
   116  			expected: []byte{1, 3, 3, 4},
   117  		},
   118  		{
   119  			name:     "byteSliceArithmeticUint32",
   120  			mutator:  byteSliceArithmeticUint32,
   121  			input:    []byte{1, 2, 3, 4},
   122  			expected: []byte{2, 2, 3, 4},
   123  		},
   124  		{
   125  			name:     "byteSliceArithmeticUint64",
   126  			mutator:  byteSliceArithmeticUint64,
   127  			input:    []byte{1, 2, 3, 4, 5, 6, 7, 8},
   128  			expected: []byte{2, 2, 3, 4, 5, 6, 7, 8},
   129  		},
   130  		{
   131  			name:     "byteSliceOverwriteInterestingUint8",
   132  			mutator:  byteSliceOverwriteInterestingUint8,
   133  			input:    []byte{1, 2, 3, 4},
   134  			expected: []byte{255, 2, 3, 4},
   135  		},
   136  		{
   137  			name:     "byteSliceOverwriteInterestingUint16",
   138  			mutator:  byteSliceOverwriteInterestingUint16,
   139  			input:    []byte{1, 2, 3, 4},
   140  			expected: []byte{255, 127, 3, 4},
   141  		},
   142  		{
   143  			name:     "byteSliceOverwriteInterestingUint32",
   144  			mutator:  byteSliceOverwriteInterestingUint32,
   145  			input:    []byte{1, 2, 3, 4},
   146  			expected: []byte{250, 0, 0, 250},
   147  		},
   148  		{
   149  			name:     "byteSliceInsertConstantBytes",
   150  			mutator:  byteSliceInsertConstantBytes,
   151  			input:    append(make([]byte, 0, 8), []byte{1, 2, 3, 4}...),
   152  			expected: []byte{3, 3, 3, 1, 2, 3, 4},
   153  		},
   154  		{
   155  			name:     "byteSliceOverwriteConstantBytes",
   156  			mutator:  byteSliceOverwriteConstantBytes,
   157  			input:    []byte{1, 2, 3, 4},
   158  			expected: []byte{3, 3, 3, 4},
   159  		},
   160  		{
   161  			name:     "byteSliceShuffleBytes",
   162  			mutator:  byteSliceShuffleBytes,
   163  			input:    []byte{1, 2, 3, 4},
   164  			expected: []byte{2, 3, 1, 4},
   165  		},
   166  		{
   167  			name:     "byteSliceSwapBytes",
   168  			mutator:  byteSliceSwapBytes,
   169  			randVals: []int{0, 2, 0, 2},
   170  			input:    append(make([]byte, 0, 9), []byte{1, 2, 3, 4}...),
   171  			expected: []byte{3, 2, 1, 4},
   172  		},
   173  	} {
   174  		t.Run(tc.name, func(t *testing.T) {
   175  			r := &mockRand{values: []int{0, 1, 2, 3, 4, 5}}
   176  			if tc.randVals != nil {
   177  				r.values = tc.randVals
   178  			}
   179  			m := &mutator{r: r}
   180  			b := tc.mutator(m, tc.input)
   181  			if !bytes.Equal(b, tc.expected) {
   182  				t.Errorf("got %x, want %x", b, tc.expected)
   183  			}
   184  		})
   185  	}
   186  }
   187  

View as plain text