github.com/ylsGit/go-ethereum@v1.6.5/node/utils_test.go (about)

     1  // Copyright 2015 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  // Contains a batch of utility type declarations used by the tests. As the node
    18  // operates on unique types, a lot of them are needed to check various features.
    19  
    20  package node
    21  
    22  import (
    23  	"reflect"
    24  
    25  	"github.com/ethereum/go-ethereum/p2p"
    26  	"github.com/ethereum/go-ethereum/rpc"
    27  )
    28  
    29  // NoopService is a trivial implementation of the Service interface.
    30  type NoopService struct{}
    31  
    32  func (s *NoopService) Protocols() []p2p.Protocol { return nil }
    33  func (s *NoopService) APIs() []rpc.API           { return nil }
    34  func (s *NoopService) Start(*p2p.Server) error   { return nil }
    35  func (s *NoopService) Stop() error               { return nil }
    36  
    37  func NewNoopService(*ServiceContext) (Service, error) { return new(NoopService), nil }
    38  
    39  // Set of services all wrapping the base NoopService resulting in the same method
    40  // signatures but different outer types.
    41  type NoopServiceA struct{ NoopService }
    42  type NoopServiceB struct{ NoopService }
    43  type NoopServiceC struct{ NoopService }
    44  type NoopServiceD struct{ NoopService }
    45  
    46  func NewNoopServiceA(*ServiceContext) (Service, error) { return new(NoopServiceA), nil }
    47  func NewNoopServiceB(*ServiceContext) (Service, error) { return new(NoopServiceB), nil }
    48  func NewNoopServiceC(*ServiceContext) (Service, error) { return new(NoopServiceC), nil }
    49  func NewNoopServiceD(*ServiceContext) (Service, error) { return new(NoopServiceD), nil }
    50  
    51  // InstrumentedService is an implementation of Service for which all interface
    52  // methods can be instrumented both return value as well as event hook wise.
    53  type InstrumentedService struct {
    54  	protocols []p2p.Protocol
    55  	apis      []rpc.API
    56  	start     error
    57  	stop      error
    58  
    59  	protocolsHook func()
    60  	startHook     func(*p2p.Server)
    61  	stopHook      func()
    62  }
    63  
    64  func NewInstrumentedService(*ServiceContext) (Service, error) { return new(InstrumentedService), nil }
    65  
    66  func (s *InstrumentedService) Protocols() []p2p.Protocol {
    67  	if s.protocolsHook != nil {
    68  		s.protocolsHook()
    69  	}
    70  	return s.protocols
    71  }
    72  
    73  func (s *InstrumentedService) APIs() []rpc.API {
    74  	return s.apis
    75  }
    76  
    77  func (s *InstrumentedService) Start(server *p2p.Server) error {
    78  	if s.startHook != nil {
    79  		s.startHook(server)
    80  	}
    81  	return s.start
    82  }
    83  
    84  func (s *InstrumentedService) Stop() error {
    85  	if s.stopHook != nil {
    86  		s.stopHook()
    87  	}
    88  	return s.stop
    89  }
    90  
    91  // InstrumentingWrapper is a method to specialize a service constructor returning
    92  // a generic InstrumentedService into one returning a wrapping specific one.
    93  type InstrumentingWrapper func(base ServiceConstructor) ServiceConstructor
    94  
    95  func InstrumentingWrapperMaker(base ServiceConstructor, kind reflect.Type) ServiceConstructor {
    96  	return func(ctx *ServiceContext) (Service, error) {
    97  		obj, err := base(ctx)
    98  		if err != nil {
    99  			return nil, err
   100  		}
   101  		wrapper := reflect.New(kind)
   102  		wrapper.Elem().Field(0).Set(reflect.ValueOf(obj).Elem())
   103  
   104  		return wrapper.Interface().(Service), nil
   105  	}
   106  }
   107  
   108  // Set of services all wrapping the base InstrumentedService resulting in the
   109  // same method signatures but different outer types.
   110  type InstrumentedServiceA struct{ InstrumentedService }
   111  type InstrumentedServiceB struct{ InstrumentedService }
   112  type InstrumentedServiceC struct{ InstrumentedService }
   113  
   114  func InstrumentedServiceMakerA(base ServiceConstructor) ServiceConstructor {
   115  	return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceA{}))
   116  }
   117  
   118  func InstrumentedServiceMakerB(base ServiceConstructor) ServiceConstructor {
   119  	return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceB{}))
   120  }
   121  
   122  func InstrumentedServiceMakerC(base ServiceConstructor) ServiceConstructor {
   123  	return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceC{}))
   124  }
   125  
   126  // OneMethodApi is a single-method API handler to be returned by test services.
   127  type OneMethodApi struct {
   128  	fun func()
   129  }
   130  
   131  func (api *OneMethodApi) TheOneMethod() {
   132  	if api.fun != nil {
   133  		api.fun()
   134  	}
   135  }