github.com/gdamore/mangos@v1.4.0/test/porthook_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  	"sync"
    19  	"testing"
    20  	"time"
    21  
    22  	"nanomsg.org/go-mangos"
    23  	"nanomsg.org/go-mangos/protocol/rep"
    24  	"nanomsg.org/go-mangos/protocol/req"
    25  	"nanomsg.org/go-mangos/transport/tcp"
    26  
    27  	. "github.com/smartystreets/goconvey/convey"
    28  )
    29  
    30  type hookinfo struct {
    31  	action mangos.PortAction
    32  	server bool
    33  	isopen bool
    34  	addr   string
    35  }
    36  
    37  func (i hookinfo) String() string {
    38  	var s string
    39  	switch i.action {
    40  	case mangos.PortActionAdd:
    41  		s = "Add "
    42  	case mangos.PortActionRemove:
    43  		s = "Rem "
    44  	default:
    45  		s = "WTH "
    46  	}
    47  	if i.server {
    48  		s += "SRV "
    49  	} else {
    50  		s += "CLI "
    51  	}
    52  	s += i.addr + " "
    53  	if i.isopen {
    54  		s += "Open "
    55  	} else {
    56  		s += "Closed "
    57  	}
    58  	return s
    59  }
    60  
    61  type hooktest struct {
    62  	t      *testing.T
    63  	calls  []hookinfo
    64  	expect []hookinfo
    65  	allow  bool
    66  	sync.Mutex
    67  }
    68  
    69  func (h *hooktest) Hook(action mangos.PortAction, p mangos.Port) bool {
    70  	h.t.Logf("Hook called - %v!", action)
    71  	i := hookinfo{action: action, addr: p.Address(), isopen: p.IsOpen(), server: p.IsServer()}
    72  	h.Lock()
    73  	h.calls = append(h.calls, i)
    74  	h.Unlock()
    75  	return h.allow
    76  }
    77  
    78  func TestPortHook(t *testing.T) {
    79  	Convey("Testing Add Hook", t, func() {
    80  
    81  		srvtest := &hooktest{allow: true, t: t}
    82  		clitest := &hooktest{allow: true, t: t}
    83  
    84  		addr := AddrTestTCP
    85  
    86  		srvtest.expect = []hookinfo{{
    87  			action: mangos.PortActionAdd,
    88  			addr:   addr,
    89  			server: true,
    90  			isopen: true,
    91  		}, {
    92  			action: mangos.PortActionRemove,
    93  			addr:   addr,
    94  			server: true,
    95  			isopen: false,
    96  		}}
    97  
    98  		clitest.expect = []hookinfo{{
    99  			action: mangos.PortActionAdd,
   100  			addr:   addr,
   101  			server: false,
   102  			isopen: true,
   103  		}, {
   104  			action: mangos.PortActionRemove,
   105  			addr:   addr,
   106  			server: false,
   107  			isopen: false,
   108  		}}
   109  
   110  		Convey("Given a REQ & REP sockets", func() {
   111  			sockreq, err := req.NewSocket()
   112  			So(err, ShouldBeNil)
   113  			So(sockreq, ShouldNotBeNil)
   114  
   115  			defer sockreq.Close()
   116  			sockreq.AddTransport(tcp.NewTransport())
   117  
   118  			sockrep, err := rep.NewSocket()
   119  			So(err, ShouldBeNil)
   120  			So(sockrep, ShouldNotBeNil)
   121  
   122  			defer sockrep.Close()
   123  			sockrep.AddTransport(tcp.NewTransport())
   124  
   125  			d, err := sockreq.NewDialer(addr, nil)
   126  			So(err, ShouldBeNil)
   127  			So(d, ShouldNotBeNil)
   128  
   129  			l, err := sockrep.NewListener(addr, nil)
   130  			So(err, ShouldBeNil)
   131  			So(l, ShouldNotBeNil)
   132  
   133  			Convey("We can set port hooks", func() {
   134  				hook := sockreq.SetPortHook(clitest.Hook)
   135  				So(hook, ShouldBeNil)
   136  
   137  				hook = sockrep.SetPortHook(srvtest.Hook)
   138  				So(hook, ShouldBeNil)
   139  
   140  				Convey("And establish a connection", func() {
   141  					err = l.Listen()
   142  					So(err, ShouldBeNil)
   143  
   144  					err = d.Dial()
   145  					So(err, ShouldBeNil)
   146  
   147  					// time for conn to establish
   148  					time.Sleep(time.Millisecond * 100)
   149  
   150  					// Shutdown the sockets
   151  					d.Close()
   152  					l.Close()
   153  
   154  					sockrep.Close()
   155  					sockreq.Close()
   156  
   157  					Convey("The hooks were called", func() {
   158  
   159  						time.Sleep(100 * time.Millisecond)
   160  
   161  						clitest.Lock()
   162  						defer clitest.Unlock()
   163  
   164  						srvtest.Lock()
   165  						defer srvtest.Unlock()
   166  
   167  						So(len(srvtest.calls), ShouldEqual, len(srvtest.expect))
   168  						for i := range srvtest.calls {
   169  							So(srvtest.calls[i].String(), ShouldEqual, srvtest.expect[i].String())
   170  						}
   171  						So(len(clitest.calls), ShouldEqual, len(clitest.expect))
   172  						for i := range clitest.calls {
   173  							So(clitest.calls[i].String(), ShouldEqual, clitest.expect[i].String())
   174  						}
   175  					})
   176  				})
   177  			})
   178  		})
   179  	})
   180  }