go.nanomsg.org/mangos/v3@v3.4.3-0.20240217232803-46464076f1f5/protocol/xrep/xrep_test.go (about) 1 // Copyright 2019 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 package xrep 16 17 import ( 18 "encoding/binary" 19 "testing" 20 "time" 21 22 "go.nanomsg.org/mangos/v3" 23 . "go.nanomsg.org/mangos/v3/internal/test" 24 . "go.nanomsg.org/mangos/v3/protocol" 25 "go.nanomsg.org/mangos/v3/protocol/req" 26 "go.nanomsg.org/mangos/v3/protocol/xreq" 27 _ "go.nanomsg.org/mangos/v3/transport/inproc" 28 ) 29 30 func TestXRepRaw(t *testing.T) { 31 VerifyRaw(t, NewSocket) 32 } 33 34 func TestXRepIdentity(t *testing.T) { 35 id := MustGetInfo(t, NewSocket) 36 MustBeTrue(t, id.Self == ProtoRep) 37 MustBeTrue(t, id.SelfName == "rep") 38 MustBeTrue(t, id.Peer == ProtoReq) 39 MustBeTrue(t, id.PeerName == "req") 40 } 41 42 func TestXRepClosed(t *testing.T) { 43 VerifyClosedRecv(t, NewSocket) 44 VerifyClosedSend(t, NewSocket) 45 VerifyClosedClose(t, NewSocket) 46 VerifyClosedDial(t, NewSocket) 47 VerifyClosedListen(t, NewSocket) 48 VerifyClosedAddPipe(t, NewSocket) 49 } 50 51 func TestXRepOptions(t *testing.T) { 52 VerifyInvalidOption(t, NewSocket) 53 VerifyOptionDuration(t, NewSocket, OptionRecvDeadline) 54 VerifyOptionDuration(t, NewSocket, OptionSendDeadline) 55 VerifyOptionInt(t, NewSocket, OptionReadQLen) 56 VerifyOptionInt(t, NewSocket, OptionWriteQLen) 57 VerifyOptionBool(t, NewSocket, OptionBestEffort) 58 VerifyOptionTTL(t, NewSocket) 59 } 60 61 func TestXRepNoHeader(t *testing.T) { 62 self := GetSocket(t, NewSocket) 63 MustSendString(t, self, "") 64 MustClose(t, self) 65 } 66 67 func TestXRepMismatchHeader(t *testing.T) { 68 self := GetSocket(t, NewSocket) 69 70 m := mangos.NewMessage(0) 71 m.Header = append(m.Header, []byte{1, 1, 1, 1, 0x80, 0, 0, 1}...) 72 73 MustSendMsg(t, self, m) 74 MustClose(t, self) 75 } 76 77 func TestXRepRecvDeadline(t *testing.T) { 78 self := GetSocket(t, NewSocket) 79 MustSucceed(t, self.SetOption(OptionRecvDeadline, time.Millisecond)) 80 MustNotRecv(t, self, ErrRecvTimeout) 81 MustClose(t, self) 82 } 83 84 func TestXRepTTLDrop(t *testing.T) { 85 TTLDropTest(t, req.NewSocket, NewSocket, xreq.NewSocket, NewSocket) 86 } 87 88 func newRequest(id uint32, content string) *mangos.Message { 89 m := mangos.NewMessage(len(content) + 8) 90 b := make([]byte, 4) 91 binary.BigEndian.PutUint32(b[:4], id|0x80000000) 92 // Requests (coming in) will be entirely on the body. 93 m.Body = append(m.Body, b...) 94 m.Body = append(m.Body, []byte(content)...) 95 return m 96 } 97 98 func newReply(id uint32, p mangos.Pipe, content string) *mangos.Message { 99 m := mangos.NewMessage(len(content)) 100 b := make([]byte, 8) 101 binary.BigEndian.PutUint32(b, p.ID()) // outgoing pipe ID 102 binary.BigEndian.PutUint32(b[4:], id|0x80000000) // request ID 103 m.Header = append(m.Header, b...) 104 m.Body = append(m.Body, []byte(content)...) 105 return m 106 } 107 108 func TestXRepSendTimeout(t *testing.T) { 109 timeout := time.Millisecond * 10 110 111 self := GetSocket(t, NewSocket) 112 113 MustSucceed(t, self.SetOption(OptionWriteQLen, 0)) 114 MustSucceed(t, self.SetOption(OptionSendDeadline, timeout)) 115 116 _, p := MockConnect(t, self) 117 MustSendMsg(t, self, newReply(0, p, "zero")) 118 MustBeError(t, self.SendMsg(newReply(1, p, "one")), ErrSendTimeout) 119 MustClose(t, self) 120 } 121 122 func TestXRepSendBestEffort(t *testing.T) { 123 timeout := time.Millisecond * 10 124 125 self := GetSocket(t, NewSocket) 126 127 MustSucceed(t, self.SetOption(OptionWriteQLen, 0)) 128 MustSucceed(t, self.SetOption(OptionSendDeadline, timeout)) 129 MustSucceed(t, self.SetOption(OptionBestEffort, true)) 130 131 _, p := MockConnect(t, self) 132 for i := 0; i < 100; i++ { 133 MustSendMsg(t, self, newReply(0, p, "")) 134 } 135 MustClose(t, self) 136 } 137 138 func TestXRepPipeCloseAbort(t *testing.T) { 139 self := GetSocket(t, NewSocket) 140 141 MustSucceed(t, self.SetOption(OptionWriteQLen, 0)) 142 MustSucceed(t, self.SetOption(OptionSendDeadline, time.Second)) 143 144 _, p := MockConnect(t, self) 145 time.AfterFunc(time.Millisecond*20, func() { 146 MustSucceed(t, p.Close()) 147 }) 148 MustSendMsg(t, self, newReply(0, p, "good")) 149 MustBeError(t, self.SendMsg(newReply(1, p, "bad")), ErrClosed) 150 MustClose(t, self) 151 } 152 153 func TestXRepRecvCloseAbort(t *testing.T) { 154 self := GetSocket(t, NewSocket) 155 156 MustSucceed(t, self.SetOption(OptionReadQLen, 1)) 157 MustSucceed(t, self.SetOption(OptionRecvDeadline, time.Millisecond*10)) 158 159 mp, p := MockConnect(t, self) 160 MockMustSendMsg(t, mp, newRequest(1, "one"), time.Second) 161 MockMustSendMsg(t, mp, newRequest(2, "two"), time.Second) 162 163 time.Sleep(time.Millisecond * 10) 164 MustSucceed(t, p.Close()) 165 MustClose(t, self) 166 } 167 168 func TestXRepResizeRecv1(t *testing.T) { 169 self := GetSocket(t, NewSocket) 170 mp, _ := MockConnect(t, self) 171 MustSucceed(t, self.SetOption(OptionReadQLen, 0)) 172 MustSucceed(t, self.SetOption(OptionRecvDeadline, time.Millisecond)) 173 MockMustSendMsg(t, mp, newRequest(1, "hello"), time.Second) 174 175 time.Sleep(time.Millisecond * 50) 176 MustSucceed(t, self.SetOption(OptionReadQLen, 2)) 177 MustNotRecv(t, self, ErrRecvTimeout) 178 MustClose(t, self) 179 } 180 181 func TestXRepResizeRecv2(t *testing.T) { 182 self := GetSocket(t, NewSocket) 183 mp, _ := MockConnect(t, self) 184 MustSucceed(t, self.SetOption(OptionReadQLen, 1)) 185 MustSucceed(t, self.SetOption(OptionRecvDeadline, time.Second)) 186 187 time.AfterFunc(time.Millisecond*50, func() { 188 MustSucceed(t, self.SetOption(OptionReadQLen, 2)) 189 MockMustSendMsg(t, mp, newRequest(1, "hello"), time.Second) 190 }) 191 MustRecvString(t, self, "hello") 192 MustClose(t, self) 193 } 194 195 func TestXRepRecvJunk(t *testing.T) { 196 self := GetSocket(t, NewSocket) 197 MustSucceed(t, self.SetOption(OptionReadQLen, 20)) 198 MustSucceed(t, self.SetOption(OptionRecvDeadline, time.Millisecond*10)) 199 200 mp, _ := MockConnect(t, self) 201 MockMustSend(t, mp, []byte{}, time.Second) 202 MockMustSend(t, mp, []byte{0, 1}, time.Second) 203 MockMustSend(t, mp, []byte{0, 1, 2, 3}, time.Second) 204 MockMustSend(t, mp, []byte{0, 1, 2, 3, 0x80}, time.Second) 205 206 MustNotRecv(t, self, ErrRecvTimeout) 207 MustClose(t, self) 208 }