github.com/lulzWill/go-agent@v2.1.2+incompatible/internal/analytics_events_test.go (about) 1 package internal 2 3 import ( 4 "bytes" 5 "strconv" 6 "testing" 7 "time" 8 ) 9 10 var ( 11 agentRunID = `12345` 12 ) 13 14 type intWriter int 15 16 func (x intWriter) WriteJSON(buf *bytes.Buffer) { 17 buf.WriteString(strconv.Itoa(int(x))) 18 } 19 20 func sampleAnalyticsEvent(stamp int) analyticsEvent { 21 return analyticsEvent{ 22 eventStamp(stamp), 23 intWriter(stamp), 24 } 25 } 26 27 func TestBasic(t *testing.T) { 28 events := newAnalyticsEvents(10) 29 events.addEvent(sampleAnalyticsEvent(1)) 30 events.addEvent(sampleAnalyticsEvent(1)) 31 events.addEvent(sampleAnalyticsEvent(1)) 32 33 json, err := events.CollectorJSON(agentRunID) 34 if nil != err { 35 t.Fatal(err) 36 } 37 38 expected := `["12345",{"reservoir_size":10,"events_seen":3},[1,1,1]]` 39 40 if string(json) != expected { 41 t.Error(string(json), expected) 42 } 43 if 3 != events.numSeen { 44 t.Error(events.numSeen) 45 } 46 if 3 != events.NumSaved() { 47 t.Error(events.NumSaved()) 48 } 49 } 50 51 func TestEmpty(t *testing.T) { 52 events := newAnalyticsEvents(10) 53 json, err := events.CollectorJSON(agentRunID) 54 if nil != err { 55 t.Fatal(err) 56 } 57 if nil != json { 58 t.Error(string(json)) 59 } 60 if 0 != events.numSeen { 61 t.Error(events.numSeen) 62 } 63 if 0 != events.NumSaved() { 64 t.Error(events.NumSaved()) 65 } 66 } 67 68 func TestSampling(t *testing.T) { 69 events := newAnalyticsEvents(3) 70 events.addEvent(sampleAnalyticsEvent(10)) 71 events.addEvent(sampleAnalyticsEvent(1)) 72 events.addEvent(sampleAnalyticsEvent(9)) 73 events.addEvent(sampleAnalyticsEvent(2)) 74 events.addEvent(sampleAnalyticsEvent(8)) 75 events.addEvent(sampleAnalyticsEvent(3)) 76 77 json, err := events.CollectorJSON(agentRunID) 78 if nil != err { 79 t.Fatal(err) 80 } 81 if string(json) != `["12345",{"reservoir_size":3,"events_seen":6},[8,10,9]]` { 82 t.Error(string(json)) 83 } 84 if 6 != events.numSeen { 85 t.Error(events.numSeen) 86 } 87 if 3 != events.NumSaved() { 88 t.Error(events.NumSaved()) 89 } 90 } 91 92 func TestMergeEmpty(t *testing.T) { 93 e1 := newAnalyticsEvents(10) 94 e2 := newAnalyticsEvents(10) 95 e1.Merge(e2) 96 json, err := e1.CollectorJSON(agentRunID) 97 if nil != err { 98 t.Fatal(err) 99 } 100 if nil != json { 101 t.Error(string(json)) 102 } 103 if 0 != e1.numSeen { 104 t.Error(e1.numSeen) 105 } 106 if 0 != e1.NumSaved() { 107 t.Error(e1.NumSaved()) 108 } 109 } 110 111 func TestMergeFull(t *testing.T) { 112 e1 := newAnalyticsEvents(2) 113 e2 := newAnalyticsEvents(3) 114 115 e1.addEvent(sampleAnalyticsEvent(5)) 116 e1.addEvent(sampleAnalyticsEvent(10)) 117 e1.addEvent(sampleAnalyticsEvent(15)) 118 119 e2.addEvent(sampleAnalyticsEvent(6)) 120 e2.addEvent(sampleAnalyticsEvent(12)) 121 e2.addEvent(sampleAnalyticsEvent(18)) 122 e2.addEvent(sampleAnalyticsEvent(24)) 123 124 e1.Merge(e2) 125 json, err := e1.CollectorJSON(agentRunID) 126 if nil != err { 127 t.Fatal(err) 128 } 129 if string(json) != `["12345",{"reservoir_size":2,"events_seen":7},[18,24]]` { 130 t.Error(string(json)) 131 } 132 if 7 != e1.numSeen { 133 t.Error(e1.numSeen) 134 } 135 if 2 != e1.NumSaved() { 136 t.Error(e1.NumSaved()) 137 } 138 } 139 140 func TestAnalyticsEventMergeFailedSuccess(t *testing.T) { 141 e1 := newAnalyticsEvents(2) 142 e2 := newAnalyticsEvents(3) 143 144 e1.addEvent(sampleAnalyticsEvent(5)) 145 e1.addEvent(sampleAnalyticsEvent(10)) 146 e1.addEvent(sampleAnalyticsEvent(15)) 147 148 e2.addEvent(sampleAnalyticsEvent(6)) 149 e2.addEvent(sampleAnalyticsEvent(12)) 150 e2.addEvent(sampleAnalyticsEvent(18)) 151 e2.addEvent(sampleAnalyticsEvent(24)) 152 153 e1.mergeFailed(e2) 154 155 json, err := e1.CollectorJSON(agentRunID) 156 if nil != err { 157 t.Fatal(err) 158 } 159 if string(json) != `["12345",{"reservoir_size":2,"events_seen":7},[18,24]]` { 160 t.Error(string(json)) 161 } 162 if 7 != e1.numSeen { 163 t.Error(e1.numSeen) 164 } 165 if 2 != e1.NumSaved() { 166 t.Error(e1.NumSaved()) 167 } 168 if 1 != e1.failedHarvests { 169 t.Error(e1.failedHarvests) 170 } 171 } 172 173 func TestAnalyticsEventMergeFailedLimitReached(t *testing.T) { 174 e1 := newAnalyticsEvents(2) 175 e2 := newAnalyticsEvents(3) 176 177 e1.addEvent(sampleAnalyticsEvent(5)) 178 e1.addEvent(sampleAnalyticsEvent(10)) 179 e1.addEvent(sampleAnalyticsEvent(15)) 180 181 e2.addEvent(sampleAnalyticsEvent(6)) 182 e2.addEvent(sampleAnalyticsEvent(12)) 183 e2.addEvent(sampleAnalyticsEvent(18)) 184 e2.addEvent(sampleAnalyticsEvent(24)) 185 186 e2.failedHarvests = failedEventsAttemptsLimit 187 188 e1.mergeFailed(e2) 189 190 json, err := e1.CollectorJSON(agentRunID) 191 if nil != err { 192 t.Fatal(err) 193 } 194 if string(json) != `["12345",{"reservoir_size":2,"events_seen":3},[10,15]]` { 195 t.Error(string(json)) 196 } 197 if 3 != e1.numSeen { 198 t.Error(e1.numSeen) 199 } 200 if 2 != e1.NumSaved() { 201 t.Error(e1.NumSaved()) 202 } 203 if 0 != e1.failedHarvests { 204 t.Error(e1.failedHarvests) 205 } 206 } 207 208 func analyticsEventBenchmarkHelper(b *testing.B, w jsonWriter) { 209 events := newAnalyticsEvents(maxTxnEvents) 210 event := analyticsEvent{eventStamp(1), w} 211 for n := 0; n < maxTxnEvents; n++ { 212 events.addEvent(event) 213 } 214 215 b.ReportAllocs() 216 b.ResetTimer() 217 218 for n := 0; n < b.N; n++ { 219 js, err := events.CollectorJSON(agentRunID) 220 if nil != err { 221 b.Fatal(err, js) 222 } 223 } 224 } 225 226 func BenchmarkTxnEventsCollectorJSON(b *testing.B) { 227 event := &TxnEvent{ 228 FinalName: "WebTransaction/Go/zip/zap", 229 Start: time.Now(), 230 Duration: 2 * time.Second, 231 Queuing: 1 * time.Second, 232 Zone: ApdexSatisfying, 233 Attrs: nil, 234 } 235 analyticsEventBenchmarkHelper(b, event) 236 } 237 238 func BenchmarkCustomEventsCollectorJSON(b *testing.B) { 239 now := time.Now() 240 ce, err := CreateCustomEvent("myEventType", map[string]interface{}{ 241 "string": "myString", 242 "bool": true, 243 "int64": int64(123), 244 "nil": nil, 245 }, now) 246 if nil != err { 247 b.Fatal(err) 248 } 249 analyticsEventBenchmarkHelper(b, ce) 250 } 251 252 func BenchmarkErrorEventsCollectorJSON(b *testing.B) { 253 e := TxnErrorFromResponseCode(time.Now(), 503) 254 e.Stack = GetStackTrace(0) 255 256 txnName := "WebTransaction/Go/zip/zap" 257 event := &ErrorEvent{ 258 ErrorData: e, 259 TxnEvent: TxnEvent{ 260 FinalName: txnName, 261 Duration: 3 * time.Second, 262 Attrs: nil, 263 }, 264 } 265 analyticsEventBenchmarkHelper(b, event) 266 }