github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/core/dispatcher/dispatcher_test.go (about) 1 /* 2 Copyright hechain. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package dispatcher_test 8 9 import ( 10 "fmt" 11 "time" 12 13 . "github.com/onsi/ginkgo" 14 . "github.com/onsi/gomega" 15 16 "github.com/hechain20/hechain/core/dispatcher" 17 "github.com/hechain20/hechain/core/dispatcher/mock" 18 19 "github.com/golang/protobuf/proto" 20 "github.com/golang/protobuf/ptypes" 21 "github.com/golang/protobuf/ptypes/timestamp" 22 ) 23 24 type TestReceiver struct{} 25 26 func (tr TestReceiver) GoodFunc(ts *timestamp.Timestamp) (*timestamp.Timestamp, error) { 27 return ptypes.TimestampProto(time.Unix(0, 0)) 28 } 29 30 func (tr TestReceiver) MissingFuncParameters() (*timestamp.Timestamp, error) { 31 return ptypes.TimestampProto(time.Unix(0, 0)) 32 } 33 34 func (tr TestReceiver) NotProtoParameter(foo *string) (*timestamp.Timestamp, error) { 35 return ptypes.TimestampProto(time.Unix(0, 0)) 36 } 37 38 func (tr TestReceiver) NotPointerParameter(foo string) (*timestamp.Timestamp, error) { 39 return ptypes.TimestampProto(time.Unix(0, 0)) 40 } 41 42 func (tr TestReceiver) NoReturnValues(ts *timestamp.Timestamp) {} 43 44 func (tr TestReceiver) NotProtoReturn(ts *timestamp.Timestamp) (string, error) { 45 return "", nil 46 } 47 48 func (tr TestReceiver) NotErrorReturn(ts *timestamp.Timestamp) (*timestamp.Timestamp, string) { 49 return nil, "" 50 } 51 52 func (tr TestReceiver) NilNilReturn(ts *timestamp.Timestamp) (*timestamp.Timestamp, error) { 53 return nil, nil 54 } 55 56 func (tr TestReceiver) ErrorReturned(ts *timestamp.Timestamp) (*timestamp.Timestamp, error) { 57 return nil, fmt.Errorf("fake-error") 58 } 59 60 var _ = Describe("Dispatcher", func() { 61 var ( 62 d *dispatcher.Dispatcher 63 fakeProto *mock.Protobuf 64 ) 65 66 BeforeEach(func() { 67 fakeProto = &mock.Protobuf{} 68 fakeProto.MarshalStub = proto.Marshal 69 fakeProto.UnmarshalStub = proto.Unmarshal 70 71 d = &dispatcher.Dispatcher{ 72 Protobuf: fakeProto, 73 } 74 }) 75 76 Describe("Dispatch", func() { 77 var ( 78 testReceiver TestReceiver 79 inputBytes []byte 80 ) 81 82 BeforeEach(func() { 83 var err error 84 inputBytes, err = proto.Marshal(ptypes.TimestampNow()) 85 Expect(err).NotTo(HaveOccurred()) 86 }) 87 88 It("unmarshals, dispatches to the correct function, and marshals the result", func() { 89 outputBytes, err := d.Dispatch(inputBytes, "GoodFunc", testReceiver) 90 Expect(err).NotTo(HaveOccurred()) 91 ts := ×tamp.Timestamp{} 92 err = proto.Unmarshal(outputBytes, ts) 93 Expect(err).NotTo(HaveOccurred()) 94 gts, err := ptypes.Timestamp(ts) 95 Expect(err).NotTo(HaveOccurred()) 96 Expect(gts).To(Equal(time.Unix(0, 0).UTC())) 97 }) 98 99 Context("when the receiver does not have a method to dispatch to", func() { 100 It("returns an error", func() { 101 _, err := d.Dispatch(inputBytes, "MissingMethod", testReceiver) 102 Expect(err).To(MatchError("receiver dispatcher_test.TestReceiver.MissingMethod does not exist")) 103 }) 104 }) 105 106 Context("when the receiver does not return the right number of parameters", func() { 107 It("returns an error", func() { 108 _, err := d.Dispatch(inputBytes, "MissingFuncParameters", testReceiver) 109 Expect(err).To(MatchError("receiver dispatcher_test.TestReceiver.MissingFuncParameters has 0 parameters but expected 1")) 110 }) 111 }) 112 113 Context("when the receiver does not take a pointer", func() { 114 It("returns an error", func() { 115 _, err := d.Dispatch(inputBytes, "NotPointerParameter", testReceiver) 116 Expect(err).To(MatchError("receiver dispatcher_test.TestReceiver.NotPointerParameter does not accept a pointer as its argument")) 117 }) 118 }) 119 120 Context("when the receiver does not take a protobuf message", func() { 121 It("returns an error", func() { 122 _, err := d.Dispatch(inputBytes, "NotProtoParameter", testReceiver) 123 Expect(err).To(MatchError("receiver dispatcher_test.TestReceiver.NotProtoParameter does not accept a proto.Message as its argument, it is '*string'")) 124 }) 125 }) 126 127 Context("when the input bytes cannot be unmarshaled", func() { 128 It("wraps and returns the error", func() { 129 _, err := d.Dispatch([]byte("garbage"), "GoodFunc", testReceiver) 130 Expect(err).To(MatchError("could not decode input arg for dispatcher_test.TestReceiver.GoodFunc: proto: can't skip unknown wire type 7")) 131 }) 132 }) 133 134 Context("when the receiver does not return the right number of parameters", func() { 135 It("returns an error", func() { 136 _, err := d.Dispatch(inputBytes, "NoReturnValues", testReceiver) 137 Expect(err).To(MatchError("receiver dispatcher_test.TestReceiver.NoReturnValues returns 0 values but expected 2")) 138 }) 139 }) 140 141 Context("when the receiver does not return a proto message as the first return value", func() { 142 It("returns an error", func() { 143 _, err := d.Dispatch(inputBytes, "NotProtoReturn", testReceiver) 144 Expect(err).To(MatchError("receiver dispatcher_test.TestReceiver.NotProtoReturn does not return a an implementor of proto.Message as its first return value")) 145 }) 146 }) 147 148 Context("when the receiver does not return an error as its second return value", func() { 149 It("returns an error", func() { 150 _, err := d.Dispatch(inputBytes, "NotErrorReturn", testReceiver) 151 Expect(err).To(MatchError("receiver dispatcher_test.TestReceiver.NotErrorReturn does not return an error as its second return value")) 152 }) 153 }) 154 155 Context("when the receiver returns nil, nil", func() { 156 It("returns an error", func() { 157 _, err := d.Dispatch(inputBytes, "NilNilReturn", testReceiver) 158 Expect(err).To(MatchError("receiver dispatcher_test.TestReceiver.NilNilReturn returned (nil, nil) which is not allowed")) 159 }) 160 }) 161 162 Context("when the receiver returns an error", func() { 163 It("returns the error", func() { 164 _, err := d.Dispatch(inputBytes, "ErrorReturned", testReceiver) 165 Expect(err).To(MatchError("fake-error")) 166 }) 167 }) 168 169 Context("when the returned output cannot be marshaled", func() { 170 BeforeEach(func() { 171 fakeProto.MarshalReturns(nil, fmt.Errorf("fake-error")) 172 }) 173 174 It("wraps and returns the error", func() { 175 _, err := d.Dispatch(inputBytes, "GoodFunc", testReceiver) 176 Expect(err).To(MatchError("failed to marshal result for dispatcher_test.TestReceiver.GoodFunc: fake-error")) 177 }) 178 }) 179 }) 180 })