owpengram-server/internal/store/postgres/groupcall_integration_test.go

88 lines
2.8 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package postgres
import (
"context"
"sync"
"testing"
"time"
"telesrv/internal/domain"
"telesrv/internal/store"
"telesrv/internal/store/storetest"
)
// TestGroupCallStoreContractPostgres 与 memory 实现共跑同一契约TELESRV_TEST_POSTGRES_DSN 门控)。
func TestGroupCallStoreContractPostgres(t *testing.T) {
pool := testPool(t)
ctx := context.Background()
var nextChannel int64 = 910_000_000
storetest.RunGroupCallStoreContract(t, func(t *testing.T) (store.GroupCallStore, int64) {
nextChannel++
channelID := nextChannel
t.Cleanup(func() {
_, _ = pool.Exec(ctx, "DELETE FROM group_calls WHERE channel_id = $1", channelID)
})
return NewGroupCallStore(pool), channelID
})
}
// TestGroupCallStoreM2ContractPostgres 跑 overrides/raise-hand 契约DSN 门控)。
func TestGroupCallStoreM2ContractPostgres(t *testing.T) {
pool := testPool(t)
ctx := context.Background()
var nextChannel int64 = 920_000_000
storetest.RunGroupCallStoreM2Contract(t, func(t *testing.T) (store.GroupCallStore, int64) {
nextChannel++
channelID := nextChannel
t.Cleanup(func() {
_, _ = pool.Exec(ctx, "DELETE FROM group_calls WHERE channel_id = $1", channelID)
})
return NewGroupCallStore(pool), channelID
})
}
// TestGroupCallStoreConcurrentJoinVersions 验证行锁串行化下 version 无跳号。
func TestGroupCallStoreConcurrentJoinVersions(t *testing.T) {
pool := testPool(t)
ctx := context.Background()
const channelID = 910_900_001
t.Cleanup(func() {
_, _ = pool.Exec(ctx, "DELETE FROM group_calls WHERE channel_id = $1", channelID)
})
st := NewGroupCallStore(pool)
// 时间基准取运行时刻:测试库可能与运行中的开发服务器共库,远古
// last_check_date 会被线上 sweeper 当幽灵清掉,污染 version/count 断言。
now := int(time.Now().Unix())
call, err := st.CreateGroupCall(ctx, domain.GroupCall{ID: 910_900_100, AccessHash: 5, ChannelID: channelID, CreatorUserID: 1, CreatedAt: now})
if err != nil {
t.Fatalf("create: %v", err)
}
const joiners = 8
var wg sync.WaitGroup
versions := make(chan int, joiners)
for i := int64(0); i < joiners; i++ {
wg.Add(1)
go func(userID int64) {
defer wg.Done()
mut, err := st.JoinGroupCall(ctx, domain.JoinGroupCallRequest{CallID: call.ID, UserID: userID, SSRC: 7000 + userID, Now: now})
if err != nil {
t.Errorf("join %d: %v", userID, err)
return
}
versions <- mut.Call.Version
}(100 + i)
}
wg.Wait()
close(versions)
seen := map[int]bool{}
for v := range versions {
if seen[v] {
t.Fatalf("duplicate version %d under concurrency", v)
}
seen[v] = true
}
final, _, err := st.GetGroupCall(ctx, call.ID)
if err != nil || final.Version != 1+joiners || final.ParticipantsCount != joiners {
t.Fatalf("final call = %+v err=%v", final, err)
}
}