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 }