github.com/gdamore/mangos@v1.4.0/test/star_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 "math/rand" 19 "testing" 20 "time" 21 22 "nanomsg.org/go-mangos" 23 "nanomsg.org/go-mangos/protocol/star" 24 "nanomsg.org/go-mangos/transport/tcp" 25 ) 26 27 type starTester struct { 28 id int 29 sock mangos.Socket 30 rdoneq chan bool 31 sdoneq chan bool 32 } 33 34 func starTestSender(t *testing.T, bt *starTester, cnt int) { 35 defer close(bt.sdoneq) 36 for i := 0; i < cnt; i++ { 37 // Inject a small delay to give receivers a chance to catch up 38 // Maximum is 10 msec. 39 d := time.Duration(rand.Uint32() % 10000) 40 time.Sleep(d * time.Microsecond) 41 t.Logf("Peer %d: Sending %d", bt.id, i) 42 msg := mangos.NewMessage(2) 43 msg.Body = append(msg.Body, byte(bt.id), byte(i)) 44 if err := bt.sock.SendMsg(msg); err != nil { 45 t.Errorf("Peer %d send %d fail: %v", bt.id, i, err) 46 return 47 } 48 } 49 } 50 51 func starTestReceiver(t *testing.T, bt *starTester, cnt int, numID int) { 52 var rcpt = make([]int, numID) 53 defer close(bt.rdoneq) 54 55 for tot := 0; tot < (numID-1)*cnt; { 56 msg, err := bt.sock.RecvMsg() 57 if err != nil { 58 t.Errorf("Peer %d: Recv fail: %v", bt.id, err) 59 return 60 } 61 62 if len(msg.Body) != 2 { 63 t.Errorf("Peer %d: Received wrong length", bt.id) 64 return 65 } 66 peer := int(msg.Body[0]) 67 if peer == bt.id { 68 t.Errorf("Peer %d: Got its own message!", bt.id) 69 return 70 } 71 if int(msg.Body[1]) != rcpt[peer] { 72 t.Errorf("Peer %d: Bad message from peer %d: %d s/b %d", 73 bt.id, peer, msg.Body[1], rcpt[peer]) 74 return 75 } 76 if int(msg.Body[1]) >= cnt { 77 t.Errorf("Peer %d: Too many from peer %d", bt.id, 78 peer) 79 return 80 } 81 t.Logf("Peer %d: Good rcv from peer %d (%d)", bt.id, peer, 82 rcpt[peer]) 83 rcpt[peer]++ 84 tot++ 85 msg.Free() 86 } 87 t.Logf("Peer %d: Finish", bt.id) 88 } 89 90 func starTestNewServer(t *testing.T, addr string, id int) *starTester { 91 var err error 92 bt := &starTester{id: id, rdoneq: make(chan bool), sdoneq: make(chan bool)} 93 94 if bt.sock, err = star.NewSocket(); err != nil { 95 t.Errorf("Failed getting server %d socket: %v", id, err) 96 return nil 97 } 98 bt.sock.AddTransport(tcp.NewTransport()) 99 100 if err = bt.sock.Listen(addr); err != nil { 101 t.Errorf("Failed server %d listening: %v", id, err) 102 bt.sock.Close() 103 return nil 104 } 105 return bt 106 } 107 108 func starTestNewClient(t *testing.T, addr string, id int) *starTester { 109 var err error 110 bt := &starTester{id: id, rdoneq: make(chan bool), sdoneq: make(chan bool)} 111 112 if bt.sock, err = star.NewSocket(); err != nil { 113 t.Errorf("Failed getting client %d socket: %v", id, err) 114 return nil 115 } 116 bt.sock.AddTransport(tcp.NewTransport()) 117 if err = bt.sock.Dial(addr); err != nil { 118 t.Errorf("Failed client %d dialing: %v", id, err) 119 bt.sock.Close() 120 return nil 121 } 122 return bt 123 } 124 125 func starTestCleanup(t *testing.T, bts []*starTester) { 126 for id := 0; id < len(bts); id++ { 127 t.Logf("Cleanup %d", id) 128 if bts[id].sock != nil { 129 bts[id].sock.Close() 130 } 131 } 132 } 133 134 func TestStar(t *testing.T) { 135 addr := "tcp://127.0.0.1:3538" 136 137 num := 5 138 pkts := 7 139 bts := make([]*starTester, num) 140 defer starTestCleanup(t, bts) 141 142 t.Logf("Creating star network") 143 for id := 0; id < num; id++ { 144 if id == 0 { 145 bts[id] = starTestNewServer(t, addr, id) 146 } else { 147 bts[id] = starTestNewClient(t, addr, id) 148 } 149 if bts[id] == nil { 150 t.Errorf("Failed creating %d", id) 151 return 152 } 153 } 154 155 // wait a little bit for connections to establish 156 time.Sleep(time.Microsecond * 500) 157 158 // start receivers first... avoids first missed dropped packet 159 t.Logf("Starting recv") 160 for id := 0; id < num; id++ { 161 go starTestReceiver(t, bts[id], pkts, num) 162 } 163 164 // wait a little just to be sure go routines are all running 165 time.Sleep(time.Millisecond * 10) 166 167 // then start senders 168 t.Logf("Starting send") 169 for id := 0; id < num; id++ { 170 go starTestSender(t, bts[id], pkts) 171 } 172 173 tmout := time.After(5 * time.Second) 174 175 for id := 0; id < num; id++ { 176 select { 177 case <-bts[id].sdoneq: 178 continue 179 case <-tmout: 180 t.Errorf("Timeout waiting for sender id %d", id) 181 return 182 } 183 } 184 185 for id := 0; id < num; id++ { 186 select { 187 case <-bts[id].rdoneq: 188 continue 189 case <-tmout: 190 t.Errorf("Timeout waiting for receiver id %d", id) 191 return 192 } 193 } 194 t.Logf("All pass") 195 } 196 197 func TestStarTTLZero(t *testing.T) { 198 SetTTLZero(t, star.NewSocket) 199 } 200 201 func TestStarTTLNegative(t *testing.T) { 202 SetTTLNegative(t, star.NewSocket) 203 } 204 205 func TestStarTTLTooBig(t *testing.T) { 206 SetTTLTooBig(t, star.NewSocket) 207 } 208 209 func TestStarTTLNotInt(t *testing.T) { 210 SetTTLNotInt(t, star.NewSocket) 211 } 212 213 func TestStarTTLSet(t *testing.T) { 214 SetTTL(t, star.NewSocket) 215 } 216 217 func TestStarTTLDrop(t *testing.T) { 218 TTLDropTest(t, star.NewSocket, star.NewSocket) 219 }