File: nrelastic_test.go

package info (click to toggle)
golang-github-newrelic-go-agent 3.15.2-9
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 8,356 kB
  • sloc: sh: 65; makefile: 6
file content (504 lines) | stat: -rw-r--r-- 31,938 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package nrelasticsearch

import (
	"context"
	"errors"
	"net/http"
	"net/url"
	"strings"
	"testing"

	elasticsearch "github.com/elastic/go-elasticsearch/v7"
	"github.com/elastic/go-elasticsearch/v7/esapi"
	"github.com/newrelic/go-agent/v3/internal"
	"github.com/newrelic/go-agent/v3/internal/integrationsupport"
	newrelic "github.com/newrelic/go-agent/v3/newrelic"
)

func TestParseRequest(t *testing.T) {
	testcases := []struct {
		// Input
		Method string
		Path   string
		// Expect
		Collection string
		Operation  string
	}{
		// These index operations are not worth worrying about.  They
		// are only going to be used in db setup.
		{Method: "DELETE", Path: "/{index}/{type}/{id}", Collection: "", Operation: ""},
		{Method: "HEAD", Path: "/{index}/{type}/{id}", Collection: "", Operation: ""},
		{Method: "GET", Path: "/{index}/{type}/{id}", Collection: "", Operation: ""},
		{Method: "POST", Path: "/{index}/{type}", Collection: "", Operation: ""},
		{Method: "POST", Path: "/{index}/{type}/{id}", Collection: "", Operation: ""},
		{Method: "PUT", Path: "/{index}/{type}/{id}", Collection: "", Operation: ""},
		{Method: "PUT", Path: "/{index}", Collection: "", Operation: ""},
		{Method: "DELETE", Path: "/{index}", Collection: "", Operation: ""},
		{Method: "HEAD", Path: "/{index}", Collection: "", Operation: ""},
		{Method: "GET", Path: "/{index}", Collection: "", Operation: ""},

		{Method: "GET", Path: "/", Collection: "", Operation: "info"},
		{Method: "HEAD", Path: "/", Collection: "", Operation: "ping"},

		{Method: "DELETE", Path: "/{index}/_alias/{name}", Collection: "{index}", Operation: "alias"},
		{Method: "HEAD", Path: "/_alias/{name}", Operation: "alias"},
		{Method: "HEAD", Path: "/{index}/_alias/{name}", Collection: "{index}", Operation: "alias"},
		{Method: "GET", Path: "/_alias", Operation: "alias"},
		{Method: "GET", Path: "/_alias/{name}", Operation: "alias"},
		{Method: "GET", Path: "/{index}/_alias", Collection: "{index}", Operation: "alias"},
		{Method: "GET", Path: "/{index}/_alias/{name}", Collection: "{index}", Operation: "alias"},
		{Method: "POST", Path: "/{index}/_alias/{name}", Collection: "{index}", Operation: "alias"},
		{Method: "PUT", Path: "/{index}/_alias/{name}", Collection: "{index}", Operation: "alias"},
		{Method: "DELETE", Path: "/{index}/_aliases/{name}", Collection: "{index}", Operation: "aliases"},
		{Method: "POST", Path: "/{index}/_aliases/{name}", Collection: "{index}", Operation: "aliases"},
		{Method: "PUT", Path: "/{index}/_aliases/{name}", Collection: "{index}", Operation: "aliases"},
		{Method: "POST", Path: "/_aliases", Operation: "aliases"},
		{Method: "GET", Path: "/_analyze", Operation: "analyze"},
		{Method: "GET", Path: "/{index}/_analyze", Collection: "{index}", Operation: "analyze"},
		{Method: "POST", Path: "/_analyze", Operation: "analyze"},
		{Method: "POST", Path: "/{index}/_analyze", Collection: "{index}", Operation: "analyze"},
		{Method: "POST", Path: "/_bulk", Operation: "bulk"},
		{Method: "POST", Path: "/{index}/_bulk", Collection: "{index}", Operation: "bulk"},
		{Method: "POST", Path: "/{index}/{type}/_bulk", Collection: "{index}", Operation: "bulk"},
		{Method: "PUT", Path: "/_bulk", Operation: "bulk"},
		{Method: "PUT", Path: "/{index}/_bulk", Collection: "{index}", Operation: "bulk"},
		{Method: "PUT", Path: "/{index}/{type}/_bulk", Collection: "{index}", Operation: "bulk"},
		{Method: "POST", Path: "/_cache/clear", Operation: "cache"},
		{Method: "POST", Path: "/{index}/_cache/clear", Collection: "{index}", Operation: "cache"},
		{Method: "GET", Path: "/_cat/aliases", Operation: "cat"},
		{Method: "GET", Path: "/_cat/aliases/{name}", Operation: "cat"},
		{Method: "GET", Path: "/_cat/allocation", Operation: "cat"},
		{Method: "GET", Path: "/_cat/allocation/{node_id}", Operation: "cat"},
		{Method: "GET", Path: "/_cat/count", Operation: "cat"},
		{Method: "GET", Path: "/_cat/count/{index}", Collection: "", Operation: "cat"},
		{Method: "GET", Path: "/_cat/fielddata", Operation: "cat"},
		{Method: "GET", Path: "/_cat/fielddata/{fields}", Operation: "cat"},
		{Method: "GET", Path: "/_cat/health", Operation: "cat"},
		{Method: "GET", Path: "/_cat", Operation: "cat"},
		{Method: "GET", Path: "/_cat/indices", Operation: "cat"},
		{Method: "GET", Path: "/_cat/indices/{index}", Collection: "", Operation: "cat"},
		{Method: "GET", Path: "/_cat/master", Operation: "cat"},
		{Method: "GET", Path: "/_cat/nodeattrs", Operation: "cat"},
		{Method: "GET", Path: "/_cat/nodes", Operation: "cat"},
		{Method: "GET", Path: "/_cat/pending_tasks", Operation: "cat"},
		{Method: "GET", Path: "/_cat/plugins", Operation: "cat"},
		{Method: "GET", Path: "/_cat/recovery", Operation: "cat"},
		{Method: "GET", Path: "/_cat/recovery/{index}", Collection: "", Operation: "cat"},
		{Method: "GET", Path: "/_cat/repositories", Operation: "cat"},
		{Method: "GET", Path: "/_cat/segments", Operation: "cat"},
		{Method: "GET", Path: "/_cat/segments/{index}", Collection: "", Operation: "cat"},
		{Method: "GET", Path: "/_cat/shards", Operation: "cat"},
		{Method: "GET", Path: "/_cat/shards/{index}", Collection: "", Operation: "cat"},
		{Method: "GET", Path: "/_cat/snapshots", Operation: "cat"},
		{Method: "GET", Path: "/_cat/snapshots/{repository}", Operation: "cat"},
		{Method: "GET", Path: "/_cat/tasks", Operation: "cat"},
		{Method: "GET", Path: "/_cat/templates", Operation: "cat"},
		{Method: "GET", Path: "/_cat/templates/{name}", Operation: "cat"},
		{Method: "GET", Path: "/_cat/thread_pool", Operation: "cat"},
		{Method: "GET", Path: "/_cat/thread_pool/{thread_pool_patterns}", Operation: "cat"},
		{Method: "POST", Path: "/{index}/_clone/{target}", Collection: "{index}", Operation: "clone"},
		{Method: "PUT", Path: "/{index}/_clone/{target}", Collection: "{index}", Operation: "clone"},
		{Method: "POST", Path: "/{index}/_close", Collection: "{index}", Operation: "close"},
		{Method: "GET", Path: "/_cluster/allocation/explain", Operation: "cluster"},
		{Method: "POST", Path: "/_cluster/allocation/explain", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/settings", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/health", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/health/{index}", Collection: "", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/pending_tasks", Operation: "cluster"},
		{Method: "PUT", Path: "/_cluster/settings", Operation: "cluster"},
		{Method: "POST", Path: "/_cluster/reroute", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/state", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/state/{metric}", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/state/{metric}/{index}", Collection: "", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/stats", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/stats/nodes/{node_id}", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/nodes/hot_threads", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/nodes/hotthreads", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/nodes/{node_id}/hot_threads", Operation: "cluster"},
		{Method: "GET", Path: "/_cluster/nodes/{node_id}/hotthreads", Operation: "cluster"},
		{Method: "GET", Path: "/_count", Operation: "count"},
		{Method: "GET", Path: "/{index}/_count", Collection: "{index}", Operation: "count"},
		{Method: "GET", Path: "/{index}/{type}/_count", Collection: "{index}", Operation: "count"},
		{Method: "POST", Path: "/_count", Operation: "count"},
		{Method: "POST", Path: "/{index}/_count", Collection: "{index}", Operation: "count"},
		{Method: "POST", Path: "/{index}/{type}/_count", Collection: "{index}", Operation: "count"},
		{Method: "POST", Path: "/{index}/_create/{id}", Collection: "{index}", Operation: "create"},
		{Method: "POST", Path: "/{index}/{type}/{id}/_create", Collection: "{index}", Operation: "create"},
		{Method: "PUT", Path: "/{index}/_create/{id}", Collection: "{index}", Operation: "create"},
		{Method: "PUT", Path: "/{index}/{type}/{id}/_create", Collection: "{index}", Operation: "create"},
		{Method: "POST", Path: "/{index}/_delete_by_query", Collection: "{index}", Operation: "delete_by_query"},
		{Method: "POST", Path: "/{index}/{type}/_delete_by_query", Collection: "{index}", Operation: "delete_by_query"},
		{Method: "POST", Path: "/_delete_by_query/{task_id}/_rethrottle", Operation: "delete_by_query"},

		{Method: "DELETE", Path: "/{index}/_doc/{id}", Collection: "{index}", Operation: "delete"},
		{Method: "HEAD", Path: "/{index}/_doc/{id}", Collection: "{index}", Operation: "exists"},
		{Method: "GET", Path: "/{index}/_doc/{id}", Collection: "{index}", Operation: "get"},
		{Method: "POST", Path: "/{index}/_doc", Collection: "{index}", Operation: "create"},
		{Method: "POST", Path: "/{index}/_doc/{id}", Collection: "{index}", Operation: "create"},
		{Method: "PUT", Path: "/{index}/_doc/{id}", Collection: "{index}", Operation: "update"},

		{Method: "GET", Path: "/{index}/_explain/{id}", Collection: "{index}", Operation: "explain"},
		{Method: "GET", Path: "/{index}/{type}/{id}/_explain", Collection: "{index}", Operation: "explain"},
		{Method: "POST", Path: "/{index}/_explain/{id}", Collection: "{index}", Operation: "explain"},
		{Method: "POST", Path: "/{index}/{type}/{id}/_explain", Collection: "{index}", Operation: "explain"},
		{Method: "GET", Path: "/_field_caps", Operation: "field_caps"},
		{Method: "GET", Path: "/{index}/_field_caps", Collection: "{index}", Operation: "field_caps"},
		{Method: "POST", Path: "/_field_caps", Operation: "field_caps"},
		{Method: "POST", Path: "/{index}/_field_caps", Collection: "{index}", Operation: "field_caps"},
		{Method: "GET", Path: "/_flush", Operation: "flush"},
		{Method: "GET", Path: "/{index}/_flush", Collection: "{index}", Operation: "flush"},
		{Method: "POST", Path: "/_flush", Operation: "flush"},
		{Method: "POST", Path: "/{index}/_flush", Collection: "{index}", Operation: "flush"},
		{Method: "GET", Path: "/_flush/synced", Operation: "flush"},
		{Method: "GET", Path: "/{index}/_flush/synced", Collection: "{index}", Operation: "flush"},
		{Method: "POST", Path: "/_flush/synced", Operation: "flush"},
		{Method: "POST", Path: "/{index}/_flush/synced", Collection: "{index}", Operation: "flush"},
		{Method: "POST", Path: "/_forcemerge", Operation: "forcemerge"},
		{Method: "POST", Path: "/{index}/_forcemerge", Collection: "{index}", Operation: "forcemerge"},
		{Method: "DELETE", Path: "/_ingest/pipeline/{id}", Operation: "ingest"},
		{Method: "GET", Path: "/_ingest/pipeline", Operation: "ingest"},
		{Method: "GET", Path: "/_ingest/pipeline/{id}", Operation: "ingest"},
		{Method: "GET", Path: "/_ingest/processor/grok", Operation: "ingest"},
		{Method: "PUT", Path: "/_ingest/pipeline/{id}", Operation: "ingest"},
		{Method: "GET", Path: "/_ingest/pipeline/_simulate", Operation: "ingest"},
		{Method: "GET", Path: "/_ingest/pipeline/{id}/_simulate", Operation: "ingest"},
		{Method: "POST", Path: "/_ingest/pipeline/_simulate", Operation: "ingest"},
		{Method: "POST", Path: "/_ingest/pipeline/{id}/_simulate", Operation: "ingest"},
		{Method: "HEAD", Path: "/{index}/_mapping/{type}", Collection: "{index}", Operation: "mapping"},
		{Method: "GET", Path: "/_mapping/field/{fields}", Operation: "mapping"},
		{Method: "GET", Path: "/_mapping/{type}/field/{fields}", Operation: "mapping"},
		{Method: "GET", Path: "/{index}/_mapping/field/{fields}", Collection: "{index}", Operation: "mapping"},
		{Method: "GET", Path: "/{index}/_mapping/{type}/field/{fields}", Collection: "{index}", Operation: "mapping"},
		{Method: "GET", Path: "/_mapping", Operation: "mapping"},
		{Method: "GET", Path: "/_mapping/{type}", Operation: "mapping"},
		{Method: "GET", Path: "/{index}/_mapping", Collection: "{index}", Operation: "mapping"},
		{Method: "GET", Path: "/{index}/_mapping/{type}", Collection: "{index}", Operation: "mapping"},
		{Method: "POST", Path: "/_mapping/{type}", Operation: "mapping"},
		{Method: "POST", Path: "/{index}/_mapping/{type}", Collection: "{index}", Operation: "mapping"},
		{Method: "POST", Path: "/{index}/{type}/_mapping", Collection: "{index}", Operation: "mapping"},
		{Method: "POST", Path: "{index}/_mapping", Collection: "{index}", Operation: "mapping"},
		{Method: "PUT", Path: "/_mapping/{type}", Operation: "mapping"},
		{Method: "PUT", Path: "/{index}/_mapping/{type}", Collection: "{index}", Operation: "mapping"},
		{Method: "PUT", Path: "/{index}/{type}/_mapping", Collection: "{index}", Operation: "mapping"},
		{Method: "PUT", Path: "{index}/_mapping", Collection: "{index}", Operation: "mapping"},
		{Method: "POST", Path: "/_mappings/{type}", Operation: "mappings"},
		{Method: "POST", Path: "/{index}/_mappings/{type}", Collection: "{index}", Operation: "mappings"},
		{Method: "POST", Path: "/{index}/{type}/_mappings", Collection: "{index}", Operation: "mappings"},
		{Method: "POST", Path: "{index}/_mappings", Collection: "{index}", Operation: "mappings"},
		{Method: "PUT", Path: "/_mappings/{type}", Operation: "mappings"},
		{Method: "PUT", Path: "/{index}/_mappings/{type}", Collection: "{index}", Operation: "mappings"},
		{Method: "PUT", Path: "/{index}/{type}/_mappings", Collection: "{index}", Operation: "mappings"},
		{Method: "PUT", Path: "{index}/_mappings", Collection: "{index}", Operation: "mappings"},
		{Method: "GET", Path: "/_mget", Operation: "mget"},
		{Method: "GET", Path: "/{index}/_mget", Collection: "{index}", Operation: "mget"},
		{Method: "GET", Path: "/{index}/{type}/_mget", Collection: "{index}", Operation: "mget"},
		{Method: "POST", Path: "/_mget", Operation: "mget"},
		{Method: "POST", Path: "/{index}/_mget", Collection: "{index}", Operation: "mget"},
		{Method: "POST", Path: "/{index}/{type}/_mget", Collection: "{index}", Operation: "mget"},
		{Method: "GET", Path: "/_msearch", Operation: "msearch"},
		{Method: "GET", Path: "/{index}/_msearch", Collection: "{index}", Operation: "msearch"},
		{Method: "GET", Path: "/{index}/{type}/_msearch", Collection: "{index}", Operation: "msearch"},
		{Method: "POST", Path: "/_msearch", Operation: "msearch"},
		{Method: "POST", Path: "/{index}/_msearch", Collection: "{index}", Operation: "msearch"},
		{Method: "POST", Path: "/{index}/{type}/_msearch", Collection: "{index}", Operation: "msearch"},
		{Method: "GET", Path: "/_msearch/template", Operation: "msearch"},
		{Method: "GET", Path: "/{index}/_msearch/template", Collection: "{index}", Operation: "msearch"},
		{Method: "GET", Path: "/{index}/{type}/_msearch/template", Collection: "{index}", Operation: "msearch"},
		{Method: "POST", Path: "/_msearch/template", Operation: "msearch"},
		{Method: "POST", Path: "/{index}/_msearch/template", Collection: "{index}", Operation: "msearch"},
		{Method: "POST", Path: "/{index}/{type}/_msearch/template", Collection: "{index}", Operation: "msearch"},
		{Method: "GET", Path: "/_mtermvectors", Operation: "mtermvectors"},
		{Method: "GET", Path: "/{index}/_mtermvectors", Collection: "{index}", Operation: "mtermvectors"},
		{Method: "GET", Path: "/{index}/{type}/_mtermvectors", Collection: "{index}", Operation: "mtermvectors"},
		{Method: "POST", Path: "/_mtermvectors", Operation: "mtermvectors"},
		{Method: "POST", Path: "/{index}/_mtermvectors", Collection: "{index}", Operation: "mtermvectors"},
		{Method: "POST", Path: "/{index}/{type}/_mtermvectors", Collection: "{index}", Operation: "mtermvectors"},
		{Method: "GET", Path: "/_nodes/hot_threads", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/hotthreads", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}/hot_threads", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}/hotthreads", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{metric}", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}/{metric}", Operation: "nodes"},
		{Method: "POST", Path: "/_nodes/reload_secure_settings", Operation: "nodes"},
		{Method: "POST", Path: "/_nodes/{node_id}/reload_secure_settings", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/stats", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/stats/{metric}", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/stats/{metric}/{index_metric}", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}/stats", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}/stats/{metric}", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}/stats/{metric}/{index_metric}", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/usage", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/usage/{metric}", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}/usage", Operation: "nodes"},
		{Method: "GET", Path: "/_nodes/{node_id}/usage/{metric}", Operation: "nodes"},
		{Method: "POST", Path: "/{index}/_open", Collection: "{index}", Operation: "open"},
		{Method: "GET", Path: "/_rank_eval", Operation: "rank_eval"},
		{Method: "GET", Path: "/{index}/_rank_eval", Collection: "{index}", Operation: "rank_eval"},
		{Method: "POST", Path: "/_rank_eval", Operation: "rank_eval"},
		{Method: "POST", Path: "/{index}/_rank_eval", Collection: "{index}", Operation: "rank_eval"},
		{Method: "GET", Path: "/_recovery", Operation: "recovery"},
		{Method: "GET", Path: "/{index}/_recovery", Collection: "{index}", Operation: "recovery"},
		{Method: "GET", Path: "/_refresh", Operation: "refresh"},
		{Method: "GET", Path: "/{index}/_refresh", Collection: "{index}", Operation: "refresh"},
		{Method: "POST", Path: "/_refresh", Operation: "refresh"},
		{Method: "POST", Path: "/{index}/_refresh", Collection: "{index}", Operation: "refresh"},
		{Method: "POST", Path: "/_reindex", Operation: "reindex"},
		{Method: "POST", Path: "/_reindex/{task_id}/_rethrottle", Operation: "reindex"},
		{Method: "GET", Path: "/_remote/info", Operation: "remote"},
		{Method: "GET", Path: "/_render/template", Operation: "render"},
		{Method: "GET", Path: "/_render/template/{id}", Operation: "render"},
		{Method: "POST", Path: "/_render/template", Operation: "render"},
		{Method: "POST", Path: "/_render/template/{id}", Operation: "render"},
		{Method: "POST", Path: "/{alias}/_rollover", Operation: "rollover", Collection: "{alias}"},
		{Method: "POST", Path: "/{alias}/_rollover/{new_index}", Operation: "rollover", Collection: "{alias}"},
		{Method: "DELETE", Path: "/_scripts/{id}", Operation: "scripts"},
		{Method: "GET", Path: "/_scripts/{id}", Operation: "scripts"},
		{Method: "POST", Path: "/_scripts/{id}", Operation: "scripts"},
		{Method: "POST", Path: "/_scripts/{id}/{context}", Operation: "scripts"},
		{Method: "PUT", Path: "/_scripts/{id}", Operation: "scripts"},
		{Method: "PUT", Path: "/_scripts/{id}/{context}", Operation: "scripts"},
		{Method: "GET", Path: "/_scripts/painless/_execute", Operation: "scripts"},
		{Method: "POST", Path: "/_scripts/painless/_execute", Operation: "scripts"},

		{Method: "DELETE", Path: "/_search/scroll", Operation: "clear_scroll"},
		{Method: "DELETE", Path: "/_search/scroll/{scroll_id}", Operation: "clear_scroll"},
		{Method: "GET", Path: "/_search/scroll", Operation: "scroll"},
		{Method: "GET", Path: "/_search/scroll/{scroll_id}", Operation: "scroll"},
		{Method: "POST", Path: "/_search/scroll", Operation: "scroll"},
		{Method: "POST", Path: "/_search/scroll/{scroll_id}", Operation: "scroll"},
		{Method: "GET", Path: "/_search", Operation: "search"},
		{Method: "GET", Path: "/{index}/_search", Collection: "{index}", Operation: "search"},
		{Method: "GET", Path: "/{index}/{type}/_search", Collection: "{index}", Operation: "search"},
		{Method: "POST", Path: "/_search", Operation: "search"},
		{Method: "POST", Path: "/{index}/_search", Collection: "{index}", Operation: "search"},
		{Method: "POST", Path: "/{index}/{type}/_search", Collection: "{index}", Operation: "search"},
		{Method: "GET", Path: "/_search/template", Operation: "search_template"},
		{Method: "GET", Path: "/{index}/_search/template", Collection: "{index}", Operation: "search_template"},
		{Method: "GET", Path: "/{index}/{type}/_search/template", Collection: "{index}", Operation: "search_template"},
		{Method: "POST", Path: "/_search/template", Operation: "search_template"},
		{Method: "POST", Path: "/{index}/_search/template", Collection: "{index}", Operation: "search_template"},
		{Method: "POST", Path: "/{index}/{type}/_search/template", Collection: "{index}", Operation: "search_template"},

		{Method: "GET", Path: "/_search_shards", Operation: "search_shards"},
		{Method: "GET", Path: "/{index}/_search_shards", Collection: "{index}", Operation: "search_shards"},
		{Method: "POST", Path: "/_search_shards", Operation: "search_shards"},
		{Method: "POST", Path: "/{index}/_search_shards", Collection: "{index}", Operation: "search_shards"},
		{Method: "GET", Path: "/_segments", Operation: "segments"},
		{Method: "GET", Path: "/{index}/_segments", Collection: "{index}", Operation: "segments"},
		{Method: "GET", Path: "/_settings", Operation: "settings"},
		{Method: "GET", Path: "/_settings/{name}", Operation: "settings"},
		{Method: "GET", Path: "/{index}/_settings", Collection: "{index}", Operation: "settings"},
		{Method: "GET", Path: "/{index}/_settings/{name}", Collection: "{index}", Operation: "settings"},
		{Method: "PUT", Path: "/_settings", Operation: "settings"},
		{Method: "PUT", Path: "/{index}/_settings", Collection: "{index}", Operation: "settings"},
		{Method: "GET", Path: "/_shard_stores", Operation: "shard_stores"},
		{Method: "GET", Path: "/{index}/_shard_stores", Collection: "{index}", Operation: "shard_stores"},
		{Method: "POST", Path: "/{index}/_shrink/{target}", Collection: "{index}", Operation: "shrink"},
		{Method: "PUT", Path: "/{index}/_shrink/{target}", Collection: "{index}", Operation: "shrink"},
		{Method: "POST", Path: "/_snapshot/{repository}/_cleanup", Operation: "snapshot"},
		{Method: "POST", Path: "/_snapshot/{repository}/{snapshot}", Operation: "snapshot"},
		{Method: "PUT", Path: "/_snapshot/{repository}/{snapshot}", Operation: "snapshot"},
		{Method: "POST", Path: "/_snapshot/{repository}", Operation: "snapshot"},
		{Method: "PUT", Path: "/_snapshot/{repository}", Operation: "snapshot"},
		{Method: "DELETE", Path: "/_snapshot/{repository}/{snapshot}", Operation: "snapshot"},
		{Method: "DELETE", Path: "/_snapshot/{repository}", Operation: "snapshot"},
		{Method: "GET", Path: "/_snapshot/{repository}/{snapshot}", Operation: "snapshot"},
		{Method: "GET", Path: "/_snapshot", Operation: "snapshot"},
		{Method: "GET", Path: "/_snapshot/{repository}", Operation: "snapshot"},
		{Method: "POST", Path: "/_snapshot/{repository}/{snapshot}/_restore", Operation: "snapshot"},
		{Method: "GET", Path: "/_snapshot/_status", Operation: "snapshot"},
		{Method: "GET", Path: "/_snapshot/{repository}/_status", Operation: "snapshot"},
		{Method: "GET", Path: "/_snapshot/{repository}/{snapshot}/_status", Operation: "snapshot"},
		{Method: "POST", Path: "/_snapshot/{repository}/_verify", Operation: "snapshot"},
		{Method: "HEAD", Path: "/{index}/_source/{id}", Collection: "{index}", Operation: "source"},
		{Method: "HEAD", Path: "/{index}/{type}/{id}/_source", Collection: "{index}", Operation: "source"},
		{Method: "GET", Path: "/{index}/_source/{id}", Collection: "{index}", Operation: "source"},
		{Method: "GET", Path: "/{index}/{type}/{id}/_source", Collection: "{index}", Operation: "source"},
		{Method: "POST", Path: "/{index}/_split/{target}", Collection: "{index}", Operation: "split"},
		{Method: "PUT", Path: "/{index}/_split/{target}", Collection: "{index}", Operation: "split"},
		{Method: "GET", Path: "/_stats", Operation: "stats"},
		{Method: "GET", Path: "/_stats/{metric}", Operation: "stats"},
		{Method: "GET", Path: "/{index}/_stats", Collection: "{index}", Operation: "stats"},
		{Method: "GET", Path: "/{index}/_stats/{metric}", Collection: "{index}", Operation: "stats"},
		{Method: "POST", Path: "/_tasks/_cancel", Operation: "tasks"},
		{Method: "POST", Path: "/_tasks/{task_id}/_cancel", Operation: "tasks"},
		{Method: "GET", Path: "/_tasks/{task_id}", Operation: "tasks"},
		{Method: "GET", Path: "/_tasks", Operation: "tasks"},
		{Method: "DELETE", Path: "/_template/{name}", Operation: "template"},
		{Method: "HEAD", Path: "/_template/{name}", Operation: "template"},
		{Method: "GET", Path: "/_template", Operation: "template"},
		{Method: "GET", Path: "/_template/{name}", Operation: "template"},
		{Method: "POST", Path: "/_template/{name}", Operation: "template"},
		{Method: "PUT", Path: "/_template/{name}", Operation: "template"},
		{Method: "GET", Path: "/{index}/_termvectors", Collection: "{index}", Operation: "termvectors"},
		{Method: "GET", Path: "/{index}/_termvectors/{id}", Collection: "{index}", Operation: "termvectors"},
		{Method: "GET", Path: "/{index}/{type}/_termvectors", Collection: "{index}", Operation: "termvectors"},
		{Method: "GET", Path: "/{index}/{type}/{id}/_termvectors", Collection: "{index}", Operation: "termvectors"},
		{Method: "POST", Path: "/{index}/_termvectors", Collection: "{index}", Operation: "termvectors"},
		{Method: "POST", Path: "/{index}/_termvectors/{id}", Collection: "{index}", Operation: "termvectors"},
		{Method: "POST", Path: "/{index}/{type}/_termvectors", Collection: "{index}", Operation: "termvectors"},
		{Method: "POST", Path: "/{index}/{type}/{id}/_termvectors", Collection: "{index}", Operation: "termvectors"},
		{Method: "POST", Path: "/{index}/_update/{id}", Collection: "{index}", Operation: "update"},
		{Method: "POST", Path: "/{index}/{type}/{id}/_update", Collection: "{index}", Operation: "update"},
		{Method: "POST", Path: "/{index}/_update_by_query", Collection: "{index}", Operation: "update_by_query"},
		{Method: "POST", Path: "/{index}/{type}/_update_by_query", Collection: "{index}", Operation: "update_by_query"},
		{Method: "POST", Path: "/_update_by_query/{task_id}/_rethrottle", Operation: "update_by_query"},
		{Method: "GET", Path: "/_upgrade", Operation: "upgrade"},
		{Method: "GET", Path: "/{index}/_upgrade", Collection: "{index}", Operation: "upgrade"},
		{Method: "POST", Path: "/_upgrade", Operation: "upgrade"},
		{Method: "POST", Path: "/{index}/_upgrade", Collection: "{index}", Operation: "upgrade"},
		{Method: "GET", Path: "/_validate/query", Operation: "validate"},
		{Method: "GET", Path: "/{index}/_validate/query", Collection: "{index}", Operation: "validate"},
		{Method: "GET", Path: "/{index}/{type}/_validate/query", Collection: "{index}", Operation: "validate"},
		{Method: "POST", Path: "/_validate/query", Operation: "validate"},
		{Method: "POST", Path: "/{index}/_validate/query", Collection: "{index}", Operation: "validate"},
		{Method: "POST", Path: "/{index}/{type}/_validate/query", Collection: "{index}", Operation: "validate"},
	}

	for _, tc := range testcases {
		r := &http.Request{
			URL: &url.URL{
				Path: tc.Path,
			},
			Method: tc.Method,
		}
		segment := parseRequest(r)
		if segment.Operation != tc.Operation {
			t.Error("wrong operation", tc.Method, tc.Path, segment.Operation, tc.Operation)
		}
		if segment.Collection != tc.Collection {
			t.Error("wrong operation", tc.Method, tc.Path, segment.Collection, tc.Collection)
		}
	}
}

