github.com/pyroscope-io/pyroscope@v0.37.3-0.20230725203016-5f6947968bd0/pkg/storage/storage_test.go (about) 1 //go:build !windows 2 // +build !windows 3 4 package storage 5 6 import ( 7 "context" 8 "runtime" 9 "strconv" 10 "time" 11 12 . "github.com/onsi/ginkgo/v2" 13 . "github.com/onsi/gomega" 14 "github.com/prometheus/client_golang/prometheus" 15 "github.com/shirou/gopsutil/mem" 16 "github.com/sirupsen/logrus" 17 18 "github.com/pyroscope-io/pyroscope/pkg/config" 19 "github.com/pyroscope-io/pyroscope/pkg/flameql" 20 "github.com/pyroscope-io/pyroscope/pkg/health" 21 "github.com/pyroscope-io/pyroscope/pkg/storage/dimension" 22 "github.com/pyroscope-io/pyroscope/pkg/storage/segment" 23 "github.com/pyroscope-io/pyroscope/pkg/storage/tree" 24 "github.com/pyroscope-io/pyroscope/pkg/testing" 25 ) 26 27 // 21:22:08 air | (time.Duration) 16m40s, 28 // 21:22:08 air | (time.Duration) 2h46m40s, 29 // 21:22:08 air | (time.Duration) 27h46m40s, 30 // 21:22:08 air | (time.Duration) 277h46m40s, 31 // 21:22:08 air | (time.Duration) 2777h46m40s, 32 // 21:22:08 air | (time.Duration) 27777h46m40s 33 34 var s *Storage 35 36 var maxTime = time.Unix(1<<62, 999999999) 37 38 var _ = Describe("storage package", func() { 39 suite := func() { 40 Context("delete tests", func() { 41 Context("simple delete", func() { 42 It("works correctly", func() { 43 tree := tree.New() 44 tree.Insert([]byte("a;b"), uint64(1)) 45 tree.Insert([]byte("a;c"), uint64(2)) 46 st := testing.SimpleTime(10) 47 et := testing.SimpleTime(19) 48 st2 := testing.SimpleTime(0) 49 et2 := testing.SimpleTime(30) 50 key, _ := segment.ParseKey("foo") 51 52 s.Put(context.TODO(), &PutInput{ 53 StartTime: st, 54 EndTime: et, 55 Key: key, 56 Val: tree, 57 SpyName: "testspy", 58 SampleRate: 100, 59 }) 60 61 Expect(s.Delete(context.TODO(), &DeleteInput{key})).ToNot(HaveOccurred()) 62 gOut, err := s.Get(context.TODO(), &GetInput{ 63 StartTime: st2, 64 EndTime: et2, 65 Key: key, 66 }) 67 68 Expect(err).ToNot(HaveOccurred()) 69 Expect(gOut).To(BeNil()) 70 Expect(s.Close()).ToNot(HaveOccurred()) 71 }) 72 }) 73 Context("delete all trees", func() { 74 It("works correctly", func() { 75 tree1 := tree.New() 76 tree1.Insert([]byte("a;b"), uint64(1)) 77 tree1.Insert([]byte("a;c"), uint64(2)) 78 tree2 := tree.New() 79 tree2.Insert([]byte("c;d"), uint64(1)) 80 tree2.Insert([]byte("e;f"), uint64(2)) 81 st := testing.SimpleTime(10) 82 et := testing.SimpleTime(19) 83 st2 := testing.SimpleTime(0) 84 et2 := testing.SimpleTime(30) 85 key, _ := segment.ParseKey("foo") 86 87 s.Put(context.TODO(), &PutInput{ 88 StartTime: st, 89 EndTime: et, 90 Key: key, 91 Val: tree1, 92 SpyName: "testspy", 93 SampleRate: 100, 94 }) 95 96 s.Put(context.TODO(), &PutInput{ 97 StartTime: st, 98 EndTime: et, 99 Key: key, 100 Val: tree2, 101 SpyName: "testspy", 102 SampleRate: 100, 103 }) 104 105 Expect(s.Delete(context.TODO(), &DeleteInput{key})).ToNot(HaveOccurred()) 106 s.GetValues(context.TODO(), "__name__", func(v string) bool { 107 Fail("app name label was not removed") 108 return false 109 }) 110 111 gOut, err := s.Get(context.TODO(), &GetInput{ 112 StartTime: st2, 113 EndTime: et2, 114 Key: key, 115 }) 116 117 Expect(err).ToNot(HaveOccurred()) 118 Expect(gOut).To(BeNil()) 119 Expect(s.Close()).ToNot(HaveOccurred()) 120 }) 121 }) 122 Context("put after delete", func() { 123 It("works correctly", func() { 124 tree1 := tree.New() 125 tree1.Insert([]byte("a;b"), uint64(1)) 126 tree1.Insert([]byte("a;c"), uint64(2)) 127 tree2 := tree.New() 128 tree2.Insert([]byte("c;d"), uint64(1)) 129 tree2.Insert([]byte("e;f"), uint64(2)) 130 st := testing.SimpleTime(10) 131 et := testing.SimpleTime(19) 132 st2 := testing.SimpleTime(0) 133 et2 := testing.SimpleTime(30) 134 key, _ := segment.ParseKey("foo") 135 136 err := s.Put(context.TODO(), &PutInput{ 137 StartTime: st, 138 EndTime: et, 139 Key: key, 140 Val: tree1, 141 SpyName: "testspy", 142 SampleRate: 100, 143 }) 144 Expect(err).ToNot(HaveOccurred()) 145 146 Expect(s.Delete(context.TODO(), &DeleteInput{key})).ToNot(HaveOccurred()) 147 s.Put(context.TODO(), &PutInput{ 148 StartTime: st, 149 EndTime: et, 150 Key: key, 151 Val: tree2, 152 SpyName: "testspy", 153 SampleRate: 100, 154 }) 155 156 gOut, err := s.Get(context.TODO(), &GetInput{ 157 StartTime: st2, 158 EndTime: et2, 159 Key: key, 160 }) 161 162 Expect(err).ToNot(HaveOccurred()) 163 Expect(gOut.Tree).ToNot(BeNil()) 164 Expect(gOut.Tree.String()).To(Equal(tree2.String())) 165 Expect(s.Close()).ToNot(HaveOccurred()) 166 }) 167 }) 168 }) 169 170 Context("smoke tests", func() { 171 Context("check segment cache", func() { 172 It("works correctly", func() { 173 tree := tree.New() 174 175 size := 32 176 treeKey := make([]byte, size) 177 for i := 0; i < size; i++ { 178 treeKey[i] = 'a' 179 } 180 for i := 0; i < 60; i++ { 181 k := string(treeKey) + strconv.Itoa(i+1) 182 tree.Insert([]byte(k), uint64(i+1)) 183 184 key, _ := segment.ParseKey("tree_key" + strconv.Itoa(i+1)) 185 err := s.Put(context.TODO(), &PutInput{ 186 Key: key, 187 Val: tree, 188 SpyName: "testspy", 189 SampleRate: 100, 190 }) 191 Expect(err).ToNot(HaveOccurred()) 192 } 193 Expect(s.Close()).ToNot(HaveOccurred()) 194 }) 195 }) 196 Context("simple 10 second write", func() { 197 It("works correctly", func() { 198 tree := tree.New() 199 tree.Insert([]byte("a;b"), uint64(1)) 200 tree.Insert([]byte("a;c"), uint64(2)) 201 st := testing.SimpleTime(10) 202 et := testing.SimpleTime(19) 203 st2 := testing.SimpleTime(0) 204 et2 := testing.SimpleTime(30) 205 key, _ := segment.ParseKey("foo") 206 207 err := s.Put(context.TODO(), &PutInput{ 208 StartTime: st, 209 EndTime: et, 210 Key: key, 211 Val: tree, 212 SpyName: "testspy", 213 SampleRate: 100, 214 }) 215 Expect(err).ToNot(HaveOccurred()) 216 217 o, err := s.Get(context.TODO(), &GetInput{ 218 StartTime: st2, 219 EndTime: et2, 220 Key: key, 221 }) 222 223 Expect(err).ToNot(HaveOccurred()) 224 Expect(o.Tree).ToNot(BeNil()) 225 Expect(o.Tree.String()).To(Equal(tree.String())) 226 Expect(s.Close()).ToNot(HaveOccurred()) 227 }) 228 }) 229 Context("simple 20 second write", func() { 230 It("works correctly", func() { 231 tree := tree.New() 232 tree.Insert([]byte("a;b"), uint64(2)) 233 tree.Insert([]byte("a;c"), uint64(4)) 234 st := testing.SimpleTime(10) 235 et := testing.SimpleTime(29) 236 st2 := testing.SimpleTime(0) 237 et2 := testing.SimpleTime(30) 238 key, _ := segment.ParseKey("foo") 239 240 err := s.Put(context.TODO(), &PutInput{ 241 StartTime: st, 242 EndTime: et, 243 Key: key, 244 Val: tree, 245 SpyName: "testspy", 246 SampleRate: 100, 247 }) 248 Expect(err).ToNot(HaveOccurred()) 249 250 o, err := s.Get(context.TODO(), &GetInput{ 251 StartTime: st2, 252 EndTime: et2, 253 Key: key, 254 }) 255 256 Expect(err).ToNot(HaveOccurred()) 257 Expect(o.Tree).ToNot(BeNil()) 258 Expect(o.Tree.String()).To(Equal(tree.String())) 259 Expect(s.Close()).ToNot(HaveOccurred()) 260 }) 261 }) 262 Context("evict cache items periodically", func() { 263 It("works correctly", func() { 264 tree := tree.New() 265 266 size := 16 267 treeKey := make([]byte, size) 268 for i := 0; i < size; i++ { 269 treeKey[i] = 'a' 270 } 271 for i := 0; i < 200; i++ { 272 k := string(treeKey) + strconv.Itoa(i+1) 273 tree.Insert([]byte(k), uint64(i+1)) 274 275 key, _ := segment.ParseKey("tree_key" + strconv.Itoa(i+1)) 276 err := s.Put(context.TODO(), &PutInput{ 277 Key: key, 278 Val: tree, 279 SpyName: "testspy", 280 SampleRate: 100, 281 }) 282 Expect(err).ToNot(HaveOccurred()) 283 } 284 285 for i := 0; i < 5; i++ { 286 _, err := mem.VirtualMemory() 287 Expect(err).ToNot(HaveOccurred()) 288 289 var m runtime.MemStats 290 runtime.ReadMemStats(&m) 291 time.Sleep(time.Second) 292 } 293 Expect(s.Close()).ToNot(HaveOccurred()) 294 }) 295 }) 296 }) 297 } 298 299 logrus.SetLevel(logrus.InfoLevel) 300 301 // Disk-based storage 302 testing.WithConfig(func(cfg **config.Config) { 303 JustBeforeEach(func() { 304 var err error 305 s, err = New(NewConfig(&(*cfg).Server), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 306 Expect(err).ToNot(HaveOccurred()) 307 }) 308 suite() 309 }) 310 311 // In-memory storage 312 testing.WithConfig(func(cfg **config.Config) { 313 JustBeforeEach(func() { 314 var err error 315 s, err = New(NewConfig(&(*cfg).Server).WithInMemory(), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 316 Expect(err).ToNot(HaveOccurred()) 317 }) 318 suite() 319 }) 320 }) 321 322 var _ = Describe("persistence", func() { 323 // Disk-based storage 324 testing.WithConfig(func(cfg **config.Config) { 325 JustBeforeEach(func() { 326 var err error 327 s, err = New(NewConfig(&(*cfg).Server), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 328 Expect(err).ToNot(HaveOccurred()) 329 }) 330 Context("persist data between restarts", func() { 331 It("works correctly", func() { 332 tree := tree.New() 333 tree.Insert([]byte("a;b"), uint64(1)) 334 tree.Insert([]byte("a;c"), uint64(2)) 335 st := testing.SimpleTime(10) 336 et := testing.SimpleTime(19) 337 st2 := testing.SimpleTime(0) 338 et2 := testing.SimpleTime(30) 339 340 appKey, _ := segment.ParseKey("foo") 341 key, _ := segment.ParseKey("foo{tag=value}") 342 343 err := s.Put(context.TODO(), &PutInput{ 344 StartTime: st, 345 EndTime: et, 346 Key: key, 347 Val: tree, 348 SpyName: "testspy", 349 SampleRate: 100, 350 }) 351 Expect(err).ToNot(HaveOccurred()) 352 353 o, err := s.Get(context.TODO(), &GetInput{ 354 StartTime: st2, 355 EndTime: et2, 356 Key: appKey, 357 }) 358 359 Expect(err).ToNot(HaveOccurred()) 360 Expect(o.Tree).ToNot(BeNil()) 361 Expect(o.Tree.String()).To(Equal(tree.String())) 362 Expect(s.Close()).ToNot(HaveOccurred()) 363 364 s2, err := New(NewConfig(&(*cfg).Server), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 365 Expect(err).ToNot(HaveOccurred()) 366 367 o2, err := s2.Get(context.TODO(), &GetInput{ 368 StartTime: st2, 369 EndTime: et2, 370 Key: appKey, 371 }) 372 Expect(err).ToNot(HaveOccurred()) 373 Expect(o2.Tree).ToNot(BeNil()) 374 Expect(o2.Tree.String()).To(Equal(tree.String())) 375 Expect(s2.Close()).ToNot(HaveOccurred()) 376 }) 377 }) 378 }) 379 }) 380 381 var _ = Describe("querying", func() { 382 setup := func() { 383 keys := []string{ 384 "app.name{foo=bar,baz=qux}", 385 "app.name{foo=bar,baz=xxx}", 386 "app.name{waldo=fred,baz=xxx}", 387 } 388 for _, k := range keys { 389 t := tree.New() 390 t.Insert([]byte("a;b"), uint64(1)) 391 t.Insert([]byte("a;c"), uint64(2)) 392 st := testing.SimpleTime(10) 393 et := testing.SimpleTime(19) 394 key, err := segment.ParseKey(k) 395 Expect(err).ToNot(HaveOccurred()) 396 err = s.Put(context.TODO(), &PutInput{ 397 StartTime: st, 398 EndTime: et, 399 Key: key, 400 Val: t, 401 SpyName: "testspy", 402 SampleRate: 100, 403 }) 404 Expect(err).ToNot(HaveOccurred()) 405 } 406 } 407 408 suite := func() { 409 Context("basic queries", func() { 410 It("get returns result with query", func() { 411 qry, err := flameql.ParseQuery(`app.name{foo="bar"}`) 412 Expect(err).ToNot(HaveOccurred()) 413 output, err := s.Get(context.TODO(), &GetInput{ 414 StartTime: time.Time{}, 415 EndTime: maxTime, 416 Query: qry, 417 }) 418 Expect(err).ToNot(HaveOccurred()) 419 Expect(output).ToNot(BeNil()) 420 Expect(output.Tree).ToNot(BeNil()) 421 Expect(output.Tree.Samples()).To(Equal(uint64(6))) 422 Expect(s.Close()).ToNot(HaveOccurred()) 423 }) 424 425 It("get returns a particular tree for a fully qualified key", func() { 426 k, err := segment.ParseKey(`app.name{foo=bar,baz=qux}`) 427 Expect(err).ToNot(HaveOccurred()) 428 output, err := s.Get(context.TODO(), &GetInput{ 429 StartTime: time.Time{}, 430 EndTime: maxTime, 431 Key: k, 432 }) 433 Expect(err).ToNot(HaveOccurred()) 434 Expect(output).ToNot(BeNil()) 435 Expect(output.Tree).ToNot(BeNil()) 436 Expect(output.Tree.Samples()).To(Equal(uint64(3))) 437 Expect(s.Close()).ToNot(HaveOccurred()) 438 }) 439 440 It("get returns all results for a key containing only app name", func() { 441 k, err := segment.ParseKey(`app.name`) 442 Expect(err).ToNot(HaveOccurred()) 443 output, err := s.Get(context.TODO(), &GetInput{ 444 StartTime: time.Time{}, 445 EndTime: maxTime, 446 Key: k, 447 }) 448 Expect(err).ToNot(HaveOccurred()) 449 Expect(output).ToNot(BeNil()) 450 Expect(output.Tree).ToNot(BeNil()) 451 Expect(output.Tree.Samples()).To(Equal(uint64(9))) 452 Expect(s.Close()).ToNot(HaveOccurred()) 453 }) 454 455 It("query returns expected results", func() { 456 type testCase struct { 457 query string 458 segmentKeys []dimension.Key 459 } 460 461 testCases := []testCase{ 462 {`app.name`, []dimension.Key{ 463 dimension.Key("app.name{baz=qux,foo=bar}"), 464 dimension.Key("app.name{baz=xxx,foo=bar}"), 465 dimension.Key("app.name{baz=xxx,waldo=fred}"), 466 }}, 467 {`app.name{foo="bar"}`, []dimension.Key{ 468 dimension.Key("app.name{baz=qux,foo=bar}"), 469 dimension.Key("app.name{baz=xxx,foo=bar}"), 470 }}, 471 {`app.name{foo=~"^b.*"}`, []dimension.Key{ 472 dimension.Key("app.name{baz=qux,foo=bar}"), 473 dimension.Key("app.name{baz=xxx,foo=bar}"), 474 }}, 475 {`app.name{baz=~"xxx|qux"}`, []dimension.Key{ 476 dimension.Key("app.name{baz=qux,foo=bar}"), 477 dimension.Key("app.name{baz=xxx,foo=bar}"), 478 dimension.Key("app.name{baz=xxx,waldo=fred}"), 479 }}, 480 {`app.name{baz!="xxx"}`, []dimension.Key{ 481 dimension.Key("app.name{baz=qux,foo=bar}"), 482 }}, 483 {`app.name{foo!="bar"}`, []dimension.Key{ 484 dimension.Key("app.name{baz=xxx,waldo=fred}"), 485 }}, 486 {`app.name{foo!~".*"}`, []dimension.Key{ 487 dimension.Key("app.name{baz=xxx,waldo=fred}"), 488 }}, 489 {`app.name{baz!~"^x.*"}`, []dimension.Key{ 490 dimension.Key("app.name{baz=qux,foo=bar}"), 491 }}, 492 {`app.name{foo="bar",baz!~"^x.*"}`, []dimension.Key{ 493 dimension.Key("app.name{baz=qux,foo=bar}"), 494 }}, 495 496 {`app.name{foo=~"b.*",foo!~".*r"}`, nil}, 497 498 {`app.name{foo!="non-existing-value"}`, []dimension.Key{ 499 dimension.Key("app.name{baz=qux,foo=bar}"), 500 dimension.Key("app.name{baz=xxx,foo=bar}"), 501 dimension.Key("app.name{baz=xxx,waldo=fred}"), 502 }}, 503 {`app.name{foo!~"non-existing-.*"}`, []dimension.Key{ 504 dimension.Key("app.name{baz=qux,foo=bar}"), 505 dimension.Key("app.name{baz=xxx,foo=bar}"), 506 dimension.Key("app.name{baz=xxx,waldo=fred}"), 507 }}, 508 {`app.name{non_existing_key!="bar"}`, []dimension.Key{ 509 dimension.Key("app.name{baz=qux,foo=bar}"), 510 dimension.Key("app.name{baz=xxx,foo=bar}"), 511 dimension.Key("app.name{baz=xxx,waldo=fred}"), 512 }}, 513 {`app.name{non_existing_key!~"bar"}`, []dimension.Key{ 514 dimension.Key("app.name{baz=qux,foo=bar}"), 515 dimension.Key("app.name{baz=xxx,foo=bar}"), 516 dimension.Key("app.name{baz=xxx,waldo=fred}"), 517 }}, 518 519 {`app.name{foo="non-existing-value"}`, nil}, 520 {`app.name{foo=~"non-existing-.*"}`, nil}, 521 {`app.name{non_existing_key="bar"}`, nil}, 522 {`app.name{non_existing_key=~"bar"}`, nil}, 523 524 {`non-existing-app{}`, nil}, 525 } 526 527 for _, tc := range testCases { 528 qry, err := flameql.ParseQuery(tc.query) 529 Expect(err).ToNot(HaveOccurred()) 530 r := s.execQuery(context.TODO(), qry) 531 if tc.segmentKeys == nil { 532 Expect(r).To(BeEmpty()) 533 continue 534 } 535 Expect(r).To(ConsistOf(tc.segmentKeys)) 536 } 537 Expect(s.Close()).ToNot(HaveOccurred()) 538 }) 539 }) 540 } 541 542 // Disk-based storage 543 testing.WithConfig(func(cfg **config.Config) { 544 JustBeforeEach(func() { 545 var err error 546 s, err = New(NewConfig(&(*cfg).Server), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 547 Expect(err).ToNot(HaveOccurred()) 548 setup() 549 }) 550 suite() 551 }) 552 553 // In-memory storage 554 testing.WithConfig(func(cfg **config.Config) { 555 JustBeforeEach(func() { 556 var err error 557 s, err = New(NewConfig(&(*cfg).Server).WithInMemory(), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 558 Expect(err).ToNot(HaveOccurred()) 559 setup() 560 }) 561 suite() 562 }) 563 }) 564 565 var _ = Describe("CollectGarbage", func() { 566 suite := func() { 567 Context("RetentionPolicy", func() { 568 It("removes data outside retention period", func() { 569 key, _ := segment.ParseKey("foo") 570 tree := tree.New() 571 tree.Insert([]byte("a;b"), uint64(1)) 572 tree.Insert([]byte("a;c"), uint64(2)) 573 now := time.Now() 574 575 err := s.Put(context.TODO(), &PutInput{ 576 StartTime: now.Add(-3 * time.Hour), 577 EndTime: now.Add(-3 * time.Hour).Add(time.Second * 10), 578 Key: key, 579 Val: tree, 580 SpyName: "testspy", 581 SampleRate: 100, 582 }) 583 Expect(err).ToNot(HaveOccurred()) 584 585 err = s.Put(context.TODO(), &PutInput{ 586 StartTime: now.Add(-time.Minute), 587 EndTime: now.Add(-time.Minute).Add(time.Second * 10), 588 Key: key, 589 Val: tree, 590 SpyName: "testspy", 591 SampleRate: 100, 592 }) 593 Expect(err).ToNot(HaveOccurred()) 594 595 rp := segment.NewRetentionPolicy().SetAbsolutePeriod(time.Hour) 596 s.enforceRetentionPolicy(context.Background(), rp) 597 Expect(err).ToNot(HaveOccurred()) 598 599 o, err := s.Get(context.TODO(), &GetInput{ 600 StartTime: now.Add(-3 * time.Hour), 601 EndTime: now.Add(-3 * time.Hour).Add(time.Second * 10), 602 Key: key, 603 }) 604 605 Expect(err).ToNot(HaveOccurred()) 606 Expect(o).To(BeNil()) 607 608 o, err = s.Get(context.TODO(), &GetInput{ 609 StartTime: now.Add(-time.Minute), 610 EndTime: now.Add(-time.Minute).Add(time.Second * 10), 611 Key: key, 612 }) 613 614 Expect(err).ToNot(HaveOccurred()) 615 Expect(o).ToNot(BeNil()) 616 617 Expect(s.Close()).ToNot(HaveOccurred()) 618 }) 619 }) 620 } 621 622 // Disk-based storage 623 testing.WithConfig(func(cfg **config.Config) { 624 JustBeforeEach(func() { 625 var err error 626 s, err = New(NewConfig(&(*cfg).Server), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 627 Expect(err).ToNot(HaveOccurred()) 628 }) 629 suite() 630 }) 631 632 // In-memory storage 633 testing.WithConfig(func(cfg **config.Config) { 634 JustBeforeEach(func() { 635 var err error 636 s, err = New(NewConfig(&(*cfg).Server).WithInMemory(), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 637 Expect(err).ToNot(HaveOccurred()) 638 }) 639 suite() 640 }) 641 }) 642 643 var _ = Describe("Getters", func() { 644 testing.WithConfig(func(cfg **config.Config) { 645 JustBeforeEach(func() { 646 var err error 647 s, err = New(NewConfig(&(*cfg).Server), logrus.StandardLogger(), prometheus.NewRegistry(), new(health.Controller), NoopApplicationMetadataService{}) 648 Expect(err).ToNot(HaveOccurred()) 649 }) 650 651 It("gets app names correctly", func() { 652 tree := tree.New() 653 tree.Insert([]byte("a;b"), uint64(1)) 654 tree.Insert([]byte("a;c"), uint64(2)) 655 st := testing.SimpleTime(10) 656 et := testing.SimpleTime(19) 657 key, _ := segment.ParseKey("foo") 658 659 s.Put(context.TODO(), &PutInput{ 660 StartTime: st, 661 EndTime: et, 662 Key: key, 663 Val: tree, 664 SpyName: "testspy", 665 SampleRate: 100, 666 }) 667 668 want := []string{"foo"} 669 Expect(s.GetAppNames(context.TODO())).To(Equal( 670 want, 671 )) 672 Expect(s.Close()).ToNot(HaveOccurred()) 673 }) 674 }) 675 })