github.com/gdamore/mangos@v1.4.0/test/bus_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  	"encoding/binary"
    19  	"testing"
    20  
    21  	"nanomsg.org/go-mangos"
    22  	"nanomsg.org/go-mangos/protocol/bus"
    23  )
    24  
    25  type busTest struct {
    26  	nbus   uint32
    27  	nstart uint32
    28  	start  map[uint32]bool
    29  	resp   map[uint32]uint32
    30  	send   uint32
    31  	T
    32  }
    33  
    34  func (bt *busTest) Init(t *testing.T, addr string) bool {
    35  	var err error
    36  	bt.resp = make(map[uint32]uint32)
    37  	bt.start = make(map[uint32]bool)
    38  	bt.send = 0
    39  	bt.nstart = 0
    40  	if bt.Sock, err = bus.NewSocket(); err != nil {
    41  		bt.Errorf("NewSocket(): %v", err)
    42  		return false
    43  	}
    44  	return bt.T.Init(t, addr)
    45  }
    46  
    47  func (bt *busTest) WaitRecv() bool {
    48  	// We provide our own, so that we can provide more
    49  	// detailed error reporting about packet mismatches.
    50  	r := bt.T.WaitRecv()
    51  	bt.Lock()
    52  	defer bt.Unlock()
    53  	if !r {
    54  		bt.Errorf("Timeout socket %d", uint32(bt.GetID()))
    55  		for v, c := range bt.resp {
    56  			bt.Errorf("Last packet %d from %d", c, v)
    57  		}
    58  	}
    59  	return r
    60  }
    61  
    62  func (bt *busTest) RecvStart() bool {
    63  	m, err := bt.RecvMsg()
    64  	if err != nil {
    65  		bt.Errorf("RecvMsg failed: %v", err)
    66  		return false
    67  	}
    68  	defer m.Free()
    69  	v, ok := ParseStart(m)
    70  	if !ok {
    71  		bt.Errorf("Bad START message received: %v", m)
    72  		return false
    73  	}
    74  	if v == uint32(bt.GetID()) {
    75  		bt.Errorf("Got my own START message")
    76  		return false
    77  	}
    78  	if yes, ok := bt.start[v]; ok && yes {
    79  		bt.Logf("Got dup START from %d", v)
    80  		return false
    81  	}
    82  	bt.Debugf("Got START from %d", v)
    83  	bt.start[v] = true
    84  	bt.nstart++
    85  	if bt.Server {
    86  		return bt.nstart == bt.nbus-1
    87  	}
    88  	return true
    89  }
    90  
    91  func (bt *busTest) SendHook(m *mangos.Message) bool {
    92  	bt.Lock()
    93  	defer bt.Unlock()
    94  	v := uint32(bt.GetID())
    95  	w := bt.send
    96  	bt.send++
    97  	m.Body = m.Body[0:8]
    98  
    99  	binary.BigEndian.PutUint32(m.Body, v)
   100  	binary.BigEndian.PutUint32(m.Body[4:], w)
   101  
   102  	// Inject a sleep to avoid overwhelming the bus and dropping messages.
   103  	//d := time.Duration(rand.Uint32() % 10000)
   104  	//time.Sleep(d * time.Microsecond)
   105  
   106  	return bt.T.SendHook(m)
   107  }
   108  
   109  func (bt *busTest) RecvHook(m *mangos.Message) bool {
   110  	bt.Lock()
   111  	defer bt.Unlock()
   112  	if len(m.Body) < 8 {
   113  		bt.Errorf("Recv message length %d < 8", len(m.Body))
   114  		return false
   115  	}
   116  
   117  	v := binary.BigEndian.Uint32(m.Body)
   118  	w := binary.BigEndian.Uint32(m.Body[4:])
   119  	if v == uint32(bt.GetID()) {
   120  		bt.Errorf("Got my own message %v", m.Body)
   121  		return false
   122  	}
   123  	if w != uint32(bt.resp[v]) {
   124  		bt.Errorf("Got wrong message #%d (!= %d) from %d", w, bt.resp[v], v)
   125  		return false
   126  	}
   127  	bt.resp[v]++
   128  	bt.Debugf("Response %d from id %d", w, v)
   129  	bt.BumpRecv()
   130  	return true
   131  }
   132  
   133  func busCases() []TestCase {
   134  
   135  	nbus := 5
   136  	npkt := 7
   137  
   138  	cases := make([]TestCase, nbus)
   139  	for i := 0; i < nbus; i++ {
   140  		bus := &busTest{}
   141  		bus.ID = i
   142  		bus.nbus = uint32(nbus)
   143  		bus.MsgSize = 8
   144  		bus.WantTx = int32(npkt)
   145  		// Only the server receives from all peers.  The clients
   146  		// only get packets sent by the server.
   147  		if i == 0 {
   148  			bus.Server = true
   149  			bus.WantRx = int32(npkt * (nbus - 1))
   150  		} else {
   151  			bus.WantRx = int32(npkt)
   152  		}
   153  		cases[i] = bus
   154  	}
   155  	return cases
   156  }
   157  
   158  func TestBusInp(t *testing.T) {
   159  	RunTestsInp(t, busCases())
   160  }
   161  
   162  func TestBusTCP(t *testing.T) {
   163  	RunTestsTCP(t, busCases())
   164  }
   165  
   166  func TestBusIPC(t *testing.T) {
   167  	RunTestsIPC(t, busCases())
   168  }
   169  
   170  func TestBusTLS(t *testing.T) {
   171  	RunTestsTLS(t, busCases())
   172  }