|
1 | 1 | package ingester
|
2 | 2 |
|
3 | 3 | import (
|
| 4 | + "fmt" |
4 | 5 | "io/ioutil"
|
5 | 6 | "math"
|
6 | 7 | "net/http"
|
@@ -138,13 +139,21 @@ func TestIngester_v2Push(t *testing.T) {
|
138 | 139 | registry := prometheus.NewRegistry()
|
139 | 140 |
|
140 | 141 | // Create a mocked ingester
|
141 |
| - i, cleanup, err := newIngesterMockWithTSDBStorage(defaultIngesterTestConfig(), registry) |
| 142 | + cfg := defaultIngesterTestConfig() |
| 143 | + cfg.LifecyclerConfig.JoinAfter = 0 |
| 144 | + |
| 145 | + i, cleanup, err := newIngesterMockWithTSDBStorage(cfg, registry) |
142 | 146 | require.NoError(t, err)
|
143 | 147 | defer i.Shutdown()
|
144 | 148 | defer cleanup()
|
145 | 149 |
|
146 | 150 | ctx := user.InjectOrgID(context.Background(), "test")
|
147 | 151 |
|
| 152 | + // Wait until the ingester is ACTIVE |
| 153 | + test.Poll(t, 100*time.Millisecond, ring.ACTIVE, func() interface{} { |
| 154 | + return i.lifecycler.GetState() |
| 155 | + }) |
| 156 | + |
148 | 157 | // Push timeseries
|
149 | 158 | for idx, req := range testData.reqs {
|
150 | 159 | _, err := i.v2Push(ctx, req)
|
@@ -388,6 +397,147 @@ func Test_Ingester_v2Query(t *testing.T) {
|
388 | 397 | })
|
389 | 398 | }
|
390 | 399 | }
|
| 400 | +func TestIngester_v2Query_ShouldNotCreateTSDBIfDoesNotExists(t *testing.T) { |
| 401 | + i, cleanup, err := newIngesterMockWithTSDBStorage(defaultIngesterTestConfig(), nil) |
| 402 | + require.NoError(t, err) |
| 403 | + defer i.Shutdown() |
| 404 | + defer cleanup() |
| 405 | + |
| 406 | + // Mock request |
| 407 | + userID := "test" |
| 408 | + ctx := user.InjectOrgID(context.Background(), userID) |
| 409 | + req := &client.QueryRequest{} |
| 410 | + |
| 411 | + res, err := i.v2Query(ctx, req) |
| 412 | + require.NoError(t, err) |
| 413 | + assert.Equal(t, &client.QueryResponse{}, res) |
| 414 | + |
| 415 | + // Check if the TSDB has been created |
| 416 | + _, tsdbCreated := i.TSDBState.dbs[userID] |
| 417 | + assert.False(t, tsdbCreated) |
| 418 | +} |
| 419 | + |
| 420 | +func TestIngester_v2LabelValues_ShouldNotCreateTSDBIfDoesNotExists(t *testing.T) { |
| 421 | + i, cleanup, err := newIngesterMockWithTSDBStorage(defaultIngesterTestConfig(), nil) |
| 422 | + require.NoError(t, err) |
| 423 | + defer i.Shutdown() |
| 424 | + defer cleanup() |
| 425 | + |
| 426 | + // Mock request |
| 427 | + userID := "test" |
| 428 | + ctx := user.InjectOrgID(context.Background(), userID) |
| 429 | + req := &client.LabelValuesRequest{} |
| 430 | + |
| 431 | + res, err := i.v2LabelValues(ctx, req) |
| 432 | + require.NoError(t, err) |
| 433 | + assert.Equal(t, &client.LabelValuesResponse{}, res) |
| 434 | + |
| 435 | + // Check if the TSDB has been created |
| 436 | + _, tsdbCreated := i.TSDBState.dbs[userID] |
| 437 | + assert.False(t, tsdbCreated) |
| 438 | +} |
| 439 | + |
| 440 | +func TestIngester_v2LabelNames_ShouldNotCreateTSDBIfDoesNotExists(t *testing.T) { |
| 441 | + i, cleanup, err := newIngesterMockWithTSDBStorage(defaultIngesterTestConfig(), nil) |
| 442 | + require.NoError(t, err) |
| 443 | + defer i.Shutdown() |
| 444 | + defer cleanup() |
| 445 | + |
| 446 | + // Mock request |
| 447 | + userID := "test" |
| 448 | + ctx := user.InjectOrgID(context.Background(), userID) |
| 449 | + req := &client.LabelNamesRequest{} |
| 450 | + |
| 451 | + res, err := i.v2LabelNames(ctx, req) |
| 452 | + require.NoError(t, err) |
| 453 | + assert.Equal(t, &client.LabelNamesResponse{}, res) |
| 454 | + |
| 455 | + // Check if the TSDB has been created |
| 456 | + _, tsdbCreated := i.TSDBState.dbs[userID] |
| 457 | + assert.False(t, tsdbCreated) |
| 458 | +} |
| 459 | + |
| 460 | +func TestIngester_v2Push_ShouldNotCreateTSDBIfNotInActiveState(t *testing.T) { |
| 461 | + i, cleanup, err := newIngesterMockWithTSDBStorage(defaultIngesterTestConfig(), nil) |
| 462 | + require.NoError(t, err) |
| 463 | + defer i.Shutdown() |
| 464 | + defer cleanup() |
| 465 | + require.Equal(t, ring.PENDING, i.lifecycler.GetState()) |
| 466 | + |
| 467 | + // Mock request |
| 468 | + userID := "test" |
| 469 | + ctx := user.InjectOrgID(context.Background(), userID) |
| 470 | + req := &client.WriteRequest{} |
| 471 | + |
| 472 | + res, err := i.v2Push(ctx, req) |
| 473 | + assert.Equal(t, fmt.Errorf(errTSDBCreateIncompatibleState, "PENDING"), err) |
| 474 | + assert.Nil(t, res) |
| 475 | + |
| 476 | + // Check if the TSDB has been created |
| 477 | + _, tsdbCreated := i.TSDBState.dbs[userID] |
| 478 | + assert.False(t, tsdbCreated) |
| 479 | +} |
| 480 | + |
| 481 | +func TestIngester_getOrCreateTSDB_ShouldNotAllowToCreateTSDBIfIngesterStateIsNotActive(t *testing.T) { |
| 482 | + tests := map[string]struct { |
| 483 | + state ring.IngesterState |
| 484 | + expectedErr error |
| 485 | + }{ |
| 486 | + "not allow to create TSDB if in PENDING state": { |
| 487 | + state: ring.PENDING, |
| 488 | + expectedErr: fmt.Errorf(errTSDBCreateIncompatibleState, ring.PENDING), |
| 489 | + }, |
| 490 | + "not allow to create TSDB if in JOINING state": { |
| 491 | + state: ring.JOINING, |
| 492 | + expectedErr: fmt.Errorf(errTSDBCreateIncompatibleState, ring.JOINING), |
| 493 | + }, |
| 494 | + "not allow to create TSDB if in LEAVING state": { |
| 495 | + state: ring.LEAVING, |
| 496 | + expectedErr: fmt.Errorf(errTSDBCreateIncompatibleState, ring.LEAVING), |
| 497 | + }, |
| 498 | + "allow to create TSDB if in ACTIVE state": { |
| 499 | + state: ring.ACTIVE, |
| 500 | + expectedErr: nil, |
| 501 | + }, |
| 502 | + } |
| 503 | + |
| 504 | + for testName, testData := range tests { |
| 505 | + t.Run(testName, func(t *testing.T) { |
| 506 | + cfg := defaultIngesterTestConfig() |
| 507 | + cfg.LifecyclerConfig.JoinAfter = 60 * time.Second |
| 508 | + |
| 509 | + i, cleanup, err := newIngesterMockWithTSDBStorage(cfg, nil) |
| 510 | + require.NoError(t, err) |
| 511 | + defer i.Shutdown() |
| 512 | + defer cleanup() |
| 513 | + |
| 514 | + // Switch ingester state to the expected one in the test |
| 515 | + if i.lifecycler.GetState() != testData.state { |
| 516 | + var stateChain []ring.IngesterState |
| 517 | + |
| 518 | + if testData.state == ring.LEAVING { |
| 519 | + stateChain = []ring.IngesterState{ring.ACTIVE, ring.LEAVING} |
| 520 | + } else { |
| 521 | + stateChain = []ring.IngesterState{testData.state} |
| 522 | + } |
| 523 | + |
| 524 | + for _, s := range stateChain { |
| 525 | + err = i.lifecycler.ChangeState(context.Background(), s) |
| 526 | + require.NoError(t, err) |
| 527 | + } |
| 528 | + } |
| 529 | + |
| 530 | + db, err := i.getOrCreateTSDB("test", false) |
| 531 | + assert.Equal(t, testData.expectedErr, err) |
| 532 | + |
| 533 | + if testData.expectedErr != nil { |
| 534 | + assert.Nil(t, db) |
| 535 | + } else { |
| 536 | + assert.NotNil(t, db) |
| 537 | + } |
| 538 | + }) |
| 539 | + } |
| 540 | +} |
391 | 541 |
|
392 | 542 | func mockWriteRequest(lbls labels.Labels, value float64, timestampMs int64) (*client.WriteRequest, *client.QueryResponse) {
|
393 | 543 | samples := []client.Sample{
|
@@ -432,7 +582,7 @@ func newIngesterMockWithTSDBStorage(ingesterCfg Config, registerer prometheus.Re
|
432 | 582 | ingesterCfg.TSDBConfig.Backend = "s3"
|
433 | 583 | ingesterCfg.TSDBConfig.S3.Endpoint = "localhost"
|
434 | 584 |
|
435 |
| - ingester, err := NewV2(ingesterCfg, clientCfg, overrides, nil, registerer) |
| 585 | + ingester, err := NewV2(ingesterCfg, clientCfg, overrides, registerer) |
436 | 586 | if err != nil {
|
437 | 587 | return nil, nil, err
|
438 | 588 | }
|
|
0 commit comments