go.uber.org/yarpc@v1.72.1/serialize/serialize_test.go (about) 1 // Copyright (c) 2022 Uber Technologies, Inc. 2 // 3 // Permission is hereby granted, free of charge, to any person obtaining a copy 4 // of this software and associated documentation files (the "Software"), to deal 5 // in the Software without restriction, including without limitation the rights 6 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 // copies of the Software, and to permit persons to whom the Software is 8 // furnished to do so, subject to the following conditions: 9 // 10 // The above copyright notice and this permission notice shall be included in 11 // all copies or substantial portions of the Software. 12 // 13 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 19 // THE SOFTWARE. 20 21 package serialize 22 23 import ( 24 "bytes" 25 "context" 26 "testing" 27 "time" 28 29 "github.com/opentracing/opentracing-go" 30 "github.com/stretchr/testify/assert" 31 "github.com/stretchr/testify/require" 32 jaeger "github.com/uber/jaeger-client-go" 33 "go.uber.org/yarpc/api/transport" 34 "go.uber.org/yarpc/api/transport/transporttest" 35 ) 36 37 func TestSerialization(t *testing.T) { 38 tracer := opentracing.NoopTracer{} 39 spanContext := tracer.StartSpan("test-span").Context() 40 41 headers := map[string]string{ 42 "hello": "world", 43 "foo": "bar", 44 } 45 body := []byte( 46 "My mind is tellin' me no... but my body... my body's tellin' me yes", 47 ) 48 49 haveReq := &transport.Request{ 50 Caller: "Caller", 51 Service: "ServiceName", 52 Encoding: "Encoding", 53 Procedure: "Procedure", 54 Headers: transport.HeadersFromMap(headers), 55 ShardKey: "ShardKey", 56 RoutingKey: "RoutingKey", 57 RoutingDelegate: "RoutingDelegate", 58 Body: bytes.NewReader(body), 59 } 60 61 matcher := transporttest.NewRequestMatcher(t, haveReq) 62 63 marshalledReq, err := ToBytes(tracer, spanContext, haveReq) 64 require.NoError(t, err, "could not marshal RPC to bytes") 65 assert.NotEmpty(t, marshalledReq) 66 assert.Equal(t, byte(0), marshalledReq[0], "serialization byte invalid") 67 68 _, gotReq, err := FromBytes(tracer, marshalledReq) 69 require.NoError(t, err, "could not unmarshal RPC from bytes") 70 71 assert.True(t, matcher.Matches(gotReq)) 72 } 73 74 func TestDeserializationFailure(t *testing.T) { 75 tracer := opentracing.NoopTracer{} 76 spanContext := tracer.StartSpan("test-span").Context() 77 78 req := &transport.Request{ 79 Caller: "Caller", 80 Service: "ServiceName", 81 Procedure: "Procedure", 82 Body: bytes.NewReader([]byte("someBODY")), 83 } 84 85 marshalledReq, err := ToBytes(tracer, spanContext, req) 86 require.NoError(t, err, "could not marshal RPC to bytes") 87 require.NotEmpty(t, marshalledReq) 88 89 // modify serialization byte to something unsupported 90 marshalledReq[0] = 1 91 92 _, _, err = FromBytes(tracer, marshalledReq) 93 assert.Error(t, err, "able to deserialize RPC from bytes") 94 } 95 96 func TestContextSerialization(t *testing.T) { 97 tracer, closer := initTracer() 98 defer closer() 99 100 req := &transport.Request{} 101 baggage := map[string]string{ 102 "hello": "world", 103 "foo": "bar", 104 ":)": ":(", 105 } 106 107 createOpenTracingSpan := transport.CreateOpenTracingSpan{ 108 Tracer: tracer, 109 TransportName: "fake-transport", 110 StartTime: time.Now(), 111 } 112 113 _, span := createOpenTracingSpan.Do(context.Background(), req) 114 addBaggage(span, baggage) 115 span.Finish() 116 117 spanCtxBytes, err := spanContextToBytes(tracer, span.Context()) 118 assert.NoError(t, err) 119 assert.NotEmpty(t, spanCtxBytes) 120 121 spanContext, err := spanContextFromBytes(tracer, spanCtxBytes) 122 assert.NoError(t, err) 123 assert.NotNil(t, span) 124 125 extractOpenTracingSpan := transport.ExtractOpenTracingSpan{ 126 ParentSpanContext: spanContext, 127 Tracer: tracer, 128 TransportName: "fake-transport", 129 StartTime: time.Now(), 130 } 131 132 _, span = extractOpenTracingSpan.Do(context.Background(), req) 133 defer span.Finish() 134 135 assert.Equal(t, baggage, getBaggage(span)) 136 } 137 138 func initTracer() (opentracing.Tracer, func() error) { 139 tracer, closer := jaeger.NewTracer( 140 "internal-propagation", 141 jaeger.NewConstSampler(true), 142 jaeger.NewNullReporter()) 143 opentracing.InitGlobalTracer(tracer) 144 return tracer, closer.Close 145 } 146 147 func addBaggage(span opentracing.Span, baggage map[string]string) { 148 for k, v := range baggage { 149 span.SetBaggageItem(k, v) 150 } 151 } 152 func getBaggage(span opentracing.Span) map[string]string { 153 baggage := make(map[string]string) 154 span.Context().ForeachBaggageItem(func(k, v string) bool { 155 baggage[k] = v 156 return true 157 }) 158 159 return baggage 160 }