Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 1 | package unixfd |
| 2 | |
| 3 | import ( |
| 4 | "bytes" |
| 5 | "io" |
| 6 | "net" |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 7 | "reflect" |
| 8 | "testing" |
| 9 | ) |
| 10 | |
| 11 | type nothing struct{} |
| 12 | |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 13 | func dial(fd *fileDescriptor) (net.Conn, net.Addr, error) { |
| 14 | addr := fd.releaseAddr() |
Cosmos Nicolaou | 87c0a55 | 2014-12-02 23:05:49 -0800 | [diff] [blame] | 15 | conn, err := unixFDConn(Network, addr.String(), 0) |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 16 | return conn, addr, err |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 17 | } |
| 18 | |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 19 | func listen(fd *fileDescriptor) (net.Listener, net.Addr, error) { |
| 20 | addr := fd.releaseAddr() |
Cosmos Nicolaou | 87c0a55 | 2014-12-02 23:05:49 -0800 | [diff] [blame] | 21 | l, err := unixFDListen(Network, addr.String()) |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 22 | return l, addr, err |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 23 | } |
| 24 | |
| 25 | func 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 | |
| 36 | func 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 | |
| 48 | func TestDial(t *testing.T) { |
Bogdan Caprita | bb37c54 | 2015-01-22 10:21:57 -0800 | [diff] [blame] | 49 | local, remote, err := socketpair() |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 50 | if err != nil { |
| 51 | t.Fatalf("socketpair: %v", err) |
| 52 | } |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 53 | a, a_addr, err := dial(local) |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 54 | if err != nil { |
| 55 | t.Fatalf("dial: %v", err) |
| 56 | } |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 57 | b, b_addr, err := dial(remote) |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 58 | 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 Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 67 | if !reflect.DeepEqual(a.LocalAddr(), a_addr) { |
| 68 | t.Errorf("Invalid address %v, expected %v", a.LocalAddr(), a_addr) |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 69 | } |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 70 | if !reflect.DeepEqual(a.RemoteAddr(), a_addr) { |
| 71 | t.Errorf("Invalid address %v, expected %v", a.RemoteAddr(), a_addr) |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 72 | } |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 73 | if !reflect.DeepEqual(b.LocalAddr(), b_addr) { |
| 74 | t.Errorf("Invalid address %v, expected %v", a.LocalAddr(), b_addr) |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 75 | } |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 76 | if !reflect.DeepEqual(b.RemoteAddr(), b_addr) { |
| 77 | t.Errorf("Invalid address %v, expected %v", a.RemoteAddr(), b_addr) |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 78 | } |
| 79 | } |
| 80 | |
| 81 | func TestListen(t *testing.T) { |
Bogdan Caprita | bb37c54 | 2015-01-22 10:21:57 -0800 | [diff] [blame] | 82 | local, remote, err := socketpair() |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 83 | if err != nil { |
| 84 | t.Fatalf("socketpair: %v", err) |
| 85 | } |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 86 | a, _, err := dial(local) |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 87 | if err != nil { |
| 88 | t.Fatalf("dial: %v", err) |
| 89 | } |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 90 | l, _, err := listen(remote) |
Ryan Brown | fed691e | 2014-09-15 13:09:40 -0700 | [diff] [blame] | 91 | 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 Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 129 | |
| 130 | func 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 Brown | fac212e | 2014-11-13 12:23:47 -0800 | [diff] [blame] | 139 | 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 Brown | 53a8e2b | 2015-01-07 10:50:04 -0800 | [diff] [blame] | 145 | var ack func() |
| 146 | saddr, n, ack, readErr = ReadConnection(server, buf) |
| 147 | if ack != nil { |
| 148 | ack() |
| 149 | } |
Ryan Brown | fac212e | 2014-11-13 12:23:47 -0800 | [diff] [blame] | 150 | close(done) |
| 151 | }() |
Bogdan Caprita | bb37c54 | 2015-01-22 10:21:57 -0800 | [diff] [blame] | 152 | caddr, err := SendConnection(uclient.(*net.UnixConn), []byte("hello")) |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 153 | if err != nil { |
| 154 | t.Fatalf("SendConnection: %v", err) |
| 155 | } |
Ryan Brown | fac212e | 2014-11-13 12:23:47 -0800 | [diff] [blame] | 156 | <-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 Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 162 | } |
| 163 | data := buf[0:n] |
| 164 | if !bytes.Equal([]byte("hello"), data) { |
| 165 | t.Fatalf("unexpected data %q", data) |
| 166 | } |
| 167 | |
Cosmos Nicolaou | 87c0a55 | 2014-12-02 23:05:49 -0800 | [diff] [blame] | 168 | a, err := unixFDConn(Network, caddr.String(), 0) |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 169 | if err != nil { |
| 170 | t.Fatalf("dial %v: %v", caddr, err) |
| 171 | } |
Cosmos Nicolaou | 87c0a55 | 2014-12-02 23:05:49 -0800 | [diff] [blame] | 172 | b, err := unixFDConn(Network, saddr.String(), 0) |
Ryan Brown | 50b473a | 2014-09-23 14:23:00 -0700 | [diff] [blame] | 173 | 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 | } |