TestAsyncInitConfigUpdates verifies that a database with in-progress async index initialization can accept all config updates from the local node. (prior to CBG-4008, operations would block waiting for async init to complete)
(t *testing.T)
| 626 | // index initialization can accept all config updates from the local node. |
| 627 | // (prior to CBG-4008, operations would block waiting for async init to complete) |
| 628 | func TestAsyncInitConfigUpdates(t *testing.T) { |
| 629 | if base.UnitTestUrlIsWalrus() { |
| 630 | t.Skip("This test only works against Couchbase Server") |
| 631 | } |
| 632 | base.TestRequiresCollections(t) |
| 633 | base.SetUpTestLogging(t, base.LevelDebug, base.KeyHTTP) |
| 634 | |
| 635 | sc, closeFn := rest.StartBootstrapServer(t) |
| 636 | defer closeFn() |
| 637 | |
| 638 | // Set testing callbacks for async initialization |
| 639 | collectionCount := int64(0) |
| 640 | initStarted := make(chan error) |
| 641 | unblockInit := make(chan error) |
| 642 | collectionCompleteCallback := func(_ string, _ base.ScopeAndCollectionName, status db.CollectionIndexStatus) { |
| 643 | if status != db.CollectionIndexStatusReady { |
| 644 | return |
| 645 | } |
| 646 | count := atomic.AddInt64(&collectionCount, 1) |
| 647 | // On first collection, close initStarted channel |
| 648 | log.Printf("collection callback count: %v", count) |
| 649 | if count == 1 { |
| 650 | log.Printf("closing initStarted") |
| 651 | close(initStarted) |
| 652 | } |
| 653 | rest.WaitForChannel(t, unblockInit, "waiting for test to unblock initialization") |
| 654 | } |
| 655 | sc.DatabaseInitManager.SetTestCallbacks(collectionCompleteCallback, nil) |
| 656 | |
| 657 | ctx := base.TestCtx(t) |
| 658 | // Get a test bucket, and use it to create the database. |
| 659 | tb := base.GetTestBucket(t) |
| 660 | defer tb.Close(ctx) |
| 661 | |
| 662 | importFilter := "function(doc) { return true }" |
| 663 | syncFunc := "function(doc){ channel(doc.channels); }" |
| 664 | |
| 665 | dbConfig := makeDbConfig(t, tb, syncFunc, importFilter) |
| 666 | dbConfig.StartOffline = base.Ptr(true) |
| 667 | dbConfigPayload, err := json.Marshal(dbConfig) |
| 668 | require.NoError(t, err) |
| 669 | dbName := "db" |
| 670 | |
| 671 | keyspace := dbName |
| 672 | if len(dbConfig.Scopes) > 0 { |
| 673 | keyspaces := getRESTKeyspaces(dbName, dbConfig.Scopes) |
| 674 | keyspace = keyspaces[0] |
| 675 | } |
| 676 | |
| 677 | // Create database with offline=true |
| 678 | resp := rest.BootstrapAdminRequest(t, sc, http.MethodPut, "/"+dbName+"/", string(dbConfigPayload)) |
| 679 | resp.RequireStatus(http.StatusCreated) |
| 680 | |
| 681 | // Wait for init to start before interacting with the db, validate db state is offline |
| 682 | rest.WaitForChannel(t, initStarted, "waiting for initialization to start") |
| 683 | log.Printf("initialization started") |
| 684 | waitAndRequireDBState(t, sc, dbName, db.DBOffline) |
| 685 |
nothing calls this directly
no test coverage detected