carlos / platform Public

Clone
git clone https://amadan.net/carlos/platform

Plain git — no account needed to clone.

Download

Download this file

1package host
2
3import (
4 "context"
5 "net"
6 "sync"
7 "testing"
8 "time"
9
10 "github.com/carlosframework/platform/internal/instancectl"
11)
12
13func TestClaimStopFullDuplexSocket(t *testing.T) {
14 c, req, _ := claimStopFixture(t)
15 peer, err := c.Peers.AuthenticatedPeer(t.Context())
16 if err != nil {
17 t.Fatal(err)
18 }
19 client, serverConn := net.Pipe()
20 ln := &stopPipeListener{conn: serverConn, closed: make(chan struct{})}
21 ctx, cancel := context.WithCancel(t.Context())
22 defer cancel()
23 handler := ClaimStopHTTP{Coordinator: c, Authenticate: func(context.Context, net.Conn) (StopPeer, error) { return peer, nil }}
24 server := instancectl.Server{PeerOK: func(net.Conn) error { return nil }, ClaimStop: handler}
25 done := make(chan error, 1)
26 go func() { done <- server.Serve(ctx, ln) }()
27 ctx, timeout := context.WithTimeout(ctx, 5*time.Second)
28 defer timeout()
29 got, err := collectClaimStop(ctx, "unused", req, c.Drainer, func(context.Context, string, string) (net.Conn, error) { return client, nil })
30 if err != nil {
31 t.Fatal(err)
32 }
33 if got.Digest == "" || len(got.Bytes) == 0 {
34 t.Fatal("missing receipt")
35 }
36 cancel()
37 if err := <-done; err != nil {
38 t.Fatal(err)
39 }
40}
41
42type stopPipeListener struct {
43 mu sync.Mutex
44 conn net.Conn
45 closed chan struct{}
46 once sync.Once
47}
48
49func (l *stopPipeListener) Accept() (net.Conn, error) {
50 l.mu.Lock()
51 c := l.conn
52 l.conn = nil
53 l.mu.Unlock()
54 if c != nil {
55 return c, nil
56 }
57 <-l.closed
58 return nil, net.ErrClosed
59}
60func (l *stopPipeListener) Close() error { l.once.Do(func() { close(l.closed) }); return nil }
61func (l *stopPipeListener) Addr() net.Addr { return &net.UnixAddr{Name: "fixture", Net: "unix"} }
62