forked from netrack/openflow
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathserver_test.go
119 lines (93 loc) · 2.71 KB
/
server_test.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
package openflow
import (
"io"
"net"
"testing"
)
func TestReceiver(t *testing.T) {
dconn := new(dummyConn)
dconn.r.Write(newHeader(TypeHello))
rcvr := &receiver{Conn: newConn(dconn)}
wrap := <-rcvr.C()
if wrap.err != nil {
t.Fatalf("Error returned from receiver: %s", wrap.err)
}
htype := wrap.req.Header.Type
if htype != TypeHello {
t.Fatalf("Incorrect request type returned: %d", htype)
}
// Receive of another request should fail with EOF.
wrap = <-rcvr.C()
if wrap.err != io.EOF {
t.Fatalf("Expected EOF on second receive: %s", wrap.err)
}
_, ok := <-rcvr.C()
if ok {
t.Fatalf("Channel should be closed on error")
}
}
func TestServeMaxConns(t *testing.T) {
s := Server{MaxConns: 2}
defer s.close()
// Create three connection, with a maximum connections set to two.
// This means, a third client should be closed by the server.
dconn1 := new(dummyBlockConn)
dconn2 := new(dummyBlockConn)
dconn3 := new(dummyBlockConn)
defer dconn1.Close()
defer dconn2.Close()
dln := &dummyListener{[]net.Conn{dconn1, dconn2, dconn3}}
err := s.Serve(dln)
// The mock of the listener returns an error, when connections
// have been extracted from the queue completely.
if err != io.EOF {
t.Errorf("Serving of the listener failed: %s", err)
}
if dconn1.closed || dconn2.closed {
t.Errorf("Two first connection expected to be alive")
}
if !dconn3.closed {
t.Errorf("Third connection expected to be closed")
}
}
func TestServerServe(t *testing.T) {
var req *Request
done := make(chan struct{})
h := func(rw ResponseWriter, r *Request) {
// Save the request for further analysis.
req = r
done <- struct{}{}
}
// Define a connection state transition callback to validate the
// transition of the client connections.
states := make(map[ConnState]int)
connState := func(c Conn, s ConnState) {
// Simply increase a counter of the connection states.
states[s]++
}
dconn := new(dummyConn)
dconn.r.Write(newHeader(TypeHello))
dln := &dummyListener{[]net.Conn{dconn}}
s := Server{Handler: HandlerFunc(h), ConnState: connState}
defer s.close()
s.Serve(dln)
// Wait for handler being called for the client connection.
<-done
if req.Conn().(*conn).rwc != dconn {
t.Fatalf("Wrong connection instance returned")
}
if req.ProtoMajor != 1 || req.ProtoMinor != 3 {
t.Fatalf("Wrong version of OpenFlow protocol: %d.%d",
req.ProtoMajor, req.ProtoMinor)
}
// Ensure the client connection transitioned all required states.
if states[StateNew] != 1 {
t.Errorf("Connection did not transition new state")
}
if states[StateHandshake] != 1 {
t.Errorf("Connection did not transition handshake state")
}
if states[StateClosed] != 1 {
t.Errorf("Connection did not transition closed state")
}
}