github.com/gdamore/mangos@v1.4.0/compat/compat_test.go (about)

     1  // Copyright 2017 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 nanomsg
    16  
    17  import (
    18  	"testing"
    19  	"time"
    20  )
    21  
    22  type creqTest struct {
    23  	cur   uint32
    24  	tot   uint32
    25  	ok    bool
    26  	debug bool
    27  	addr  string
    28  	sock  *Socket
    29  	done  chan struct{}
    30  	t     *testing.T
    31  }
    32  
    33  type crepTest struct {
    34  	cur   uint32
    35  	tot   uint32
    36  	ok    bool
    37  	debug bool
    38  	addr  string
    39  	sock  *Socket
    40  	done  chan struct{}
    41  	t     *testing.T
    42  }
    43  
    44  // For now, we take a very simple pairwise approach to req/rep.  We should
    45  // consider additional tests for raw mode multiple responders.
    46  
    47  func (rt *creqTest) Init(t *testing.T, addr string, num uint32) bool {
    48  	var e error
    49  	if rt.sock, e = NewSocket(AF_SP, REQ); e != nil {
    50  		t.Errorf("NewSocket(): %v", e)
    51  		return false
    52  	}
    53  	if e = rt.sock.SetSendTimeout(time.Second); e != nil {
    54  		t.Errorf("Failed SetSendTimeout: %s", e)
    55  		return false
    56  	}
    57  	if e = rt.sock.SetRecvTimeout(time.Second); e != nil {
    58  		t.Errorf("Failed SetRecvTimeout: %s", e)
    59  		return false
    60  	}
    61  	rt.t = t
    62  	rt.cur = 0
    63  	rt.tot = num
    64  	rt.addr = addr
    65  	rt.done = make(chan struct{})
    66  
    67  	if _, err := rt.sock.Connect(rt.addr); err != nil {
    68  		rt.t.Errorf("Failed to connect: %s", err)
    69  		return false
    70  	}
    71  
    72  	return true
    73  }
    74  
    75  func (rt *creqTest) Finish() {
    76  	rt.ok = rt.cur == rt.tot
    77  	close(rt.done)
    78  }
    79  
    80  func (rt *creqTest) DoTest() bool {
    81  	defer rt.Finish()
    82  	for rt.cur < rt.tot {
    83  		var e error
    84  		var n int
    85  		m := make([]byte, 1)
    86  		m[0] = byte(rt.cur)
    87  
    88  		if rt.debug {
    89  			rt.t.Logf("Send request %d", rt.cur)
    90  		}
    91  		if n, e = rt.sock.Send(m, 0); n != 1 || e != nil {
    92  			rt.t.Errorf("%d/%d: Failed to send, %d sent, err %s", rt.cur, rt.tot, n, e)
    93  			return false
    94  		}
    95  		if rt.debug {
    96  			rt.t.Logf("Sent request %d", rt.cur)
    97  		}
    98  
    99  		m, e = rt.sock.Recv(0)
   100  		if e != nil {
   101  			rt.t.Errorf("%d/%d: Failed to recv reply: %s", rt.cur, rt.tot, e)
   102  			return false
   103  		}
   104  		if len(m) != 1 {
   105  			rt.t.Errorf("%d/%d: Got wrong length: %d != 1", rt.cur, rt.tot, len(m))
   106  			return false
   107  		}
   108  		if m[0] != byte(rt.cur) {
   109  			rt.t.Errorf("%d/%d: Got wrong reply: %d != %d", rt.cur, rt.tot, m[0], byte(rt.cur))
   110  			return false
   111  		}
   112  		if rt.debug {
   113  			rt.t.Logf("Got good reply %d", rt.cur)
   114  		}
   115  		rt.cur++
   116  	}
   117  	rt.t.Logf("Req got all %d replies", rt.cur)
   118  	return true
   119  }
   120  
   121  func (rt *crepTest) Init(t *testing.T, addr string, num uint32) bool {
   122  	var e error
   123  	if rt.sock, e = NewSocket(AF_SP, REP); e != nil {
   124  		t.Errorf("NewSocket(): %v", e)
   125  		return false
   126  	}
   127  	if e = rt.sock.SetSendTimeout(time.Second); e != nil {
   128  		t.Errorf("Failed SetSendTimeout: %s", e)
   129  		return false
   130  	}
   131  	if e = rt.sock.SetRecvTimeout(time.Second); e != nil {
   132  		t.Errorf("Failed SetRecvTimeout: %s", e)
   133  		return false
   134  	}
   135  	rt.t = t
   136  	rt.cur = 0
   137  	rt.tot = num
   138  	rt.addr = addr
   139  	rt.done = make(chan struct{})
   140  	if _, err := rt.sock.Bind(rt.addr); err != nil {
   141  		rt.t.Errorf("Failed Bind: %s", err)
   142  		return false
   143  	}
   144  	return true
   145  }
   146  
   147  func (rt *crepTest) Finish() {
   148  	rt.ok = rt.cur == rt.tot
   149  	close(rt.done)
   150  }
   151  
   152  func (rt *crepTest) DoTest() bool {
   153  	defer rt.Finish()
   154  
   155  	for rt.cur < rt.tot {
   156  		var m []byte
   157  		var e error
   158  		var n int
   159  
   160  		if rt.debug {
   161  			rt.t.Logf("Wait for request %d", rt.cur)
   162  		}
   163  		if m, e = rt.sock.Recv(0); e != nil {
   164  			rt.t.Errorf("%d/%d: Failed to recv request: %s", rt.cur, rt.tot, e)
   165  			return false
   166  		}
   167  		if len(m) != 1 {
   168  			rt.t.Errorf("%d/%d: Got wrong length: %d != 1", rt.cur, rt.tot, len(m))
   169  			return false
   170  		}
   171  		if m[0] != byte(rt.cur) {
   172  			rt.t.Errorf("%d/%d: Got wrong request: %d != %d", rt.cur, rt.tot, m[0], byte(rt.cur))
   173  			return false
   174  		}
   175  		if rt.debug {
   176  			rt.t.Logf("Got good request %d", rt.cur)
   177  		}
   178  
   179  		if n, e = rt.sock.Send(m, 0); e != nil || n != 1 {
   180  			rt.t.Errorf("%d/%d: Failed to send reply: %v", rt.cur, rt.tot, e)
   181  			return false
   182  		}
   183  		if rt.debug {
   184  			rt.t.Logf("Sent reply %d", rt.cur)
   185  		}
   186  		rt.cur++
   187  	}
   188  	rt.t.Logf("Rep sent %d replies", rt.cur)
   189  	return true
   190  }
   191  
   192  func ReqRepCompat(t *testing.T, addr string, num uint32) {
   193  	req := &creqTest{}
   194  	rep := &crepTest{}
   195  
   196  	rep.Init(t, addr, num)
   197  	req.Init(t, addr, num)
   198  
   199  	// We wait a bit for the connection to establish
   200  	time.Sleep(time.Millisecond * 100)
   201  
   202  	t.Logf("Doing %d exchanges", num)
   203  
   204  	go func() {
   205  		rep.ok = rep.DoTest()
   206  	}()
   207  
   208  	go func() {
   209  		req.ok = req.DoTest()
   210  	}()
   211  
   212  	t.Logf("Waiting for tests to complete")
   213  
   214  	<-rep.done
   215  	t.Logf("Rep complete")
   216  
   217  	<-req.done
   218  	t.Logf("Req complete")
   219  
   220  	req.sock.Close()
   221  	rep.sock.Close()
   222  }
   223  
   224  func TestCompatTCP(t *testing.T) {
   225  	addr := "tcp://127.0.0.1:34444"
   226  	ReqRepCompat(t, addr, 50000)
   227  }
   228  
   229  func TestCompatInp(t *testing.T) {
   230  	addr := "inproc:///SOMENAME"
   231  	ReqRepCompat(t, addr, 500000)
   232  }
   233  
   234  // Don't do this right now.  There was a request at one point for send to
   235  // timeout when no transport was present.  But that semantic is diametrically
   236  // opposed with guaranteed delivery.  The only time we block or timeout is
   237  // if there is backpressure.
   238  func TestCompatSendTimeout(t *testing.T) {
   239  
   240  	addr := "tcp://127.0.0.1:19"
   241  	push, err := NewSocket(AF_SP, PUSH)
   242  	if err != nil {
   243  		t.Errorf("NewSocket: %v", err)
   244  		return
   245  	}
   246  	if err = push.SetSendTimeout(time.Duration(3000) * time.Millisecond); err != nil {
   247  		t.Errorf("SetSendTimeout: %v", err)
   248  		return
   249  	}
   250  	if _, err = push.Connect(addr); err != nil {
   251  		t.Errorf("Connect: %v", err)
   252  		return
   253  	}
   254  	t.Logf("Trying to send (should timeout)")
   255  	_, err = push.Send([]byte("TEST"), 0)
   256  	if err == nil {
   257  		t.Errorf("Passed, but should have timed out")
   258  		return
   259  	}
   260  	t.Logf("Expected timeout, got %v", err)
   261  }