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