package host import ( "context" "net" "sync" "testing" "time" "github.com/carlosframework/platform/internal/instancectl" ) func TestClaimStopFullDuplexSocket(t *testing.T) { c, req, _ := claimStopFixture(t) peer, err := c.Peers.AuthenticatedPeer(t.Context()) if err != nil { t.Fatal(err) } client, serverConn := net.Pipe() ln := &stopPipeListener{conn: serverConn, closed: make(chan struct{})} ctx, cancel := context.WithCancel(t.Context()) defer cancel() handler := ClaimStopHTTP{Coordinator: c, Authenticate: func(context.Context, net.Conn) (StopPeer, error) { return peer, nil }} server := instancectl.Server{PeerOK: func(net.Conn) error { return nil }, ClaimStop: handler} done := make(chan error, 1) go func() { done <- server.Serve(ctx, ln) }() ctx, timeout := context.WithTimeout(ctx, 5*time.Second) defer timeout() got, err := collectClaimStop(ctx, "unused", req, c.Drainer, func(context.Context, string, string) (net.Conn, error) { return client, nil }) if err != nil { t.Fatal(err) } if got.Digest == "" || len(got.Bytes) == 0 { t.Fatal("missing receipt") } cancel() if err := <-done; err != nil { t.Fatal(err) } } type stopPipeListener struct { mu sync.Mutex conn net.Conn closed chan struct{} once sync.Once } func (l *stopPipeListener) Accept() (net.Conn, error) { l.mu.Lock() c := l.conn l.conn = nil l.mu.Unlock() if c != nil { return c, nil } <-l.closed return nil, net.ErrClosed } func (l *stopPipeListener) Close() error { l.once.Do(func() { close(l.closed) }); return nil } func (l *stopPipeListener) Addr() net.Addr { return &net.UnixAddr{Name: "fixture", Net: "unix"} }