blob: 801258c760ad6483c0456ff5f22c491f2711080c [file] [log] [blame]
Ryan Brownfed691e2014-09-15 13:09:40 -07001package unixfd
2
3import (
4 "bytes"
5 "io"
6 "net"
Ryan Brownfed691e2014-09-15 13:09:40 -07007 "reflect"
8 "testing"
9)
10
11type nothing struct{}
12
Ryan Brown50b473a2014-09-23 14:23:00 -070013func dial(fd *fileDescriptor) (net.Conn, net.Addr, error) {
14 addr := fd.releaseAddr()
Cosmos Nicolaou87c0a552014-12-02 23:05:49 -080015 conn, err := unixFDConn(Network, addr.String(), 0)
Ryan Brown50b473a2014-09-23 14:23:00 -070016 return conn, addr, err
Ryan Brownfed691e2014-09-15 13:09:40 -070017}
18
Ryan Brown50b473a2014-09-23 14:23:00 -070019func listen(fd *fileDescriptor) (net.Listener, net.Addr, error) {
20 addr := fd.releaseAddr()
Cosmos Nicolaou87c0a552014-12-02 23:05:49 -080021 l, err := unixFDListen(Network, addr.String())
Ryan Brown50b473a2014-09-23 14:23:00 -070022 return l, addr, err
Ryan Brownfed691e2014-09-15 13:09:40 -070023}
24
25func testWrite(t *testing.T, c net.Conn, data string) {
26 n, err := c.Write([]byte(data))
27 if err != nil {
28 t.Errorf("Write: %v", err)
29 return
30 }
31 if n != len(data) {
32 t.Errorf("Wrote %d bytes, expected %d", n, len(data))
33 }
34}
35
36func testRead(t *testing.T, c net.Conn, expected string) {
37 buf := make([]byte, len(expected)+2)
38 n, err := c.Read(buf)
39 if err != nil {
40 t.Errorf("Read: %v", err)
41 return
42 }
43 if n != len(expected) || !bytes.Equal(buf[0:n], []byte(expected)) {
44 t.Errorf("got %q, expected %q", buf[0:n], expected)
45 }
46}
47
48func TestDial(t *testing.T) {
Bogdan Capritabb37c542015-01-22 10:21:57 -080049 local, remote, err := socketpair()
Ryan Brownfed691e2014-09-15 13:09:40 -070050 if err != nil {
51 t.Fatalf("socketpair: %v", err)
52 }
Ryan Brown50b473a2014-09-23 14:23:00 -070053 a, a_addr, err := dial(local)
Ryan Brownfed691e2014-09-15 13:09:40 -070054 if err != nil {
55 t.Fatalf("dial: %v", err)
56 }
Ryan Brown50b473a2014-09-23 14:23:00 -070057 b, b_addr, err := dial(remote)
Ryan Brownfed691e2014-09-15 13:09:40 -070058 if err != nil {
59 t.Fatalf("dial: %v", err)
60 }
61
62 testWrite(t, a, "TEST1")
63 testRead(t, b, "TEST1")
64 testWrite(t, b, "TEST2")
65 testRead(t, a, "TEST2")
66
Ryan Brown50b473a2014-09-23 14:23:00 -070067 if !reflect.DeepEqual(a.LocalAddr(), a_addr) {
68 t.Errorf("Invalid address %v, expected %v", a.LocalAddr(), a_addr)
Ryan Brownfed691e2014-09-15 13:09:40 -070069 }
Ryan Brown50b473a2014-09-23 14:23:00 -070070 if !reflect.DeepEqual(a.RemoteAddr(), a_addr) {
71 t.Errorf("Invalid address %v, expected %v", a.RemoteAddr(), a_addr)
Ryan Brownfed691e2014-09-15 13:09:40 -070072 }
Ryan Brown50b473a2014-09-23 14:23:00 -070073 if !reflect.DeepEqual(b.LocalAddr(), b_addr) {
74 t.Errorf("Invalid address %v, expected %v", a.LocalAddr(), b_addr)
Ryan Brownfed691e2014-09-15 13:09:40 -070075 }
Ryan Brown50b473a2014-09-23 14:23:00 -070076 if !reflect.DeepEqual(b.RemoteAddr(), b_addr) {
77 t.Errorf("Invalid address %v, expected %v", a.RemoteAddr(), b_addr)
Ryan Brownfed691e2014-09-15 13:09:40 -070078 }
79}
80
81func TestListen(t *testing.T) {
Bogdan Capritabb37c542015-01-22 10:21:57 -080082 local, remote, err := socketpair()
Ryan Brownfed691e2014-09-15 13:09:40 -070083 if err != nil {
84 t.Fatalf("socketpair: %v", err)
85 }
Ryan Brown50b473a2014-09-23 14:23:00 -070086 a, _, err := dial(local)
Ryan Brownfed691e2014-09-15 13:09:40 -070087 if err != nil {
88 t.Fatalf("dial: %v", err)
89 }
Ryan Brown50b473a2014-09-23 14:23:00 -070090 l, _, err := listen(remote)
Ryan Brownfed691e2014-09-15 13:09:40 -070091 if err != nil {
92 t.Fatalf("listen: %v", err)
93 }
94 b, err := l.Accept()
95 if err != nil {
96 t.Fatalf("accept: %v", err)
97 }
98 start := make(chan nothing, 0)
99 done := make(chan nothing)
100 go func() {
101 defer close(done)
102 <-start
103 if _, err := l.Accept(); err != io.EOF {
104 t.Fatalf("accept: expected EOF, got %v", err)
105 }
106 }()
107
108 // block until the goroutine starts running
109 start <- nothing{}
110 testWrite(t, a, "LISTEN")
111 testRead(t, b, "LISTEN")
112
113 err = l.Close()
114 if err != nil {
115 t.Fatalf("close: %v", err)
116 }
117 <-done
118
119 // After closed, accept should fail immediately
120 _, err = l.Accept()
121 if err == nil {
122 t.Fatalf("Accept succeeded after close")
123 }
124 err = l.Close()
125 if err == nil {
126 t.Fatalf("Close succeeded twice")
127 }
128}
Ryan Brown50b473a2014-09-23 14:23:00 -0700129
130func TestSendConnection(t *testing.T) {
131 server, client, err := Socketpair()
132 if err != nil {
133 t.Fatalf("Socketpair: %v", err)
134 }
135 uclient, err := net.FileConn(client)
136 if err != nil {
137 t.Fatalf("FileConn: %v", err)
138 }
Ryan Brownfac212e2014-11-13 12:23:47 -0800139 var readErr error
140 var n int
141 var saddr net.Addr
142 done := make(chan struct{})
143 buf := make([]byte, 10)
144 go func() {
Ryan Brown53a8e2b2015-01-07 10:50:04 -0800145 var ack func()
146 saddr, n, ack, readErr = ReadConnection(server, buf)
147 if ack != nil {
148 ack()
149 }
Ryan Brownfac212e2014-11-13 12:23:47 -0800150 close(done)
151 }()
Bogdan Capritabb37c542015-01-22 10:21:57 -0800152 caddr, err := SendConnection(uclient.(*net.UnixConn), []byte("hello"))
Ryan Brown50b473a2014-09-23 14:23:00 -0700153 if err != nil {
154 t.Fatalf("SendConnection: %v", err)
155 }
Ryan Brownfac212e2014-11-13 12:23:47 -0800156 <-done
157 if readErr != nil {
158 t.Fatalf("ReadConnection: %v", readErr)
159 }
160 if saddr == nil {
161 t.Fatalf("ReadConnection returned nil, %d", n)
Ryan Brown50b473a2014-09-23 14:23:00 -0700162 }
163 data := buf[0:n]
164 if !bytes.Equal([]byte("hello"), data) {
165 t.Fatalf("unexpected data %q", data)
166 }
167
Cosmos Nicolaou87c0a552014-12-02 23:05:49 -0800168 a, err := unixFDConn(Network, caddr.String(), 0)
Ryan Brown50b473a2014-09-23 14:23:00 -0700169 if err != nil {
170 t.Fatalf("dial %v: %v", caddr, err)
171 }
Cosmos Nicolaou87c0a552014-12-02 23:05:49 -0800172 b, err := unixFDConn(Network, saddr.String(), 0)
Ryan Brown50b473a2014-09-23 14:23:00 -0700173 if err != nil {
174 t.Fatalf("dial %v: %v", saddr, err)
175 }
176
177 testWrite(t, a, "TEST1")
178 testRead(t, b, "TEST1")
179 testWrite(t, b, "TEST2")
180 testRead(t, a, "TEST2")
181}