github.com/galaxyobe/gen@v0.0.0-20220910125335-392fa8f0990f/cmd/deepcopy-gen/output_tests/output_test.go (about)

     1  package output_tests
     2  
     3  import (
     4  	"fmt"
     5  	"reflect"
     6  	"testing"
     7  
     8  	"github.com/davecgh/go-spew/spew"
     9  	"github.com/google/gofuzz"
    10  
    11  	"github.com/galaxyobe/gen/cmd/deepcopy-gen/output_tests/aliases"
    12  	"github.com/galaxyobe/gen/cmd/deepcopy-gen/output_tests/builtins"
    13  	"github.com/galaxyobe/gen/cmd/deepcopy-gen/output_tests/interfaces"
    14  	"github.com/galaxyobe/gen/cmd/deepcopy-gen/output_tests/maps"
    15  	"github.com/galaxyobe/gen/cmd/deepcopy-gen/output_tests/pointer"
    16  	"github.com/galaxyobe/gen/cmd/deepcopy-gen/output_tests/slices"
    17  	"github.com/galaxyobe/gen/cmd/deepcopy-gen/output_tests/structs"
    18  )
    19  
    20  func TestWithValueFuzzer(t *testing.T) {
    21  	tests := []interface{}{
    22  		aliases.Ttest{},
    23  		builtins.Ttest{},
    24  		interfaces.Ttest{},
    25  		maps.Ttest{},
    26  		pointer.Ttest{},
    27  		slices.Ttest{},
    28  		structs.Ttest{},
    29  	}
    30  
    31  	fuzzer := fuzz.New()
    32  	fuzzer.NilChance(0.5)
    33  	fuzzer.NumElements(0, 2)
    34  	fuzzer.Funcs(interfaceFuzzers...)
    35  
    36  	for _, test := range tests {
    37  		t.Run(fmt.Sprintf("%T", test), func(t *testing.T) {
    38  			N := 1000
    39  			for i := 0; i < N; i++ {
    40  				original := reflect.New(reflect.TypeOf(test)).Interface()
    41  
    42  				fuzzer.Fuzz(original)
    43  
    44  				reflectCopy := ReflectDeepCopy(original)
    45  
    46  				if !reflect.DeepEqual(original, reflectCopy) {
    47  					t.Errorf("original and reflectCopy are different:\n\n  original = %s\n\n  jsonCopy = %s", spew.Sdump(original), spew.Sdump(reflectCopy))
    48  				}
    49  
    50  				deepCopy := reflect.ValueOf(original).MethodByName("DeepCopy").Call(nil)[0].Interface()
    51  
    52  				if !reflect.DeepEqual(original, deepCopy) {
    53  					t.Fatalf("original and deepCopy are different:\n\n  original = %s\n\n  deepCopy() = %s", spew.Sdump(original), spew.Sdump(deepCopy))
    54  				}
    55  
    56  				ValueFuzz(original)
    57  
    58  				if !reflect.DeepEqual(reflectCopy, deepCopy) {
    59  					t.Fatalf("reflectCopy and deepCopy are different:\n\n  origin = %s\n\n  jsonCopy() = %s", spew.Sdump(original), spew.Sdump(deepCopy))
    60  				}
    61  			}
    62  		})
    63  	}
    64  }
    65  
    66  func BenchmarkReflectDeepCopy(b *testing.B) {
    67  	fourtytwo := "fourtytwo"
    68  	fourtytwoPtr := &fourtytwo
    69  	var nilMap map[string]string
    70  	var nilSlice []string
    71  	mapPtr := &map[string]string{"0": "fourtytwo", "1": "fourtytwo"}
    72  	slicePtr := &[]string{"fourtytwo", "fourtytwo", "fourtytwo"}
    73  	structPtr := &pointer.Ttest{
    74  		Builtin: &fourtytwo,
    75  		Ptr:     &fourtytwoPtr,
    76  	}
    77  
    78  	tests := []interface{}{
    79  		maps.Ttest{
    80  			Byte:         map[string]byte{"0": 42, "1": 42, "3": 42},
    81  			Int16:        map[string]int16{"0": 42, "1": 42, "3": 42},
    82  			Int32:        map[string]int32{"0": 42, "1": 42, "3": 42},
    83  			Int64:        map[string]int64{"0": 42, "1": 42, "3": 42},
    84  			Uint8:        map[string]uint8{"0": 42, "1": 42, "3": 42},
    85  			Uint16:       map[string]uint16{"0": 42, "1": 42, "3": 42},
    86  			Uint32:       map[string]uint32{"0": 42, "1": 42, "3": 42},
    87  			Uint64:       map[string]uint64{"0": 42, "1": 42, "3": 42},
    88  			Float32:      map[string]float32{"0": 42.0, "1": 42.0, "3": 42.0},
    89  			Float64:      map[string]float64{"0": 42, "1": 42, "3": 42},
    90  			String:       map[string]string{"0": "fourtytwo", "1": "fourtytwo", "3": "fourtytwo"},
    91  			StringPtr:    map[string]*string{"0": &fourtytwo, "1": &fourtytwo, "3": &fourtytwo},
    92  			StringPtrPtr: map[string]**string{"0": &fourtytwoPtr, "1": &fourtytwoPtr, "3": &fourtytwoPtr},
    93  			Map:          map[string]map[string]string{"0": nil, "1": {"a": fourtytwo, "b": fourtytwo}, "3": {}},
    94  			MapPtr:       map[string]*map[string]string{"0": nil, "1": {"a": fourtytwo, "b": fourtytwo}, "3": &nilMap},
    95  			Slice:        map[string][]string{"0": nil, "1": {"a", "b"}, "2": {}},
    96  			SlicePtr:     map[string]*[]string{"0": nil, "1": {"a", "b"}, "2": &nilSlice},
    97  			Struct:       map[string]maps.Ttest{"0": {}, "1": {Byte: map[string]byte{"0": 42, "1": 42, "3": 42}}},
    98  			StructPtr:    map[string]*maps.Ttest{"0": nil, "1": {}, "2": {Byte: map[string]byte{"0": 42, "1": 42, "3": 42}}},
    99  		},
   100  		slices.Ttest{
   101  			Byte:         []byte{42, 42, 42},
   102  			Int16:        []int16{42, 42, 42},
   103  			Int32:        []int32{42, 42, 42},
   104  			Int64:        []int64{42, 42, 42},
   105  			Uint8:        []uint8{42, 42, 42},
   106  			Uint16:       []uint16{42, 42, 42},
   107  			Uint32:       []uint32{42, 42, 42},
   108  			Uint64:       []uint64{42, 42, 42},
   109  			Float32:      []float32{42.0, 42.0, 42.0},
   110  			Float64:      []float64{42, 42, 42},
   111  			String:       []string{"fourtytwo", "fourtytwo", "fourtytwo"},
   112  			StringPtr:    []*string{&fourtytwo, &fourtytwo, &fourtytwo},
   113  			StringPtrPtr: []**string{&fourtytwoPtr, &fourtytwoPtr, &fourtytwoPtr},
   114  			Map:          []map[string]string{nil, {"a": fourtytwo, "b": fourtytwo}, {}},
   115  			MapPtr:       []*map[string]string{nil, {"a": fourtytwo, "b": fourtytwo}, &nilMap},
   116  			Slice:        [][]string{nil, {"a", "b"}, {}},
   117  			SlicePtr:     []*[]string{nil, {"a", "b"}, &nilSlice},
   118  			Struct:       []slices.Ttest{{}, {Byte: []byte{42, 42, 42}}},
   119  			StructPtr:    []*slices.Ttest{nil, {}, {Byte: []byte{42, 42, 42}}},
   120  		},
   121  		pointer.Ttest{
   122  			Builtin:  &fourtytwo,
   123  			Ptr:      &fourtytwoPtr,
   124  			Map:      &map[string]string{"0": "fourtytwo", "1": "fourtytwo"},
   125  			Slice:    &[]string{"fourtytwo", "fourtytwo", "fourtytwo"},
   126  			MapPtr:   &mapPtr,
   127  			SlicePtr: &slicePtr,
   128  			Struct: &pointer.Ttest{
   129  				Builtin: &fourtytwo,
   130  				Ptr:     &fourtytwoPtr,
   131  			},
   132  			StructPtr: &structPtr,
   133  		},
   134  	}
   135  
   136  	fuzzer := fuzz.New()
   137  	fuzzer.NilChance(0.5)
   138  	fuzzer.NumElements(0, 2)
   139  	fuzzer.Funcs(interfaceFuzzers...)
   140  
   141  	for _, test := range tests {
   142  		b.Run(fmt.Sprintf("%T", test), func(b *testing.B) {
   143  			for i := 0; i < b.N; i++ {
   144  				switch t := test.(type) {
   145  				case maps.Ttest:
   146  					t.DeepCopy()
   147  				case slices.Ttest:
   148  					t.DeepCopy()
   149  				case pointer.Ttest:
   150  					t.DeepCopy()
   151  				default:
   152  					b.Fatalf("missing type case in switch for %T", t)
   153  				}
   154  			}
   155  		})
   156  	}
   157  }