github.com/newrelic/go-agent@v3.26.0+incompatible/internal/errors_test.go (about)

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package internal
     5  
     6  import (
     7  	"encoding/json"
     8  	"errors"
     9  	"testing"
    10  	"time"
    11  )
    12  
    13  var (
    14  	emptyStackTrace = make([]uintptr, 0)
    15  )
    16  
    17  func testExpectedJSON(t testing.TB, expect string, actual string) {
    18  	// Type assertion to support early Go versions.
    19  	if h, ok := t.(interface {
    20  		Helper()
    21  	}); ok {
    22  		h.Helper()
    23  	}
    24  	compactExpect := CompactJSONString(expect)
    25  	if compactExpect != actual {
    26  		t.Errorf("\nexpect=%s\nactual=%s\n", compactExpect, actual)
    27  	}
    28  }
    29  
    30  func TestErrorTraceMarshal(t *testing.T) {
    31  	he := &tracedError{
    32  		ErrorData: ErrorData{
    33  			When:  time.Date(2014, time.November, 28, 1, 1, 0, 0, time.UTC),
    34  			Stack: emptyStackTrace,
    35  			Msg:   "my_msg",
    36  			Klass: "my_class",
    37  		},
    38  		TxnEvent: TxnEvent{
    39  			FinalName: "my_txn_name",
    40  			Attrs:     nil,
    41  			BetterCAT: BetterCAT{
    42  				Enabled:  true,
    43  				ID:       "txn-id",
    44  				Priority: 0.5,
    45  			},
    46  			TotalTime: 2 * time.Second,
    47  		},
    48  	}
    49  	js, err := json.Marshal(he)
    50  	if nil != err {
    51  		t.Error(err)
    52  	}
    53  
    54  	expect := `
    55  	[
    56  		1.41713646e+12,
    57  		"my_txn_name",
    58  		"my_msg",
    59  		"my_class",
    60  		{
    61  			"agentAttributes":{},
    62  			"userAttributes":{},
    63  			"intrinsics":{
    64  				"totalTime":2,
    65  				"guid":"txn-id",
    66  				"traceId":"txn-id",
    67  				"priority":0.500000,
    68  				"sampled":false
    69  			},
    70  			"stack_trace":[]
    71  		}
    72  	]`
    73  	testExpectedJSON(t, expect, string(js))
    74  }
    75  
    76  func TestErrorTraceMarshalOldCAT(t *testing.T) {
    77  	he := &tracedError{
    78  		ErrorData: ErrorData{
    79  			When:  time.Date(2014, time.November, 28, 1, 1, 0, 0, time.UTC),
    80  			Stack: emptyStackTrace,
    81  			Msg:   "my_msg",
    82  			Klass: "my_class",
    83  		},
    84  		TxnEvent: TxnEvent{
    85  			FinalName: "my_txn_name",
    86  			Attrs:     nil,
    87  			BetterCAT: BetterCAT{
    88  				Enabled: false,
    89  			},
    90  			TotalTime: 2 * time.Second,
    91  		},
    92  	}
    93  	js, err := json.Marshal(he)
    94  	if nil != err {
    95  		t.Error(err)
    96  	}
    97  
    98  	expect := `
    99  	[
   100  		1.41713646e+12,
   101  		"my_txn_name",
   102  		"my_msg",
   103  		"my_class",
   104  		{
   105  			"agentAttributes":{},
   106  			"userAttributes":{},
   107  			"intrinsics":{
   108  				"totalTime":2
   109  			},
   110  			"stack_trace":[]
   111  		}
   112  	]`
   113  	testExpectedJSON(t, expect, string(js))
   114  }
   115  
   116  func TestErrorTraceAttributes(t *testing.T) {
   117  	aci := sampleAttributeConfigInput
   118  	aci.ErrorCollector.Exclude = append(aci.ErrorCollector.Exclude, "zap")
   119  	aci.ErrorCollector.Exclude = append(aci.ErrorCollector.Exclude, AttributeHostDisplayName.name())
   120  	cfg := CreateAttributeConfig(aci, true)
   121  	attr := NewAttributes(cfg)
   122  	attr.Agent.Add(AttributeHostDisplayName, "exclude me", nil)
   123  	attr.Agent.Add(attributeRequestURI, "my_request_uri", nil)
   124  	AddUserAttribute(attr, "zap", 123, DestAll)
   125  	AddUserAttribute(attr, "zip", 456, DestAll)
   126  
   127  	he := &tracedError{
   128  		ErrorData: ErrorData{
   129  			When:  time.Date(2014, time.November, 28, 1, 1, 0, 0, time.UTC),
   130  			Stack: nil,
   131  			Msg:   "my_msg",
   132  			Klass: "my_class",
   133  		},
   134  		TxnEvent: TxnEvent{
   135  			FinalName: "my_txn_name",
   136  			Attrs:     attr,
   137  			BetterCAT: BetterCAT{
   138  				Enabled:  true,
   139  				ID:       "txn-id",
   140  				Priority: 0.5,
   141  			},
   142  			TotalTime: 2 * time.Second,
   143  		},
   144  	}
   145  	js, err := json.Marshal(he)
   146  	if nil != err {
   147  		t.Error(err)
   148  	}
   149  	expect := `
   150  	[
   151  		1.41713646e+12,
   152  		"my_txn_name",
   153  		"my_msg",
   154  		"my_class",
   155  		{
   156  			"agentAttributes":{"request.uri":"my_request_uri"},
   157  			"userAttributes":{"zip":456},
   158  			"intrinsics":{
   159  				"totalTime":2,
   160  				"guid":"txn-id",
   161  				"traceId":"txn-id",
   162  				"priority":0.500000,
   163  				"sampled":false
   164  			}
   165  		}
   166  	]`
   167  	testExpectedJSON(t, expect, string(js))
   168  }
   169  
   170  func TestErrorTraceAttributesOldCAT(t *testing.T) {
   171  	aci := sampleAttributeConfigInput
   172  	aci.ErrorCollector.Exclude = append(aci.ErrorCollector.Exclude, "zap")
   173  	aci.ErrorCollector.Exclude = append(aci.ErrorCollector.Exclude, AttributeHostDisplayName.name())
   174  	cfg := CreateAttributeConfig(aci, true)
   175  	attr := NewAttributes(cfg)
   176  	attr.Agent.Add(AttributeHostDisplayName, "exclude me", nil)
   177  	attr.Agent.Add(attributeRequestURI, "my_request_uri", nil)
   178  	AddUserAttribute(attr, "zap", 123, DestAll)
   179  	AddUserAttribute(attr, "zip", 456, DestAll)
   180  
   181  	he := &tracedError{
   182  		ErrorData: ErrorData{
   183  			When:  time.Date(2014, time.November, 28, 1, 1, 0, 0, time.UTC),
   184  			Stack: nil,
   185  			Msg:   "my_msg",
   186  			Klass: "my_class",
   187  		},
   188  		TxnEvent: TxnEvent{
   189  			FinalName: "my_txn_name",
   190  			Attrs:     attr,
   191  			BetterCAT: BetterCAT{
   192  				Enabled: false,
   193  			},
   194  			TotalTime: 2 * time.Second,
   195  		},
   196  	}
   197  	js, err := json.Marshal(he)
   198  	if nil != err {
   199  		t.Error(err)
   200  	}
   201  	expect := `
   202  	[
   203  		1.41713646e+12,
   204  		"my_txn_name",
   205  		"my_msg",
   206  		"my_class",
   207  		{
   208  			"agentAttributes":{"request.uri":"my_request_uri"},
   209  			"userAttributes":{"zip":456},
   210  			"intrinsics":{
   211  				"totalTime":2
   212  			}
   213  		}
   214  	]`
   215  	testExpectedJSON(t, expect, string(js))
   216  }
   217  
   218  func TestErrorsLifecycle(t *testing.T) {
   219  	ers := NewTxnErrors(5)
   220  
   221  	when := time.Date(2014, time.November, 28, 1, 1, 0, 0, time.UTC)
   222  	ers.Add(TxnErrorFromResponseCode(when, 15))
   223  	ers.Add(TxnErrorFromResponseCode(when, 400))
   224  	ers.Add(TxnErrorFromPanic(when, errors.New("oh no panic")))
   225  	ers.Add(TxnErrorFromPanic(when, 123))
   226  	ers.Add(TxnErrorFromPanic(when, 123))
   227  
   228  	he := newHarvestErrors(4)
   229  	MergeTxnErrors(&he, ers, TxnEvent{
   230  		FinalName: "txnName",
   231  		Attrs:     nil,
   232  		BetterCAT: BetterCAT{
   233  			Enabled:  true,
   234  			ID:       "txn-id",
   235  			Priority: 0.5,
   236  		},
   237  		TotalTime: 2 * time.Second,
   238  	})
   239  	js, err := he.Data("agentRunID", time.Now())
   240  	if nil != err {
   241  		t.Error(err)
   242  	}
   243  	expect := CompactJSONString(`
   244  [
   245     "agentRunID",
   246     [
   247        [
   248           1.41713646e+12,
   249           "txnName",
   250           "response code 15",
   251           "15",
   252           {
   253              "agentAttributes":{},
   254              "userAttributes":{},
   255              "intrinsics":{
   256                 "totalTime":2,
   257                 "guid":"txn-id",
   258                 "traceId":"txn-id",
   259                 "priority":0.500000,
   260                 "sampled":false
   261              }
   262           }
   263        ],
   264        [
   265           1.41713646e+12,
   266           "txnName",
   267           "Bad Request",
   268           "400",
   269           {
   270              "agentAttributes":{},
   271              "userAttributes":{},
   272              "intrinsics":{
   273                 "totalTime":2,
   274                 "guid":"txn-id",
   275                 "traceId":"txn-id",
   276                 "priority":0.500000,
   277                 "sampled":false
   278              }
   279           }
   280        ],
   281        [
   282           1.41713646e+12,
   283           "txnName",
   284           "oh no panic",
   285           "panic",
   286           {
   287              "agentAttributes":{},
   288              "userAttributes":{},
   289              "intrinsics":{
   290                 "totalTime":2,
   291                 "guid":"txn-id",
   292                 "traceId":"txn-id",
   293                 "priority":0.500000,
   294                 "sampled":false
   295              }
   296           }
   297        ],
   298        [
   299           1.41713646e+12,
   300           "txnName",
   301           "123",
   302           "panic",
   303           {
   304              "agentAttributes":{},
   305              "userAttributes":{},
   306              "intrinsics":{
   307                 "totalTime":2,
   308                 "guid":"txn-id",
   309                 "traceId":"txn-id",
   310                 "priority":0.500000,
   311                 "sampled":false
   312              }
   313           }
   314        ]
   315     ]
   316  ]`)
   317  	if string(js) != expect {
   318  		t.Error(string(js), expect)
   319  	}
   320  }
   321  
   322  func BenchmarkErrorsJSON(b *testing.B) {
   323  	when := time.Date(2014, time.November, 28, 1, 1, 0, 0, time.UTC)
   324  	max := 20
   325  	ers := NewTxnErrors(max)
   326  
   327  	for i := 0; i < max; i++ {
   328  		ers.Add(ErrorData{
   329  			When:  time.Date(2014, time.November, 28, 1, 1, 0, 0, time.UTC),
   330  			Msg:   "error message",
   331  			Klass: "error class",
   332  		})
   333  	}
   334  
   335  	cfg := CreateAttributeConfig(sampleAttributeConfigInput, true)
   336  	attr := NewAttributes(cfg)
   337  	attr.Agent.Add(attributeRequestMethod, "GET", nil)
   338  	AddUserAttribute(attr, "zip", 456, DestAll)
   339  
   340  	he := newHarvestErrors(max)
   341  	MergeTxnErrors(&he, ers, TxnEvent{
   342  		FinalName: "WebTransaction/Go/hello",
   343  		Attrs:     attr,
   344  	})
   345  
   346  	b.ReportAllocs()
   347  	b.ResetTimer()
   348  
   349  	for n := 0; n < b.N; n++ {
   350  		js, err := he.Data("agentRundID", when)
   351  		if nil != err || nil == js {
   352  			b.Fatal(err, js)
   353  		}
   354  	}
   355  }