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  }