67be43319e
Desktop Client Build / Resolve Build Metadata (push) Successful in 1m13s
Desktop Client Build / Build Desktop Client (push) Has been cancelled
Desktop Client Build / Publish Client Artifacts to NAS (push) Has been cancelled
Backend CI / Backend (push) Failing after 13m49s
Frontend CI / Frontend (push) Successful in 6m38s
- Added new fields to DesktopAccountInfo for tracking account session and task consumer online status, along with queued publish task count and oldest queued publish task timestamp. - Updated DesktopDispatchEvent to include server time for better synchronization. - Implemented separate presence management for task consumers, including marking presence and loading presence state. - Enhanced DesktopAccountService to apply publish queue summaries and manage task consumer presence. - Introduced new methods for replaying queued publish tasks in DesktopDispatchHandler. - Updated tests to cover new presence management logic and ensure correct behavior of account session and task consumer online status.
114 lines
3.5 KiB
Go
114 lines
3.5 KiB
Go
package app
|
|
|
|
import (
|
|
"context"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/alicebob/miniredis/v2"
|
|
"github.com/google/uuid"
|
|
goredis "github.com/redis/go-redis/v9"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
|
|
"github.com/geo-platform/tenant-api/internal/tenant/repository"
|
|
)
|
|
|
|
func TestDesktopUserOnlineClientCountPrefersRedisPresenceIndex(t *testing.T) {
|
|
ctx := context.Background()
|
|
server := miniredis.RunT(t)
|
|
redis := goredis.NewClient(&goredis.Options{Addr: server.Addr()})
|
|
t.Cleanup(func() {
|
|
require.NoError(t, redis.Close())
|
|
})
|
|
|
|
tenantID := int64(7)
|
|
workspaceID := int64(11)
|
|
userID := int64(23)
|
|
firstClientID := uuid.New()
|
|
secondClientID := uuid.New()
|
|
|
|
markDesktopClientPresentForUser(ctx, redis, firstClientID, tenantID, workspaceID, userID)
|
|
markDesktopClientPresentForUser(ctx, redis, secondClientID, tenantID, workspaceID, userID)
|
|
|
|
count, ok := loadDesktopUserOnlineClientCount(ctx, redis, tenantID, workspaceID, userID, time.Now().UTC())
|
|
|
|
require.True(t, ok)
|
|
assert.Equal(t, 2, count)
|
|
}
|
|
|
|
func TestDesktopClientServiceOnlineCountReturnsRedisCountBeforeRepoFallback(t *testing.T) {
|
|
ctx := context.Background()
|
|
server := miniredis.RunT(t)
|
|
redis := goredis.NewClient(&goredis.Options{Addr: server.Addr()})
|
|
t.Cleanup(func() {
|
|
require.NoError(t, redis.Close())
|
|
})
|
|
|
|
client := &repository.DesktopClient{
|
|
ID: uuid.New(),
|
|
TenantID: 7,
|
|
WorkspaceID: 11,
|
|
UserID: 23,
|
|
}
|
|
markDesktopClientPresentForUser(ctx, redis, client.ID, client.TenantID, client.WorkspaceID, client.UserID)
|
|
markDesktopClientPresentForUser(ctx, redis, uuid.New(), client.TenantID, client.WorkspaceID, client.UserID)
|
|
|
|
count, err := (&DesktopClientService{redis: redis}).currentUserOnlineClientCount(ctx, client)
|
|
|
|
require.NoError(t, err)
|
|
assert.Equal(t, 2, count)
|
|
}
|
|
|
|
func TestDesktopUserOnlineClientCountPrunesStaleRedisPresence(t *testing.T) {
|
|
ctx := context.Background()
|
|
server := miniredis.RunT(t)
|
|
redis := goredis.NewClient(&goredis.Options{Addr: server.Addr()})
|
|
t.Cleanup(func() {
|
|
require.NoError(t, redis.Close())
|
|
})
|
|
|
|
tenantID := int64(7)
|
|
workspaceID := int64(11)
|
|
userID := int64(23)
|
|
key := desktopUserClientsPresenceKey(tenantID, workspaceID, userID)
|
|
now := time.Date(2026, 5, 6, 12, 0, 0, 0, time.UTC)
|
|
|
|
require.NoError(t, redis.ZAdd(ctx, key,
|
|
goredis.Z{Score: float64(now.Add(-2 * desktopClientPresenceTTL).UnixMilli()), Member: uuid.NewString()},
|
|
goredis.Z{Score: float64(now.Add(-time.Second).UnixMilli()), Member: uuid.NewString()},
|
|
).Err())
|
|
|
|
count, ok := loadDesktopUserOnlineClientCount(ctx, redis, tenantID, workspaceID, userID, now)
|
|
|
|
require.True(t, ok)
|
|
assert.Equal(t, 1, count)
|
|
}
|
|
|
|
func TestDesktopTaskConsumerPresenceIsSeparateFromHeartbeatPresence(t *testing.T) {
|
|
ctx := context.Background()
|
|
server := miniredis.RunT(t)
|
|
redis := goredis.NewClient(&goredis.Options{Addr: server.Addr()})
|
|
t.Cleanup(func() {
|
|
require.NoError(t, redis.Close())
|
|
})
|
|
|
|
clientID := uuid.New()
|
|
|
|
markDesktopClientPresent(ctx, redis, clientID)
|
|
|
|
clientPresence := loadDesktopClientPresence(ctx, redis, []uuid.UUID{clientID})
|
|
taskConsumerPresence := loadDesktopTaskConsumerPresence(ctx, redis, []uuid.UUID{clientID})
|
|
|
|
require.NotNil(t, clientPresence)
|
|
require.NotNil(t, taskConsumerPresence)
|
|
assert.True(t, clientPresence[clientID])
|
|
assert.False(t, taskConsumerPresence[clientID])
|
|
|
|
markDesktopTaskConsumerPresent(ctx, redis, clientID)
|
|
taskConsumerPresence = loadDesktopTaskConsumerPresence(ctx, redis, []uuid.UUID{clientID})
|
|
|
|
require.NotNil(t, taskConsumerPresence)
|
|
assert.True(t, taskConsumerPresence[clientID])
|
|
}
|