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