github.com/newrelic/go-agent@v3.26.0+incompatible/internal/custom_event_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 "strconv" 9 "testing" 10 "time" 11 ) 12 13 var ( 14 now = time.Date(2014, time.November, 28, 1, 1, 0, 0, time.UTC) 15 strLen512 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 16 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 17 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 18 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 19 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 20 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 21 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 22 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 23 strLen255 = "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 24 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 25 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" + 26 "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa" 27 ) 28 29 // Tests use a single key-value pair in params to ensure deterministic JSON 30 // ordering. 31 32 func TestCreateCustomEventSuccess(t *testing.T) { 33 event, err := CreateCustomEvent("myEvent", map[string]interface{}{"alpha": 1}, now) 34 if nil != err { 35 t.Fatal(err) 36 } 37 js, err := json.Marshal(event) 38 if nil != err { 39 t.Fatal(err) 40 } 41 if string(js) != `[{"type":"myEvent","timestamp":1.41713646e+09},{"alpha":1},{}]` { 42 t.Fatal(string(js)) 43 } 44 } 45 46 func TestInvalidEventTypeCharacter(t *testing.T) { 47 event, err := CreateCustomEvent("myEvent!", map[string]interface{}{"alpha": 1}, now) 48 if err != ErrEventTypeRegex { 49 t.Fatal(err) 50 } 51 if nil != event { 52 t.Fatal(event) 53 } 54 } 55 56 func TestLongEventType(t *testing.T) { 57 event, err := CreateCustomEvent(strLen512, map[string]interface{}{"alpha": 1}, now) 58 if err != errEventTypeLength { 59 t.Fatal(err) 60 } 61 if nil != event { 62 t.Fatal(event) 63 } 64 } 65 66 func TestNilParams(t *testing.T) { 67 event, err := CreateCustomEvent("myEvent", nil, now) 68 if nil != err { 69 t.Fatal(err) 70 } 71 js, err := json.Marshal(event) 72 if nil != err { 73 t.Fatal(err) 74 } 75 if string(js) != `[{"type":"myEvent","timestamp":1.41713646e+09},{},{}]` { 76 t.Fatal(string(js)) 77 } 78 } 79 80 func TestMissingEventType(t *testing.T) { 81 event, err := CreateCustomEvent("", map[string]interface{}{"alpha": 1}, now) 82 if err != ErrEventTypeRegex { 83 t.Fatal(err) 84 } 85 if nil != event { 86 t.Fatal(event) 87 } 88 } 89 90 func TestEmptyParams(t *testing.T) { 91 event, err := CreateCustomEvent("myEvent", map[string]interface{}{}, now) 92 if nil != err { 93 t.Fatal(err) 94 } 95 js, err := json.Marshal(event) 96 if nil != err { 97 t.Fatal(err) 98 } 99 if string(js) != `[{"type":"myEvent","timestamp":1.41713646e+09},{},{}]` { 100 t.Fatal(string(js)) 101 } 102 } 103 104 func TestTruncatedStringValue(t *testing.T) { 105 event, err := CreateCustomEvent("myEvent", map[string]interface{}{"alpha": strLen512}, now) 106 if nil != err { 107 t.Fatal(err) 108 } 109 js, err := json.Marshal(event) 110 if nil != err { 111 t.Fatal(err) 112 } 113 if string(js) != `[{"type":"myEvent","timestamp":1.41713646e+09},{"alpha":"`+strLen255+`"},{}]` { 114 t.Fatal(string(js)) 115 } 116 } 117 118 func TestInvalidValueType(t *testing.T) { 119 event, err := CreateCustomEvent("myEvent", map[string]interface{}{"alpha": []string{}}, now) 120 if _, ok := err.(ErrInvalidAttributeType); !ok { 121 t.Fatal(err) 122 } 123 if nil != event { 124 t.Fatal(event) 125 } 126 } 127 128 func TestInvalidCustomAttributeKey(t *testing.T) { 129 event, err := CreateCustomEvent("myEvent", map[string]interface{}{strLen512: 1}, now) 130 if nil == err { 131 t.Fatal(err) 132 } 133 if _, ok := err.(invalidAttributeKeyErr); !ok { 134 t.Fatal(err) 135 } 136 if nil != event { 137 t.Fatal(event) 138 } 139 } 140 141 func TestTooManyAttributes(t *testing.T) { 142 params := make(map[string]interface{}) 143 for i := 0; i < customEventAttributeLimit+1; i++ { 144 params[strconv.Itoa(i)] = i 145 } 146 event, err := CreateCustomEvent("myEvent", params, now) 147 if errNumAttributes != err { 148 t.Fatal(err) 149 } 150 if nil != event { 151 t.Fatal(event) 152 } 153 } 154 155 func TestCustomEventAttributeTypes(t *testing.T) { 156 testcases := []struct { 157 val interface{} 158 js string 159 }{ 160 {"string", `"string"`}, 161 {true, `true`}, 162 {false, `false`}, 163 {uint8(1), `1`}, 164 {uint16(1), `1`}, 165 {uint32(1), `1`}, 166 {uint64(1), `1`}, 167 {int8(1), `1`}, 168 {int16(1), `1`}, 169 {int32(1), `1`}, 170 {int64(1), `1`}, 171 {float32(1), `1`}, 172 {float64(1), `1`}, 173 {uint(1), `1`}, 174 {int(1), `1`}, 175 {uintptr(1), `1`}, 176 } 177 178 for _, tc := range testcases { 179 event, err := CreateCustomEvent("myEvent", map[string]interface{}{"key": tc.val}, now) 180 if nil != err { 181 t.Fatal(err) 182 } 183 js, err := json.Marshal(event) 184 if nil != err { 185 t.Fatal(err) 186 } 187 if string(js) != `[{"type":"myEvent","timestamp":1.41713646e+09},{"key":`+tc.js+`},{}]` { 188 t.Fatal(string(js)) 189 } 190 } 191 } 192 193 func TestCustomParamsCopied(t *testing.T) { 194 params := map[string]interface{}{"alpha": 1} 195 event, err := CreateCustomEvent("myEvent", params, now) 196 if nil != err { 197 t.Fatal(err) 198 } 199 // Attempt to change the params after the event created: 200 params["zip"] = "zap" 201 js, err := json.Marshal(event) 202 if nil != err { 203 t.Fatal(err) 204 } 205 if string(js) != `[{"type":"myEvent","timestamp":1.41713646e+09},{"alpha":1},{}]` { 206 t.Fatal(string(js)) 207 } 208 } 209 210 func TestMultipleAttributeJSON(t *testing.T) { 211 params := map[string]interface{}{"alpha": 1, "beta": 2} 212 event, err := CreateCustomEvent("myEvent", params, now) 213 if nil != err { 214 t.Fatal(err) 215 } 216 js, err := json.Marshal(event) 217 if nil != err { 218 t.Fatal(err) 219 } 220 // Params order may not be deterministic, so we simply test that the 221 // JSON created is valid. 222 var valid interface{} 223 if err := json.Unmarshal(js, &valid); nil != err { 224 t.Error(string(js)) 225 } 226 }