github.com/gdamore/mangos@v1.4.0/test/device_test.go (about)

     1  // Copyright 2018 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 test
    16  
    17  import (
    18  	"strings"
    19  	"testing"
    20  	"time"
    21  
    22  	"nanomsg.org/go-mangos"
    23  	"nanomsg.org/go-mangos/protocol/pair"
    24  	"nanomsg.org/go-mangos/protocol/rep"
    25  	"nanomsg.org/go-mangos/protocol/req"
    26  	"nanomsg.org/go-mangos/transport/inproc"
    27  	"nanomsg.org/go-mangos/transport/ipc"
    28  	"nanomsg.org/go-mangos/transport/tcp"
    29  	"nanomsg.org/go-mangos/transport/tlstcp"
    30  	"nanomsg.org/go-mangos/transport/ws"
    31  	"nanomsg.org/go-mangos/transport/wss"
    32  )
    33  
    34  func TestDeviceBadPair(t *testing.T) {
    35  	s1, err := req.NewSocket()
    36  	if err != nil {
    37  		t.Errorf("Failed to open S1: %v", err)
    38  		return
    39  	}
    40  	defer s1.Close()
    41  	s2, err := pair.NewSocket()
    42  	if err != nil {
    43  		t.Errorf("Failed to open S2: %v", err)
    44  		return
    45  	}
    46  	defer s2.Close()
    47  
    48  	switch err := mangos.Device(s1, s2); err {
    49  	case mangos.ErrBadProto:
    50  		t.Logf("Got expected err: %v", err)
    51  		return
    52  	case nil:
    53  		t.Errorf("Matching incompatible types succeeded")
    54  		return
    55  	default:
    56  		t.Errorf("Got unexpected err: %v", err)
    57  		return
    58  	}
    59  }
    60  
    61  func TestDeviceBadSingle(t *testing.T) {
    62  	s1, err := req.NewSocket()
    63  	if err != nil {
    64  		t.Errorf("Failed to open S1: %v", err)
    65  		return
    66  	}
    67  	defer s1.Close()
    68  
    69  	switch err := mangos.Device(s1, s1); err {
    70  	case mangos.ErrBadProto:
    71  		t.Logf("Got expected err: %v", err)
    72  		return
    73  	case nil:
    74  		t.Errorf("Matching incompatible types succeeded")
    75  		return
    76  	default:
    77  		t.Errorf("Got unexpected err: %v", err)
    78  		return
    79  	}
    80  }
    81  
    82  func TestDeviceFirstNil(t *testing.T) {
    83  	s1, err := pair.NewSocket()
    84  	if err != nil {
    85  		t.Errorf("Failed to open S1: %v", err)
    86  		return
    87  	}
    88  	defer s1.Close()
    89  
    90  	switch err := mangos.Device(nil, s1); err {
    91  	case nil:
    92  		t.Logf("Ok!")
    93  		return
    94  	default:
    95  		t.Errorf("Got unexpected err: %v", err)
    96  		return
    97  	}
    98  }
    99  
   100  func TestDeviceSecondNil(t *testing.T) {
   101  	s1, err := pair.NewSocket()
   102  	if err != nil {
   103  		t.Errorf("Failed to open S1: %v", err)
   104  		return
   105  	}
   106  	defer s1.Close()
   107  
   108  	switch err := mangos.Device(s1, nil); err {
   109  	case nil:
   110  		t.Logf("Ok!")
   111  		return
   112  	default:
   113  		t.Errorf("Got unexpected err: %v", err)
   114  		return
   115  	}
   116  }
   117  
   118  func TestDeviceBothNil(t *testing.T) {
   119  	switch err := mangos.Device(nil, nil); err {
   120  	case mangos.ErrClosed:
   121  		t.Logf("Got expected err: %v", err)
   122  		return
   123  	case nil:
   124  		t.Errorf("Matching incompatible types succeeded")
   125  		return
   126  	default:
   127  		t.Errorf("Got unexpected err: %v", err)
   128  		return
   129  	}
   130  }
   131  
   132  func TestDeviceReqRep(t *testing.T) {
   133  	s1, err := req.NewSocket()
   134  	if err != nil {
   135  		t.Errorf("Failed to open S1: %v", err)
   136  		return
   137  	}
   138  	defer s1.Close()
   139  	s2, err := rep.NewSocket()
   140  	if err != nil {
   141  		t.Errorf("Failed to open S2: %v", err)
   142  		return
   143  	}
   144  	defer s2.Close()
   145  
   146  	switch err := mangos.Device(s1, s2); err {
   147  	case nil:
   148  		t.Logf("Matching req/rep ok!")
   149  		return
   150  	default:
   151  		t.Errorf("Got unexpected err: %v", err)
   152  		return
   153  	}
   154  }
   155  
   156  // TODO: Add fanout and concurrency testing.
   157  type devTest struct {
   158  	T
   159  }
   160  
   161  func (dt *devTest) Init(t *testing.T, addr string) bool {
   162  	var err error
   163  	if dt.Sock, err = pair.NewSocket(); err != nil {
   164  		t.Fatalf("pair.NewSocket(): %v", err)
   165  	}
   166  	return dt.T.Init(t, addr)
   167  }
   168  
   169  func (dt *devTest) SendHook(m *mangos.Message) bool {
   170  	m.Body = append(m.Body, byte(dt.GetSend()))
   171  	return dt.T.SendHook(m)
   172  }
   173  
   174  func (dt *devTest) RecvHook(m *mangos.Message) bool {
   175  	if len(m.Body) != 1 {
   176  		dt.Errorf("Recv message length %d != 1", len(m.Body))
   177  		return false
   178  	}
   179  	if m.Body[0] != byte(dt.GetRecv()) {
   180  		dt.Errorf("Wrong message: %d != %d", m.Body[0], byte(dt.GetRecv()))
   181  		return false
   182  	}
   183  	return dt.T.RecvHook(m)
   184  }
   185  
   186  func deviceCaseClient() []TestCase {
   187  	dev := &devTest{}
   188  	dev.ID = 0
   189  	dev.MsgSize = 4
   190  	dev.WantTx = 50
   191  	dev.WantRx = 50
   192  	cases := []TestCase{dev}
   193  	return cases
   194  }
   195  
   196  func testDevLoop(t *testing.T, addr string) {
   197  	s1, err := pair.NewSocket()
   198  	if err != nil {
   199  		t.Errorf("Failed to open S1: %v", err)
   200  		return
   201  	}
   202  	defer s1.Close()
   203  	s1.AddTransport(tcp.NewTransport())
   204  	s1.AddTransport(inproc.NewTransport())
   205  	s1.AddTransport(ipc.NewTransport())
   206  	s1.AddTransport(tlstcp.NewTransport())
   207  	s1.AddTransport(ws.NewTransport())
   208  	s1.AddTransport(wss.NewTransport())
   209  
   210  	options := make(map[string]interface{})
   211  	if strings.HasPrefix(addr, "wss://") || strings.HasPrefix(addr, "tls+tcp://") {
   212  		options[mangos.OptionTLSConfig] = srvCfg
   213  	}
   214  
   215  	if err := s1.ListenOptions(addr, options); err != nil {
   216  		t.Errorf("Failed listening to %s: %v", addr, err)
   217  		return
   218  	}
   219  
   220  	if err := mangos.Device(s1, s1); err != nil {
   221  		t.Errorf("Device failed: %v", err)
   222  		return
   223  	}
   224  
   225  	RunTests(t, addr, deviceCaseClient())
   226  }
   227  
   228  func testDevChain(t *testing.T, addr1 string, addr2 string, addr3 string) {
   229  	// This tests using multiple devices across a few transports.
   230  	// It looks like this:  addr1->addr2->addr3 <==> addr3->addr2->addr1
   231  	var err error
   232  	s := make([]mangos.Socket, 5)
   233  	for i := 0; i < 5; i++ {
   234  		if s[i], err = pair.NewSocket(); err != nil {
   235  			t.Errorf("Failed to open S1_1: %v", err)
   236  			return
   237  		}
   238  		defer s[i].Close()
   239  		s[i].AddTransport(tcp.NewTransport())
   240  		s[i].AddTransport(inproc.NewTransport())
   241  		s[i].AddTransport(tlstcp.NewTransport())
   242  		s[i].AddTransport(ipc.NewTransport())
   243  		s[i].AddTransport(ws.NewTransport())
   244  	}
   245  
   246  	if err = s[0].Listen(addr1); err != nil {
   247  		t.Errorf("s[0] Listen: %v", err)
   248  		return
   249  	}
   250  	if err = s[1].Dial(addr2); err != nil {
   251  		t.Errorf("s[1] Dial: %v", err)
   252  		return
   253  	}
   254  	if err = s[2].Listen(addr2); err != nil {
   255  		t.Errorf("s[2] Listen: %v", err)
   256  		return
   257  	}
   258  	if err = s[3].Dial(addr3); err != nil {
   259  		t.Errorf("s[3] Dial: %v", err)
   260  		return
   261  	}
   262  	if err = s[4].Listen(addr3); err != nil {
   263  		t.Errorf("s[4] Listen: %v", err)
   264  		return
   265  	}
   266  	if err = mangos.Device(s[0], s[1]); err != nil {
   267  		t.Errorf("s[0],s[1] Device: %v", err)
   268  		return
   269  	}
   270  	if err = mangos.Device(s[2], s[3]); err != nil {
   271  		t.Errorf("s[2],s[3] Device: %v", err)
   272  		return
   273  	}
   274  	if err = mangos.Device(s[4], nil); err != nil {
   275  		t.Errorf("s[4] Device: %v", err)
   276  		return
   277  	}
   278  	RunTests(t, addr1, deviceCaseClient())
   279  }
   280  
   281  func TestDeviceChain(t *testing.T) {
   282  	testDevChain(t, AddrTestTCP, AddrTestWS, AddrTestInp)
   283  	// Some platforms (windows) need a little time to wind up the close
   284  	time.Sleep(100 * time.Millisecond)
   285  }
   286  
   287  func TestDeviceLoopTCP(t *testing.T) {
   288  	testDevLoop(t, AddrTestTCP)
   289  }
   290  
   291  func TestDeviceLoopInp(t *testing.T) {
   292  	testDevLoop(t, AddrTestInp)
   293  }
   294  
   295  func TestDeviceLoopIPC(t *testing.T) {
   296  	testDevLoop(t, AddrTestIPC)
   297  }
   298  
   299  func TestDeviceLoopTLS(t *testing.T) {
   300  	testDevLoop(t, AddrTestTLS)
   301  }
   302  
   303  func TestDeviceLoopWS(t *testing.T) {
   304  	testDevLoop(t, AddrTestWS)
   305  }
   306  
   307  func TestDeviceLoopWSS(t *testing.T) {
   308  	testDevLoop(t, AddrTestWSS)
   309  }