TestAsyncInitWithResync verifies that resync can run successfully while async index initialization is in progress. Handles the case where data has been migrated between buckets but index doesn't yet exist in new bucket. 1. Creates a database, writes documents via SG to generate metadata 2. Deletes t
(t *testing.T)
| 235 | // 4. Recreates the database with blocking callback for index initialization |
| 236 | // 5. Runs resync while init is blocked/in progress |
| 237 | func TestAsyncInitWithResync(t *testing.T) { |
| 238 | if base.UnitTestUrlIsWalrus() { |
| 239 | t.Skip("This test only works against Couchbase Server") |
| 240 | } |
| 241 | if !base.TestUseXattrs() { |
| 242 | t.Skip("this test uses xattrs for verification of sync metadata") |
| 243 | } |
| 244 | base.TestRequiresCollections(t) |
| 245 | base.SetUpTestLogging(t, base.LevelDebug, base.KeyHTTP) |
| 246 | |
| 247 | sc, closeFn := rest.StartBootstrapServer(t) |
| 248 | defer closeFn() |
| 249 | |
| 250 | ctx := base.TestCtx(t) |
| 251 | // Seed the bucket with some documents |
| 252 | tb := base.GetTestBucket(t) |
| 253 | defer tb.Close(ctx) |
| 254 | |
| 255 | syncFunc := "function(doc){ channel(doc.channel1); }" |
| 256 | dbConfig := makeDbConfig(t, tb, syncFunc, "") |
| 257 | dbConfig.StartOffline = base.Ptr(false) |
| 258 | dbConfigPayload, err := json.Marshal(dbConfig) |
| 259 | require.NoError(t, err) |
| 260 | dbName := "db" |
| 261 | |
| 262 | docCollection, err := base.AsCollection(tb.GetSingleDataStore()) |
| 263 | require.NoError(t, err) |
| 264 | keyspace := dbName + "." + docCollection.ScopeName() + "." + docCollection.CollectionName() |
| 265 | |
| 266 | // Persist config |
| 267 | resp := rest.BootstrapAdminRequest(t, sc, http.MethodPut, "/"+dbName+"/", string(dbConfigPayload)) |
| 268 | resp.RequireStatus(http.StatusCreated) |
| 269 | waitAndRequireDBState(t, sc, dbName, db.DBOnline) |
| 270 | |
| 271 | for i := 0; i < 5; i++ { |
| 272 | docID := fmt.Sprintf("doc%d", i) |
| 273 | docBody := `{"channel1":["ABC"], "channel2":["DEF"]}` |
| 274 | resp := rest.BootstrapAdminRequest(t, sc, http.MethodPut, "/"+keyspace+"/"+docID, docBody) |
| 275 | resp.RequireStatus(http.StatusCreated) |
| 276 | } |
| 277 | |
| 278 | // Delete the database |
| 279 | resp = rest.BootstrapAdminRequest(t, sc, http.MethodDelete, "/"+dbName+"/", "") |
| 280 | resp.RequireStatus(http.StatusOK) |
| 281 | |
| 282 | rest.DropAllTestIndexesIncludingPrimary(t, tb) |
| 283 | |
| 284 | // Set testing callbacks for async initialization |
| 285 | collectionCount := int64(0) |
| 286 | initStarted := make(chan error) |
| 287 | unblockInit := make(chan error) |
| 288 | collectionCompleteCallback := func(_ string, _ base.ScopeAndCollectionName, status db.CollectionIndexStatus) { |
| 289 | if status != db.CollectionIndexStatusReady { |
| 290 | return |
| 291 | } |
| 292 | count := atomic.AddInt64(&collectionCount, 1) |
| 293 | // On first collection, close initStarted channel |
| 294 | log.Printf("collection callback count: %v", count) |
nothing calls this directly
no test coverage detected