github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/blockchain/utdbql/utdbql_test.go (about) 1 // Copyright © 2021 Kaleido, Inc. 2 // 3 // SPDX-License-Identifier: Apache-2.0 4 // 5 // Licensed under the Apache License, Version 2.0 (the "License"); 6 // you may not use this file except in compliance with the License. 7 // You may obtain a copy of the License at 8 // 9 // http://www.apache.org/licenses/LICENSE-2.0 10 // 11 // Unless required by applicable law or agreed to in writing, software 12 // distributed under the License is distributed on an "AS IS" BASIS, 13 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 // See the License for the specific language governing permissions and 15 // limitations under the License. 16 17 package utdbql 18 19 import ( 20 "context" 21 "fmt" 22 "testing" 23 "time" 24 25 "github.com/kaleido-io/firefly/internal/config" 26 "github.com/kaleido-io/firefly/mocks/blockchainmocks" 27 "github.com/kaleido-io/firefly/pkg/blockchain" 28 "github.com/kaleido-io/firefly/pkg/fftypes" 29 "github.com/stretchr/testify/assert" 30 "github.com/stretchr/testify/mock" 31 ) 32 33 var utConfPrefix = config.NewPluginConfig("utdbql_unit_tests") 34 35 func resetConf() { 36 config.Reset() 37 u := &UTDBQL{} 38 u.InitPrefix(utConfPrefix) 39 } 40 41 func TestInit(t *testing.T) { 42 u := &UTDBQL{} 43 44 resetConf() 45 utConfPrefix.Set(UTDBQLConfURL, "memory://") 46 47 err := u.Init(context.Background(), utConfPrefix, &blockchainmocks.Callbacks{}) 48 assert.NoError(t, err) 49 50 assert.Equal(t, "utdbql", u.Name()) 51 assert.NotNil(t, u.Capabilities()) 52 u.Close() 53 } 54 55 func TestInitBadURL(t *testing.T) { 56 u := &UTDBQL{} 57 58 resetConf() 59 utConfPrefix.Set(UTDBQLConfURL, "!badness://") 60 61 err := u.Init(context.Background(), utConfPrefix, &blockchainmocks.Callbacks{}) 62 assert.Error(t, err) 63 } 64 65 func TestVerifyIdentitySyntaxOK(t *testing.T) { 66 u := &UTDBQL{} 67 err := u.VerifyIdentitySyntax(context.Background(), &fftypes.Identity{OnChain: "good"}) 68 assert.NoError(t, err) 69 } 70 71 func TestVerifyIdentitySyntaxFail(t *testing.T) { 72 u := &UTDBQL{} 73 err := u.VerifyIdentitySyntax(context.Background(), &fftypes.Identity{OnChain: "!bad"}) 74 assert.Regexp(t, "FF10131", err) 75 } 76 77 func TestVerifyBroadcastBatchTXCycle(t *testing.T) { 78 u := &UTDBQL{} 79 me := &blockchainmocks.Callbacks{} 80 81 sbbEv := make(chan bool, 1) 82 sbb := me.On("BatchPinComplete", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) 83 sbb.RunFn = func(a mock.Arguments) { 84 sbbEv <- true 85 } 86 87 txEv := make(chan bool, 1) 88 tx := me.On("TxSubmissionUpdate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) 89 tx.RunFn = func(a mock.Arguments) { 90 txEv <- true 91 } 92 93 resetConf() 94 utConfPrefix.Set(UTDBQLConfURL, "memory://") 95 96 err := u.Init(context.Background(), utConfPrefix, me) 97 assert.NoError(t, err) 98 defer u.Close() 99 100 u.Start() 101 102 trackingID, err := u.SubmitBatchPin(context.Background(), nil, &fftypes.Identity{OnChain: "id1"}, &blockchain.BatchPin{ 103 TransactionID: fftypes.NewUUID(), 104 BatchID: fftypes.NewUUID(), 105 BatchHash: fftypes.NewRandB32(), 106 BatchPaylodRef: fftypes.NewRandB32(), 107 Contexts: []*fftypes.Bytes32{ 108 fftypes.NewRandB32(), 109 }, 110 }) 111 assert.NoError(t, err) 112 assert.NotEmpty(t, trackingID) 113 114 if err == nil { 115 <-txEv 116 <-sbbEv 117 } 118 119 } 120 121 func TestCloseOnEventDispatchError(t *testing.T) { 122 u := &UTDBQL{} 123 me := &blockchainmocks.Callbacks{} 124 125 sbbEv := make(chan bool, 1) 126 sbb := me.On("BatchPinComplete", mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(fmt.Errorf("Pop")) 127 sbb.RunFn = func(a mock.Arguments) { 128 sbbEv <- true 129 } 130 131 me.On("TxSubmissionUpdate", mock.Anything, mock.Anything, mock.Anything, mock.Anything, mock.Anything).Return(nil) 132 133 resetConf() 134 utConfPrefix.Set(UTDBQLConfURL, "memory://") 135 136 err := u.Init(context.Background(), utConfPrefix, me) 137 assert.NoError(t, err) 138 defer u.Close() 139 140 u.Start() 141 142 trackingID, err := u.SubmitBatchPin(context.Background(), nil, &fftypes.Identity{OnChain: "id1"}, &blockchain.BatchPin{ 143 TransactionID: fftypes.NewUUID(), 144 BatchID: fftypes.NewUUID(), 145 BatchHash: fftypes.NewRandB32(), 146 BatchPaylodRef: fftypes.NewRandB32(), 147 Contexts: []*fftypes.Bytes32{ 148 fftypes.NewRandB32(), 149 }, 150 }) 151 assert.NoError(t, err) 152 assert.NotEmpty(t, trackingID) 153 154 for !u.closed { 155 time.Sleep(1 * time.Microsecond) 156 } 157 } 158 159 func TestVerifyBroadcastDBError(t *testing.T) { 160 u := &UTDBQL{} 161 me := &blockchainmocks.Callbacks{} 162 163 resetConf() 164 utConfPrefix.Set(UTDBQLConfURL, "memory://") 165 166 err := u.Init(context.Background(), utConfPrefix, me) 167 assert.NoError(t, err) 168 u.Close() 169 170 _, err = u.SubmitBatchPin(context.Background(), nil, &fftypes.Identity{OnChain: "id1"}, &blockchain.BatchPin{ 171 TransactionID: fftypes.NewUUID(), 172 BatchID: fftypes.NewUUID(), 173 BatchHash: fftypes.NewRandB32(), 174 BatchPaylodRef: fftypes.NewRandB32(), 175 Contexts: []*fftypes.Bytes32{ 176 fftypes.NewRandB32(), 177 }, 178 }) 179 assert.Error(t, err) 180 181 } 182 183 func TestVerifyEventLoopCancelledContext(t *testing.T) { 184 u := &UTDBQL{} 185 me := &blockchainmocks.Callbacks{} 186 187 resetConf() 188 utConfPrefix.Set(UTDBQLConfURL, "memory://") 189 190 err := u.Init(context.Background(), utConfPrefix, me) 191 assert.NoError(t, err) 192 defer u.Close() 193 194 ctx, cancel := context.WithCancel(context.Background()) 195 cancel() 196 u.ctx = ctx 197 u.eventLoop() // Just confirming it exits 198 } 199 200 func TestVerifyDispatchEventBadData(t *testing.T) { 201 u := &UTDBQL{} 202 me := &blockchainmocks.Callbacks{} 203 204 resetConf() 205 utConfPrefix.Set(UTDBQLConfURL, "memory://") 206 207 err := u.Init(context.Background(), utConfPrefix, me) 208 assert.NoError(t, err) 209 defer u.Close() 210 211 u.dispatchEvent(&utEvent{ 212 txType: utDBQLEventTypeBatchPinComplete, 213 data: []byte(`!json`), 214 }) // Just confirming it handles it 215 }