github.com/daragao/go-ethereum@v1.8.14-0.20180809141559-45eaef243198/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  	"testing"
    23  	"time"
    24  
    25  	"github.com/ethereum/go-ethereum/crypto/sha3"
    26  	p2ptest "github.com/ethereum/go-ethereum/p2p/testing"
    27  )
    28  
    29  func TestStreamerSubscribe(t *testing.T) {
    30  	tester, streamer, _, teardown, err := newStreamerTester(t)
    31  	defer teardown()
    32  	if err != nil {
    33  		t.Fatal(err)
    34  	}
    35  
    36  	stream := NewStream("foo", "", true)
    37  	err = streamer.Subscribe(tester.IDs[0], stream, NewRange(0, 0), Top)
    38  	if err == nil || err.Error() != "stream foo not registered" {
    39  		t.Fatalf("Expected error %v, got %v", "stream foo not registered", err)
    40  	}
    41  }
    42  
    43  func TestStreamerRequestSubscription(t *testing.T) {
    44  	tester, streamer, _, teardown, err := newStreamerTester(t)
    45  	defer teardown()
    46  	if err != nil {
    47  		t.Fatal(err)
    48  	}
    49  
    50  	stream := NewStream("foo", "", false)
    51  	err = streamer.RequestSubscription(tester.IDs[0], stream, &Range{}, Top)
    52  	if err == nil || err.Error() != "stream foo not registered" {
    53  		t.Fatalf("Expected error %v, got %v", "stream foo not registered", err)
    54  	}
    55  }
    56  
    57  var (
    58  	hash0     = sha3.Sum256([]byte{0})
    59  	hash1     = sha3.Sum256([]byte{1})
    60  	hash2     = sha3.Sum256([]byte{2})
    61  	hashesTmp = append(hash0[:], hash1[:]...)
    62  	hashes    = append(hashesTmp, hash2[:]...)
    63  )
    64  
    65  type testClient struct {
    66  	t              string
    67  	wait0          chan bool
    68  	wait2          chan bool
    69  	batchDone      chan bool
    70  	receivedHashes map[string][]byte
    71  }
    72  
    73  func newTestClient(t string) *testClient {
    74  	return &testClient{
    75  		t:              t,
    76  		wait0:          make(chan bool),
    77  		wait2:          make(chan bool),
    78  		batchDone:      make(chan bool),
    79  		receivedHashes: make(map[string][]byte),
    80  	}
    81  }
    82  
    83  func (self *testClient) NeedData(ctx context.Context, hash []byte) func() {
    84  	self.receivedHashes[string(hash)] = hash
    85  	if bytes.Equal(hash, hash0[:]) {
    86  		return func() {
    87  			<-self.wait0
    88  		}
    89  	} else if bytes.Equal(hash, hash2[:]) {
    90  		return func() {
    91  			<-self.wait2
    92  		}
    93  	}
    94  	return nil
    95  }
    96  
    97  func (self *testClient) BatchDone(Stream, uint64, []byte, []byte) func() (*TakeoverProof, error) {
    98  	close(self.batchDone)
    99  	return nil
   100  }
   101  
   102  func (self *testClient) Close() {}
   103  
   104  type testServer struct {
   105  	t string
   106  }
   107  
   108  func newTestServer(t string) *testServer {
   109  	return &testServer{
   110  		t: t,
   111  	}
   112  }
   113  
   114  func (self *testServer) SetNextBatch(from uint64, to uint64) ([]byte, uint64, uint64, *HandoverProof, error) {
   115  	return make([]byte, HashSize), from + 1, to + 1, nil, nil
   116  }
   117  
   118  func (self *testServer) GetData(context.Context, []byte) ([]byte, error) {
   119  	return nil, nil
   120  }
   121  
   122  func (self *testServer) Close() {
   123  }
   124  
   125  func TestStreamerDownstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
   126  	tester, streamer, _, teardown, err := newStreamerTester(t)
   127  	defer teardown()
   128  	if err != nil {
   129  		t.Fatal(err)
   130  	}
   131  
   132  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   133  		return newTestClient(t), nil
   134  	})
   135  
   136  	peerID := tester.IDs[0]
   137  
   138  	stream := NewStream("foo", "", true)
   139  	err = streamer.Subscribe(peerID, stream, NewRange(5, 8), Top)
   140  	if err != nil {
   141  		t.Fatalf("Expected no error, got %v", err)
   142  	}
   143  
   144  	err = tester.TestExchanges(
   145  		p2ptest.Exchange{
   146  			Label: "Subscribe message",
   147  			Expects: []p2ptest.Expect{
   148  				{
   149  					Code: 4,
   150  					Msg: &SubscribeMsg{
   151  						Stream:   stream,
   152  						History:  NewRange(5, 8),
   153  						Priority: Top,
   154  					},
   155  					Peer: peerID,
   156  				},
   157  			},
   158  		},
   159  		// trigger OfferedHashesMsg to actually create the client
   160  		p2ptest.Exchange{
   161  			Label: "OfferedHashes message",
   162  			Triggers: []p2ptest.Trigger{
   163  				{
   164  					Code: 1,
   165  					Msg: &OfferedHashesMsg{
   166  						HandoverProof: &HandoverProof{
   167  							Handover: &Handover{},
   168  						},
   169  						Hashes: hashes,
   170  						From:   5,
   171  						To:     8,
   172  						Stream: stream,
   173  					},
   174  					Peer: peerID,
   175  				},
   176  			},
   177  			Expects: []p2ptest.Expect{
   178  				{
   179  					Code: 2,
   180  					Msg: &WantedHashesMsg{
   181  						Stream: stream,
   182  						Want:   []byte{5},
   183  						From:   9,
   184  						To:     0,
   185  					},
   186  					Peer: peerID,
   187  				},
   188  			},
   189  		},
   190  	)
   191  	if err != nil {
   192  		t.Fatal(err)
   193  	}
   194  
   195  	err = streamer.Unsubscribe(peerID, stream)
   196  	if err != nil {
   197  		t.Fatalf("Expected no error, got %v", err)
   198  	}
   199  
   200  	err = tester.TestExchanges(p2ptest.Exchange{
   201  		Label: "Unsubscribe message",
   202  		Expects: []p2ptest.Expect{
   203  			{
   204  				Code: 0,
   205  				Msg: &UnsubscribeMsg{
   206  					Stream: stream,
   207  				},
   208  				Peer: peerID,
   209  			},
   210  		},
   211  	})
   212  
   213  	if err != nil {
   214  		t.Fatal(err)
   215  	}
   216  }
   217  
   218  func TestStreamerUpstreamSubscribeUnsubscribeMsgExchange(t *testing.T) {
   219  	tester, streamer, _, teardown, err := newStreamerTester(t)
   220  	defer teardown()
   221  	if err != nil {
   222  		t.Fatal(err)
   223  	}
   224  
   225  	stream := NewStream("foo", "", false)
   226  
   227  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   228  		return newTestServer(t), nil
   229  	})
   230  
   231  	peerID := tester.IDs[0]
   232  
   233  	err = tester.TestExchanges(p2ptest.Exchange{
   234  		Label: "Subscribe message",
   235  		Triggers: []p2ptest.Trigger{
   236  			{
   237  				Code: 4,
   238  				Msg: &SubscribeMsg{
   239  					Stream:   stream,
   240  					History:  NewRange(5, 8),
   241  					Priority: Top,
   242  				},
   243  				Peer: peerID,
   244  			},
   245  		},
   246  		Expects: []p2ptest.Expect{
   247  			{
   248  				Code: 1,
   249  				Msg: &OfferedHashesMsg{
   250  					Stream: stream,
   251  					HandoverProof: &HandoverProof{
   252  						Handover: &Handover{},
   253  					},
   254  					Hashes: make([]byte, HashSize),
   255  					From:   6,
   256  					To:     9,
   257  				},
   258  				Peer: peerID,
   259  			},
   260  		},
   261  	})
   262  
   263  	if err != nil {
   264  		t.Fatal(err)
   265  	}
   266  
   267  	err = tester.TestExchanges(p2ptest.Exchange{
   268  		Label: "unsubscribe message",
   269  		Triggers: []p2ptest.Trigger{
   270  			{
   271  				Code: 0,
   272  				Msg: &UnsubscribeMsg{
   273  					Stream: stream,
   274  				},
   275  				Peer: peerID,
   276  			},
   277  		},
   278  	})
   279  
   280  	if err != nil {
   281  		t.Fatal(err)
   282  	}
   283  }
   284  
   285  func TestStreamerUpstreamSubscribeUnsubscribeMsgExchangeLive(t *testing.T) {
   286  	tester, streamer, _, teardown, err := newStreamerTester(t)
   287  	defer teardown()
   288  	if err != nil {
   289  		t.Fatal(err)
   290  	}
   291  
   292  	stream := NewStream("foo", "", true)
   293  
   294  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   295  		return newTestServer(t), nil
   296  	})
   297  
   298  	peerID := tester.IDs[0]
   299  
   300  	err = tester.TestExchanges(p2ptest.Exchange{
   301  		Label: "Subscribe message",
   302  		Triggers: []p2ptest.Trigger{
   303  			{
   304  				Code: 4,
   305  				Msg: &SubscribeMsg{
   306  					Stream:   stream,
   307  					Priority: Top,
   308  				},
   309  				Peer: peerID,
   310  			},
   311  		},
   312  		Expects: []p2ptest.Expect{
   313  			{
   314  				Code: 1,
   315  				Msg: &OfferedHashesMsg{
   316  					Stream: stream,
   317  					HandoverProof: &HandoverProof{
   318  						Handover: &Handover{},
   319  					},
   320  					Hashes: make([]byte, HashSize),
   321  					From:   1,
   322  					To:     1,
   323  				},
   324  				Peer: peerID,
   325  			},
   326  		},
   327  	})
   328  
   329  	if err != nil {
   330  		t.Fatal(err)
   331  	}
   332  
   333  	err = tester.TestExchanges(p2ptest.Exchange{
   334  		Label: "unsubscribe message",
   335  		Triggers: []p2ptest.Trigger{
   336  			{
   337  				Code: 0,
   338  				Msg: &UnsubscribeMsg{
   339  					Stream: stream,
   340  				},
   341  				Peer: peerID,
   342  			},
   343  		},
   344  	})
   345  
   346  	if err != nil {
   347  		t.Fatal(err)
   348  	}
   349  }
   350  
   351  func TestStreamerUpstreamSubscribeErrorMsgExchange(t *testing.T) {
   352  	tester, streamer, _, teardown, err := newStreamerTester(t)
   353  	defer teardown()
   354  	if err != nil {
   355  		t.Fatal(err)
   356  	}
   357  
   358  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   359  		return newTestServer(t), nil
   360  	})
   361  
   362  	stream := NewStream("bar", "", true)
   363  
   364  	peerID := tester.IDs[0]
   365  
   366  	err = tester.TestExchanges(p2ptest.Exchange{
   367  		Label: "Subscribe message",
   368  		Triggers: []p2ptest.Trigger{
   369  			{
   370  				Code: 4,
   371  				Msg: &SubscribeMsg{
   372  					Stream:   stream,
   373  					History:  NewRange(5, 8),
   374  					Priority: Top,
   375  				},
   376  				Peer: peerID,
   377  			},
   378  		},
   379  		Expects: []p2ptest.Expect{
   380  			{
   381  				Code: 7,
   382  				Msg: &SubscribeErrorMsg{
   383  					Error: "stream bar not registered",
   384  				},
   385  				Peer: peerID,
   386  			},
   387  		},
   388  	})
   389  
   390  	if err != nil {
   391  		t.Fatal(err)
   392  	}
   393  }
   394  
   395  func TestStreamerUpstreamSubscribeLiveAndHistory(t *testing.T) {
   396  	tester, streamer, _, teardown, err := newStreamerTester(t)
   397  	defer teardown()
   398  	if err != nil {
   399  		t.Fatal(err)
   400  	}
   401  
   402  	stream := NewStream("foo", "", true)
   403  
   404  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   405  		return &testServer{
   406  			t: t,
   407  		}, nil
   408  	})
   409  
   410  	peerID := tester.IDs[0]
   411  
   412  	err = tester.TestExchanges(p2ptest.Exchange{
   413  		Label: "Subscribe message",
   414  		Triggers: []p2ptest.Trigger{
   415  			{
   416  				Code: 4,
   417  				Msg: &SubscribeMsg{
   418  					Stream:   stream,
   419  					History:  NewRange(5, 8),
   420  					Priority: Top,
   421  				},
   422  				Peer: peerID,
   423  			},
   424  		},
   425  		Expects: []p2ptest.Expect{
   426  			{
   427  				Code: 1,
   428  				Msg: &OfferedHashesMsg{
   429  					Stream: NewStream("foo", "", false),
   430  					HandoverProof: &HandoverProof{
   431  						Handover: &Handover{},
   432  					},
   433  					Hashes: make([]byte, HashSize),
   434  					From:   6,
   435  					To:     9,
   436  				},
   437  				Peer: peerID,
   438  			},
   439  			{
   440  				Code: 1,
   441  				Msg: &OfferedHashesMsg{
   442  					Stream: stream,
   443  					HandoverProof: &HandoverProof{
   444  						Handover: &Handover{},
   445  					},
   446  					From:   1,
   447  					To:     1,
   448  					Hashes: make([]byte, HashSize),
   449  				},
   450  				Peer: peerID,
   451  			},
   452  		},
   453  	})
   454  
   455  	if err != nil {
   456  		t.Fatal(err)
   457  	}
   458  }
   459  
   460  func TestStreamerDownstreamOfferedHashesMsgExchange(t *testing.T) {
   461  	tester, streamer, _, teardown, err := newStreamerTester(t)
   462  	defer teardown()
   463  	if err != nil {
   464  		t.Fatal(err)
   465  	}
   466  
   467  	stream := NewStream("foo", "", true)
   468  
   469  	var tc *testClient
   470  
   471  	streamer.RegisterClientFunc("foo", func(p *Peer, t string, live bool) (Client, error) {
   472  		tc = newTestClient(t)
   473  		return tc, nil
   474  	})
   475  
   476  	peerID := tester.IDs[0]
   477  
   478  	err = streamer.Subscribe(peerID, stream, NewRange(5, 8), Top)
   479  	if err != nil {
   480  		t.Fatalf("Expected no error, got %v", err)
   481  	}
   482  
   483  	err = tester.TestExchanges(p2ptest.Exchange{
   484  		Label: "Subscribe message",
   485  		Expects: []p2ptest.Expect{
   486  			{
   487  				Code: 4,
   488  				Msg: &SubscribeMsg{
   489  					Stream:   stream,
   490  					History:  NewRange(5, 8),
   491  					Priority: Top,
   492  				},
   493  				Peer: peerID,
   494  			},
   495  		},
   496  	},
   497  		p2ptest.Exchange{
   498  			Label: "WantedHashes message",
   499  			Triggers: []p2ptest.Trigger{
   500  				{
   501  					Code: 1,
   502  					Msg: &OfferedHashesMsg{
   503  						HandoverProof: &HandoverProof{
   504  							Handover: &Handover{},
   505  						},
   506  						Hashes: hashes,
   507  						From:   5,
   508  						To:     8,
   509  						Stream: stream,
   510  					},
   511  					Peer: peerID,
   512  				},
   513  			},
   514  			Expects: []p2ptest.Expect{
   515  				{
   516  					Code: 2,
   517  					Msg: &WantedHashesMsg{
   518  						Stream: stream,
   519  						Want:   []byte{5},
   520  						From:   9,
   521  						To:     0,
   522  					},
   523  					Peer: peerID,
   524  				},
   525  			},
   526  		})
   527  	if err != nil {
   528  		t.Fatal(err)
   529  	}
   530  
   531  	if len(tc.receivedHashes) != 3 {
   532  		t.Fatalf("Expected number of received hashes %v, got %v", 3, len(tc.receivedHashes))
   533  	}
   534  
   535  	close(tc.wait0)
   536  
   537  	timeout := time.NewTimer(100 * time.Millisecond)
   538  	defer timeout.Stop()
   539  
   540  	select {
   541  	case <-tc.batchDone:
   542  		t.Fatal("batch done early")
   543  	case <-timeout.C:
   544  	}
   545  
   546  	close(tc.wait2)
   547  
   548  	timeout2 := time.NewTimer(10000 * time.Millisecond)
   549  	defer timeout2.Stop()
   550  
   551  	select {
   552  	case <-tc.batchDone:
   553  	case <-timeout2.C:
   554  		t.Fatal("timeout waiting batchdone call")
   555  	}
   556  
   557  }
   558  
   559  func TestStreamerRequestSubscriptionQuitMsgExchange(t *testing.T) {
   560  	tester, streamer, _, teardown, err := newStreamerTester(t)
   561  	defer teardown()
   562  	if err != nil {
   563  		t.Fatal(err)
   564  	}
   565  
   566  	streamer.RegisterServerFunc("foo", func(p *Peer, t string, live bool) (Server, error) {
   567  		return newTestServer(t), nil
   568  	})
   569  
   570  	peerID := tester.IDs[0]
   571  
   572  	stream := NewStream("foo", "", true)
   573  	err = streamer.RequestSubscription(peerID, stream, NewRange(5, 8), Top)
   574  	if err != nil {
   575  		t.Fatalf("Expected no error, got %v", err)
   576  	}
   577  
   578  	err = tester.TestExchanges(
   579  		p2ptest.Exchange{
   580  			Label: "RequestSubscription message",
   581  			Expects: []p2ptest.Expect{
   582  				{
   583  					Code: 8,
   584  					Msg: &RequestSubscriptionMsg{
   585  						Stream:   stream,
   586  						History:  NewRange(5, 8),
   587  						Priority: Top,
   588  					},
   589  					Peer: peerID,
   590  				},
   591  			},
   592  		},
   593  		p2ptest.Exchange{
   594  			Label: "Subscribe message",
   595  			Triggers: []p2ptest.Trigger{
   596  				{
   597  					Code: 4,
   598  					Msg: &SubscribeMsg{
   599  						Stream:   stream,
   600  						History:  NewRange(5, 8),
   601  						Priority: Top,
   602  					},
   603  					Peer: peerID,
   604  				},
   605  			},
   606  			Expects: []p2ptest.Expect{
   607  				{
   608  					Code: 1,
   609  					Msg: &OfferedHashesMsg{
   610  						Stream: NewStream("foo", "", false),
   611  						HandoverProof: &HandoverProof{
   612  							Handover: &Handover{},
   613  						},
   614  						Hashes: make([]byte, HashSize),
   615  						From:   6,
   616  						To:     9,
   617  					},
   618  					Peer: peerID,
   619  				},
   620  				{
   621  					Code: 1,
   622  					Msg: &OfferedHashesMsg{
   623  						Stream: stream,
   624  						HandoverProof: &HandoverProof{
   625  							Handover: &Handover{},
   626  						},
   627  						From:   1,
   628  						To:     1,
   629  						Hashes: make([]byte, HashSize),
   630  					},
   631  					Peer: peerID,
   632  				},
   633  			},
   634  		},
   635  	)
   636  	if err != nil {
   637  		t.Fatal(err)
   638  	}
   639  
   640  	err = streamer.Quit(peerID, stream)
   641  	if err != nil {
   642  		t.Fatalf("Expected no error, got %v", err)
   643  	}
   644  
   645  	err = tester.TestExchanges(p2ptest.Exchange{
   646  		Label: "Quit message",
   647  		Expects: []p2ptest.Expect{
   648  			{
   649  				Code: 9,
   650  				Msg: &QuitMsg{
   651  					Stream: stream,
   652  				},
   653  				Peer: peerID,
   654  			},
   655  		},
   656  	})
   657  
   658  	if err != nil {
   659  		t.Fatal(err)
   660  	}
   661  
   662  	historyStream := getHistoryStream(stream)
   663  
   664  	err = streamer.Quit(peerID, historyStream)
   665  	if err != nil {
   666  		t.Fatalf("Expected no error, got %v", err)
   667  	}
   668  
   669  	err = tester.TestExchanges(p2ptest.Exchange{
   670  		Label: "Quit message",
   671  		Expects: []p2ptest.Expect{
   672  			{
   673  				Code: 9,
   674  				Msg: &QuitMsg{
   675  					Stream: historyStream,
   676  				},
   677  				Peer: peerID,
   678  			},
   679  		},
   680  	})
   681  
   682  	if err != nil {
   683  		t.Fatal(err)
   684  	}
   685  }