github.com/zignig/go-ipfs@v0.0.0-20141111235910-c9e5fdf55a52/net/mux/mux_test.go (about) 1 package mux 2 3 import ( 4 "bytes" 5 "fmt" 6 "sync" 7 "testing" 8 "time" 9 10 mh "github.com/jbenet/go-ipfs/Godeps/_workspace/src/github.com/jbenet/go-multihash" 11 msg "github.com/jbenet/go-ipfs/net/message" 12 pb "github.com/jbenet/go-ipfs/net/mux/internal/pb" 13 peer "github.com/jbenet/go-ipfs/peer" 14 15 context "github.com/jbenet/go-ipfs/Godeps/_workspace/src/code.google.com/p/go.net/context" 16 ) 17 18 type TestProtocol struct { 19 *msg.Pipe 20 } 21 22 func (t *TestProtocol) GetPipe() *msg.Pipe { 23 return t.Pipe 24 } 25 26 func newPeer(t *testing.T, id string) peer.Peer { 27 mh, err := mh.FromHexString(id) 28 if err != nil { 29 t.Error(err) 30 return nil 31 } 32 33 return peer.WithID(peer.ID(mh)) 34 } 35 36 func testMsg(t *testing.T, m msg.NetMessage, data []byte) { 37 if !bytes.Equal(data, m.Data()) { 38 t.Errorf("Data does not match: %v != %v", data, m.Data()) 39 } 40 } 41 42 func testWrappedMsg(t *testing.T, m msg.NetMessage, pid pb.ProtocolID, data []byte) { 43 data2, pid2, err := unwrapData(m.Data()) 44 if err != nil { 45 t.Error(err) 46 } 47 48 if pid != pid2 { 49 t.Errorf("ProtocolIDs do not match: %v != %v", pid, pid2) 50 } 51 52 if !bytes.Equal(data, data2) { 53 t.Errorf("Data does not match: %v != %v", data, data2) 54 } 55 } 56 57 func TestSimpleMuxer(t *testing.T) { 58 ctx := context.Background() 59 60 // setup 61 p1 := &TestProtocol{Pipe: msg.NewPipe(10)} 62 p2 := &TestProtocol{Pipe: msg.NewPipe(10)} 63 pid1 := pb.ProtocolID_Test 64 pid2 := pb.ProtocolID_Routing 65 mux1 := NewMuxer(ctx, ProtocolMap{ 66 pid1: p1, 67 pid2: p2, 68 }) 69 peer1 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275aaaaaa") 70 // peer2 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275bbbbbb") 71 72 // test outgoing p1 73 for _, s := range []string{"foo", "bar", "baz"} { 74 p1.Outgoing <- msg.New(peer1, []byte(s)) 75 testWrappedMsg(t, <-mux1.Outgoing, pid1, []byte(s)) 76 } 77 78 // test incoming p1 79 for _, s := range []string{"foo", "bar", "baz"} { 80 d, err := wrapData([]byte(s), pid1) 81 if err != nil { 82 t.Error(err) 83 } 84 mux1.Incoming <- msg.New(peer1, d) 85 testMsg(t, <-p1.Incoming, []byte(s)) 86 } 87 88 // test outgoing p2 89 for _, s := range []string{"foo", "bar", "baz"} { 90 p2.Outgoing <- msg.New(peer1, []byte(s)) 91 testWrappedMsg(t, <-mux1.Outgoing, pid2, []byte(s)) 92 } 93 94 // test incoming p2 95 for _, s := range []string{"foo", "bar", "baz"} { 96 d, err := wrapData([]byte(s), pid2) 97 if err != nil { 98 t.Error(err) 99 } 100 mux1.Incoming <- msg.New(peer1, d) 101 testMsg(t, <-p2.Incoming, []byte(s)) 102 } 103 } 104 105 func TestSimultMuxer(t *testing.T) { 106 // run muxer 107 ctx, cancel := context.WithCancel(context.Background()) 108 109 // setup 110 p1 := &TestProtocol{Pipe: msg.NewPipe(10)} 111 p2 := &TestProtocol{Pipe: msg.NewPipe(10)} 112 pid1 := pb.ProtocolID_Test 113 pid2 := pb.ProtocolID_Identify 114 mux1 := NewMuxer(ctx, ProtocolMap{ 115 pid1: p1, 116 pid2: p2, 117 }) 118 peer1 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275aaaaaa") 119 // peer2 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275bbbbbb") 120 121 // counts 122 total := 10000 123 speed := time.Microsecond * 1 124 counts := [2][2][2]int{} 125 var countsLock sync.Mutex 126 127 // run producers at every end sending incrementing messages 128 produceOut := func(pid pb.ProtocolID, size int) { 129 limiter := time.Tick(speed) 130 for i := 0; i < size; i++ { 131 <-limiter 132 s := fmt.Sprintf("proto %v out %v", pid, i) 133 m := msg.New(peer1, []byte(s)) 134 mux1.Protocols[pid].GetPipe().Outgoing <- m 135 countsLock.Lock() 136 counts[pid][0][0]++ 137 countsLock.Unlock() 138 // log.Debug("sent %v", s) 139 } 140 } 141 142 produceIn := func(pid pb.ProtocolID, size int) { 143 limiter := time.Tick(speed) 144 for i := 0; i < size; i++ { 145 <-limiter 146 s := fmt.Sprintf("proto %v in %v", pid, i) 147 d, err := wrapData([]byte(s), pid) 148 if err != nil { 149 t.Error(err) 150 } 151 152 m := msg.New(peer1, d) 153 mux1.Incoming <- m 154 countsLock.Lock() 155 counts[pid][1][0]++ 156 countsLock.Unlock() 157 // log.Debug("sent %v", s) 158 } 159 } 160 161 consumeOut := func() { 162 for { 163 select { 164 case m := <-mux1.Outgoing: 165 data, pid, err := unwrapData(m.Data()) 166 if err != nil { 167 t.Error(err) 168 } 169 170 // log.Debug("got %v", string(data)) 171 _ = data 172 countsLock.Lock() 173 counts[pid][1][1]++ 174 countsLock.Unlock() 175 176 case <-ctx.Done(): 177 return 178 } 179 } 180 } 181 182 consumeIn := func(pid pb.ProtocolID) { 183 for { 184 select { 185 case m := <-mux1.Protocols[pid].GetPipe().Incoming: 186 countsLock.Lock() 187 counts[pid][0][1]++ 188 countsLock.Unlock() 189 // log.Debug("got %v", string(m.Data())) 190 _ = m 191 case <-ctx.Done(): 192 return 193 } 194 } 195 } 196 197 go produceOut(pid1, total) 198 go produceOut(pid2, total) 199 go produceIn(pid1, total) 200 go produceIn(pid2, total) 201 go consumeOut() 202 go consumeIn(pid1) 203 go consumeIn(pid2) 204 205 limiter := time.Tick(speed) 206 for { 207 <-limiter 208 countsLock.Lock() 209 got := counts[0][0][0] + counts[0][0][1] + 210 counts[0][1][0] + counts[0][1][1] + 211 counts[1][0][0] + counts[1][0][1] + 212 counts[1][1][0] + counts[1][1][1] 213 countsLock.Unlock() 214 215 if got == total*8 { 216 cancel() 217 return 218 } 219 } 220 221 } 222 223 func TestStopping(t *testing.T) { 224 ctx := context.Background() 225 226 // setup 227 p1 := &TestProtocol{Pipe: msg.NewPipe(10)} 228 p2 := &TestProtocol{Pipe: msg.NewPipe(10)} 229 pid1 := pb.ProtocolID_Test 230 pid2 := pb.ProtocolID_Identify 231 mux1 := NewMuxer(ctx, ProtocolMap{ 232 pid1: p1, 233 pid2: p2, 234 }) 235 peer1 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275aaaaaa") 236 // peer2 := newPeer(t, "11140beec7b5ea3f0fdbc95d0dd47f3c5bc275bbbbbb") 237 238 // test outgoing p1 239 for _, s := range []string{"foo1", "bar1", "baz1"} { 240 p1.Outgoing <- msg.New(peer1, []byte(s)) 241 testWrappedMsg(t, <-mux1.Outgoing, pid1, []byte(s)) 242 } 243 244 // test incoming p1 245 for _, s := range []string{"foo2", "bar2", "baz2"} { 246 d, err := wrapData([]byte(s), pid1) 247 if err != nil { 248 t.Error(err) 249 } 250 mux1.Incoming <- msg.New(peer1, d) 251 testMsg(t, <-p1.Incoming, []byte(s)) 252 } 253 254 mux1.Close() // waits 255 256 // test outgoing p1 257 for _, s := range []string{"foo3", "bar3", "baz3"} { 258 p1.Outgoing <- msg.New(peer1, []byte(s)) 259 select { 260 case m := <-mux1.Outgoing: 261 t.Errorf("should not have received anything. Got: %v", string(m.Data())) 262 case <-time.After(time.Millisecond): 263 } 264 } 265 266 // test incoming p1 267 for _, s := range []string{"foo4", "bar4", "baz4"} { 268 d, err := wrapData([]byte(s), pid1) 269 if err != nil { 270 t.Error(err) 271 } 272 mux1.Incoming <- msg.New(peer1, d) 273 select { 274 case <-p1.Incoming: 275 t.Error("should not have received anything.") 276 case <-time.After(time.Millisecond): 277 } 278 } 279 }