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

     1  // Copyright 2020 New Relic Corporation. All rights reserved.
     2  // SPDX-License-Identifier: Apache-2.0
     3  
     4  package newrelic
     5  
     6  import (
     7  	"reflect"
     8  	"testing"
     9  
    10  	"github.com/newrelic/go-agent/internal"
    11  )
    12  
    13  func browserReplyFields(reply *internal.ConnectReply) {
    14  	reply.AgentLoader = "loader"
    15  	reply.Beacon = "beacon"
    16  	reply.BrowserKey = "key"
    17  	reply.AppID = "app"
    18  	reply.ErrorBeacon = "error"
    19  	reply.JSAgentFile = "agent"
    20  }
    21  
    22  func TestBrowserTimingHeaderSuccess(t *testing.T) {
    23  	includeAttributes := func(cfg *Config) {
    24  		cfg.BrowserMonitoring.Attributes.Enabled = true
    25  		cfg.BrowserMonitoring.Attributes.Include = []string{AttributeResponseCode}
    26  	}
    27  	app := testApp(browserReplyFields, includeAttributes, t)
    28  	txn := app.StartTransaction("hello", nil, nil)
    29  	txn.WriteHeader(200)
    30  	txn.AddAttribute("zip", "zap")
    31  	hdr, err := txn.BrowserTimingHeader()
    32  	if nil != err {
    33  		t.Fatal(err)
    34  	}
    35  
    36  	encodingKey := browserEncodingKey(testLicenseKey)
    37  	obfuscatedTxnName, _ := internal.Obfuscate([]byte("OtherTransaction/Go/hello"), encodingKey)
    38  	obfuscatedAttributes, _ := internal.Obfuscate([]byte(`{"u":{"zip":"zap"},"a":{"httpResponseCode":"200"}}`), encodingKey)
    39  
    40  	// This is a cheat: we can't deterministically set this, but DeepEqual
    41  	// doesn't have any ability to say "equal everything except these
    42  	// fields".
    43  	hdr.info.QueueTimeMillis = 12
    44  	hdr.info.ApplicationTimeMillis = 34
    45  	expected := &BrowserTimingHeader{
    46  		agentLoader: "loader",
    47  		info: browserInfo{
    48  			Beacon:                "beacon",
    49  			LicenseKey:            "key",
    50  			ApplicationID:         "app",
    51  			TransactionName:       obfuscatedTxnName,
    52  			QueueTimeMillis:       12,
    53  			ApplicationTimeMillis: 34,
    54  			ObfuscatedAttributes:  obfuscatedAttributes,
    55  			ErrorBeacon:           "error",
    56  			Agent:                 "agent",
    57  		},
    58  	}
    59  	if !reflect.DeepEqual(hdr, expected) {
    60  		txnName, _ := internal.Deobfuscate(hdr.info.TransactionName, encodingKey)
    61  		attr, _ := internal.Deobfuscate(hdr.info.ObfuscatedAttributes, encodingKey)
    62  		t.Errorf("header did not match: expected %#v; got %#v txnName=%s attr=%s",
    63  			expected, hdr, string(txnName), string(attr))
    64  	}
    65  }
    66  
    67  func TestBrowserTimingHeaderSuccessWithoutAttributes(t *testing.T) {
    68  	// Test that attributes do not get put in the browser footer by default
    69  	// configuration.
    70  
    71  	app := testApp(browserReplyFields, nil, t)
    72  	txn := app.StartTransaction("hello", nil, nil)
    73  	txn.WriteHeader(200)
    74  	txn.AddAttribute("zip", "zap")
    75  	hdr, err := txn.BrowserTimingHeader()
    76  	if nil != err {
    77  		t.Fatal(err)
    78  	}
    79  
    80  	encodingKey := browserEncodingKey(testLicenseKey)
    81  	obfuscatedTxnName, _ := internal.Obfuscate([]byte("OtherTransaction/Go/hello"), encodingKey)
    82  	obfuscatedAttributes, _ := internal.Obfuscate([]byte(`{"u":{},"a":{}}`), encodingKey)
    83  
    84  	// This is a cheat: we can't deterministically set this, but DeepEqual
    85  	// doesn't have any ability to say "equal everything except these
    86  	// fields".
    87  	hdr.info.QueueTimeMillis = 12
    88  	hdr.info.ApplicationTimeMillis = 34
    89  	expected := &BrowserTimingHeader{
    90  		agentLoader: "loader",
    91  		info: browserInfo{
    92  			Beacon:                "beacon",
    93  			LicenseKey:            "key",
    94  			ApplicationID:         "app",
    95  			TransactionName:       obfuscatedTxnName,
    96  			QueueTimeMillis:       12,
    97  			ApplicationTimeMillis: 34,
    98  			ObfuscatedAttributes:  obfuscatedAttributes,
    99  			ErrorBeacon:           "error",
   100  			Agent:                 "agent",
   101  		},
   102  	}
   103  	if !reflect.DeepEqual(hdr, expected) {
   104  		txnName, _ := internal.Deobfuscate(hdr.info.TransactionName, encodingKey)
   105  		attr, _ := internal.Deobfuscate(hdr.info.ObfuscatedAttributes, encodingKey)
   106  		t.Errorf("header did not match: expected %#v; got %#v txnName=%s attr=%s",
   107  			expected, hdr, string(txnName), string(attr))
   108  	}
   109  }
   110  
   111  func TestBrowserTimingHeaderDisabled(t *testing.T) {
   112  	disableBrowser := func(cfg *Config) {
   113  		cfg.BrowserMonitoring.Enabled = false
   114  	}
   115  	app := testApp(browserReplyFields, disableBrowser, t)
   116  	txn := app.StartTransaction("hello", nil, nil)
   117  	hdr, err := txn.BrowserTimingHeader()
   118  	if err != errBrowserDisabled {
   119  		t.Error(err)
   120  	}
   121  	if hdr.WithTags() != nil {
   122  		t.Error(hdr.WithTags())
   123  	}
   124  }
   125  
   126  func TestBrowserTimingHeaderNotConnected(t *testing.T) {
   127  	app := testApp(nil, nil, t)
   128  	txn := app.StartTransaction("hello", nil, nil)
   129  	hdr, err := txn.BrowserTimingHeader()
   130  	if err != nil {
   131  		// No error expected if the app is not yet connected.
   132  		t.Error(err)
   133  	}
   134  	if hdr.WithTags() != nil {
   135  		t.Error(hdr.WithTags())
   136  	}
   137  }
   138  
   139  func TestBrowserTimingHeaderAlreadyFinished(t *testing.T) {
   140  	app := testApp(browserReplyFields, nil, t)
   141  	txn := app.StartTransaction("hello", nil, nil)
   142  	txn.End()
   143  	hdr, err := txn.BrowserTimingHeader()
   144  	if err != errAlreadyEnded {
   145  		t.Error(err)
   146  	}
   147  	if hdr.WithTags() != nil {
   148  		t.Error(hdr.WithTags())
   149  	}
   150  }
   151  
   152  func TestBrowserTimingHeaderTxnIgnored(t *testing.T) {
   153  	app := testApp(browserReplyFields, nil, t)
   154  	txn := app.StartTransaction("hello", nil, nil)
   155  	txn.Ignore()
   156  	hdr, err := txn.BrowserTimingHeader()
   157  	if err != errTransactionIgnored {
   158  		t.Error(err)
   159  	}
   160  	if hdr.WithTags() != nil {
   161  		t.Error(hdr.WithTags())
   162  	}
   163  }
   164  
   165  func BenchmarkBrowserTimingHeaderSuccess(b *testing.B) {
   166  	app := testApp(browserReplyFields, nil, b)
   167  	txn := app.StartTransaction("my txn", nil, nil)
   168  
   169  	b.ResetTimer()
   170  	b.ReportAllocs()
   171  
   172  	for i := 0; i < b.N; i++ {
   173  		hdr, err := txn.BrowserTimingHeader()
   174  		if nil == hdr || nil != err {
   175  			b.Fatal(hdr, err)
   176  		}
   177  		hdr.WithTags()
   178  	}
   179  }