go.nanomsg.org/mangos/v3@v3.4.3-0.20240217232803-46464076f1f5/transport/ipc/ipc_unix_test.go (about) 1 // Copyright 2020 The Mangos Authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use file except in compliance with the License. 5 // You may obtain a copy of the license at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // +build !plan9,!windows,!js 16 17 package ipc 18 19 import ( 20 "errors" 21 "net" 22 "os" 23 "strings" 24 "syscall" 25 "testing" 26 "time" 27 28 "go.nanomsg.org/mangos/v3" 29 . "go.nanomsg.org/mangos/v3/internal/test" 30 ) 31 32 func TestIsSyscallError(t *testing.T) { 33 34 MustBeFalse(t, isSyscallError(errors.New("nope"), syscall.ENOENT)) 35 MustBeFalse(t, isSyscallError(&net.OpError{ 36 Op: "test", 37 Net: "none", 38 Source: nil, 39 Addr: nil, 40 Err: mangos.ErrClosed, 41 }, syscall.ENOENT)) 42 MustBeFalse(t, isSyscallError(&net.OpError{ 43 Op: "test", 44 Net: "none", 45 Source: nil, 46 Addr: nil, 47 Err: &os.SyscallError{ 48 Syscall: "none", 49 Err: syscall.EINVAL, 50 }, 51 }, syscall.ENOENT)) 52 MustBeFalse(t, isSyscallError(&net.OpError{ 53 Op: "test", 54 Net: "none", 55 Source: nil, 56 Addr: nil, 57 Err: &os.SyscallError{ 58 Syscall: "none", 59 Err: mangos.ErrNotRaw, 60 }, 61 }, syscall.ENOENT)) 62 MustBeTrue(t, isSyscallError(&net.OpError{ 63 Op: "test", 64 Net: "none", 65 Source: nil, 66 Addr: nil, 67 Err: &os.SyscallError{ 68 Syscall: "none", 69 Err: syscall.ENOENT, 70 }, 71 }, syscall.ENOENT)) 72 } 73 74 func TestIpcStaleListen(t *testing.T) { 75 addr1 := AddrTestIPC() 76 name := addr1[len("ipc://"):] 77 defer func() { 78 _ = os.Remove(name) 79 _ = os.Remove(name + ".hold") 80 }() 81 82 uaddr, _ := net.ResolveUnixAddr("unix", name) 83 sock, err := net.ListenUnix("unix", uaddr) 84 85 MustSucceed(t, err) 86 87 // We rename it so that closing won't unlink the socket. 88 // This lets us leave a stale socket behind. 89 MustSucceed(t, os.Rename(name, name+".hold")) 90 MustSucceed(t, sock.Close()) 91 MustSucceed(t, os.Rename(name+".hold", name)) 92 93 // Clean up the stale link. 94 self := GetMockSocket() 95 96 MustSucceed(t, self.Listen(addr1)) 97 defer MustClose(t, self) 98 } 99 100 func TestIpcBusyListen(t *testing.T) { 101 addr1 := AddrTestIPC() 102 name := addr1[len("ipc://"):] 103 104 uaddr, _ := net.ResolveUnixAddr("unix", name) 105 sock, err := net.ListenUnix("unix", uaddr) 106 defer func() { 107 _ = sock.Close() 108 }() 109 110 MustSucceed(t, err) 111 112 self := GetMockSocket() 113 114 MustBeError(t, self.Listen(addr1), mangos.ErrAddrInUse) 115 defer MustClose(t, self) 116 } 117 118 func TestIpcFileConflictListen(t *testing.T) { 119 addr1 := AddrTestIPC() 120 name := addr1[len("ipc://"):] 121 122 file, err := os.Create(name) 123 MustSucceed(t, err) 124 _, _ = file.WriteString("abc") 125 _ = file.Close() 126 defer func() { 127 MustSucceed(t, os.Remove(name)) 128 }() 129 130 self := GetMockSocket() 131 132 MustBeError(t, self.Listen(addr1), mangos.ErrAddrInUse) 133 defer MustClose(t, self) 134 } 135 136 type testAddr string 137 138 func (a testAddr) testDial() (net.Conn, error) { 139 return net.Dial("unix", string(a)[len("ipc://"):]) 140 } 141 142 func TestIpcAbortHandshake(t *testing.T) { 143 sock := GetMockSocket() 144 defer MustClose(t, sock) 145 addr := AddrTestIPC() 146 l, e := sock.NewListener(addr, nil) 147 MustSucceed(t, e) 148 MustSucceed(t, l.Listen()) 149 c, e := testAddr(addr).testDial() 150 MustSucceed(t, e) 151 MustSucceed(t, c.Close()) 152 } 153 154 func TestIpcBadHandshake(t *testing.T) { 155 sock := GetMockSocket() 156 defer MustClose(t, sock) 157 addr := AddrTestIPC() 158 l, e := sock.NewListener(addr, nil) 159 MustSucceed(t, e) 160 MustSucceed(t, l.Listen()) 161 TranSendConnBadHandshakes(t, testAddr(addr).testDial) 162 } 163 164 func TestIpcBadRecv(t *testing.T) { 165 sock := GetMockSocket() 166 defer MustClose(t, sock) 167 addr := AddrTestIPC() 168 l, e := sock.NewListener(addr, nil) 169 MustSucceed(t, e) 170 MustSucceed(t, l.Listen()) 171 TranSendBadMessages(t, sock.Info().Peer, true, testAddr(addr).testDial) 172 } 173 174 func TestIpcSendAbort(t *testing.T) { 175 sock := GetMockSocket() 176 defer MustClose(t, sock) 177 addr := AddrTestIPC() 178 l, e := sock.NewListener(addr, nil) 179 MustSucceed(t, e) 180 MustSucceed(t, l.Listen()) 181 c, e := testAddr(addr).testDial() 182 MustSucceed(t, e) 183 TranConnHandshake(t, c, sock.Info().Peer) 184 MustSend(t, sock, make([]byte, 1024*1024)) 185 time.Sleep(time.Millisecond * 100) 186 MustSucceed(t, c.Close()) 187 } 188 189 func TestIpcListenerOptions(t *testing.T) { 190 sock := GetMockSocket() 191 defer MustClose(t, sock) 192 addr := AddrTestIPC() 193 l, e := tran.NewListener(addr, sock) 194 MustSucceed(t, e) 195 196 MustBeError(t, l.SetOption(OptionIpcSocketOwner, true), mangos.ErrBadValue) 197 MustBeError(t, l.SetOption(OptionIpcSocketGroup, true), mangos.ErrBadValue) 198 MustBeError(t, l.SetOption(OptionIpcSocketPermissions, true), mangos.ErrBadValue) 199 MustBeError(t, l.SetOption(OptionIpcSocketPermissions, os.ModeDir), mangos.ErrBadValue) 200 MustSucceed(t, l.SetOption(OptionIpcSocketPermissions, uint32(0642))) 201 MustSucceed(t, l.SetOption(OptionIpcSocketPermissions, os.FileMode(0642))) 202 MustSucceed(t, l.SetOption(OptionIpcSocketOwner, 0)) 203 MustSucceed(t, l.SetOption(OptionIpcSocketGroup, 0)) 204 205 MustSucceed(t, l.Listen()) 206 i, e := os.Stat(strings.TrimPrefix(addr, "ipc://")) 207 MustSucceed(t, e) 208 MustBeTrue(t, i.Mode() & os.ModePerm == 0642) 209 }