var (
	errSomething = errors.New("something went wrong")
)

type roundTripperFunc func(*http.Request) (*http.Response, error)

func (fn roundTripperFunc) RoundTrip(r *http.Request) (*http.Response, error) {
	return fn(r)
}

func createTestApp() integrationsupport.ExpectApp {
	return integrationsupport.NewTestApp(nil, integrationsupport.ConfigFullTraces)
}

func TestInfo(t *testing.T) {
	app := createTestApp()
	txn := app.StartTransaction("txnName")
	ctx := newrelic.NewContext(context.Background(), txn)

	client, err := elasticsearch.NewClient(elasticsearch.Config{
		Transport: NewRoundTripper(roundTripperFunc(func(r *http.Request) (*http.Response, error) {
			return nil, errSomething
		})),
	})
	if err != nil {
		t.Fatal(err)
	}
	_, err = client.Info(client.Info.WithContext(ctx))
	if err != errSomething {
		t.Fatal(err)
	}
	txn.End()
	app.ExpectMetrics(t, []internal.WantMetric{
		{Name: "OtherTransactionTotalTime/Go/txnName"},
		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"},
		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"},
		{Name: "OtherTransaction/Go/txnName"},
		{Name: "OtherTransaction/all"},
		{Name: "OtherTransactionTotalTime"},
		{Name: "Datastore/all", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/allOther", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/Elasticsearch/all", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/Elasticsearch/allOther", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/operation/Elasticsearch/info", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/operation/Elasticsearch/info", Scope: "OtherTransaction/Go/txnName", Forced: nil, Data: nil},
	})
}

func TestSearch(t *testing.T) {
	app := createTestApp()
	txn := app.StartTransaction("txnName")
	ctx := newrelic.NewContext(context.Background(), txn)

	client, err := elasticsearch.NewClient(elasticsearch.Config{
		Transport: NewRoundTripper(roundTripperFunc(func(r *http.Request) (*http.Response, error) {
			return nil, errSomething
		})),
	})
	if err != nil {
		t.Fatal(err)
	}
	body := `{"query":{"match":{"title":"test"}}}`
	_, err = client.Search(
		client.Search.WithContext(ctx),
		client.Search.WithIndex("myindex"),
		client.Search.WithBody(strings.NewReader(body)),
	)
	if err != errSomething {
		t.Fatal(err)
	}
	txn.End()
	app.ExpectMetrics(t, []internal.WantMetric{
		{Name: "OtherTransactionTotalTime/Go/txnName"},
		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"},
		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"},
		{Name: "OtherTransaction/Go/txnName"},
		{Name: "OtherTransaction/all"},
		{Name: "OtherTransactionTotalTime"},
		{Name: "Datastore/all"},
		{Name: "Datastore/allOther"},
		{Name: "Datastore/Elasticsearch/all"},
		{Name: "Datastore/Elasticsearch/allOther"},
		{Name: "Datastore/operation/Elasticsearch/search"},
		{Name: "Datastore/statement/Elasticsearch/myindex/search"},
		{Name: "Datastore/statement/Elasticsearch/myindex/search", Scope: "OtherTransaction/Go/txnName"},
	})
}

func TestInfoRequest(t *testing.T) {
	// Test that the instrumentation works as expected when the Do()
	// request pattern is used.
	app := createTestApp()
	txn := app.StartTransaction("txnName")
	ctx := newrelic.NewContext(context.Background(), txn)

	client, err := elasticsearch.NewClient(elasticsearch.Config{
		Transport: NewRoundTripper(roundTripperFunc(func(r *http.Request) (*http.Response, error) {
			return nil, errSomething
		})),
	})
	if err != nil {
		t.Fatal(err)
	}
	req := esapi.InfoRequest{}
	_, err = req.Do(ctx, client)
	if err != errSomething {
		t.Fatal(err)
	}
	txn.End()
	app.ExpectMetrics(t, []internal.WantMetric{
		{Name: "OtherTransactionTotalTime/Go/txnName"},
		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/all"},
		{Name: "DurationByCaller/Unknown/Unknown/Unknown/Unknown/allOther"},
		{Name: "OtherTransaction/Go/txnName"},
		{Name: "OtherTransaction/all"},
		{Name: "OtherTransactionTotalTime"},
		{Name: "Datastore/all", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/allOther", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/Elasticsearch/all", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/Elasticsearch/allOther", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/operation/Elasticsearch/info", Scope: "", Forced: nil, Data: nil},
		{Name: "Datastore/operation/Elasticsearch/info", Scope: "OtherTransaction/Go/txnName", Forced: nil, Data: nil},
	})

}