github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/events/dx_callbacks_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 events 18 19 import ( 20 "encoding/json" 21 "fmt" 22 "testing" 23 24 "github.com/kaleido-io/firefly/mocks/databasemocks" 25 "github.com/kaleido-io/firefly/mocks/dataexchangemocks" 26 "github.com/kaleido-io/firefly/pkg/fftypes" 27 "github.com/stretchr/testify/mock" 28 ) 29 30 func TestMessageReceiveOK(t *testing.T) { 31 em, cancel := newTestEventManager(t) 32 defer cancel() 33 34 batch := &fftypes.Batch{ 35 ID: nil, // so that we only test up to persistBatch which will return a non-retry error 36 Author: "signingOrg", 37 } 38 b, _ := json.Marshal(batch) 39 40 mdi := em.database.(*databasemocks.Plugin) 41 mdx := &dataexchangemocks.Plugin{} 42 mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{ 43 {Name: "node1", Owner: "parentOrg"}, 44 }, nil) 45 mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{ 46 Identity: "signingOrg", Parent: "parentOrg", 47 }, nil) 48 mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(&fftypes.Organization{ 49 Identity: "parentOrg", 50 }, nil) 51 em.MessageReceived(mdx, "peer1", b) 52 53 mdi.AssertExpectations(t) 54 mdx.AssertExpectations(t) 55 } 56 57 func TestMessageReceivePersistBatchError(t *testing.T) { 58 em, cancel := newTestEventManager(t) 59 cancel() // retryable error 60 61 batch := &fftypes.Batch{ 62 ID: fftypes.NewUUID(), 63 Author: "signingOrg", 64 Payload: fftypes.BatchPayload{ 65 TX: fftypes.TransactionRef{ 66 ID: fftypes.NewUUID(), 67 }, 68 }, 69 } 70 batch.Hash = batch.Payload.Hash() 71 b, _ := json.Marshal(batch) 72 73 mdi := em.database.(*databasemocks.Plugin) 74 mdx := &dataexchangemocks.Plugin{} 75 mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{ 76 {Name: "node1", Owner: "parentOrg"}, 77 }, nil) 78 mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{ 79 Identity: "signingOrg", Parent: "parentOrg", 80 }, nil) 81 mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(&fftypes.Organization{ 82 Identity: "parentOrg", 83 }, nil) 84 mdi.On("UpsertBatch", em.ctx, mock.Anything, true, false).Return(fmt.Errorf("pop")) 85 em.MessageReceived(mdx, "peer1", b) 86 87 mdi.AssertExpectations(t) 88 mdx.AssertExpectations(t) 89 } 90 91 func TestMessageReceivedBadData(t *testing.T) { 92 em, cancel := newTestEventManager(t) 93 defer cancel() 94 95 mdx := &dataexchangemocks.Plugin{} 96 em.MessageReceived(mdx, "peer1", []byte(`!{}`)) 97 } 98 99 func TestMessageReceiveNodeLookupError(t *testing.T) { 100 em, cancel := newTestEventManager(t) 101 cancel() // to stop retry 102 103 batch := &fftypes.Batch{} 104 b, _ := json.Marshal(batch) 105 106 mdi := em.database.(*databasemocks.Plugin) 107 mdx := &dataexchangemocks.Plugin{} 108 mdi.On("GetNodes", em.ctx, mock.Anything).Return(nil, fmt.Errorf("pop")) 109 em.MessageReceived(mdx, "peer1", b) 110 } 111 112 func TestMessageReceiveNodeNotFound(t *testing.T) { 113 em, cancel := newTestEventManager(t) 114 defer cancel() 115 116 batch := &fftypes.Batch{} 117 b, _ := json.Marshal(batch) 118 119 mdi := em.database.(*databasemocks.Plugin) 120 mdx := &dataexchangemocks.Plugin{} 121 mdi.On("GetNodes", em.ctx, mock.Anything).Return(nil, nil) 122 em.MessageReceived(mdx, "peer1", b) 123 } 124 125 func TestMessageReceiveAuthorLookupError(t *testing.T) { 126 em, cancel := newTestEventManager(t) 127 cancel() // to stop retry 128 129 batch := &fftypes.Batch{} 130 b, _ := json.Marshal(batch) 131 132 mdi := em.database.(*databasemocks.Plugin) 133 mdx := &dataexchangemocks.Plugin{} 134 mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{ 135 {Name: "node1", Owner: "org1"}, 136 }, nil) 137 mdi.On("GetOrganizationByIdentity", em.ctx, mock.Anything).Return(nil, fmt.Errorf("pop")) 138 em.MessageReceived(mdx, "peer1", b) 139 } 140 141 func TestMessageReceiveAuthorNotFound(t *testing.T) { 142 em, cancel := newTestEventManager(t) 143 defer cancel() 144 145 batch := &fftypes.Batch{} 146 b, _ := json.Marshal(batch) 147 148 mdi := em.database.(*databasemocks.Plugin) 149 mdx := &dataexchangemocks.Plugin{} 150 mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{ 151 {Name: "node1", Owner: "org1"}, 152 }, nil) 153 mdi.On("GetOrganizationByIdentity", em.ctx, mock.Anything).Return(nil, nil) 154 em.MessageReceived(mdx, "peer1", b) 155 } 156 157 func TestMessageReceiveGetCandidateOrgFail(t *testing.T) { 158 em, cancel := newTestEventManager(t) 159 cancel() // retryable error so we need to break the loop 160 161 batch := &fftypes.Batch{ 162 ID: nil, // so that we only test up to persistBatch which will return a non-retry error 163 Author: "signingOrg", 164 } 165 b, _ := json.Marshal(batch) 166 167 mdi := em.database.(*databasemocks.Plugin) 168 mdx := &dataexchangemocks.Plugin{} 169 mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{ 170 {Name: "node1", Owner: "parentOrg"}, 171 }, nil) 172 mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{ 173 Identity: "signingOrg", Parent: "parentOrg", 174 }, nil) 175 mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(nil, fmt.Errorf("pop")) 176 em.MessageReceived(mdx, "peer1", b) 177 178 mdi.AssertExpectations(t) 179 mdx.AssertExpectations(t) 180 } 181 182 func TestMessageReceiveGetCandidateOrgNotFound(t *testing.T) { 183 em, cancel := newTestEventManager(t) 184 defer cancel() 185 186 batch := &fftypes.Batch{ 187 ID: nil, // so that we only test up to persistBatch which will return a non-retry error 188 Author: "signingOrg", 189 } 190 b, _ := json.Marshal(batch) 191 192 mdi := em.database.(*databasemocks.Plugin) 193 mdx := &dataexchangemocks.Plugin{} 194 mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{ 195 {Name: "node1", Owner: "parentOrg"}, 196 }, nil) 197 mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{ 198 Identity: "signingOrg", Parent: "parentOrg", 199 }, nil) 200 mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(nil, nil) 201 em.MessageReceived(mdx, "peer1", b) 202 203 mdi.AssertExpectations(t) 204 mdx.AssertExpectations(t) 205 } 206 207 func TestMessageReceiveGetCandidateOrgNotMatch(t *testing.T) { 208 em, cancel := newTestEventManager(t) 209 defer cancel() 210 211 batch := &fftypes.Batch{ 212 ID: nil, // so that we only test up to persistBatch which will return a non-retry error 213 Author: "signingOrg", 214 } 215 b, _ := json.Marshal(batch) 216 217 mdi := em.database.(*databasemocks.Plugin) 218 mdx := &dataexchangemocks.Plugin{} 219 mdi.On("GetNodes", em.ctx, mock.Anything).Return([]*fftypes.Node{ 220 {Name: "node1", Owner: "another"}, 221 }, nil) 222 mdi.On("GetOrganizationByIdentity", em.ctx, "signingOrg").Return(&fftypes.Organization{ 223 Identity: "signingOrg", Parent: "parentOrg", 224 }, nil) 225 mdi.On("GetOrganizationByIdentity", em.ctx, "parentOrg").Return(&fftypes.Organization{ 226 Identity: "parentOrg", 227 }, nil) 228 em.MessageReceived(mdx, "peer1", b) 229 230 mdi.AssertExpectations(t) 231 mdx.AssertExpectations(t) 232 } 233 234 func TestBLOBReceivedNoop(t *testing.T) { 235 em, cancel := newTestEventManager(t) 236 defer cancel() 237 238 mdx := &dataexchangemocks.Plugin{} 239 u := fftypes.NewUUID() 240 em.BLOBReceived(mdx, "peer1", "ns1", *u) 241 } 242 243 func TestTransferResultOk(t *testing.T) { 244 em, cancel := newTestEventManager(t) 245 defer cancel() 246 247 mdi := em.database.(*databasemocks.Plugin) 248 id := fftypes.NewUUID() 249 mdi.On("GetOperations", mock.Anything, mock.Anything).Return([]*fftypes.Operation{ 250 { 251 ID: id, 252 BackendID: "tracking12345", 253 }, 254 }, nil) 255 mdi.On("UpdateOperation", mock.Anything, id, mock.Anything).Return(nil) 256 257 mdx := &dataexchangemocks.Plugin{} 258 mdx.On("Name").Return("utdx") 259 em.TransferResult(mdx, "tracking12345", fftypes.OpStatusFailed, "error info", fftypes.JSONObject{"extra": "info"}) 260 261 } 262 263 func TestTransferResultNotFound(t *testing.T) { 264 em, cancel := newTestEventManager(t) 265 cancel() // avoid retries 266 267 mdi := em.database.(*databasemocks.Plugin) 268 mdi.On("GetOperations", mock.Anything, mock.Anything).Return([]*fftypes.Operation{}, nil) 269 270 mdx := &dataexchangemocks.Plugin{} 271 mdx.On("Name").Return("utdx") 272 em.TransferResult(mdx, "tracking12345", fftypes.OpStatusFailed, "error info", fftypes.JSONObject{"extra": "info"}) 273 274 } 275 276 func TestTransferUpdateFail(t *testing.T) { 277 em, cancel := newTestEventManager(t) 278 defer cancel() 279 280 mdi := em.database.(*databasemocks.Plugin) 281 id := fftypes.NewUUID() 282 mdi.On("GetOperations", mock.Anything, mock.Anything).Return([]*fftypes.Operation{ 283 { 284 ID: id, 285 BackendID: "tracking12345", 286 }, 287 }, nil) 288 mdi.On("UpdateOperation", mock.Anything, id, mock.Anything).Return(fmt.Errorf("pop")) 289 290 mdx := &dataexchangemocks.Plugin{} 291 mdx.On("Name").Return("utdx") 292 em.TransferResult(mdx, "tracking12345", fftypes.OpStatusFailed, "error info", fftypes.JSONObject{"extra": "info"}) 293 294 }