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},
})
}
|