//go:build mysql package mysql import ( "testing" "time" "github.com/tinode/chat/server/store/types" ) func TestTenantRouteCacheExpiresAndInvalidates(t *testing.T) { now := time.Now() tenantID := types.TenantID(8) tenantAdp := &adapter{tenantID: tenantID} root := &adapter{ tenantDBRouting: true, tenantAdapters: map[types.TenantID]*adapter{tenantID: tenantAdp}, tenantRouteExpiry: make(map[types.TenantID]time.Time), } root.cacheTenantAdapter(tenantID, tenantAdp, root.tenantRouteGeneration(), now.Add(time.Minute)) if got, ok := root.cachedTenantAdapter(tenantID, now); !ok || got != tenantAdp { t.Fatalf("cached route = %p, %v; want %p, true", got, ok, tenantAdp) } if got, _, err := root.TenantAdapterFor(tenantID); err != nil || got != tenantAdp { t.Fatalf("TenantAdapterFor cached route = %p, %v; want %p, nil", got, err, tenantAdp) } staleGeneration := root.tenantRouteGeneration() root.InvalidateTenantRoute(tenantID) if _, ok := root.cachedTenantAdapter(tenantID, now); ok { t.Fatal("invalidated tenant route remained cached") } root.cacheTenantAdapter(tenantID, tenantAdp, staleGeneration, now.Add(time.Minute)) if _, ok := root.cachedTenantAdapter(tenantID, now); ok { t.Fatal("an in-flight stale refresh repopulated the route cache") } root.cacheTenantAdapter(tenantID, tenantAdp, root.tenantRouteGeneration(), now.Add(-time.Second)) if _, ok := root.cachedTenantAdapter(tenantID, now); ok { t.Fatal("expired tenant route remained cached") } } func TestInvalidateAllTenantRoutes(t *testing.T) { now := time.Now() root := &adapter{ tenantDBRouting: true, tenantAdapters: map[types.TenantID]*adapter{ 8: {tenantID: 8}, 9: {tenantID: 9}, }, tenantRouteExpiry: map[types.TenantID]time.Time{ 8: now.Add(time.Minute), 9: now.Add(time.Minute), }, } root.InvalidateTenantRoute(0) for _, tenantID := range []types.TenantID{8, 9} { if _, ok := root.cachedTenantAdapter(tenantID, now); ok { t.Fatalf("tenant %d route remained cached after global invalidation", tenantID) } } }