github.com/Ethersocial/go-esn@v0.3.7/swarm/network/stream/streamer_test.go (about)

     1  // Copyright 2018 The go-ethereum Authors
     2  // This file is part of the go-ethereum library.
     3  //
     4  // The go-ethereum library is free software: you can redistribute it and/or modify
     5  // it under the terms of the GNU Lesser General Public License as published by
     6  // the Free Software Foundation, either version 3 of the License, or
     7  // (at your option) any later version.
     8  //
     9  // The go-ethereum library is distributed in the hope that it will be useful,
    10  // but WITHOUT ANY WARRANTY; without even the implied warranty of
    11  // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
    12  // GNU Lesser General Public License for more details.
    13  //
    14  // You should have received a copy of the GNU Lesser General Public License
    15  // along with the go-ethereum library. If not, see <http://www.gnu.org/licenses/>.
    16  
    17  package stream
    18  
    19  import (
    20  	"bytes"
    21  	"context"
    22  	"errors"
    23  	"strconv"
    24  	"testing"
    25  	"time"
    26  
    27  	"github.com/ethersocial/go-esn/crypto/sha3"
    28  	p2ptest "github.com/ethersocial/go-esn/p2p/testing"
    29  )
    30  
    31  func TestStreamerSubscribe(t *testing.T) {
    32  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
    33  	defer teardown()
    34  	if err != nil {
    35  		t.Fatal(err)
    36  	}
    37  
    38  	stream := NewStream("foo", "", true)
    39  	err = streamer.Subscribe(tester.Nodes[0].ID(), stream, NewRange(0, 0), Top)
    40  	if err == nil || err.Error() != "stream foo not registered" {
    41  		t.Fatalf("Expected error %v, got %v", "stream foo not registered", err)
    42  	}
    43  }
    44  
    45  func TestStreamerRequestSubscription(t *testing.T) {
    46  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
    47  	defer teardown()
    48  	if err != nil {
    49  		t.Fatal(err)
    50  	}
    51  
    52  	stream := NewStream("foo", "", false)
    53  	err = streamer.RequestSubscription(tester.Nodes[0].ID(), stream, &Range{}, Top)
    54  	if err == nil || err.Error() != "stream foo not registered" {
    55  		t.Fatalf("Expected error %v, got %v", "stream foo not registered", err)
    56  	}
    57  }
    58  
    59  var (
    60  	hash0         = sha3.Sum256([]byte{0})
    61  	hash1         = sha3.Sum256([]byte{1})
    62  	hash2         = sha3.Sum256([]byte{2})
    63  	hashesTmp     = append(hash0[:], hash1[:]...)
    64  	hashes        = append(hashesTmp, hash2[:]...)
    65  	corruptHashes = append(hashes[:40])
    66  )
    67  
    68  type testClient struct {
    69  	t              string
    70  	wait0          chan bool
    71  	wait2          chan bool
    72  	batchDone      chan bool
    73  	receivedHashes map[string][]byte
    74  }
    75  
    76  func newTestClient(t string) *testClient {
    77  	return &testClient{
    78  		t:              t,
    79  		wait0:          make(chan bool),
    80  		wait2:          make(chan bool),
    81  		batchDone:      make(chan bool),
    82  		receivedHashes: make(map[string][]byte),
    83  	}
    84  }
    85  
    86  func (self *testClient) NeedData(ctx context.Context, hash []byte) func(context.Context) error {
    87  	self.receivedHashes[string(hash)] = hash
    88  	if bytes.Equal(hash, hash0[:]) {
    89  		return func(context.Context) error {
    90  			<-self.wait0
    91  			return nil
    92  		}
    93  	} else if bytes.Equal(hash, hash2[:]) {
    94  		return func(context.Context) error {
    95  			<-self.wait2
    96  			return nil
    97  		}
    98  	}
    99  	return nil
   100  }
   101  
   102  func (self *testClient) BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error) {
   103  	close(self.batchDone)
   104  	return nil
   105  }
   106  
   107  func (self *testClient) Close() {}
   108  
   109  type testServer struct {
   110  	t string
   111  }
   112  
   113  func newTestServer(t string) *testServer {
   114  	return &testServer{
   115  		t: t,
   116  	}
   117  }
   118  
   119  func (self *testServer) SetNextBatch(from uint64, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) {
   120  	return make([]byte, HashSize), from + 1, to + 1, nil, nil
   121  }
   122  
   123  func (self *testServer) GetData(context.Context, []byte) ([]byte, error) {
   124  	return nil, nil
   125  }
   126  
   127  func (self *testServer) Close() {
   128  }
   129  
   130  func TestStreamerDownstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
   131  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   132  	defer teardown()
   133  	if err != nil {
   134  		t.Fatal(err)
   135  	}
   136  
   137  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   138  		return newTestClient(t), nil
   139  	})
   140  
   141  	node := tester.Nodes[0]
   142  
   143  	stream := NewStream("foo", "", true)
   144  	err = streamer.Subscribe(node.ID(), stream, NewRange(5, 8), Top)
   145  	if err != nil {
   146  		t.Fatalf("Expected no error, got %v", err)
   147  	}
   148  
   149  	err = tester.TestExchanges(
   150  		p2ptest.Exchange{
   151  			Label: "Subscribe message",
   152  			Expects: []p2ptest.Expect{
   153  				{
   154  					Code: 4,
   155  					Msg: &SubscribeMsg{
   156  						Stream:   stream,
   157  						History:  NewRange(5, 8),
   158  						Priority: Top,
   159  					},
   160  					Peer: node.ID(),
   161  				},
   162  			},
   163  		},
   164  		// trigger OfferedHashesMsg to actually create the client
   165  		p2ptest.Exchange{
   166  			Label: "OfferedHashes message",
   167  			Triggers: []p2ptest.Trigger{
   168  				{
   169  					Code: 1,
   170  					Msg: &OfferedHashesMsg{
   171  						HandoverProof: &HandoverProof{
   172  							Handover: &Handover{},
   173  						},
   174  						Hashes: hashes,
   175  						From:   5,
   176  						To:     8,
   177  						Stream: stream,
   178  					},
   179  					Peer: node.ID(),
   180  				},
   181  			},
   182  			Expects: []p2ptest.Expect{
   183  				{
   184  					Code: 2,
   185  					Msg: &WantedHashesMsg{
   186  						Stream: stream,
   187  						Want:   []byte{5},
   188  						From:   9,
   189  						To:     0,
   190  					},
   191  					Peer: node.ID(),
   192  				},
   193  			},
   194  		},
   195  	)
   196  	if err != nil {
   197  		t.Fatal(err)
   198  	}
   199  
   200  	err = streamer.Unsubscribe(node.ID(), stream)
   201  	if err != nil {
   202  		t.Fatalf("Expected no error, got %v", err)
   203  	}
   204  
   205  	err = tester.TestExchanges(p2ptest.Exchange{
   206  		Label: "Unsubscribe message",
   207  		Expects: []p2ptest.Expect{
   208  			{
   209  				Code: 0,
   210  				Msg: &UnsubscribeMsg{
   211  					Stream: stream,
   212  				},
   213  				Peer: node.ID(),
   214  			},
   215  		},
   216  	})
   217  
   218  	if err != nil {
   219  		t.Fatal(err)
   220  	}
   221  }
   222  
   223  func TestStreamerUpstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
   224  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   225  	defer teardown()
   226  	if err != nil {
   227  		t.Fatal(err)
   228  	}
   229  
   230  	stream := NewStream("foo", "", false)
   231  
   232  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   233  		return newTestServer(t), nil
   234  	})
   235  
   236  	node := tester.Nodes[0]
   237  
   238  	err = tester.TestExchanges(p2ptest.Exchange{
   239  		Label: "Subscribe message",
   240  		Triggers: []p2ptest.Trigger{
   241  			{
   242  				Code: 4,
   243  				Msg: &SubscribeMsg{
   244  					Stream:   stream,
   245  					History:  NewRange(5, 8),
   246  					Priority: Top,
   247  				},
   248  				Peer: node.ID(),
   249  			},
   250  		},
   251  		Expects: []p2ptest.Expect{
   252  			{
   253  				Code: 1,
   254  				Msg: &OfferedHashesMsg{
   255  					Stream: stream,
   256  					HandoverProof: &HandoverProof{
   257  						Handover: &Handover{},
   258  					},
   259  					Hashes: make([]byte, HashSize),
   260  					From:   6,
   261  					To:     9,
   262  				},
   263  				Peer: node.ID(),
   264  			},
   265  		},
   266  	})
   267  
   268  	if err != nil {
   269  		t.Fatal(err)
   270  	}
   271  
   272  	err = tester.TestExchanges(p2ptest.Exchange{
   273  		Label: "unsubscribe message",
   274  		Triggers: []p2ptest.Trigger{
   275  			{
   276  				Code: 0,
   277  				Msg: &UnsubscribeMsg{
   278  					Stream: stream,
   279  				},
   280  				Peer: node.ID(),
   281  			},
   282  		},
   283  	})
   284  
   285  	if err != nil {
   286  		t.Fatal(err)
   287  	}
   288  }
   289  
   290  func TestStreamerUpstreamSubscribeUnsubscribeMsgExchangeLive(t *testing.T) {
   291  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   292  	defer teardown()
   293  	if err != nil {
   294  		t.Fatal(err)
   295  	}
   296  
   297  	stream := NewStream("foo", "", true)
   298  
   299  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   300  		return newTestServer(t), nil
   301  	})
   302  
   303  	node := tester.Nodes[0]
   304  
   305  	err = tester.TestExchanges(p2ptest.Exchange{
   306  		Label: "Subscribe message",
   307  		Triggers: []p2ptest.Trigger{
   308  			{
   309  				Code: 4,
   310  				Msg: &SubscribeMsg{
   311  					Stream:   stream,
   312  					Priority: Top,
   313  				},
   314  				Peer: node.ID(),
   315  			},
   316  		},
   317  		Expects: []p2ptest.Expect{
   318  			{
   319  				Code: 1,
   320  				Msg: &OfferedHashesMsg{
   321  					Stream: stream,
   322  					HandoverProof: &HandoverProof{
   323  						Handover: &Handover{},
   324  					},
   325  					Hashes: make([]byte, HashSize),
   326  					From:   1,
   327  					To:     1,
   328  				},
   329  				Peer: node.ID(),
   330  			},
   331  		},
   332  	})
   333  
   334  	if err != nil {
   335  		t.Fatal(err)
   336  	}
   337  
   338  	err = tester.TestExchanges(p2ptest.Exchange{
   339  		Label: "unsubscribe message",
   340  		Triggers: []p2ptest.Trigger{
   341  			{
   342  				Code: 0,
   343  				Msg: &UnsubscribeMsg{
   344  					Stream: stream,
   345  				},
   346  				Peer: node.ID(),
   347  			},
   348  		},
   349  	})
   350  
   351  	if err != nil {
   352  		t.Fatal(err)
   353  	}
   354  }
   355  
   356  func TestStreamerUpstreamSubscribeErrorMsgExchange(t *testing.T) {
   357  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   358  	defer teardown()
   359  	if err != nil {
   360  		t.Fatal(err)
   361  	}
   362  
   363  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   364  		return newTestServer(t), nil
   365  	})
   366  
   367  	stream := NewStream("bar", "", true)
   368  
   369  	node := tester.Nodes[0]
   370  
   371  	err = tester.TestExchanges(p2ptest.Exchange{
   372  		Label: "Subscribe message",
   373  		Triggers: []p2ptest.Trigger{
   374  			{
   375  				Code: 4,
   376  				Msg: &SubscribeMsg{
   377  					Stream:   stream,
   378  					History:  NewRange(5, 8),
   379  					Priority: Top,
   380  				},
   381  				Peer: node.ID(),
   382  			},
   383  		},
   384  		Expects: []p2ptest.Expect{
   385  			{
   386  				Code: 7,
   387  				Msg: &SubscribeErrorMsg{
   388  					Error: "stream bar not registered",
   389  				},
   390  				Peer: node.ID(),
   391  			},
   392  		},
   393  	})
   394  
   395  	if err != nil {
   396  		t.Fatal(err)
   397  	}
   398  }
   399  
   400  func TestStreamerUpstreamSubscribeLiveAndHistory(t *testing.T) {
   401  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   402  	defer teardown()
   403  	if err != nil {
   404  		t.Fatal(err)
   405  	}
   406  
   407  	stream := NewStream("foo", "", true)
   408  
   409  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   410  		return &testServer{
   411  			t: t,
   412  		}, nil
   413  	})
   414  
   415  	node := tester.Nodes[0]
   416  
   417  	err = tester.TestExchanges(p2ptest.Exchange{
   418  		Label: "Subscribe message",
   419  		Triggers: []p2ptest.Trigger{
   420  			{
   421  				Code: 4,
   422  				Msg: &SubscribeMsg{
   423  					Stream:   stream,
   424  					History:  NewRange(5, 8),
   425  					Priority: Top,
   426  				},
   427  				Peer: node.ID(),
   428  			},
   429  		},
   430  		Expects: []p2ptest.Expect{
   431  			{
   432  				Code: 1,
   433  				Msg: &OfferedHashesMsg{
   434  					Stream: NewStream("foo", "", false),
   435  					HandoverProof: &HandoverProof{
   436  						Handover: &Handover{},
   437  					},
   438  					Hashes: make([]byte, HashSize),
   439  					From:   6,
   440  					To:     9,
   441  				},
   442  				Peer: node.ID(),
   443  			},
   444  			{
   445  				Code: 1,
   446  				Msg: &OfferedHashesMsg{
   447  					Stream: stream,
   448  					HandoverProof: &HandoverProof{
   449  						Handover: &Handover{},
   450  					},
   451  					From:   1,
   452  					To:     1,
   453  					Hashes: make([]byte, HashSize),
   454  				},
   455  				Peer: node.ID(),
   456  			},
   457  		},
   458  	})
   459  
   460  	if err != nil {
   461  		t.Fatal(err)
   462  	}
   463  }
   464  
   465  func TestStreamerDownstreamCorruptHashesMsgExchange(t *testing.T) {
   466  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   467  	defer teardown()
   468  	if err != nil {
   469  		t.Fatal(err)
   470  	}
   471  
   472  	stream := NewStream("foo", "", true)
   473  
   474  	var tc *testClient
   475  
   476  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   477  		tc = newTestClient(t)
   478  		return tc, nil
   479  	})
   480  
   481  	node := tester.Nodes[0]
   482  
   483  	err = streamer.Subscribe(node.ID(), stream, NewRange(5, 8), Top)
   484  	if err != nil {
   485  		t.Fatalf("Expected no error, got %v", err)
   486  	}
   487  
   488  	err = tester.TestExchanges(p2ptest.Exchange{
   489  		Label: "Subscribe message",
   490  		Expects: []p2ptest.Expect{
   491  			{
   492  				Code: 4,
   493  				Msg: &SubscribeMsg{
   494  					Stream:   stream,
   495  					History:  NewRange(5, 8),
   496  					Priority: Top,
   497  				},
   498  				Peer: node.ID(),
   499  			},
   500  		},
   501  	},
   502  		p2ptest.Exchange{
   503  			Label: "Corrupt offered hash message",
   504  			Triggers: []p2ptest.Trigger{
   505  				{
   506  					Code: 1,
   507  					Msg: &OfferedHashesMsg{
   508  						HandoverProof: &HandoverProof{
   509  							Handover: &Handover{},
   510  						},
   511  						Hashes: corruptHashes,
   512  						From:   5,
   513  						To:     8,
   514  						Stream: stream,
   515  					},
   516  					Peer: node.ID(),
   517  				},
   518  			},
   519  		})
   520  	if err != nil {
   521  		t.Fatal(err)
   522  	}
   523  
   524  	expectedError := errors.New("Message handler error: (msg code 1): error invalid hashes length (len: 40)")
   525  	if err := tester.TestDisconnected(&p2ptest.Disconnect{Peer: node.ID(), Error: expectedError}); err != nil {
   526  		t.Fatal(err)
   527  	}
   528  }
   529  
   530  func TestStreamerDownstreamOfferedHashesMsgExchange(t *testing.T) {
   531  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   532  	defer teardown()
   533  	if err != nil {
   534  		t.Fatal(err)
   535  	}
   536  
   537  	stream := NewStream("foo", "", true)
   538  
   539  	var tc *testClient
   540  
   541  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   542  		tc = newTestClient(t)
   543  		return tc, nil
   544  	})
   545  
   546  	node := tester.Nodes[0]
   547  
   548  	err = streamer.Subscribe(node.ID(), stream, NewRange(5, 8), Top)
   549  	if err != nil {
   550  		t.Fatalf("Expected no error, got %v", err)
   551  	}
   552  
   553  	err = tester.TestExchanges(p2ptest.Exchange{
   554  		Label: "Subscribe message",
   555  		Expects: []p2ptest.Expect{
   556  			{
   557  				Code: 4,
   558  				Msg: &SubscribeMsg{
   559  					Stream:   stream,
   560  					History:  NewRange(5, 8),
   561  					Priority: Top,
   562  				},
   563  				Peer: node.ID(),
   564  			},
   565  		},
   566  	},
   567  		p2ptest.Exchange{
   568  			Label: "WantedHashes message",
   569  			Triggers: []p2ptest.Trigger{
   570  				{
   571  					Code: 1,
   572  					Msg: &OfferedHashesMsg{
   573  						HandoverProof: &HandoverProof{
   574  							Handover: &Handover{},
   575  						},
   576  						Hashes: hashes,
   577  						From:   5,
   578  						To:     8,
   579  						Stream: stream,
   580  					},
   581  					Peer: node.ID(),
   582  				},
   583  			},
   584  			Expects: []p2ptest.Expect{
   585  				{
   586  					Code: 2,
   587  					Msg: &WantedHashesMsg{
   588  						Stream: stream,
   589  						Want:   []byte{5},
   590  						From:   9,
   591  						To:     0,
   592  					},
   593  					Peer: node.ID(),
   594  				},
   595  			},
   596  		})
   597  	if err != nil {
   598  		t.Fatal(err)
   599  	}
   600  
   601  	if len(tc.receivedHashes) != 3 {
   602  		t.Fatalf("Expected number of received hashes %v, got %v", 3, len(tc.receivedHashes))
   603  	}
   604  
   605  	close(tc.wait0)
   606  
   607  	timeout := time.NewTimer(100 * time.Millisecond)
   608  	defer timeout.Stop()
   609  
   610  	select {
   611  	case <-tc.batchDone:
   612  		t.Fatal("batch done early")
   613  	case <-timeout.C:
   614  	}
   615  
   616  	close(tc.wait2)
   617  
   618  	timeout2 := time.NewTimer(10000 * time.Millisecond)
   619  	defer timeout2.Stop()
   620  
   621  	select {
   622  	case <-tc.batchDone:
   623  	case <-timeout2.C:
   624  		t.Fatal("timeout waiting batchdone call")
   625  	}
   626  
   627  }
   628  
   629  func TestStreamerRequestSubscriptionQuitMsgExchange(t *testing.T) {
   630  	tester, streamer, _, teardown, err := newStreamerTester(t, nil)
   631  	defer teardown()
   632  	if err != nil {
   633  		t.Fatal(err)
   634  	}
   635  
   636  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   637  		return newTestServer(t), nil
   638  	})
   639  
   640  	node := tester.Nodes[0]
   641  
   642  	stream := NewStream("foo", "", true)
   643  	err = streamer.RequestSubscription(node.ID(), stream, NewRange(5, 8), Top)
   644  	if err != nil {
   645  		t.Fatalf("Expected no error, got %v", err)
   646  	}
   647  
   648  	err = tester.TestExchanges(
   649  		p2ptest.Exchange{
   650  			Label: "RequestSubscription message",
   651  			Expects: []p2ptest.Expect{
   652  				{
   653  					Code: 8,
   654  					Msg: &RequestSubscriptionMsg{
   655  						Stream:   stream,
   656  						History:  NewRange(5, 8),
   657  						Priority: Top,
   658  					},
   659  					Peer: node.ID(),
   660  				},
   661  			},
   662  		},
   663  		p2ptest.Exchange{
   664  			Label: "Subscribe message",
   665  			Triggers: []p2ptest.Trigger{
   666  				{
   667  					Code: 4,
   668  					Msg: &SubscribeMsg{
   669  						Stream:   stream,
   670  						History:  NewRange(5, 8),
   671  						Priority: Top,
   672  					},
   673  					Peer: node.ID(),
   674  				},
   675  			},
   676  			Expects: []p2ptest.Expect{
   677  				{
   678  					Code: 1,
   679  					Msg: &OfferedHashesMsg{
   680  						Stream: NewStream("foo", "", false),
   681  						HandoverProof: &HandoverProof{
   682  							Handover: &Handover{},
   683  						},
   684  						Hashes: make([]byte, HashSize),
   685  						From:   6,
   686  						To:     9,
   687  					},
   688  					Peer: node.ID(),
   689  				},
   690  				{
   691  					Code: 1,
   692  					Msg: &OfferedHashesMsg{
   693  						Stream: stream,
   694  						HandoverProof: &HandoverProof{
   695  							Handover: &Handover{},
   696  						},
   697  						From:   1,
   698  						To:     1,
   699  						Hashes: make([]byte, HashSize),
   700  					},
   701  					Peer: node.ID(),
   702  				},
   703  			},
   704  		},
   705  	)
   706  	if err != nil {
   707  		t.Fatal(err)
   708  	}
   709  
   710  	err = streamer.Quit(node.ID(), stream)
   711  	if err != nil {
   712  		t.Fatalf("Expected no error, got %v", err)
   713  	}
   714  
   715  	err = tester.TestExchanges(p2ptest.Exchange{
   716  		Label: "Quit message",
   717  		Expects: []p2ptest.Expect{
   718  			{
   719  				Code: 9,
   720  				Msg: &QuitMsg{
   721  					Stream: stream,
   722  				},
   723  				Peer: node.ID(),
   724  			},
   725  		},
   726  	})
   727  
   728  	if err != nil {
   729  		t.Fatal(err)
   730  	}
   731  
   732  	historyStream := getHistoryStream(stream)
   733  
   734  	err = streamer.Quit(node.ID(), historyStream)
   735  	if err != nil {
   736  		t.Fatalf("Expected no error, got %v", err)
   737  	}
   738  
   739  	err = tester.TestExchanges(p2ptest.Exchange{
   740  		Label: "Quit message",
   741  		Expects: []p2ptest.Expect{
   742  			{
   743  				Code: 9,
   744  				Msg: &QuitMsg{
   745  					Stream: historyStream,
   746  				},
   747  				Peer: node.ID(),
   748  			},
   749  		},
   750  	})
   751  
   752  	if err != nil {
   753  		t.Fatal(err)
   754  	}
   755  }
   756  
   757  // TestMaxPeerServersWithUnsubscribe creates a registry with a limited
   758  // number of stream servers, and performs a test with subscriptions and
   759  // unsubscriptions, checking if unsubscriptions will remove streams,
   760  // leaving place for new streams.
   761  func TestMaxPeerServersWithUnsubscribe(t *testing.T) {
   762  	var maxPeerServers = 6
   763  	tester, streamer, _, teardown, err := newStreamerTester(t, &RegistryOptions{
   764  		MaxPeerServers: maxPeerServers,
   765  	})
   766  	defer teardown()
   767  	if err != nil {
   768  		t.Fatal(err)
   769  	}
   770  
   771  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   772  		return newTestServer(t), nil
   773  	})
   774  
   775  	node := tester.Nodes[0]
   776  
   777  	for i := 0; i < maxPeerServers+10; i++ {
   778  		stream := NewStream("foo", strconv.Itoa(i), true)
   779  
   780  		err = tester.TestExchanges(p2ptest.Exchange{
   781  			Label: "Subscribe message",
   782  			Triggers: []p2ptest.Trigger{
   783  				{
   784  					Code: 4,
   785  					Msg: &SubscribeMsg{
   786  						Stream:   stream,
   787  						Priority: Top,
   788  					},
   789  					Peer: node.ID(),
   790  				},
   791  			},
   792  			Expects: []p2ptest.Expect{
   793  				{
   794  					Code: 1,
   795  					Msg: &OfferedHashesMsg{
   796  						Stream: stream,
   797  						HandoverProof: &HandoverProof{
   798  							Handover: &Handover{},
   799  						},
   800  						Hashes: make([]byte, HashSize),
   801  						From:   1,
   802  						To:     1,
   803  					},
   804  					Peer: node.ID(),
   805  				},
   806  			},
   807  		})
   808  
   809  		if err != nil {
   810  			t.Fatal(err)
   811  		}
   812  
   813  		err = tester.TestExchanges(p2ptest.Exchange{
   814  			Label: "unsubscribe message",
   815  			Triggers: []p2ptest.Trigger{
   816  				{
   817  					Code: 0,
   818  					Msg: &UnsubscribeMsg{
   819  						Stream: stream,
   820  					},
   821  					Peer: node.ID(),
   822  				},
   823  			},
   824  		})
   825  
   826  		if err != nil {
   827  			t.Fatal(err)
   828  		}
   829  	}
   830  }
   831  
   832  // TestMaxPeerServersWithoutUnsubscribe creates a registry with a limited
   833  // number of stream servers, and performs subscriptions to detect subscriptions
   834  // error message exchange.
   835  func TestMaxPeerServersWithoutUnsubscribe(t *testing.T) {
   836  	var maxPeerServers = 6
   837  	tester, streamer, _, teardown, err := newStreamerTester(t, &RegistryOptions{
   838  		MaxPeerServers: maxPeerServers,
   839  	})
   840  	defer teardown()
   841  	if err != nil {
   842  		t.Fatal(err)
   843  	}
   844  
   845  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   846  		return newTestServer(t), nil
   847  	})
   848  
   849  	node := tester.Nodes[0]
   850  
   851  	for i := 0; i < maxPeerServers+10; i++ {
   852  		stream := NewStream("foo", strconv.Itoa(i), true)
   853  
   854  		if i >= maxPeerServers {
   855  			err = tester.TestExchanges(p2ptest.Exchange{
   856  				Label: "Subscribe message",
   857  				Triggers: []p2ptest.Trigger{
   858  					{
   859  						Code: 4,
   860  						Msg: &SubscribeMsg{
   861  							Stream:   stream,
   862  							Priority: Top,
   863  						},
   864  						Peer: node.ID(),
   865  					},
   866  				},
   867  				Expects: []p2ptest.Expect{
   868  					{
   869  						Code: 7,
   870  						Msg: &SubscribeErrorMsg{
   871  							Error: ErrMaxPeerServers.Error(),
   872  						},
   873  						Peer: node.ID(),
   874  					},
   875  				},
   876  			})
   877  
   878  			if err != nil {
   879  				t.Fatal(err)
   880  			}
   881  			continue
   882  		}
   883  
   884  		err = tester.TestExchanges(p2ptest.Exchange{
   885  			Label: "Subscribe message",
   886  			Triggers: []p2ptest.Trigger{
   887  				{
   888  					Code: 4,
   889  					Msg: &SubscribeMsg{
   890  						Stream:   stream,
   891  						Priority: Top,
   892  					},
   893  					Peer: node.ID(),
   894  				},
   895  			},
   896  			Expects: []p2ptest.Expect{
   897  				{
   898  					Code: 1,
   899  					Msg: &OfferedHashesMsg{
   900  						Stream: stream,
   901  						HandoverProof: &HandoverProof{
   902  							Handover: &Handover{},
   903  						},
   904  						Hashes: make([]byte, HashSize),
   905  						From:   1,
   906  						To:     1,
   907  					},
   908  					Peer: node.ID(),
   909  				},
   910  			},
   911  		})
   912  
   913  		if err != nil {
   914  			t.Fatal(err)
   915  		}
   916  	}
   917  }