github.com/QuangHoangHao/kafka-go@v0.4.36/protocol/prototest/prototest.go (about) 1 package prototest 2 3 import ( 4 "bytes" 5 "errors" 6 "io" 7 "reflect" 8 "time" 9 10 "github.com/QuangHoangHao/kafka-go/protocol" 11 ) 12 13 func deepEqual(x1, x2 interface{}) bool { 14 if x1 == nil { 15 return x2 == nil 16 } 17 if r1, ok := x1.(protocol.RecordReader); ok { 18 if r2, ok := x2.(protocol.RecordReader); ok { 19 return deepEqualRecords(r1, r2) 20 } 21 return false 22 } 23 if b1, ok := x1.(protocol.Bytes); ok { 24 if b2, ok := x2.(protocol.Bytes); ok { 25 return deepEqualBytes(b1, b2) 26 } 27 return false 28 } 29 if t1, ok := x1.(time.Time); ok { 30 if t2, ok := x2.(time.Time); ok { 31 return t1.Equal(t2) 32 } 33 return false 34 } 35 return deepEqualValue(reflect.ValueOf(x1), reflect.ValueOf(x2)) 36 } 37 38 func deepEqualValue(v1, v2 reflect.Value) bool { 39 t1 := v1.Type() 40 t2 := v2.Type() 41 42 if t1 != t2 { 43 return false 44 } 45 46 switch v1.Kind() { 47 case reflect.Bool: 48 return v1.Bool() == v2.Bool() 49 case reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64: 50 return v1.Int() == v2.Int() 51 case reflect.String: 52 return v1.String() == v2.String() 53 case reflect.Struct: 54 return deepEqualStruct(v1, v2) 55 case reflect.Ptr: 56 return deepEqualPtr(v1, v2) 57 case reflect.Slice: 58 return deepEqualSlice(v1, v2) 59 default: 60 panic("comparing values of unsupported type: " + v1.Type().String()) 61 } 62 } 63 64 func deepEqualPtr(v1, v2 reflect.Value) bool { 65 if v1.IsNil() { 66 return v2.IsNil() 67 } 68 return deepEqual(v1.Elem().Interface(), v2.Elem().Interface()) 69 } 70 71 func deepEqualStruct(v1, v2 reflect.Value) bool { 72 t := v1.Type() 73 n := t.NumField() 74 75 for i := 0; i < n; i++ { 76 f := t.Field(i) 77 78 if f.PkgPath != "" { // ignore unexported fields 79 continue 80 } 81 82 f1 := v1.Field(i) 83 f2 := v2.Field(i) 84 85 if !deepEqual(f1.Interface(), f2.Interface()) { 86 return false 87 } 88 } 89 90 return true 91 } 92 93 func deepEqualSlice(v1, v2 reflect.Value) bool { 94 t := v1.Type() 95 e := t.Elem() 96 97 if e.Kind() == reflect.Uint8 { // []byte 98 return bytes.Equal(v1.Bytes(), v2.Bytes()) 99 } 100 101 n1 := v1.Len() 102 n2 := v2.Len() 103 104 if n1 != n2 { 105 return false 106 } 107 108 for i := 0; i < n1; i++ { 109 f1 := v1.Index(i) 110 f2 := v2.Index(i) 111 112 if !deepEqual(f1.Interface(), f2.Interface()) { 113 return false 114 } 115 } 116 117 return true 118 } 119 120 func deepEqualBytes(s1, s2 protocol.Bytes) bool { 121 if s1 == nil { 122 return s2 == nil 123 } 124 125 if s2 == nil { 126 return false 127 } 128 129 n1 := s1.Len() 130 n2 := s2.Len() 131 132 if n1 != n2 { 133 return false 134 } 135 136 b1 := make([]byte, n1) 137 b2 := make([]byte, n2) 138 139 if _, err := s1.(io.ReaderAt).ReadAt(b1, 0); err != nil { 140 panic(err) 141 } 142 143 if _, err := s2.(io.ReaderAt).ReadAt(b2, 0); err != nil { 144 panic(err) 145 } 146 147 return bytes.Equal(b1, b2) 148 } 149 150 func deepEqualRecords(r1, r2 protocol.RecordReader) bool { 151 for { 152 rec1, err1 := r1.ReadRecord() 153 rec2, err2 := r2.ReadRecord() 154 155 if err1 != nil || err2 != nil { 156 return errors.Is(err1, err2) 157 } 158 159 if !deepEqualRecord(rec1, rec2) { 160 return false 161 } 162 } 163 } 164 165 func deepEqualRecord(r1, r2 *protocol.Record) bool { 166 if r1.Offset != r2.Offset { 167 return false 168 } 169 170 if !r1.Time.Equal(r2.Time) { 171 return false 172 } 173 174 if !deepEqualBytes(r1.Key, r2.Key) { 175 return false 176 } 177 178 if !deepEqualBytes(r1.Value, r2.Value) { 179 return false 180 } 181 182 return deepEqual(r1.Headers, r2.Headers) 183 }