fix dtt
This commit is contained in:
@@ -0,0 +1,89 @@
|
||||
package imapx
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
"time"
|
||||
)
|
||||
|
||||
// TestKeepaliveReturnsOnContextCancel proves Keepalive is a well-behaved
|
||||
// goroutine: it exits promptly when its context is cancelled instead of
|
||||
// leaking.
|
||||
func TestKeepaliveReturnsOnContextCancel(t *testing.T) {
|
||||
ep := testEP(t)
|
||||
ctx := context.Background()
|
||||
|
||||
c, err := Connect(ctx, ep)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = c.Logout().Wait() }()
|
||||
if err := c.Login("ka1@localhost", "p").Wait(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
kctx, cancel := context.WithCancel(ctx)
|
||||
done := make(chan struct{})
|
||||
go func() { Keepalive(kctx, c, 10*time.Millisecond); close(done) }()
|
||||
|
||||
// Let a few NOOPs fire, then cancel and require a prompt return.
|
||||
time.Sleep(50 * time.Millisecond)
|
||||
cancel()
|
||||
select {
|
||||
case <-done:
|
||||
case <-time.After(2 * time.Second):
|
||||
t.Fatal("Keepalive did not return within 2s of context cancel")
|
||||
}
|
||||
}
|
||||
|
||||
// TestKeepaliveDoesNotDisruptCopy runs Keepalive on the destination connection
|
||||
// at an aggressive interval while CopyFolder is APPENDing to it, proving the
|
||||
// concurrent NOOPs do not corrupt in-flight commands (the real risk of pinging
|
||||
// a connection that is also being used for real work).
|
||||
func TestKeepaliveDoesNotDisruptCopy(t *testing.T) {
|
||||
ep := testEP(t)
|
||||
ctx := context.Background()
|
||||
|
||||
const n = 8
|
||||
seedInbox(t, ep, "kasrc@localhost", "p", n)
|
||||
|
||||
src, err := Connect(ctx, ep)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = src.Logout().Wait() }()
|
||||
if err := src.Login("kasrc@localhost", "p").Wait(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
dst, err := Connect(ctx, ep)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
defer func() { _ = dst.Logout().Wait() }()
|
||||
if err := dst.Login("kadst@localhost", "p").Wait(); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
kctx, cancel := context.WithCancel(ctx)
|
||||
defer cancel()
|
||||
go Keepalive(kctx, dst, 1*time.Millisecond)
|
||||
|
||||
seen := map[string]bool{}
|
||||
deps := CopyDeps{
|
||||
IsMigrated: func(k string) (bool, error) { return seen[k], nil },
|
||||
MarkMigrated: func(_, k string) error { seen[k] = true; return nil },
|
||||
OnProgress: func(_, _ int) {},
|
||||
}
|
||||
|
||||
r, err := CopyFolder(kctx, src, dst, "INBOX", "INBOX", deps)
|
||||
if err != nil {
|
||||
t.Fatalf("CopyFolder with concurrent keepalive: %v", err)
|
||||
}
|
||||
if r.Copied != n {
|
||||
t.Fatalf("copied=%d want %d", r.Copied, n)
|
||||
}
|
||||
if r.Errors != 0 {
|
||||
t.Fatalf("errors=%d want 0", r.Errors)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user