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  }