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  }