github.com/powerman/golang-tools@v0.1.11-0.20220410185822-5ad214d8d803/internal/lsp/lsprpc/middleware_test.go (about) 1 // Copyright 2021 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package lsprpc_test 6 7 import ( 8 "context" 9 "errors" 10 "fmt" 11 "testing" 12 "time" 13 14 jsonrpc2_v2 "github.com/powerman/golang-tools/internal/jsonrpc2_v2" 15 . "github.com/powerman/golang-tools/internal/lsp/lsprpc" 16 ) 17 18 var noopBinder = BinderFunc(func(context.Context, *jsonrpc2_v2.Connection) (jsonrpc2_v2.ConnectionOptions, error) { 19 return jsonrpc2_v2.ConnectionOptions{}, nil 20 }) 21 22 func TestHandshakeMiddleware(t *testing.T) { 23 sh := &Handshaker{ 24 Metadata: Metadata{ 25 "answer": 42, 26 }, 27 } 28 ctx := context.Background() 29 env := new(TestEnv) 30 defer env.Shutdown(t) 31 l, _ := env.serve(ctx, t, sh.Middleware(noopBinder)) 32 conn := env.dial(ctx, t, l.Dialer(), noopBinder, false) 33 ch := &Handshaker{ 34 Metadata: Metadata{ 35 "question": 6 * 9, 36 }, 37 } 38 39 check := func(connected bool) error { 40 clients := sh.Peers() 41 servers := ch.Peers() 42 want := 0 43 if connected { 44 want = 1 45 } 46 if got := len(clients); got != want { 47 return fmt.Errorf("got %d clients on the server, want %d", got, want) 48 } 49 if got := len(servers); got != want { 50 return fmt.Errorf("got %d servers on the client, want %d", got, want) 51 } 52 if !connected { 53 return nil 54 } 55 client := clients[0] 56 server := servers[0] 57 if _, ok := client.Metadata["question"]; !ok { 58 return errors.New("no client metadata") 59 } 60 if _, ok := server.Metadata["answer"]; !ok { 61 return errors.New("no server metadata") 62 } 63 if client.LocalID != server.RemoteID { 64 return fmt.Errorf("client.LocalID == %d, server.PeerID == %d", client.LocalID, server.RemoteID) 65 } 66 if client.RemoteID != server.LocalID { 67 return fmt.Errorf("client.PeerID == %d, server.LocalID == %d", client.RemoteID, server.LocalID) 68 } 69 return nil 70 } 71 72 if err := check(false); err != nil { 73 t.Fatalf("before handshake: %v", err) 74 } 75 ch.ClientHandshake(ctx, conn) 76 if err := check(true); err != nil { 77 t.Fatalf("after handshake: %v", err) 78 } 79 conn.Close() 80 // Wait for up to ~2s for connections to get cleaned up. 81 delay := 25 * time.Millisecond 82 for retries := 3; retries >= 0; retries-- { 83 time.Sleep(delay) 84 err := check(false) 85 if err == nil { 86 return 87 } 88 if retries == 0 { 89 t.Fatalf("after closing connection: %v", err) 90 } 91 delay *= 4 92 } 93 }