go.undefinedlabs.com/scopeagent@v0.4.2/tracer/testutil_test.go (about) 1 package tracer 2 3 import ( 4 "fmt" 5 "reflect" 6 "runtime" 7 "testing" 8 9 "github.com/opentracing/opentracing-go/log" 10 ) 11 12 // LogFieldValidator facilitates testing of Span.Log*() implementations. 13 // 14 // Usage: 15 // 16 // fv := log.NewLogFieldValidator(t, someLogStructure.Fields) 17 // fv. 18 // ExpectNextFieldEquals("key1", reflect.String, "some string value"). 19 // ExpectNextFieldEquals("key2", reflect.Uint32, "4294967295") 20 // 21 // LogFieldValidator satisfies the log.Encoder interface and thus is able to 22 // marshal log.Field instances (which it takes advantage of internally). 23 type LogFieldValidator struct { 24 t *testing.T 25 fieldIdx int 26 fields []log.Field 27 nextKey string 28 nextKind reflect.Kind 29 nextValAsString string 30 } 31 32 // NewLogFieldValidator returns a new validator that will test the contents of 33 // `fields`. 34 func NewLogFieldValidator(t *testing.T, fields []log.Field) *LogFieldValidator { 35 return &LogFieldValidator{ 36 t: t, 37 fields: fields, 38 } 39 } 40 41 // ExpectNextFieldEquals facilitates a fluent way of testing the contents 42 // []Field slices. 43 func (fv *LogFieldValidator) ExpectNextFieldEquals(key string, kind reflect.Kind, valAsString string) *LogFieldValidator { 44 if len(fv.fields) < fv.fieldIdx { 45 _, file, line, _ := runtime.Caller(1) 46 fv.t.Errorf("%s:%d Expecting more than the %v Fields we have", file, line, len(fv.fields)) 47 } 48 fv.nextKey = key 49 fv.nextKind = kind 50 fv.nextValAsString = valAsString 51 fv.fields[fv.fieldIdx].Marshal(fv) 52 fv.fieldIdx++ 53 return fv 54 } 55 56 // EmitString satisfies the Encoder interface 57 func (fv *LogFieldValidator) EmitString(key, value string) { 58 fv.validateNextField(key, reflect.String, value) 59 } 60 61 // EmitBool satisfies the Encoder interface 62 func (fv *LogFieldValidator) EmitBool(key string, value bool) { 63 fv.validateNextField(key, reflect.Bool, value) 64 } 65 66 // EmitInt satisfies the Encoder interface 67 func (fv *LogFieldValidator) EmitInt(key string, value int) { 68 fv.validateNextField(key, reflect.Int, value) 69 } 70 71 // EmitInt32 satisfies the Encoder interface 72 func (fv *LogFieldValidator) EmitInt32(key string, value int32) { 73 fv.validateNextField(key, reflect.Int32, value) 74 } 75 76 // EmitInt64 satisfies the Encoder interface 77 func (fv *LogFieldValidator) EmitInt64(key string, value int64) { 78 fv.validateNextField(key, reflect.Int64, value) 79 } 80 81 // EmitUint32 satisfies the Encoder interface 82 func (fv *LogFieldValidator) EmitUint32(key string, value uint32) { 83 fv.validateNextField(key, reflect.Uint32, value) 84 } 85 86 // EmitUint64 satisfies the Encoder interface 87 func (fv *LogFieldValidator) EmitUint64(key string, value uint64) { 88 fv.validateNextField(key, reflect.Uint64, value) 89 } 90 91 // EmitFloat32 satisfies the Encoder interface 92 func (fv *LogFieldValidator) EmitFloat32(key string, value float32) { 93 fv.validateNextField(key, reflect.Float32, value) 94 } 95 96 // EmitFloat64 satisfies the Encoder interface 97 func (fv *LogFieldValidator) EmitFloat64(key string, value float64) { 98 fv.validateNextField(key, reflect.Float64, value) 99 } 100 101 // EmitObject satisfies the Encoder interface 102 func (fv *LogFieldValidator) EmitObject(key string, value interface{}) { 103 fv.validateNextField(key, reflect.Interface, value) 104 } 105 106 // EmitLazyLogger satisfies the Encoder interface 107 func (fv *LogFieldValidator) EmitLazyLogger(value log.LazyLogger) { 108 fv.t.Error("Test infrastructure does not support EmitLazyLogger yet") 109 } 110 111 func (fv *LogFieldValidator) validateNextField(key string, actualKind reflect.Kind, value interface{}) { 112 // Reference the ExpectNextField caller in error messages. 113 _, file, line, _ := runtime.Caller(4) 114 if fv.nextKey != key { 115 fv.t.Errorf("%s:%d Bad key: expected %q, found %q", file, line, fv.nextKey, key) 116 } 117 if fv.nextKind != actualKind { 118 fv.t.Errorf("%s:%d Bad reflect.Kind: expected %v, found %v", file, line, fv.nextKind, actualKind) 119 return 120 } 121 if fv.nextValAsString != fmt.Sprint(value) { 122 fv.t.Errorf("%s:%d Bad value: expected %q, found %q", file, line, fv.nextValAsString, fmt.Sprint(value)) 123 } 124 // All good. 125 }