github.com/kaleido-io/firefly@v0.0.0-20210622132723-8b4b6aacb971/internal/orchestrator/orchestrator_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 orchestrator 18 19 import ( 20 "context" 21 "fmt" 22 "testing" 23 24 "github.com/kaleido-io/firefly/internal/config" 25 "github.com/kaleido-io/firefly/mocks/batchmocks" 26 "github.com/kaleido-io/firefly/mocks/blockchainmocks" 27 "github.com/kaleido-io/firefly/mocks/broadcastmocks" 28 "github.com/kaleido-io/firefly/mocks/databasemocks" 29 "github.com/kaleido-io/firefly/mocks/dataexchangemocks" 30 "github.com/kaleido-io/firefly/mocks/datamocks" 31 "github.com/kaleido-io/firefly/mocks/eventmocks" 32 "github.com/kaleido-io/firefly/mocks/identitymocks" 33 "github.com/kaleido-io/firefly/mocks/networkmapmocks" 34 "github.com/kaleido-io/firefly/mocks/privatemessagingmocks" 35 "github.com/kaleido-io/firefly/mocks/publicstoragemocks" 36 "github.com/kaleido-io/firefly/pkg/fftypes" 37 "github.com/stretchr/testify/assert" 38 "github.com/stretchr/testify/mock" 39 ) 40 41 const configDir = "../../test/data/config" 42 43 type testOrchestrator struct { 44 orchestrator 45 46 mdi *databasemocks.Plugin 47 mdm *datamocks.Manager 48 mbm *broadcastmocks.Manager 49 mba *batchmocks.Manager 50 mem *eventmocks.EventManager 51 mnm *networkmapmocks.Manager 52 mps *publicstoragemocks.Plugin 53 mpm *privatemessagingmocks.Manager 54 mbi *blockchainmocks.Plugin 55 mii *identitymocks.Plugin 56 mdx *dataexchangemocks.Plugin 57 } 58 59 func newTestOrchestrator() *testOrchestrator { 60 tor := &testOrchestrator{ 61 orchestrator: orchestrator{ 62 ctx: context.Background(), 63 }, 64 mdi: &databasemocks.Plugin{}, 65 mdm: &datamocks.Manager{}, 66 mbm: &broadcastmocks.Manager{}, 67 mba: &batchmocks.Manager{}, 68 mem: &eventmocks.EventManager{}, 69 mnm: &networkmapmocks.Manager{}, 70 mps: &publicstoragemocks.Plugin{}, 71 mpm: &privatemessagingmocks.Manager{}, 72 mbi: &blockchainmocks.Plugin{}, 73 mii: &identitymocks.Plugin{}, 74 mdx: &dataexchangemocks.Plugin{}, 75 } 76 tor.orchestrator.database = tor.mdi 77 tor.orchestrator.data = tor.mdm 78 tor.orchestrator.batch = tor.mba 79 tor.orchestrator.broadcast = tor.mbm 80 tor.orchestrator.events = tor.mem 81 tor.orchestrator.networkmap = tor.mnm 82 tor.orchestrator.publicstorage = tor.mps 83 tor.orchestrator.messaging = tor.mpm 84 tor.orchestrator.blockchain = tor.mbi 85 tor.orchestrator.identity = tor.mii 86 tor.orchestrator.dataexchange = tor.mdx 87 tor.mdi.On("Name").Return("mock-di").Maybe() 88 tor.mem.On("Name").Return("mock-ei").Maybe() 89 tor.mps.On("Name").Return("mock-ps").Maybe() 90 tor.mbi.On("Name").Return("mock-bi").Maybe() 91 tor.mii.On("Name").Return("mock-ii").Maybe() 92 tor.mdx.On("Name").Return("mock-dx").Maybe() 93 return tor 94 } 95 96 func TestNewOrchestrator(t *testing.T) { 97 or := NewOrchestrator() 98 assert.NotNil(t, or) 99 } 100 101 func TestBadDatabasePlugin(t *testing.T) { 102 or := newTestOrchestrator() 103 config.Set(config.DatabaseType, "wrong") 104 or.database = nil 105 err := or.Init(context.Background()) 106 assert.Regexp(t, "FF10122.*wrong", err) 107 } 108 109 func TestBadDatabaseInitFail(t *testing.T) { 110 or := newTestOrchestrator() 111 config.Set(config.DatabaseType, "wrong") 112 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(fmt.Errorf("pop")) 113 err := or.Init(context.Background()) 114 assert.EqualError(t, err, "pop") 115 } 116 117 func TestBadIdentityPlugin(t *testing.T) { 118 or := newTestOrchestrator() 119 config.Set(config.IdentityType, "wrong") 120 or.identity = nil 121 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 122 err := or.Init(context.Background()) 123 assert.Regexp(t, "FF10212.*wrong", err) 124 } 125 126 func TestBadIdentityInitFail(t *testing.T) { 127 or := newTestOrchestrator() 128 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 129 or.mii.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(fmt.Errorf("pop")) 130 err := or.Init(context.Background()) 131 assert.EqualError(t, err, "pop") 132 } 133 134 func TestBadBlockchainPlugin(t *testing.T) { 135 or := newTestOrchestrator() 136 config.Set(config.BlockchainType, "wrong") 137 or.blockchain = nil 138 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 139 or.mii.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 140 err := or.Init(context.Background()) 141 assert.Regexp(t, "FF10110.*wrong", err) 142 } 143 144 func TestBlockchaiInitFail(t *testing.T) { 145 or := newTestOrchestrator() 146 or.mii.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 147 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 148 or.mbi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(fmt.Errorf("pop")) 149 err := or.Init(context.Background()) 150 assert.EqualError(t, err, "pop") 151 } 152 153 func TestBadPublicStoragePlugin(t *testing.T) { 154 or := newTestOrchestrator() 155 config.Set(config.PublicStorageType, "wrong") 156 or.publicstorage = nil 157 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 158 or.mbi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 159 or.mii.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 160 or.mbi.On("VerifyIdentitySyntax", mock.Anything, mock.Anything, mock.Anything).Return("", nil) 161 err := or.Init(context.Background()) 162 assert.Regexp(t, "FF10134.*wrong", err) 163 } 164 165 func TestBadPublicStorageInitFail(t *testing.T) { 166 or := newTestOrchestrator() 167 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 168 or.mbi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 169 or.mii.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 170 or.mbi.On("VerifyIdentitySyntax", mock.Anything, mock.Anything, mock.Anything).Return("", nil) 171 or.mps.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(fmt.Errorf("pop")) 172 err := or.Init(context.Background()) 173 assert.EqualError(t, err, "pop") 174 } 175 176 func TestBadDataExchangePlugin(t *testing.T) { 177 or := newTestOrchestrator() 178 config.Set(config.DataexchangeType, "wrong") 179 or.dataexchange = nil 180 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 181 or.mbi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 182 or.mii.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 183 or.mbi.On("VerifyIdentitySyntax", mock.Anything, mock.Anything, mock.Anything).Return("", nil) 184 or.mps.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 185 err := or.Init(context.Background()) 186 assert.Regexp(t, "FF10213.*wrong", err) 187 } 188 189 func TestBadPDataExchangeInitFail(t *testing.T) { 190 or := newTestOrchestrator() 191 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 192 or.mbi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 193 or.mii.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 194 or.mbi.On("VerifyIdentitySyntax", mock.Anything, mock.Anything, mock.Anything).Return("", nil) 195 or.mps.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 196 or.mdx.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(fmt.Errorf("pop")) 197 err := or.Init(context.Background()) 198 assert.EqualError(t, err, "pop") 199 } 200 201 func TestInitMessagingomponentFail(t *testing.T) { 202 or := newTestOrchestrator() 203 or.database = nil 204 or.messaging = nil 205 err := or.initComponents(context.Background()) 206 assert.Regexp(t, "FF10128", err) 207 } 208 209 func TestInitEventsComponentFail(t *testing.T) { 210 or := newTestOrchestrator() 211 or.database = nil 212 or.events = nil 213 err := or.initComponents(context.Background()) 214 assert.Regexp(t, "FF10128", err) 215 } 216 217 func TestInitNetworkMapComponentFail(t *testing.T) { 218 or := newTestOrchestrator() 219 or.database = nil 220 or.networkmap = nil 221 err := or.initComponents(context.Background()) 222 assert.Regexp(t, "FF10128", err) 223 } 224 225 func TestInitBatchComponentFail(t *testing.T) { 226 or := newTestOrchestrator() 227 or.database = nil 228 or.batch = nil 229 err := or.initComponents(context.Background()) 230 assert.Regexp(t, "FF10128", err) 231 } 232 233 func TestInitBroadcastComponentFail(t *testing.T) { 234 or := newTestOrchestrator() 235 or.database = nil 236 or.broadcast = nil 237 err := or.initComponents(context.Background()) 238 assert.Regexp(t, "FF10128", err) 239 } 240 241 func TestInitDataComponentFail(t *testing.T) { 242 or := newTestOrchestrator() 243 or.database = nil 244 or.data = nil 245 err := or.initComponents(context.Background()) 246 assert.Regexp(t, "FF10128", err) 247 } 248 249 func TestStartBatchFail(t *testing.T) { 250 config.Reset() 251 or := newTestOrchestrator() 252 or.mba.On("Start").Return(fmt.Errorf("pop")) 253 or.mbi.On("Start").Return(nil) 254 err := or.Start() 255 assert.Regexp(t, "pop", err) 256 } 257 258 func TestStartStopOk(t *testing.T) { 259 config.Reset() 260 or := newTestOrchestrator() 261 or.mbi.On("Start").Return(nil) 262 or.mba.On("Start").Return(nil) 263 or.mem.On("Start").Return(nil) 264 or.mbm.On("Start").Return(nil) 265 or.mpm.On("Start").Return(nil) 266 or.mbi.On("WaitStop").Return(nil) 267 or.mba.On("WaitStop").Return(nil) 268 or.mem.On("WaitStop").Return(nil) 269 or.mbm.On("WaitStop").Return(nil) 270 err := or.Start() 271 assert.NoError(t, err) 272 or.WaitStop() 273 or.WaitStop() // swallows dups 274 } 275 276 func TestInitNamespacesBadName(t *testing.T) { 277 config.Reset() 278 config.Set(config.NamespacesPredefined, fftypes.JSONObjectArray{ 279 {"name": "!Badness"}, 280 }) 281 or := newTestOrchestrator() 282 err := or.initNamespaces(context.Background()) 283 assert.Regexp(t, "FF10131", err) 284 } 285 286 func TestInitNamespacesGetFail(t *testing.T) { 287 config.Reset() 288 or := newTestOrchestrator() 289 or.mdi.On("GetNamespace", mock.Anything, mock.Anything).Return(nil, fmt.Errorf("pop")) 290 err := or.initNamespaces(context.Background()) 291 assert.Regexp(t, "pop", err) 292 } 293 294 func TestInitNamespacesUpsertFail(t *testing.T) { 295 config.Reset() 296 or := newTestOrchestrator() 297 or.mdi.On("GetNamespace", mock.Anything, mock.Anything).Return(nil, nil) 298 or.mdi.On("UpsertNamespace", mock.Anything, mock.Anything, true).Return(fmt.Errorf("pop")) 299 err := or.initNamespaces(context.Background()) 300 assert.Regexp(t, "pop", err) 301 } 302 303 func TestInitNamespacesUpsertNotNeeded(t *testing.T) { 304 config.Reset() 305 or := newTestOrchestrator() 306 or.mdi.On("GetNamespace", mock.Anything, mock.Anything).Return(&fftypes.Namespace{ 307 Type: fftypes.NamespaceTypeBroadcast, // any broadcasted NS will not be updated 308 }, nil) 309 err := or.initNamespaces(context.Background()) 310 assert.NoError(t, err) 311 } 312 313 func TestInitNamespacesDefaultMissing(t *testing.T) { 314 config.Reset() 315 or := newTestOrchestrator() 316 config.Set(config.NamespacesPredefined, fftypes.JSONObjectArray{}) 317 err := or.initNamespaces(context.Background()) 318 assert.Regexp(t, "FF10166", err) 319 } 320 321 func TestInitNamespacesDupName(t *testing.T) { 322 config.Reset() 323 or := newTestOrchestrator() 324 config.Set(config.NamespacesPredefined, fftypes.JSONObjectArray{ 325 {"name": "ns1"}, 326 {"name": "ns2"}, 327 {"name": "ns2"}, 328 }) 329 config.Set(config.NamespacesDefault, "ns1") 330 nsList, err := or.getPrefdefinedNamespaces(context.Background()) 331 assert.NoError(t, err) 332 assert.Len(t, nsList, 3) 333 assert.Equal(t, fftypes.SystemNamespace, nsList[0].Name) 334 assert.Equal(t, "ns1", nsList[1].Name) 335 assert.Equal(t, "ns2", nsList[2].Name) 336 } 337 338 func TestInitOK(t *testing.T) { 339 or := newTestOrchestrator() 340 or.mdi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 341 or.mii.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 342 or.mbi.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 343 or.mbi.On("VerifyIdentitySyntax", mock.Anything, mock.Anything, mock.Anything).Return("", nil) 344 or.mps.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 345 or.mdx.On("Init", mock.Anything, mock.Anything, mock.Anything).Return(nil) 346 or.mdi.On("GetNamespace", mock.Anything, mock.Anything).Return(nil, nil) 347 or.mdi.On("UpsertNamespace", mock.Anything, mock.Anything, true).Return(nil) 348 err := config.ReadConfig(configDir + "/firefly.core.yaml") 349 assert.NoError(t, err) 350 err = or.Init(context.Background()) 351 assert.NoError(t, err) 352 353 assert.Equal(t, or.mbm, or.Broadcast()) 354 assert.Equal(t, or.mpm, or.PrivateMessaging()) 355 assert.Equal(t, or.mem, or.Events()) 356 assert.Equal(t, or.mnm, or.NetworkMap()) 357 assert.Equal(t, or.mdm, or.Data()) 358 }