github.com/linapex/ethereum-go-chinese@v0.0.0-20190316121929-f8b7a73c3fa1/node/node_test.go (about)

     1  
     2  //<developer>
     3  //    <name>linapex 曹一峰</name>
     4  //    <email>linapex@163.com</email>
     5  //    <wx>superexc</wx>
     6  //    <qqgroup>128148617</qqgroup>
     7  //    <url>https://jsq.ink</url>
     8  //    <role>pku engineer</role>
     9  //    <date>2019-03-16 19:16:40</date>
    10  //</624450102576025600>
    11  
    12  
    13  package node
    14  
    15  import (
    16  	"errors"
    17  	"io/ioutil"
    18  	"os"
    19  	"reflect"
    20  	"testing"
    21  	"time"
    22  
    23  	"github.com/ethereum/go-ethereum/crypto"
    24  	"github.com/ethereum/go-ethereum/p2p"
    25  	"github.com/ethereum/go-ethereum/rpc"
    26  )
    27  
    28  var (
    29  	testNodeKey, _ = crypto.GenerateKey()
    30  )
    31  
    32  func testNodeConfig() *Config {
    33  	return &Config{
    34  		Name: "test node",
    35  		P2P:  p2p.Config{PrivateKey: testNodeKey},
    36  	}
    37  }
    38  
    39  //测试是否可以启动、重新启动和停止空协议堆栈。
    40  func TestNodeLifeCycle(t *testing.T) {
    41  	stack, err := New(testNodeConfig())
    42  	if err != nil {
    43  		t.Fatalf("failed to create protocol stack: %v", err)
    44  	}
    45  //确保停止的节点可以再次停止
    46  	for i := 0; i < 3; i++ {
    47  		if err := stack.Stop(); err != ErrNodeStopped {
    48  			t.Fatalf("iter %d: stop failure mismatch: have %v, want %v", i, err, ErrNodeStopped)
    49  		}
    50  	}
    51  //确保节点可以成功启动,但只能启动一次
    52  	if err := stack.Start(); err != nil {
    53  		t.Fatalf("failed to start node: %v", err)
    54  	}
    55  	if err := stack.Start(); err != ErrNodeRunning {
    56  		t.Fatalf("start failure mismatch: have %v, want %v ", err, ErrNodeRunning)
    57  	}
    58  //确保节点可以任意多次重新启动
    59  	for i := 0; i < 3; i++ {
    60  		if err := stack.Restart(); err != nil {
    61  			t.Fatalf("iter %d: failed to restart node: %v", i, err)
    62  		}
    63  	}
    64  //确保节点可以停止,但只能停止一次
    65  	if err := stack.Stop(); err != nil {
    66  		t.Fatalf("failed to stop node: %v", err)
    67  	}
    68  	if err := stack.Stop(); err != ErrNodeStopped {
    69  		t.Fatalf("stop failure mismatch: have %v, want %v ", err, ErrNodeStopped)
    70  	}
    71  }
    72  
    73  //测试如果data dir已在使用中,则返回适当的错误。
    74  func TestNodeUsedDataDir(t *testing.T) {
    75  //创建用作数据目录的临时文件夹
    76  	dir, err := ioutil.TempDir("", "")
    77  	if err != nil {
    78  		t.Fatalf("failed to create temporary data directory: %v", err)
    79  	}
    80  	defer os.RemoveAll(dir)
    81  
    82  //基于数据目录创建新节点
    83  	original, err := New(&Config{DataDir: dir})
    84  	if err != nil {
    85  		t.Fatalf("failed to create original protocol stack: %v", err)
    86  	}
    87  	if err := original.Start(); err != nil {
    88  		t.Fatalf("failed to start original protocol stack: %v", err)
    89  	}
    90  	defer original.Stop()
    91  
    92  //基于相同的数据目录创建第二个节点并确保失败
    93  	duplicate, err := New(&Config{DataDir: dir})
    94  	if err != nil {
    95  		t.Fatalf("failed to create duplicate protocol stack: %v", err)
    96  	}
    97  	if err := duplicate.Start(); err != ErrDatadirUsed {
    98  		t.Fatalf("duplicate datadir failure mismatch: have %v, want %v", err, ErrDatadirUsed)
    99  	}
   100  }
   101  
   102  //测试是否可以注册服务并捕获重复项。
   103  func TestServiceRegistry(t *testing.T) {
   104  	stack, err := New(testNodeConfig())
   105  	if err != nil {
   106  		t.Fatalf("failed to create protocol stack: %v", err)
   107  	}
   108  //注册一批唯一的服务并确保它们成功启动
   109  	services := []ServiceConstructor{NewNoopServiceA, NewNoopServiceB, NewNoopServiceC}
   110  	for i, constructor := range services {
   111  		if err := stack.Register(constructor); err != nil {
   112  			t.Fatalf("service #%d: registration failed: %v", i, err)
   113  		}
   114  	}
   115  	if err := stack.Start(); err != nil {
   116  		t.Fatalf("failed to start original service stack: %v", err)
   117  	}
   118  	if err := stack.Stop(); err != nil {
   119  		t.Fatalf("failed to stop original service stack: %v", err)
   120  	}
   121  //复制一个服务,然后重试启动节点
   122  	if err := stack.Register(NewNoopServiceB); err != nil {
   123  		t.Fatalf("duplicate registration failed: %v", err)
   124  	}
   125  	if err := stack.Start(); err == nil {
   126  		t.Fatalf("duplicate service started")
   127  	} else {
   128  		if _, ok := err.(*DuplicateServiceError); !ok {
   129  			t.Fatalf("duplicate error mismatch: have %v, want %v", err, DuplicateServiceError{})
   130  		}
   131  	}
   132  }
   133  
   134  //已注册服务的测试将正确启动和停止。
   135  func TestServiceLifeCycle(t *testing.T) {
   136  	stack, err := New(testNodeConfig())
   137  	if err != nil {
   138  		t.Fatalf("failed to create protocol stack: %v", err)
   139  	}
   140  //注册一批生命周期仪表化服务
   141  	services := map[string]InstrumentingWrapper{
   142  		"A": InstrumentedServiceMakerA,
   143  		"B": InstrumentedServiceMakerB,
   144  		"C": InstrumentedServiceMakerC,
   145  	}
   146  	started := make(map[string]bool)
   147  	stopped := make(map[string]bool)
   148  
   149  	for id, maker := range services {
   150  id := id //施工单位关闭
   151  		constructor := func(*ServiceContext) (Service, error) {
   152  			return &InstrumentedService{
   153  				startHook: func(*p2p.Server) { started[id] = true },
   154  				stopHook:  func() { stopped[id] = true },
   155  			}, nil
   156  		}
   157  		if err := stack.Register(maker(constructor)); err != nil {
   158  			t.Fatalf("service %s: registration failed: %v", id, err)
   159  		}
   160  	}
   161  //启动节点并检查所有服务是否都在运行
   162  	if err := stack.Start(); err != nil {
   163  		t.Fatalf("failed to start protocol stack: %v", err)
   164  	}
   165  	for id := range services {
   166  		if !started[id] {
   167  			t.Fatalf("service %s: freshly started service not running", id)
   168  		}
   169  		if stopped[id] {
   170  			t.Fatalf("service %s: freshly started service already stopped", id)
   171  		}
   172  	}
   173  //停止节点并检查所有服务是否已停止
   174  	if err := stack.Stop(); err != nil {
   175  		t.Fatalf("failed to stop protocol stack: %v", err)
   176  	}
   177  	for id := range services {
   178  		if !stopped[id] {
   179  			t.Fatalf("service %s: freshly terminated service still running", id)
   180  		}
   181  	}
   182  }
   183  
   184  //测试服务是否作为新实例干净地重新启动。
   185  func TestServiceRestarts(t *testing.T) {
   186  	stack, err := New(testNodeConfig())
   187  	if err != nil {
   188  		t.Fatalf("failed to create protocol stack: %v", err)
   189  	}
   190  //定义不支持重新启动的服务
   191  	var (
   192  		running bool
   193  		started int
   194  	)
   195  	constructor := func(*ServiceContext) (Service, error) {
   196  		running = false
   197  
   198  		return &InstrumentedService{
   199  			startHook: func(*p2p.Server) {
   200  				if running {
   201  					panic("already running")
   202  				}
   203  				running = true
   204  				started++
   205  			},
   206  		}, nil
   207  	}
   208  //注册服务并启动协议栈
   209  	if err := stack.Register(constructor); err != nil {
   210  		t.Fatalf("failed to register the service: %v", err)
   211  	}
   212  	if err := stack.Start(); err != nil {
   213  		t.Fatalf("failed to start protocol stack: %v", err)
   214  	}
   215  	defer stack.Stop()
   216  
   217  	if !running || started != 1 {
   218  		t.Fatalf("running/started mismatch: have %v/%d, want true/1", running, started)
   219  	}
   220  //重新启动堆栈几次,并检查成功的服务重新启动
   221  	for i := 0; i < 3; i++ {
   222  		if err := stack.Restart(); err != nil {
   223  			t.Fatalf("iter %d: failed to restart stack: %v", i, err)
   224  		}
   225  	}
   226  	if !running || started != 4 {
   227  		t.Fatalf("running/started mismatch: have %v/%d, want true/4", running, started)
   228  	}
   229  }
   230  
   231  //测试如果一个服务未能初始化自身,则没有其他服务
   232  //甚至可以启动。
   233  func TestServiceConstructionAbortion(t *testing.T) {
   234  	stack, err := New(testNodeConfig())
   235  	if err != nil {
   236  		t.Fatalf("failed to create protocol stack: %v", err)
   237  	}
   238  //定义一批好服务
   239  	services := map[string]InstrumentingWrapper{
   240  		"A": InstrumentedServiceMakerA,
   241  		"B": InstrumentedServiceMakerB,
   242  		"C": InstrumentedServiceMakerC,
   243  	}
   244  	started := make(map[string]bool)
   245  	for id, maker := range services {
   246  id := id //施工单位关闭
   247  		constructor := func(*ServiceContext) (Service, error) {
   248  			return &InstrumentedService{
   249  				startHook: func(*p2p.Server) { started[id] = true },
   250  			}, nil
   251  		}
   252  		if err := stack.Register(maker(constructor)); err != nil {
   253  			t.Fatalf("service %s: registration failed: %v", id, err)
   254  		}
   255  	}
   256  //注册无法构造自身的服务
   257  	failure := errors.New("fail")
   258  	failer := func(*ServiceContext) (Service, error) {
   259  		return nil, failure
   260  	}
   261  	if err := stack.Register(failer); err != nil {
   262  		t.Fatalf("failer registration failed: %v", err)
   263  	}
   264  //启动协议栈并确保没有任何服务启动
   265  	for i := 0; i < 100; i++ {
   266  		if err := stack.Start(); err != failure {
   267  			t.Fatalf("iter %d: stack startup failure mismatch: have %v, want %v", i, err, failure)
   268  		}
   269  		for id := range services {
   270  			if started[id] {
   271  				t.Fatalf("service %s: started should not have", id)
   272  			}
   273  			delete(started, id)
   274  		}
   275  	}
   276  }
   277  
   278  //测试如果一个服务未能启动,所有其他服务将在启动之前启动
   279  //关闭。
   280  func TestServiceStartupAbortion(t *testing.T) {
   281  	stack, err := New(testNodeConfig())
   282  	if err != nil {
   283  		t.Fatalf("failed to create protocol stack: %v", err)
   284  	}
   285  //注册一批优质服务
   286  	services := map[string]InstrumentingWrapper{
   287  		"A": InstrumentedServiceMakerA,
   288  		"B": InstrumentedServiceMakerB,
   289  		"C": InstrumentedServiceMakerC,
   290  	}
   291  	started := make(map[string]bool)
   292  	stopped := make(map[string]bool)
   293  
   294  	for id, maker := range services {
   295  id := id //施工单位关闭
   296  		constructor := func(*ServiceContext) (Service, error) {
   297  			return &InstrumentedService{
   298  				startHook: func(*p2p.Server) { started[id] = true },
   299  				stopHook:  func() { stopped[id] = true },
   300  			}, nil
   301  		}
   302  		if err := stack.Register(maker(constructor)); err != nil {
   303  			t.Fatalf("service %s: registration failed: %v", id, err)
   304  		}
   305  	}
   306  //注册无法启动的服务
   307  	failure := errors.New("fail")
   308  	failer := func(*ServiceContext) (Service, error) {
   309  		return &InstrumentedService{
   310  			start: failure,
   311  		}, nil
   312  	}
   313  	if err := stack.Register(failer); err != nil {
   314  		t.Fatalf("failer registration failed: %v", err)
   315  	}
   316  //启动协议栈并确保所有启动的服务都停止
   317  	for i := 0; i < 100; i++ {
   318  		if err := stack.Start(); err != failure {
   319  			t.Fatalf("iter %d: stack startup failure mismatch: have %v, want %v", i, err, failure)
   320  		}
   321  		for id := range services {
   322  			if started[id] && !stopped[id] {
   323  				t.Fatalf("service %s: started but not stopped", id)
   324  			}
   325  			delete(started, id)
   326  			delete(stopped, id)
   327  		}
   328  	}
   329  }
   330  
   331  //测试即使注册的服务无法完全关闭,它也会
   332  //不会影响其余的关机调用。
   333  func TestServiceTerminationGuarantee(t *testing.T) {
   334  	stack, err := New(testNodeConfig())
   335  	if err != nil {
   336  		t.Fatalf("failed to create protocol stack: %v", err)
   337  	}
   338  //注册一批优质服务
   339  	services := map[string]InstrumentingWrapper{
   340  		"A": InstrumentedServiceMakerA,
   341  		"B": InstrumentedServiceMakerB,
   342  		"C": InstrumentedServiceMakerC,
   343  	}
   344  	started := make(map[string]bool)
   345  	stopped := make(map[string]bool)
   346  
   347  	for id, maker := range services {
   348  id := id //施工单位关闭
   349  		constructor := func(*ServiceContext) (Service, error) {
   350  			return &InstrumentedService{
   351  				startHook: func(*p2p.Server) { started[id] = true },
   352  				stopHook:  func() { stopped[id] = true },
   353  			}, nil
   354  		}
   355  		if err := stack.Register(maker(constructor)); err != nil {
   356  			t.Fatalf("service %s: registration failed: %v", id, err)
   357  		}
   358  	}
   359  //注册一个无法完全关闭的服务
   360  	failure := errors.New("fail")
   361  	failer := func(*ServiceContext) (Service, error) {
   362  		return &InstrumentedService{
   363  			stop: failure,
   364  		}, nil
   365  	}
   366  	if err := stack.Register(failer); err != nil {
   367  		t.Fatalf("failer registration failed: %v", err)
   368  	}
   369  //启动协议栈,并确保失败的关机终止所有
   370  	for i := 0; i < 100; i++ {
   371  //启动堆栈并确保全部联机
   372  		if err := stack.Start(); err != nil {
   373  			t.Fatalf("iter %d: failed to start protocol stack: %v", i, err)
   374  		}
   375  		for id := range services {
   376  			if !started[id] {
   377  				t.Fatalf("iter %d, service %s: service not running", i, id)
   378  			}
   379  			if stopped[id] {
   380  				t.Fatalf("iter %d, service %s: service already stopped", i, id)
   381  			}
   382  		}
   383  //停止堆栈,验证故障并检查所有终端
   384  		err := stack.Stop()
   385  		if err, ok := err.(*StopError); !ok {
   386  			t.Fatalf("iter %d: termination failure mismatch: have %v, want StopError", i, err)
   387  		} else {
   388  			failer := reflect.TypeOf(&InstrumentedService{})
   389  			if err.Services[failer] != failure {
   390  				t.Fatalf("iter %d: failer termination failure mismatch: have %v, want %v", i, err.Services[failer], failure)
   391  			}
   392  			if len(err.Services) != 1 {
   393  				t.Fatalf("iter %d: failure count mismatch: have %d, want %d", i, len(err.Services), 1)
   394  			}
   395  		}
   396  		for id := range services {
   397  			if !stopped[id] {
   398  				t.Fatalf("iter %d, service %s: service not terminated", i, id)
   399  			}
   400  			delete(started, id)
   401  			delete(stopped, id)
   402  		}
   403  	}
   404  }
   405  
   406  //TestServiceRetrieval测试可以检索单个服务。
   407  func TestServiceRetrieval(t *testing.T) {
   408  //创建一个简单的堆栈并注册两种服务类型
   409  	stack, err := New(testNodeConfig())
   410  	if err != nil {
   411  		t.Fatalf("failed to create protocol stack: %v", err)
   412  	}
   413  	if err := stack.Register(NewNoopService); err != nil {
   414  		t.Fatalf("noop service registration failed: %v", err)
   415  	}
   416  	if err := stack.Register(NewInstrumentedService); err != nil {
   417  		t.Fatalf("instrumented service registration failed: %v", err)
   418  	}
   419  //确保在启动之前无法检索任何服务
   420  	var noopServ *NoopService
   421  	if err := stack.Service(&noopServ); err != ErrNodeStopped {
   422  		t.Fatalf("noop service retrieval mismatch: have %v, want %v", err, ErrNodeStopped)
   423  	}
   424  	var instServ *InstrumentedService
   425  	if err := stack.Service(&instServ); err != ErrNodeStopped {
   426  		t.Fatalf("instrumented service retrieval mismatch: have %v, want %v", err, ErrNodeStopped)
   427  	}
   428  //启动堆栈并确保现在可以检索所有内容
   429  	if err := stack.Start(); err != nil {
   430  		t.Fatalf("failed to start stack: %v", err)
   431  	}
   432  	defer stack.Stop()
   433  
   434  	if err := stack.Service(&noopServ); err != nil {
   435  		t.Fatalf("noop service retrieval mismatch: have %v, want %v", err, nil)
   436  	}
   437  	if err := stack.Service(&instServ); err != nil {
   438  		t.Fatalf("instrumented service retrieval mismatch: have %v, want %v", err, nil)
   439  	}
   440  }
   441  
   442  //测试由单个服务定义的所有协议是否启动。
   443  func TestProtocolGather(t *testing.T) {
   444  	stack, err := New(testNodeConfig())
   445  	if err != nil {
   446  		t.Fatalf("failed to create protocol stack: %v", err)
   447  	}
   448  //用一些已配置的协议数注册一批服务
   449  	services := map[string]struct {
   450  		Count int
   451  		Maker InstrumentingWrapper
   452  	}{
   453  		"zero": {0, InstrumentedServiceMakerA},
   454  		"one":  {1, InstrumentedServiceMakerB},
   455  		"many": {10, InstrumentedServiceMakerC},
   456  	}
   457  	for id, config := range services {
   458  		protocols := make([]p2p.Protocol, config.Count)
   459  		for i := 0; i < len(protocols); i++ {
   460  			protocols[i].Name = id
   461  			protocols[i].Version = uint(i)
   462  		}
   463  		constructor := func(*ServiceContext) (Service, error) {
   464  			return &InstrumentedService{
   465  				protocols: protocols,
   466  			}, nil
   467  		}
   468  		if err := stack.Register(config.Maker(constructor)); err != nil {
   469  			t.Fatalf("service %s: registration failed: %v", id, err)
   470  		}
   471  	}
   472  //启动服务并确保所有协议成功启动
   473  	if err := stack.Start(); err != nil {
   474  		t.Fatalf("failed to start protocol stack: %v", err)
   475  	}
   476  	defer stack.Stop()
   477  
   478  	protocols := stack.Server().Protocols
   479  	if len(protocols) != 11 {
   480  		t.Fatalf("mismatching number of protocols launched: have %d, want %d", len(protocols), 26)
   481  	}
   482  	for id, config := range services {
   483  		for ver := 0; ver < config.Count; ver++ {
   484  			launched := false
   485  			for i := 0; i < len(protocols); i++ {
   486  				if protocols[i].Name == id && protocols[i].Version == uint(ver) {
   487  					launched = true
   488  					break
   489  				}
   490  			}
   491  			if !launched {
   492  				t.Errorf("configured protocol not launched: %s v%d", id, ver)
   493  			}
   494  		}
   495  	}
   496  }
   497  
   498  //测试由单个服务定义的所有API是否公开。
   499  func TestAPIGather(t *testing.T) {
   500  	stack, err := New(testNodeConfig())
   501  	if err != nil {
   502  		t.Fatalf("failed to create protocol stack: %v", err)
   503  	}
   504  //用一些已配置的API注册一批服务
   505  	calls := make(chan string, 1)
   506  	makeAPI := func(result string) *OneMethodAPI {
   507  		return &OneMethodAPI{fun: func() { calls <- result }}
   508  	}
   509  	services := map[string]struct {
   510  		APIs  []rpc.API
   511  		Maker InstrumentingWrapper
   512  	}{
   513  		"Zero APIs": {
   514  			[]rpc.API{}, InstrumentedServiceMakerA},
   515  		"Single API": {
   516  			[]rpc.API{
   517  				{Namespace: "single", Version: "1", Service: makeAPI("single.v1"), Public: true},
   518  			}, InstrumentedServiceMakerB},
   519  		"Many APIs": {
   520  			[]rpc.API{
   521  				{Namespace: "multi", Version: "1", Service: makeAPI("multi.v1"), Public: true},
   522  				{Namespace: "multi.v2", Version: "2", Service: makeAPI("multi.v2"), Public: true},
   523  				{Namespace: "multi.v2.nested", Version: "2", Service: makeAPI("multi.v2.nested"), Public: true},
   524  			}, InstrumentedServiceMakerC},
   525  	}
   526  
   527  	for id, config := range services {
   528  		config := config
   529  		constructor := func(*ServiceContext) (Service, error) {
   530  			return &InstrumentedService{apis: config.APIs}, nil
   531  		}
   532  		if err := stack.Register(config.Maker(constructor)); err != nil {
   533  			t.Fatalf("service %s: registration failed: %v", id, err)
   534  		}
   535  	}
   536  //启动服务并确保所有API成功启动
   537  	if err := stack.Start(); err != nil {
   538  		t.Fatalf("failed to start protocol stack: %v", err)
   539  	}
   540  	defer stack.Stop()
   541  
   542  //连接到RPC服务器并验证各种已注册的终结点
   543  	client, err := stack.Attach()
   544  	if err != nil {
   545  		t.Fatalf("failed to connect to the inproc API server: %v", err)
   546  	}
   547  	defer client.Close()
   548  
   549  	tests := []struct {
   550  		Method string
   551  		Result string
   552  	}{
   553  		{"single_theOneMethod", "single.v1"},
   554  		{"multi_theOneMethod", "multi.v1"},
   555  		{"multi.v2_theOneMethod", "multi.v2"},
   556  		{"multi.v2.nested_theOneMethod", "multi.v2.nested"},
   557  	}
   558  	for i, test := range tests {
   559  		if err := client.Call(nil, test.Method); err != nil {
   560  			t.Errorf("test %d: API request failed: %v", i, err)
   561  		}
   562  		select {
   563  		case result := <-calls:
   564  			if result != test.Result {
   565  				t.Errorf("test %d: result mismatch: have %s, want %s", i, result, test.Result)
   566  			}
   567  		case <-time.After(time.Second):
   568  			t.Fatalf("test %d: rpc execution timeout", i)
   569  		}
   570  	}
   571  }
   572