TestChannelCacheBypass validates that the bypass 'cache' is used when the cache max_num_channels is reached. To force this scenario, HWM is set to 100%, which effectively disables compaction.
(t *testing.T)
| 465 | // TestChannelCacheBypass validates that the bypass 'cache' is used when the cache max_num_channels is reached. |
| 466 | // To force this scenario, HWM is set to 100%, which effectively disables compaction. |
| 467 | func TestChannelCacheBypass(t *testing.T) { |
| 468 | base.SetUpTestLogging(t, base.LevelWarn, base.KeyCache) |
| 469 | |
| 470 | // Define cache with max channels 20, watermarks 50/100 |
| 471 | options := DefaultCacheOptions().ChannelCacheOptions |
| 472 | options.MaxNumChannels = 20 |
| 473 | options.CompactHighWatermarkPercent = 100 |
| 474 | options.CompactLowWatermarkPercent = 50 |
| 475 | |
| 476 | stats, err := base.NewSyncGatewayStats() |
| 477 | require.NoError(t, err) |
| 478 | dbstats, err := stats.NewDBStats("", false, false, false, nil, nil) |
| 479 | require.NoError(t, err) |
| 480 | testStats := dbstats.Cache() |
| 481 | queryHandler := &testQueryHandler{} |
| 482 | activeChannelStat := &base.SgwIntStat{} |
| 483 | activeChannels := channels.NewActiveChannels(activeChannelStat) |
| 484 | ctx := base.TestCtx(t) |
| 485 | cache, err := newChannelCache(ctx, "testDb", options, queryHandler.asFactory, activeChannels, testStats) |
| 486 | require.NoError(t, err, "Background task error whilst creating channel cache") |
| 487 | defer cache.Stop(ctx) |
| 488 | |
| 489 | channelCount := 100 |
| 490 | // define channel set |
| 491 | channelNames := make([]string, 0) |
| 492 | for i := 1; i <= channelCount; i++ { |
| 493 | channelName := fmt.Sprintf("chan_%d", i) |
| 494 | channelNames = append(channelNames, channelName) |
| 495 | } |
| 496 | |
| 497 | // Seed the query handler with a single doc that's in all the channels |
| 498 | queryEntry := testLogEntryForChannels(1, channelNames) |
| 499 | queryHandler.seedEntries(LogEntries{queryEntry}) |
| 500 | |
| 501 | // Send entry to the cache. Don't reuse queryEntry here, as AddToCache strips out the channels property |
| 502 | logEntry := testLogEntryForChannels(1, channelNames) |
| 503 | cache.AddToCache(ctx, logEntry) |
| 504 | |
| 505 | // Issue queries for all channels. First 20 should end up in the cache, remaining 80 should trigger bypass |
| 506 | for c := 1; c <= channelCount; c++ { |
| 507 | channel := channels.NewID(fmt.Sprintf("chan_%d", c), base.DefaultCollectionID) |
| 508 | options := getChangesOptionsWithCtxOnly(t) |
| 509 | changes, err := cache.GetChanges(base.TestCtx(t), channel, options) |
| 510 | assert.NoError(t, err, fmt.Sprintf("Error getting changes for channel %q", channel)) |
| 511 | assert.True(t, len(changes) == 1, "Expected one change per channel") |
| 512 | } |
| 513 | |
| 514 | // check bypass count stat |
| 515 | bypassCountStat := testStats.ChannelCacheBypassCount |
| 516 | require.NotNil(t, bypassCountStat) |
| 517 | assert.Equal(t, 80, int(bypassCountStat.Value())) |
| 518 | } |
| 519 | |
| 520 | func waitForCompaction(cache *channelCacheImpl) (compactionComplete bool) { |
| 521 | for i := 0; i <= 10; i++ { |
nothing calls this directly
no test coverage detected