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  }