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  }