github.com/SmartMeshFoundation/Spectrum@v0.0.0-20220621030607-452a266fee1e/node/utils_test.go (about) 1 // Copyright 2015 The Spectrum Authors 2 // This file is part of the Spectrum library. 3 // 4 // The Spectrum 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 Spectrum 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 Spectrum 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/SmartMeshFoundation/Spectrum/p2p" 26 "github.com/SmartMeshFoundation/Spectrum/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 45 func NewNoopServiceA(*ServiceContext) (Service, error) { return new(NoopServiceA), nil } 46 func NewNoopServiceB(*ServiceContext) (Service, error) { return new(NoopServiceB), nil } 47 func NewNoopServiceC(*ServiceContext) (Service, error) { return new(NoopServiceC), nil } 48 49 // InstrumentedService is an implementation of Service for which all interface 50 // methods can be instrumented both return value as well as event hook wise. 51 type InstrumentedService struct { 52 protocols []p2p.Protocol 53 apis []rpc.API 54 start error 55 stop error 56 57 protocolsHook func() 58 startHook func(*p2p.Server) 59 stopHook func() 60 } 61 62 func NewInstrumentedService(*ServiceContext) (Service, error) { return new(InstrumentedService), nil } 63 64 func (s *InstrumentedService) Protocols() []p2p.Protocol { 65 if s.protocolsHook != nil { 66 s.protocolsHook() 67 } 68 return s.protocols 69 } 70 71 func (s *InstrumentedService) APIs() []rpc.API { 72 return s.apis 73 } 74 75 func (s *InstrumentedService) Start(server *p2p.Server) error { 76 if s.startHook != nil { 77 s.startHook(server) 78 } 79 return s.start 80 } 81 82 func (s *InstrumentedService) Stop() error { 83 if s.stopHook != nil { 84 s.stopHook() 85 } 86 return s.stop 87 } 88 89 // InstrumentingWrapper is a method to specialize a service constructor returning 90 // a generic InstrumentedService into one returning a wrapping specific one. 91 type InstrumentingWrapper func(base ServiceConstructor) ServiceConstructor 92 93 func InstrumentingWrapperMaker(base ServiceConstructor, kind reflect.Type) ServiceConstructor { 94 return func(ctx *ServiceContext) (Service, error) { 95 obj, err := base(ctx) 96 if err != nil { 97 return nil, err 98 } 99 wrapper := reflect.New(kind) 100 wrapper.Elem().Field(0).Set(reflect.ValueOf(obj).Elem()) 101 102 return wrapper.Interface().(Service), nil 103 } 104 } 105 106 // Set of services all wrapping the base InstrumentedService resulting in the 107 // same method signatures but different outer types. 108 type InstrumentedServiceA struct{ InstrumentedService } 109 type InstrumentedServiceB struct{ InstrumentedService } 110 type InstrumentedServiceC struct{ InstrumentedService } 111 112 func InstrumentedServiceMakerA(base ServiceConstructor) ServiceConstructor { 113 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceA{})) 114 } 115 116 func InstrumentedServiceMakerB(base ServiceConstructor) ServiceConstructor { 117 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceB{})) 118 } 119 120 func InstrumentedServiceMakerC(base ServiceConstructor) ServiceConstructor { 121 return InstrumentingWrapperMaker(base, reflect.TypeOf(InstrumentedServiceC{})) 122 } 123 124 // OneMethodApi is a single-method API handler to be returned by test services. 125 type OneMethodApi struct { 126 fun func() 127 } 128 129 func (api *OneMethodApi) TheOneMethod() { 130 if api.fun != nil { 131 api.fun() 132 } 133 }