1// Copyright 2020 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 5package jsonrpc2 6 7import ( 8 "context" 9 "net" 10 "sync" 11 "testing" 12 "time" 13 14 "golang.org/x/tools/internal/stack/stacktest" 15) 16 17func TestIdleTimeout(t *testing.T) { 18 stacktest.NoLeak(t) 19 ctx, cancel := context.WithTimeout(context.Background(), 10*time.Second) 20 defer cancel() 21 22 ln, err := net.Listen("tcp", "localhost:0") 23 if err != nil { 24 t.Fatal(err) 25 } 26 defer ln.Close() 27 28 connect := func() net.Conn { 29 conn, err := net.DialTimeout("tcp", ln.Addr().String(), 5*time.Second) 30 if err != nil { 31 panic(err) 32 } 33 return conn 34 } 35 36 server := HandlerServer(MethodNotFound) 37 // connTimer := &fakeTimer{c: make(chan time.Time, 1)} 38 var ( 39 runErr error 40 wg sync.WaitGroup 41 ) 42 wg.Add(1) 43 go func() { 44 defer wg.Done() 45 runErr = Serve(ctx, ln, server, 100*time.Millisecond) 46 }() 47 48 // Exercise some connection/disconnection patterns, and then assert that when 49 // our timer fires, the server exits. 50 conn1 := connect() 51 conn2 := connect() 52 conn1.Close() 53 conn2.Close() 54 conn3 := connect() 55 conn3.Close() 56 57 wg.Wait() 58 59 if runErr != ErrIdleTimeout { 60 t.Errorf("run() returned error %v, want %v", runErr, ErrIdleTimeout) 61 } 62} 63