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  }