go.nanomsg.org/mangos/v3@v3.4.3-0.20240217232803-46464076f1f5/protocol/xpull/xpull_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 xpull
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  
    21  	"go.nanomsg.org/mangos/v3"
    22  	. "go.nanomsg.org/mangos/v3/internal/test"
    23  	"go.nanomsg.org/mangos/v3/protocol/push"
    24  	_ "go.nanomsg.org/mangos/v3/transport/inproc"
    25  )
    26  
    27  func TestXPullIdentity(t *testing.T) {
    28  	s := GetSocket(t, NewSocket)
    29  	id := s.Info()
    30  	MustBeTrue(t, id.Self == mangos.ProtoPull)
    31  	MustBeTrue(t, id.SelfName == "pull")
    32  	MustBeTrue(t, id.Peer == mangos.ProtoPush)
    33  	MustBeTrue(t, id.PeerName == "push")
    34  	MustSucceed(t, s.Close())
    35  }
    36  
    37  func TestXPullRaw(t *testing.T) {
    38  	VerifyRaw(t, NewSocket)
    39  }
    40  
    41  func TestXPullReadOnly(t *testing.T) {
    42  	CannotSend(t, NewSocket)
    43  }
    44  
    45  func TestXPullClosed(t *testing.T) {
    46  	VerifyClosedListen(t, NewSocket)
    47  	VerifyClosedDial(t, NewSocket)
    48  	VerifyClosedClose(t, NewSocket)
    49  	VerifyClosedRecv(t, NewSocket)
    50  	VerifyClosedAddPipe(t, NewSocket)
    51  }
    52  
    53  func TestXPullOptions(t *testing.T) {
    54  	VerifyInvalidOption(t, NewSocket)
    55  	VerifyOptionDuration(t, NewSocket, mangos.OptionRecvDeadline)
    56  	VerifyOptionQLen(t, NewSocket, mangos.OptionReadQLen)
    57  
    58  }
    59  
    60  func TestXPullRecvDeadline(t *testing.T) {
    61  	s := GetSocket(t, NewSocket)
    62  	MustSucceed(t, s.SetOption(mangos.OptionRecvDeadline, time.Millisecond))
    63  	d, e := s.Recv()
    64  	MustBeError(t, e, mangos.ErrRecvTimeout)
    65  	MustBeNil(t, d)
    66  	MustSucceed(t, s.Close())
    67  }
    68  
    69  func TestXPullRecvClosePipe(t *testing.T) {
    70  	s := GetSocket(t, NewSocket)
    71  	p := GetSocket(t, push.NewSocket)
    72  	MustSucceed(t, p.SetOption(mangos.OptionWriteQLen, 1))
    73  	MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 3))
    74  	MustSucceed(t, s.SetOption(mangos.OptionRecvDeadline, time.Minute))
    75  	ConnectPair(t, s, p)
    76  	MustSucceed(t, p.Send([]byte{}))
    77  	m, e := s.RecvMsg()
    78  	MustSucceed(t, e)
    79  	MustSucceed(t, p.SetOption(mangos.OptionSendDeadline, time.Millisecond))
    80  
    81  	// Fill the pipe
    82  	for i := 0; i < 20; i++ {
    83  		// These all will work, but the back-pressure will go all the
    84  		// way to the sender.
    85  		if e := p.Send([]byte{byte(i)}); e != nil {
    86  			MustBeError(t, e, mangos.ErrSendTimeout)
    87  			break
    88  		}
    89  	}
    90  
    91  	time.Sleep(time.Millisecond * 10)
    92  	MustSucceed(t, m.Pipe.Close())
    93  
    94  	time.Sleep(time.Millisecond * 10)
    95  	MustSucceed(t, s.Close())
    96  }
    97  
    98  func TestXPullRecvCloseSocket(t *testing.T) {
    99  	s := GetSocket(t, NewSocket)
   100  	p := GetSocket(t, push.NewSocket)
   101  	MustSucceed(t, p.SetOption(mangos.OptionWriteQLen, 1))
   102  	MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 3))
   103  	MustSucceed(t, s.SetOption(mangos.OptionRecvDeadline, time.Minute))
   104  	MustSucceed(t, p.SetOption(mangos.OptionSendDeadline, time.Millisecond))
   105  	ConnectPair(t, s, p)
   106  
   107  	// Fill the pipe
   108  	for i := 0; i < 20; i++ {
   109  		// These all will work, but the back-pressure will go all the
   110  		// way to the sender.
   111  		if e := p.Send([]byte{byte(i)}); e != nil {
   112  			MustBeError(t, e, mangos.ErrSendTimeout)
   113  			break
   114  		}
   115  	}
   116  
   117  	time.Sleep(time.Millisecond * 10)
   118  	MustSucceed(t, s.Close())
   119  }
   120  
   121  func TestXPullRecv(t *testing.T) {
   122  	s := GetSocket(t, NewSocket)
   123  	p := GetSocket(t, push.NewSocket)
   124  	MustSucceed(t, s.SetOption(mangos.OptionRecvDeadline, time.Second))
   125  	ConnectPair(t, s, p)
   126  
   127  	for i := 0; i < 100; i++ {
   128  		MustSucceed(t, p.Send([]byte{byte(i)}))
   129  		v, e := s.Recv()
   130  		MustSucceed(t, e)
   131  		MustBeTrue(t, len(v) == 1)
   132  		MustBeTrue(t, v[0] == byte(i))
   133  	}
   134  	MustSucceed(t, s.Close())
   135  	MustSucceed(t, p.Close())
   136  }
   137  
   138  func TestXPullResizeRecv(t *testing.T) {
   139  	s := GetSocket(t, NewSocket)
   140  	p := GetSocket(t, push.NewSocket)
   141  	MustSucceed(t, p.SetOption(mangos.OptionWriteQLen, 1))
   142  	MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 20))
   143  	MustSucceed(t, s.SetOption(mangos.OptionRecvDeadline, time.Millisecond))
   144  	ConnectPair(t, s, p)
   145  
   146  	// Fill the pipe
   147  	for i := 0; i < 20; i++ {
   148  		// These all will work, but the back-pressure will go all the
   149  		// way to the sender.
   150  		MustSucceed(t, p.Send([]byte{byte(i)}))
   151  	}
   152  
   153  	time.Sleep(time.Millisecond * 10)
   154  	MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 1))
   155  	// Sleep so the resize filler finishes
   156  	time.Sleep(time.Millisecond * 20)
   157  
   158  	for i := 0; i < 20; i++ {
   159  		if _, e := s.Recv(); e != nil {
   160  			MustBeError(t, e, mangos.ErrRecvTimeout)
   161  			break
   162  		}
   163  	}
   164  	MustSucceed(t, s.Close())
   165  }
   166  
   167  func TestXPullResizeRecv2(t *testing.T) {
   168  	s := GetSocket(t, NewSocket)
   169  	p := GetSocket(t, push.NewSocket)
   170  	MustSucceed(t, p.SetOption(mangos.OptionWriteQLen, 1))
   171  	MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 3))
   172  	MustSucceed(t, s.SetOption(mangos.OptionRecvDeadline, time.Millisecond))
   173  	MustSucceed(t, p.SetOption(mangos.OptionSendDeadline, time.Millisecond))
   174  	ConnectPair(t, s, p)
   175  
   176  	// Fill the pipe
   177  	for i := 0; i < 20; i++ {
   178  		// These all will work, but the back-pressure will go all the
   179  		// way to the sender.
   180  		if e := p.Send([]byte{byte(i)}); e != nil {
   181  			MustBeError(t, e, mangos.ErrSendTimeout)
   182  			break
   183  		}
   184  	}
   185  
   186  	MustSucceed(t, p.SetOption(mangos.OptionSendDeadline, time.Minute))
   187  	go func() {
   188  		MustSucceed(t, p.Send([]byte{'A'}))
   189  	}()
   190  
   191  	time.Sleep(time.Millisecond * 10)
   192  	MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 10))
   193  	// Sleep so the resize filler finishes
   194  	time.Sleep(time.Millisecond * 20)
   195  
   196  	for i := 0; i < 20; i++ {
   197  		if _, e := s.Recv(); e != nil {
   198  			MustBeError(t, e, mangos.ErrRecvTimeout)
   199  			break
   200  		}
   201  	}
   202  	MustSucceed(t, s.Close())
   203  }
   204  
   205  func TestXPullResizeRecv3(t *testing.T) {
   206  	s := GetSocket(t, NewSocket)
   207  	p := GetSocket(t, push.NewSocket)
   208  	MustSucceed(t, p.SetOption(mangos.OptionWriteQLen, 1))
   209  	MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 3))
   210  	MustSucceed(t, s.SetOption(mangos.OptionRecvDeadline, time.Minute))
   211  	MustSucceed(t, p.SetOption(mangos.OptionSendDeadline, time.Millisecond))
   212  	MustSucceed(t, s.SetOption("_resizeDiscards", true))
   213  	ConnectPair(t, s, p)
   214  
   215  	time.AfterFunc(time.Millisecond*20, func() {
   216  		MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 10))
   217  		time.Sleep(time.Millisecond * 10)
   218  		MustSucceed(t, p.Send([]byte{}))
   219  	})
   220  
   221  	b, e := s.Recv()
   222  	MustSucceed(t, e)
   223  	MustNotBeNil(t, b)
   224  	MustSucceed(t, s.Close())
   225  }
   226  
   227  func TestXPullResizeRecv4(t *testing.T) {
   228  	s := GetSocket(t, NewSocket)
   229  	p := GetSocket(t, push.NewSocket)
   230  	MustSucceed(t, p.SetOption(mangos.OptionWriteQLen, 1))
   231  	MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 3))
   232  	MustSucceed(t, s.SetOption(mangos.OptionRecvDeadline, time.Minute))
   233  	MustSucceed(t, p.SetOption(mangos.OptionSendDeadline, time.Millisecond))
   234  	MustSucceed(t, s.SetOption("_resizeDiscards", true))
   235  	ConnectPair(t, s, p)
   236  
   237  	// Fill the pipe
   238  	for i := 0; i < 20; i++ {
   239  		if e := p.Send([]byte{byte(i)}); e != nil {
   240  			MustBeError(t, e, mangos.ErrSendTimeout)
   241  			break
   242  		}
   243  	}
   244  
   245  	time.AfterFunc(time.Millisecond*20, func() {
   246  		MustSucceed(t, s.SetOption(mangos.OptionReadQLen, 10))
   247  	})
   248  
   249  	time.Sleep(time.Millisecond * 50)
   250  	MustSucceed(t, s.Close())
   251  }