11package server
22
3- import "testing"
3+ import (
4+ "net"
5+ "testing"
6+ "time"
7+ )
8+
9+ type mockHandler struct {
10+ listenCalled chan net.Listener
11+ closeCalled chan struct {}
12+ closeNotify chan struct {}
13+ }
14+
15+ func newMockHandler () * mockHandler {
16+ return & mockHandler {
17+ listenCalled : make (chan net.Listener , 1 ),
18+ closeCalled : make (chan struct {}, 1 ),
19+ closeNotify : make (chan struct {}),
20+ }
21+ }
22+
23+ func (m * mockHandler ) listen (l net.Listener ) {
24+ m .listenCalled <- l
25+ <- m .closeNotify
26+ }
27+
28+ func (m * mockHandler ) close () error {
29+ close (m .closeNotify )
30+ m .closeCalled <- struct {}{}
31+ return nil
32+ }
433
534func TestServerStopIdempotent (t * testing.T ) {
635 s := NewServer ([]* Listener {})
@@ -13,3 +42,49 @@ func TestServerStopIdempotent(t *testing.T) {
1342 }()
1443 s .Stop ()
1544}
45+
46+ func TestServerStartAndStopClosesHandlers (t * testing.T ) {
47+ handler := newMockHandler ()
48+ s := NewServer ([]* Listener {{Port : 0 , Handler : handler , Type : TCP }})
49+
50+ done := make (chan struct {})
51+ go func () {
52+ s .Start ()
53+ close (done )
54+ }()
55+
56+ select {
57+ case l := <- handler .listenCalled :
58+ if l == nil {
59+ t .Fatalf ("listener was nil" )
60+ }
61+ case <- time .After (time .Second ):
62+ t .Fatalf ("listen was not called" )
63+ }
64+
65+ s .Stop ()
66+
67+ select {
68+ case <- handler .closeCalled :
69+ case <- time .After (time .Second ):
70+ t .Fatalf ("close was not called" )
71+ }
72+
73+ select {
74+ case <- done :
75+ case <- time .After (time .Second ):
76+ t .Fatalf ("server did not exit after stop" )
77+ }
78+ }
79+
80+ func TestCreateListenerPanicsOnFailure (t * testing.T ) {
81+ s := & Server {}
82+ l := & Listener {Port : - 1 , Type : ConnectionType ("invalid" )}
83+ defer func () {
84+ if r := recover (); r == nil {
85+ t .Fatalf ("expected panic creating listener" )
86+ }
87+ }()
88+
89+ _ = s .createListener (l )
90+ }
0 commit comments