github.com/braveheart12/just@v0.8.7/testutils/testmessagebus/testmessagebus.go (about) 1 /* 2 * Copyright 2019 Insolar Technologies 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package testmessagebus 18 19 import ( 20 "context" 21 "encoding/gob" 22 "fmt" 23 "io" 24 "reflect" 25 "testing" 26 27 "github.com/pkg/errors" 28 29 "github.com/insolar/insolar/component" 30 "github.com/insolar/insolar/core" 31 "github.com/insolar/insolar/core/delegationtoken" 32 "github.com/insolar/insolar/core/message" 33 "github.com/insolar/insolar/instrumentation/inslogger" 34 "github.com/insolar/insolar/messagebus" 35 "github.com/insolar/insolar/platformpolicy" 36 "github.com/insolar/insolar/testutils" 37 ) 38 39 type TapeRecord struct { 40 Message core.Message 41 Reply core.Reply 42 Error error 43 } 44 45 type TestMessageBus struct { 46 handlers map[core.MessageType]core.MessageHandler 47 pf message.ParcelFactory 48 PulseStorage core.PulseStorage 49 ReadingTape []TapeRecord 50 WritingTape []TapeRecord 51 } 52 53 func (mb *TestMessageBus) NewPlayer(ctx context.Context, reader io.Reader) (core.MessageBus, error) { 54 tape := make([]TapeRecord, 0) 55 enc := gob.NewDecoder(reader) 56 err := enc.Decode(&tape) 57 if err != nil { 58 return nil, err 59 } 60 res := *mb 61 res.ReadingTape = tape 62 return &res, nil 63 } 64 65 func (mb *TestMessageBus) WriteTape(ctx context.Context, writer io.Writer) error { 66 if mb.WritingTape == nil { 67 return errors.New("Not writing message bus") 68 } 69 enc := gob.NewEncoder(writer) 70 err := enc.Encode(mb.WritingTape) 71 if err != nil { 72 return err 73 } 74 75 return nil 76 } 77 78 func (mb *TestMessageBus) NewRecorder(ctx context.Context, currentPulse core.Pulse) (core.MessageBus, error) { 79 tape := make([]TapeRecord, 0) 80 res := *mb 81 res.WritingTape = tape 82 return &res, nil 83 } 84 85 func NewTestMessageBus(t *testing.T) *TestMessageBus { 86 cryptoServiceMock := testutils.NewCryptographyServiceMock(t) 87 cryptoServiceMock.SignFunc = func(p []byte) (r *core.Signature, r1 error) { 88 signature := core.SignatureFromBytes(nil) 89 return &signature, nil 90 } 91 92 delegationTokenFactory := delegationtoken.NewDelegationTokenFactory() 93 94 parcelFactory := messagebus.NewParcelFactory() 95 96 cm := &component.Manager{} 97 cm.Register(platformpolicy.NewPlatformCryptographyScheme()) 98 cm.Inject(delegationTokenFactory, parcelFactory, cryptoServiceMock) 99 100 return &TestMessageBus{handlers: map[core.MessageType]core.MessageHandler{}, pf: parcelFactory} 101 } 102 103 func (mb *TestMessageBus) Register(p core.MessageType, handler core.MessageHandler) error { 104 _, ok := mb.handlers[p] 105 if ok { 106 return errors.New("handler for this type already exists") 107 } 108 109 mb.handlers[p] = handler 110 return nil 111 } 112 113 func (mb *TestMessageBus) ReRegister(p core.MessageType, handler core.MessageHandler) { 114 mb.handlers[p] = handler 115 } 116 117 func (mb *TestMessageBus) MustRegister(p core.MessageType, handler core.MessageHandler) { 118 err := mb.Register(p, handler) 119 if err != nil { 120 panic(err) 121 } 122 } 123 124 func (mb *TestMessageBus) Send(ctx context.Context, m core.Message, _ *core.MessageSendOptions) (core.Reply, error) { 125 if mb.ReadingTape != nil { 126 if len(mb.ReadingTape) == 0 { 127 return nil, errors.Errorf("No expected messages, got %+v", m) 128 } 129 head, tail := mb.ReadingTape[0], mb.ReadingTape[1:] 130 mb.ReadingTape = tail 131 132 inslogger.FromContext(ctx).Debugf("Reading message %+v off the tape", head.Message) 133 134 if !reflect.DeepEqual(head.Message, m) { 135 return nil, errors.Errorf("Message in the tape and sended arn't equal; got: %+v, expected: %+v", m, head.Message) 136 } 137 return head.Reply, head.Error 138 } 139 140 currentPulse, err := mb.PulseStorage.Current(ctx) 141 if err != nil { 142 return nil, err 143 } 144 145 parcel, err := mb.pf.Create(ctx, m, testutils.RandomRef(), nil, core.Pulse{PulseNumber: currentPulse.PulseNumber, Entropy: core.Entropy{}}) 146 if err != nil { 147 return nil, err 148 } 149 t := parcel.Message().Type() 150 handler, ok := mb.handlers[t] 151 if !ok { 152 return nil, errors.New(fmt.Sprint("no handler for message type:", t.String())) 153 } 154 155 ctx = parcel.Context(context.Background()) 156 157 reply, err := handler(ctx, parcel) 158 if mb.WritingTape != nil { 159 // WARNING! The following commented line of code is cursed. 160 // It makes some test (e.g. TestNilResults) hang under the debugger, and we have no idea why. 161 // Don't uncomment unless you solved this mystery. 162 // inslogger.FromContext(ctx).Debugf("Writing message %+v on the tape", m) 163 mb.WritingTape = append(mb.WritingTape, TapeRecord{Message: m, Reply: reply, Error: err}) 164 } 165 166 return reply, err 167 } 168 169 func (mb *TestMessageBus) OnPulse(context.Context, core.Pulse) error { 170 return nil 171 }