Initial open source release
This commit is contained in:
commit
74992e893f
377 changed files with 118084 additions and 0 deletions
127
internal/store/postgres/contiguous_pts_integration_test.go
Normal file
127
internal/store/postgres/contiguous_pts_integration_test.go
Normal file
|
|
@ -0,0 +1,127 @@
|
|||
package postgres
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"telesrv/internal/domain"
|
||||
)
|
||||
|
||||
// TestMaxContiguousPtsStopsAtHole 用真实 PG 验证 RecentUserPts 窗口查询 + 连续计算:
|
||||
// 存在在途空洞时只报告最大连续 pts,补洞后回升。
|
||||
func TestMaxContiguousPtsStopsAtHole(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
|
||||
suffix := randomSuffix(t)
|
||||
owner, err := NewUserStore(pool).Create(ctx, domain.User{
|
||||
AccessHash: 1,
|
||||
Phone: "+1556" + suffix + "01",
|
||||
FirstName: "Contig",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create user: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM user_update_events WHERE user_id = $1", owner.ID)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = $1", owner.ID)
|
||||
})
|
||||
|
||||
events := NewUpdateEventStore(pool)
|
||||
appendPts := func(pts int) {
|
||||
if err := events.Append(ctx, owner.ID, domain.UpdateEvent{
|
||||
Type: domain.UpdateEventNoop,
|
||||
Pts: pts,
|
||||
PtsCount: 1,
|
||||
Date: 1700000000 + pts,
|
||||
}); err != nil {
|
||||
t.Fatalf("append pts=%d: %v", pts, err)
|
||||
}
|
||||
}
|
||||
|
||||
for _, p := range []int{1, 2, 3, 5, 6} { // pts=4 为在途空洞
|
||||
appendPts(p)
|
||||
}
|
||||
if _, err := pool.Exec(ctx, "DELETE FROM user_update_watermarks WHERE user_id = $1", owner.ID); err != nil {
|
||||
t.Fatalf("delete watermark fallback row: %v", err)
|
||||
}
|
||||
got, err := events.MaxContiguousPts(ctx, owner.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("MaxContiguousPts: %v", err)
|
||||
}
|
||||
if got != 3 {
|
||||
t.Fatalf("contiguous = %d, want 3(止于 pts=4 空洞,最大已提交为 6)", got)
|
||||
}
|
||||
|
||||
appendPts(4) // 在途事务提交/补洞
|
||||
got, err = events.MaxContiguousPts(ctx, owner.ID)
|
||||
if err != nil {
|
||||
t.Fatalf("MaxContiguousPts after fill: %v", err)
|
||||
}
|
||||
if got != 6 {
|
||||
t.Fatalf("contiguous after fill = %d, want 6", got)
|
||||
}
|
||||
}
|
||||
|
||||
func TestAppendWithDispatchWritesEventAndOutboxAtomically(t *testing.T) {
|
||||
pool := testPool(t)
|
||||
ctx := context.Background()
|
||||
|
||||
suffix := randomSuffix(t)
|
||||
owner, err := NewUserStore(pool).Create(ctx, domain.User{
|
||||
AccessHash: 2,
|
||||
Phone: "+1557" + suffix + "01",
|
||||
FirstName: "Dispatch",
|
||||
})
|
||||
if err != nil {
|
||||
t.Fatalf("create user: %v", err)
|
||||
}
|
||||
t.Cleanup(func() {
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM dispatch_outbox WHERE target_user_id = $1", owner.ID)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM user_update_events WHERE user_id = $1", owner.ID)
|
||||
_, _ = pool.Exec(ctx, "DELETE FROM users WHERE id = $1", owner.ID)
|
||||
})
|
||||
|
||||
event := domain.UpdateEvent{
|
||||
UserID: owner.ID,
|
||||
Type: domain.UpdateEventDialogPinned,
|
||||
Pts: 1,
|
||||
PtsCount: 1,
|
||||
Date: 1700000001,
|
||||
Peer: domain.Peer{Type: domain.PeerTypeUser, ID: 1000000002},
|
||||
Settings: domain.PeerSettings{
|
||||
ShareContact: true,
|
||||
},
|
||||
Bool: true,
|
||||
}
|
||||
var excludeAuthKeyID [8]byte
|
||||
excludeAuthKeyID[0] = 9
|
||||
if err := NewUpdateEventStore(pool).AppendWithDispatch(ctx, owner.ID, event, excludeAuthKeyID, 77); err != nil {
|
||||
t.Fatalf("AppendWithDispatch: %v", err)
|
||||
}
|
||||
|
||||
got, err := NewUpdateEventStore(pool).ListAfter(ctx, owner.ID, 0, 10)
|
||||
if err != nil {
|
||||
t.Fatalf("ListAfter: %v", err)
|
||||
}
|
||||
if len(got) != 1 || got[0].Type != event.Type || got[0].Peer != event.Peer || !got[0].Bool {
|
||||
t.Fatalf("events = %+v, want dialog pinned event", got)
|
||||
}
|
||||
|
||||
var outbox struct {
|
||||
pts int
|
||||
eventType string
|
||||
excludeAuthKeyID int64
|
||||
excludeSessionID int64
|
||||
}
|
||||
if err := pool.QueryRow(ctx, `
|
||||
SELECT pts, event_type, exclude_auth_key_id, exclude_session_id
|
||||
FROM dispatch_outbox
|
||||
WHERE target_user_id = $1
|
||||
`, owner.ID).Scan(&outbox.pts, &outbox.eventType, &outbox.excludeAuthKeyID, &outbox.excludeSessionID); err != nil {
|
||||
t.Fatalf("query dispatch outbox: %v", err)
|
||||
}
|
||||
if outbox.pts != 1 || outbox.eventType != string(domain.UpdateEventDialogPinned) || outbox.excludeAuthKeyID != authKeyIDToInt64(excludeAuthKeyID) || outbox.excludeSessionID != 77 {
|
||||
t.Fatalf("outbox = %+v, want event dispatch excluding current session", outbox)
|
||||
}
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue