github.com/waldiirawan/apm-agent-go/v2@v2.2.2/spancontext_test.go (about) 1 // Licensed to Elasticsearch B.V. under one or more contributor 2 // license agreements. See the NOTICE file distributed with 3 // this work for additional information regarding copyright 4 // ownership. Elasticsearch B.V. licenses this file to you under 5 // the Apache License, Version 2.0 (the "License"); you may 6 // not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, 12 // software distributed under the License is distributed on an 13 // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 14 // KIND, either express or implied. See the License for the 15 // specific language governing permissions and limitations 16 // under the License. 17 18 package apm_test 19 20 import ( 21 "context" 22 "fmt" 23 "net/http" 24 "net/url" 25 "testing" 26 27 "github.com/stretchr/testify/assert" 28 "github.com/stretchr/testify/require" 29 30 "github.com/waldiirawan/apm-agent-go/v2" 31 "github.com/waldiirawan/apm-agent-go/v2/apmtest" 32 "github.com/waldiirawan/apm-agent-go/v2/model" 33 ) 34 35 func TestSpanContextSetLabel(t *testing.T) { 36 _, spans, _ := apmtest.WithTransaction(func(ctx context.Context) { 37 span, _ := apm.StartSpan(ctx, "name", "type") 38 span.Context.SetLabel("foo", "bar") 39 span.Context.SetLabel("foo", "bar!") // Last instance wins 40 span.Context.SetLabel("bar", "baz") 41 span.Context.SetLabel("baz", 123.456) 42 span.Context.SetLabel("qux", true) 43 span.End() 44 }) 45 require.Len(t, spans, 1) 46 assert.Equal(t, model.IfaceMap{ 47 {Key: "bar", Value: "baz"}, 48 {Key: "baz", Value: 123.456}, 49 {Key: "foo", Value: "bar!"}, 50 {Key: "qux", Value: true}, 51 }, spans[0].Context.Tags) 52 } 53 54 func TestSpanContextSetHTTPRequest(t *testing.T) { 55 type testcase struct { 56 url string 57 58 addr string 59 port int 60 name string 61 resource string 62 } 63 64 testcases := []testcase{{ 65 url: "http://localhost/foo/bar", 66 addr: "localhost", 67 port: 80, 68 name: "http://localhost", 69 resource: "localhost:80", 70 }, { 71 url: "http://localhost:80/foo/bar", 72 addr: "localhost", 73 port: 80, 74 name: "http://localhost", 75 resource: "localhost:80", 76 }, { 77 url: "https://[::1]/foo/bar", 78 addr: "::1", 79 port: 443, 80 name: "https://[::1]", 81 resource: "[::1]:443", 82 }, { 83 url: "https://[::1]:8443/foo/bar", 84 addr: "::1", 85 port: 8443, 86 name: "https://[::1]:8443", 87 resource: "[::1]:8443", 88 }, { 89 url: "gopher://gopher.invalid:70", 90 addr: "gopher.invalid", 91 port: 70, 92 name: "gopher://gopher.invalid:70", 93 resource: "gopher.invalid:70", 94 }, { 95 url: "gopher://gopher.invalid", 96 addr: "gopher.invalid", 97 port: 0, 98 name: "gopher://gopher.invalid", 99 resource: "gopher.invalid", 100 }} 101 102 for _, tc := range testcases { 103 t.Run(tc.url, func(t *testing.T) { 104 url, err := url.Parse(tc.url) 105 require.NoError(t, err) 106 107 _, spans, _ := apmtest.WithTransaction(func(ctx context.Context) { 108 span, _ := apm.StartSpanOptions(ctx, "name", "http", apm.SpanOptions{ 109 ExitSpan: true, 110 }) 111 span.Context.SetHTTPRequest(&http.Request{URL: url}) 112 span.End() 113 }) 114 require.Len(t, spans, 1) 115 116 assert.Equal(t, &model.DestinationSpanContext{ 117 Address: tc.addr, 118 Port: tc.port, 119 Service: &model.DestinationServiceSpanContext{ 120 Type: spans[0].Type, 121 Name: tc.name, 122 Resource: tc.resource, 123 }, 124 }, spans[0].Context.Destination) 125 assert.Equal(t, &model.ServiceTargetSpanContext{ 126 Type: "http", 127 Name: tc.resource, 128 }, spans[0].Context.Service.Target) 129 }) 130 } 131 } 132 133 func TestSetDestinationService(t *testing.T) { 134 type testcase struct { 135 name string 136 resource string 137 expectEmpty bool 138 } 139 140 testcases := []testcase{{ 141 resource: "", 142 expectEmpty: true, 143 }, { 144 resource: "nonempty", 145 expectEmpty: false, 146 }, { 147 resource: "", 148 expectEmpty: true, 149 }, { 150 resource: "nonempty", 151 }} 152 for _, tc := range testcases { 153 t.Run(fmt.Sprintf("%s_%s", tc.name, tc.resource), func(t *testing.T) { 154 _, spans, _ := apmtest.WithTransaction(func(ctx context.Context) { 155 span, _ := apm.StartSpan(ctx, "name", "span_type") 156 span.Context.SetDestinationAddress("testing.invalid", 123) 157 span.Context.SetDestinationService(apm.DestinationServiceSpanContext{ 158 Resource: tc.resource, 159 }) 160 span.End() 161 }) 162 require.Len(t, spans, 1) 163 if tc.expectEmpty { 164 assert.Nil(t, spans[0].Context.Destination.Service) 165 } else { 166 assert.Equal(t, &model.DestinationServiceSpanContext{ 167 Resource: tc.resource, 168 Type: "span_type", 169 }, spans[0].Context.Destination.Service) 170 } 171 }) 172 } 173 }