github.com/kyma-incubator/compass/components/director@v0.0.0-20230623144113-d764f56ff805/internal/domain/formation/asa_engine_test.go (about) 1 package formation_test 2 3 import ( 4 "testing" 5 6 "github.com/kyma-incubator/compass/components/director/internal/domain/formation" 7 "github.com/kyma-incubator/compass/components/director/internal/domain/formation/automock" 8 "github.com/kyma-incubator/compass/components/director/internal/model" 9 "github.com/kyma-incubator/compass/components/director/pkg/apperrors" 10 "github.com/kyma-incubator/compass/components/director/pkg/graphql" 11 "github.com/kyma-incubator/compass/components/director/pkg/resource" 12 "github.com/pkg/errors" 13 "github.com/stretchr/testify/mock" 14 "github.com/stretchr/testify/require" 15 ) 16 17 func TestService_EnsureScenarioAssigned(t *testing.T) { 18 ctx := fixCtxWithTenant() 19 20 testErr := errors.New("test err") 21 22 rtmIDs := []string{"123", "456", "789"} 23 rtmNames := []string{"first", "second", "third"} 24 25 runtimes := []*model.Runtime{ 26 { 27 ID: rtmIDs[0], 28 Name: rtmNames[0], 29 }, 30 { 31 ID: rtmIDs[1], 32 Name: rtmNames[1], 33 }, 34 { 35 ID: rtmIDs[2], 36 Name: rtmNames[2], 37 }, 38 } 39 40 ownedRuntimes := []*model.Runtime{runtimes[0], runtimes[1]} 41 42 rtmContexts := []*model.RuntimeContext{ 43 { 44 ID: "1", 45 RuntimeID: rtmIDs[0], 46 Key: "test", 47 Value: "test", 48 }, 49 { 50 ID: "2", 51 RuntimeID: rtmIDs[2], 52 Key: "test", 53 Value: "test", 54 }, 55 } 56 57 tnt := tenantID.String() 58 testFormation := fixModel(testFormationName) 59 60 testCases := []struct { 61 Name string 62 RuntimeRepoFN func() *automock.RuntimeRepository 63 RuntimeContextRepoFn func() *automock.RuntimeContextRepository 64 FormationRepositoryFn func() *automock.FormationRepository 65 FormationTemplateRepositoryFn func() *automock.FormationTemplateRepository 66 ProcessFunc func() *automock.ProcessFunc 67 InputASA model.AutomaticScenarioAssignment 68 ExpectedErrMessage string 69 }{ 70 { 71 Name: "Success", 72 RuntimeRepoFN: func() *automock.RuntimeRepository { 73 runtimeRepo := &automock.RuntimeRepository{} 74 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 75 runtimeRepo.On("ListAllWithUnionSetCombination", ctx, TargetTenantID, runtimeLblFilters).Return(runtimes, nil).Once() 76 return runtimeRepo 77 }, 78 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 79 runtimeContextRepo := &automock.RuntimeContextRepository{} 80 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 81 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(true, nil).Once() 82 83 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(rtmContexts[0], nil).Once() 84 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(nil, apperrors.NewNotFoundError(resource.RuntimeContext, rtmContexts[0].ID)).Once() 85 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[2]).Return(rtmContexts[1], nil).Once() 86 87 return runtimeContextRepo 88 }, 89 FormationRepositoryFn: func() *automock.FormationRepository { 90 repo := &automock.FormationRepository{} 91 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 92 return repo 93 }, 94 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 95 repo := &automock.FormationTemplateRepository{} 96 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 97 return repo 98 }, 99 ProcessFunc: func() *automock.ProcessFunc { 100 f := &automock.ProcessFunc{} 101 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 102 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, rtmContexts[0].ID, graphql.FormationObjectTypeRuntimeContext, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 103 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, rtmContexts[1].ID, graphql.FormationObjectTypeRuntimeContext, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 104 return f 105 }, 106 InputASA: fixModel(testFormationName), 107 ExpectedErrMessage: "", 108 }, 109 { 110 Name: "Returns error getting formation by name fails", 111 RuntimeRepoFN: unusedRuntimeRepo, 112 RuntimeContextRepoFn: unusedRuntimeContextRepo, 113 FormationRepositoryFn: func() *automock.FormationRepository { 114 repo := &automock.FormationRepository{} 115 repo.On("GetByName", ctx, testFormationName, tnt).Return(nil, testErr).Times(1) 116 return repo 117 }, 118 FormationTemplateRepositoryFn: unusedFormationTemplateRepo, 119 InputASA: fixModel(testFormationName), 120 ExpectedErrMessage: testErr.Error(), 121 }, 122 { 123 Name: "Returns error getting formation template by ID fails", 124 RuntimeRepoFN: unusedRuntimeRepo, 125 RuntimeContextRepoFn: unusedRuntimeContextRepo, 126 FormationRepositoryFn: func() *automock.FormationRepository { 127 repo := &automock.FormationRepository{} 128 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Times(1) 129 return repo 130 }, 131 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 132 repo := &automock.FormationTemplateRepository{} 133 repo.On("Get", ctx, FormationTemplateID).Return(nil, testErr).Once() 134 return repo 135 }, 136 InputASA: fixModel(testFormationName), 137 ExpectedErrMessage: testErr.Error(), 138 }, 139 { 140 Name: "Returns error when listing owned runtimes fails", 141 RuntimeRepoFN: func() *automock.RuntimeRepository { 142 runtimeRepo := &automock.RuntimeRepository{} 143 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(nil, testErr).Once() 144 return runtimeRepo 145 }, 146 RuntimeContextRepoFn: unusedRuntimeContextRepo, 147 FormationRepositoryFn: func() *automock.FormationRepository { 148 repo := &automock.FormationRepository{} 149 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Times(1) 150 return repo 151 }, 152 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 153 repo := &automock.FormationTemplateRepository{} 154 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 155 return repo 156 }, 157 InputASA: fixModel(testFormationName), 158 ExpectedErrMessage: testErr.Error(), 159 }, 160 { 161 Name: "Returns error when checking if runtime exists by id fails", 162 RuntimeRepoFN: func() *automock.RuntimeRepository { 163 runtimeRepo := &automock.RuntimeRepository{} 164 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 165 return runtimeRepo 166 }, 167 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 168 runtimeContextRepo := &automock.RuntimeContextRepository{} 169 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, testErr).Once() 170 return runtimeContextRepo 171 }, 172 FormationRepositoryFn: func() *automock.FormationRepository { 173 repo := &automock.FormationRepository{} 174 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Times(1) 175 return repo 176 }, 177 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 178 repo := &automock.FormationTemplateRepository{} 179 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 180 return repo 181 }, 182 InputASA: fixModel(testFormationName), 183 ExpectedErrMessage: testErr.Error(), 184 }, 185 { 186 Name: "Returns error when assigning runtime to formation fails", 187 RuntimeRepoFN: func() *automock.RuntimeRepository { 188 runtimeRepo := &automock.RuntimeRepository{} 189 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 190 return runtimeRepo 191 }, 192 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 193 runtimeContextRepo := &automock.RuntimeContextRepository{} 194 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 195 return runtimeContextRepo 196 }, 197 FormationRepositoryFn: func() *automock.FormationRepository { 198 repo := &automock.FormationRepository{} 199 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 200 return repo 201 }, 202 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 203 repo := &automock.FormationTemplateRepository{} 204 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 205 return repo 206 }, 207 ProcessFunc: func() *automock.ProcessFunc { 208 f := &automock.ProcessFunc{} 209 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, testErr).Once() 210 return f 211 }, 212 InputASA: fixModel(testFormationName), 213 ExpectedErrMessage: testErr.Error(), 214 }, 215 { 216 Name: "Returns error when listing all runtimes fails", 217 RuntimeRepoFN: func() *automock.RuntimeRepository { 218 runtimeRepo := &automock.RuntimeRepository{} 219 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 220 runtimeRepo.On("ListAllWithUnionSetCombination", ctx, TargetTenantID, runtimeLblFilters).Return(nil, testErr).Once() 221 return runtimeRepo 222 }, 223 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 224 runtimeContextRepo := &automock.RuntimeContextRepository{} 225 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 226 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(true, nil).Once() 227 228 return runtimeContextRepo 229 }, 230 FormationRepositoryFn: func() *automock.FormationRepository { 231 repo := &automock.FormationRepository{} 232 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 233 return repo 234 }, 235 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 236 repo := &automock.FormationTemplateRepository{} 237 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 238 return repo 239 }, 240 ProcessFunc: func() *automock.ProcessFunc { 241 f := &automock.ProcessFunc{} 242 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 243 return f 244 }, 245 InputASA: fixModel(testFormationName), 246 ExpectedErrMessage: testErr.Error(), 247 }, 248 { 249 Name: "Returns error when listing runtime contexts for runtime fails", 250 RuntimeRepoFN: func() *automock.RuntimeRepository { 251 runtimeRepo := &automock.RuntimeRepository{} 252 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 253 runtimeRepo.On("ListAllWithUnionSetCombination", ctx, TargetTenantID, runtimeLblFilters).Return(runtimes, nil).Once() 254 return runtimeRepo 255 }, 256 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 257 runtimeContextRepo := &automock.RuntimeContextRepository{} 258 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 259 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(true, nil).Once() 260 261 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(nil, testErr).Once() 262 263 return runtimeContextRepo 264 }, 265 FormationRepositoryFn: func() *automock.FormationRepository { 266 repo := &automock.FormationRepository{} 267 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 268 return repo 269 }, 270 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 271 repo := &automock.FormationTemplateRepository{} 272 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 273 return repo 274 }, 275 ProcessFunc: func() *automock.ProcessFunc { 276 f := &automock.ProcessFunc{} 277 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 278 return f 279 }, 280 InputASA: fixModel(testFormationName), 281 ExpectedErrMessage: testErr.Error(), 282 }, 283 { 284 Name: "Returns error when assigning runtime context to formation fails", 285 RuntimeRepoFN: func() *automock.RuntimeRepository { 286 runtimeRepo := &automock.RuntimeRepository{} 287 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 288 runtimeRepo.On("ListAllWithUnionSetCombination", ctx, TargetTenantID, runtimeLblFilters).Return(runtimes, nil).Once() 289 return runtimeRepo 290 }, 291 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 292 runtimeContextRepo := &automock.RuntimeContextRepository{} 293 294 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 295 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(true, nil).Once() 296 297 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(rtmContexts[0], nil).Once() 298 return runtimeContextRepo 299 }, 300 FormationRepositoryFn: func() *automock.FormationRepository { 301 repo := &automock.FormationRepository{} 302 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 303 return repo 304 }, 305 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 306 repo := &automock.FormationTemplateRepository{} 307 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 308 return repo 309 }, 310 ProcessFunc: func() *automock.ProcessFunc { 311 f := &automock.ProcessFunc{} 312 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 313 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, rtmContexts[0].ID, graphql.FormationObjectTypeRuntimeContext, model.Formation{Name: testFormation.ScenarioName}).Return(nil, testErr).Once() 314 return f 315 }, 316 InputASA: fixModel(testFormationName), 317 ExpectedErrMessage: testErr.Error(), 318 }, 319 } 320 for _, testCase := range testCases { 321 t.Run(testCase.Name, func(t *testing.T) { 322 // GIVEN 323 runtimeRepo := unusedRuntimeRepo() 324 if testCase.RuntimeRepoFN != nil { 325 runtimeRepo = testCase.RuntimeRepoFN() 326 } 327 runtimeContextRepo := unusedRuntimeContextRepo() 328 if testCase.RuntimeContextRepoFn != nil { 329 runtimeContextRepo = testCase.RuntimeContextRepoFn() 330 } 331 formationRepo := unusedFormationRepo() 332 if testCase.FormationRepositoryFn != nil { 333 formationRepo = testCase.FormationRepositoryFn() 334 } 335 formationTemplateRepo := unusedFormationTemplateRepo() 336 if testCase.FormationTemplateRepositoryFn != nil { 337 formationTemplateRepo = testCase.FormationTemplateRepositoryFn() 338 } 339 processFuncMock := unusedProcessFunc() 340 if testCase.ProcessFunc != nil { 341 processFuncMock = testCase.ProcessFunc() 342 } 343 344 svc := formation.NewASAEngine(nil, runtimeRepo, runtimeContextRepo, formationRepo, formationTemplateRepo, runtimeType, applicationType) 345 346 // WHEN 347 err := svc.EnsureScenarioAssigned(ctx, testCase.InputASA, processFuncMock.ProcessScenarioFunc) 348 349 // THEN 350 if testCase.ExpectedErrMessage == "" { 351 require.NoError(t, err) 352 } else { 353 require.Error(t, err) 354 require.Contains(t, err.Error(), testCase.ExpectedErrMessage) 355 } 356 357 mock.AssertExpectationsForObjects(t, runtimeRepo, runtimeContextRepo, formationRepo, formationTemplateRepo, processFuncMock) 358 }) 359 } 360 } 361 362 func TestService_RemoveAssignedScenario(t *testing.T) { 363 ctx := fixCtxWithTenant() 364 365 testErr := errors.New("test err") 366 367 rtmIDs := []string{"123", "456", "789"} 368 rtmNames := []string{"first", "second", "third"} 369 370 runtimes := []*model.Runtime{ 371 { 372 ID: rtmIDs[0], 373 Name: rtmNames[0], 374 }, 375 { 376 ID: rtmIDs[1], 377 Name: rtmNames[1], 378 }, 379 { 380 ID: rtmIDs[2], 381 Name: rtmNames[2], 382 }, 383 } 384 ownedRuntimes := []*model.Runtime{runtimes[0], runtimes[1]} 385 386 rtmContexts := []*model.RuntimeContext{ 387 { 388 ID: "1", 389 RuntimeID: rtmIDs[0], 390 Key: "test", 391 Value: "test", 392 }, 393 { 394 ID: "2", 395 RuntimeID: rtmIDs[2], 396 Key: "test", 397 Value: "test", 398 }, 399 } 400 401 tnt := tenantID.String() 402 testFormation := fixModel(testFormationName) 403 404 testCases := []struct { 405 Name string 406 RuntimeRepoFN func() *automock.RuntimeRepository 407 RuntimeContextRepoFn func() *automock.RuntimeContextRepository 408 FormationRepositoryFn func() *automock.FormationRepository 409 FormationTemplateRepositoryFn func() *automock.FormationTemplateRepository 410 ProcessFunc func() *automock.ProcessFunc 411 InputASA model.AutomaticScenarioAssignment 412 ExpectedErrMessage string 413 }{ 414 { 415 Name: "Success", 416 RuntimeRepoFN: func() *automock.RuntimeRepository { 417 runtimeRepo := &automock.RuntimeRepository{} 418 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 419 runtimeRepo.On("ListAllWithUnionSetCombination", ctx, TargetTenantID, runtimeLblFilters).Return(runtimes, nil).Once() 420 return runtimeRepo 421 }, 422 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 423 runtimeContextRepo := &automock.RuntimeContextRepository{} 424 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 425 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(true, nil).Once() 426 427 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(rtmContexts[0], nil).Once() 428 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(nil, apperrors.NewNotFoundError(resource.RuntimeContext, rtmContexts[0].ID)).Once() 429 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[2]).Return(rtmContexts[1], nil).Once() 430 431 return runtimeContextRepo 432 }, 433 FormationRepositoryFn: func() *automock.FormationRepository { 434 repo := &automock.FormationRepository{} 435 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 436 return repo 437 }, 438 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 439 repo := &automock.FormationTemplateRepository{} 440 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 441 return repo 442 }, 443 ProcessFunc: func() *automock.ProcessFunc { 444 f := &automock.ProcessFunc{} 445 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 446 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, rtmContexts[0].ID, graphql.FormationObjectTypeRuntimeContext, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 447 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, rtmContexts[1].ID, graphql.FormationObjectTypeRuntimeContext, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 448 return f 449 }, 450 InputASA: fixModel(testFormationName), 451 ExpectedErrMessage: "", 452 }, 453 { 454 Name: "Returns error when processing scenarios for runtime context fails", 455 RuntimeRepoFN: func() *automock.RuntimeRepository { 456 runtimeRepo := &automock.RuntimeRepository{} 457 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 458 runtimeRepo.On("ListAllWithUnionSetCombination", ctx, TargetTenantID, runtimeLblFilters).Return(runtimes, nil).Once() 459 460 return runtimeRepo 461 }, 462 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 463 runtimeContextRepo := &automock.RuntimeContextRepository{} 464 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 465 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(true, nil).Once() 466 467 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(rtmContexts[0], nil).Once() 468 469 return runtimeContextRepo 470 }, 471 FormationRepositoryFn: func() *automock.FormationRepository { 472 repo := &automock.FormationRepository{} 473 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 474 return repo 475 }, 476 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 477 repo := &automock.FormationTemplateRepository{} 478 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 479 return repo 480 }, 481 ProcessFunc: func() *automock.ProcessFunc { 482 f := &automock.ProcessFunc{} 483 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 484 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, rtmContexts[0].ID, graphql.FormationObjectTypeRuntimeContext, model.Formation{Name: testFormation.ScenarioName}).Return(nil, testErr).Once() 485 return f 486 }, 487 InputASA: fixModel(testFormationName), 488 ExpectedErrMessage: testErr.Error(), 489 }, 490 { 491 Name: "Returns error when getting runtime context for runtime fails", 492 RuntimeRepoFN: func() *automock.RuntimeRepository { 493 runtimeRepo := &automock.RuntimeRepository{} 494 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 495 runtimeRepo.On("ListAllWithUnionSetCombination", ctx, TargetTenantID, runtimeLblFilters).Return(runtimes, nil).Once() 496 return runtimeRepo 497 }, 498 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 499 runtimeContextRepo := &automock.RuntimeContextRepository{} 500 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 501 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(true, nil).Once() 502 503 runtimeContextRepo.On("GetByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(nil, testErr).Once() 504 505 return runtimeContextRepo 506 }, 507 FormationRepositoryFn: func() *automock.FormationRepository { 508 repo := &automock.FormationRepository{} 509 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 510 return repo 511 }, 512 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 513 repo := &automock.FormationTemplateRepository{} 514 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 515 return repo 516 }, 517 ProcessFunc: func() *automock.ProcessFunc { 518 f := &automock.ProcessFunc{} 519 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 520 return f 521 }, 522 InputASA: fixModel(testFormationName), 523 ExpectedErrMessage: testErr.Error(), 524 }, 525 { 526 Name: "Returns error when listing all runtimes fails", 527 RuntimeRepoFN: func() *automock.RuntimeRepository { 528 runtimeRepo := &automock.RuntimeRepository{} 529 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 530 runtimeRepo.On("ListAllWithUnionSetCombination", ctx, TargetTenantID, runtimeLblFilters).Return(nil, testErr).Once() 531 return runtimeRepo 532 }, 533 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 534 runtimeContextRepo := &automock.RuntimeContextRepository{} 535 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 536 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[1]).Return(true, nil).Once() 537 538 return runtimeContextRepo 539 }, 540 FormationRepositoryFn: func() *automock.FormationRepository { 541 repo := &automock.FormationRepository{} 542 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 543 return repo 544 }, 545 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 546 repo := &automock.FormationTemplateRepository{} 547 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 548 return repo 549 }, 550 ProcessFunc: func() *automock.ProcessFunc { 551 f := &automock.ProcessFunc{} 552 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, nil).Once() 553 return f 554 }, 555 InputASA: fixModel(testFormationName), 556 ExpectedErrMessage: testErr.Error(), 557 }, 558 { 559 Name: "Returns error when processing scenarios for runtime fails", 560 RuntimeRepoFN: func() *automock.RuntimeRepository { 561 runtimeRepo := &automock.RuntimeRepository{} 562 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 563 return runtimeRepo 564 }, 565 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 566 runtimeContextRepo := &automock.RuntimeContextRepository{} 567 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, nil).Once() 568 return runtimeContextRepo 569 }, 570 FormationRepositoryFn: func() *automock.FormationRepository { 571 repo := &automock.FormationRepository{} 572 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 573 return repo 574 }, 575 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 576 repo := &automock.FormationTemplateRepository{} 577 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 578 return repo 579 }, 580 ProcessFunc: func() *automock.ProcessFunc { 581 f := &automock.ProcessFunc{} 582 f.On("ProcessScenarioFunc", ctx, testFormation.Tenant, ownedRuntimes[0].ID, graphql.FormationObjectTypeRuntime, model.Formation{Name: testFormation.ScenarioName}).Return(nil, testErr).Once() 583 return f 584 }, 585 InputASA: fixModel(testFormationName), 586 ExpectedErrMessage: testErr.Error(), 587 }, 588 { 589 Name: "Returns error when checking if runtime context exists by parent runtime id fails", 590 RuntimeRepoFN: func() *automock.RuntimeRepository { 591 runtimeRepo := &automock.RuntimeRepository{} 592 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(ownedRuntimes, nil).Once() 593 return runtimeRepo 594 }, 595 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 596 runtimeContextRepo := &automock.RuntimeContextRepository{} 597 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, rtmIDs[0]).Return(false, testErr).Once() 598 return runtimeContextRepo 599 }, 600 FormationRepositoryFn: func() *automock.FormationRepository { 601 repo := &automock.FormationRepository{} 602 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 603 return repo 604 }, 605 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 606 repo := &automock.FormationTemplateRepository{} 607 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 608 return repo 609 }, 610 InputASA: fixModel(testFormationName), 611 ExpectedErrMessage: testErr.Error(), 612 }, 613 { 614 Name: "Returns error when listing owned runtimes fails", 615 RuntimeRepoFN: func() *automock.RuntimeRepository { 616 runtimeRepo := &automock.RuntimeRepository{} 617 runtimeRepo.On("ListOwnedRuntimes", ctx, TargetTenantID, runtimeLblFilters).Return(nil, testErr).Once() 618 return runtimeRepo 619 }, 620 FormationRepositoryFn: func() *automock.FormationRepository { 621 repo := &automock.FormationRepository{} 622 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 623 return repo 624 }, 625 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 626 repo := &automock.FormationTemplateRepository{} 627 repo.On("Get", ctx, FormationTemplateID).Return(&formationTemplate, nil).Once() 628 return repo 629 }, 630 InputASA: fixModel(testFormationName), 631 ExpectedErrMessage: testErr.Error(), 632 }, 633 { 634 Name: "Returns error when getting formation template by id fails", 635 FormationRepositoryFn: func() *automock.FormationRepository { 636 repo := &automock.FormationRepository{} 637 repo.On("GetByName", ctx, testFormationName, tnt).Return(&modelFormation, nil).Once() 638 return repo 639 }, 640 FormationTemplateRepositoryFn: func() *automock.FormationTemplateRepository { 641 repo := &automock.FormationTemplateRepository{} 642 repo.On("Get", ctx, FormationTemplateID).Return(nil, testErr).Once() 643 return repo 644 }, 645 InputASA: fixModel(testFormationName), 646 ExpectedErrMessage: testErr.Error(), 647 }, 648 { 649 Name: "Returns error when getting formation by name fails", 650 FormationRepositoryFn: func() *automock.FormationRepository { 651 repo := &automock.FormationRepository{} 652 repo.On("GetByName", ctx, testFormationName, tnt).Return(nil, testErr).Once() 653 return repo 654 }, 655 InputASA: fixModel(testFormationName), 656 ExpectedErrMessage: testErr.Error(), 657 }, 658 } 659 for _, testCase := range testCases { 660 t.Run(testCase.Name, func(t *testing.T) { 661 // GIVEN 662 runtimeRepo := unusedRuntimeRepo() 663 if testCase.RuntimeRepoFN != nil { 664 runtimeRepo = testCase.RuntimeRepoFN() 665 } 666 runtimeContextRepo := unusedRuntimeContextRepo() 667 if testCase.RuntimeContextRepoFn != nil { 668 runtimeContextRepo = testCase.RuntimeContextRepoFn() 669 } 670 formationRepo := unusedFormationRepo() 671 if testCase.FormationRepositoryFn != nil { 672 formationRepo = testCase.FormationRepositoryFn() 673 } 674 formationTemplateRepo := unusedFormationTemplateRepo() 675 if testCase.FormationTemplateRepositoryFn != nil { 676 formationTemplateRepo = testCase.FormationTemplateRepositoryFn() 677 } 678 processFuncMock := unusedProcessFunc() 679 if testCase.ProcessFunc != nil { 680 processFuncMock = testCase.ProcessFunc() 681 } 682 svc := formation.NewASAEngine(nil, runtimeRepo, runtimeContextRepo, formationRepo, formationTemplateRepo, runtimeType, applicationType) 683 684 // WHEN 685 err := svc.RemoveAssignedScenario(ctx, testCase.InputASA, processFuncMock.ProcessScenarioFunc) 686 687 // THEN 688 if testCase.ExpectedErrMessage == "" { 689 require.NoError(t, err) 690 } else { 691 require.Error(t, err) 692 require.Contains(t, err.Error(), testCase.ExpectedErrMessage) 693 } 694 695 mock.AssertExpectationsForObjects(t, runtimeRepo, runtimeContextRepo, formationRepo, formationTemplateRepo, processFuncMock) 696 }) 697 } 698 } 699 700 func TestService_GetScenariosFromMatchingASAs(t *testing.T) { 701 ctx := fixCtxWithTenant() 702 runtimeID := "runtimeID" 703 runtimeID2 := "runtimeID2" 704 705 testErr := errors.New(ErrMsg) 706 notFoudErr := apperrors.NewNotFoundError(resource.Runtime, runtimeID2) 707 708 testScenarios := []*model.AutomaticScenarioAssignment{ 709 { 710 ScenarioName: ScenarioName, 711 Tenant: tenantID.String(), 712 TargetTenantID: TargetTenantID, 713 }, 714 { 715 ScenarioName: ScenarioName2, 716 Tenant: TenantID2, 717 TargetTenantID: TargetTenantID2, 718 }, 719 } 720 721 formations := []*model.Formation{ 722 { 723 ID: FormationID, 724 TenantID: tenantID.String(), 725 FormationTemplateID: FormationTemplateID, 726 Name: ScenarioName, 727 }, 728 { 729 ID: FormationID, 730 TenantID: tenantID.String(), 731 FormationTemplateID: FormationTemplateID, 732 Name: ScenarioName2, 733 }, 734 } 735 736 rtmCtx := &model.RuntimeContext{ 737 ID: RuntimeContextID, 738 Key: "subscription", 739 Value: "subscriptionValue", 740 RuntimeID: runtimeID, 741 } 742 743 rtmCtx2 := &model.RuntimeContext{ 744 ID: RuntimeContextID, 745 Key: "subscription", 746 Value: "subscriptionValue", 747 RuntimeID: runtimeID2, 748 } 749 750 testCases := []struct { 751 Name string 752 ScenarioAssignmentRepoFn func() *automock.AutomaticFormationAssignmentRepository 753 RuntimeRepoFn func() *automock.RuntimeRepository 754 RuntimeContextRepoFn func() *automock.RuntimeContextRepository 755 FormationRepoFn func() *automock.FormationRepository 756 FormationTemplateRepoFn func() *automock.FormationTemplateRepository 757 ObjectID string 758 ObjectType graphql.FormationObjectType 759 ExpectedErrorMessage string 760 ExpectedScenarios []string 761 }{ 762 { 763 Name: "Success for runtime", 764 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 765 repo := &automock.AutomaticFormationAssignmentRepository{} 766 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 767 return repo 768 }, 769 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 770 runtimeContextRepo := &automock.RuntimeContextRepository{} 771 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, RuntimeID).Return(false, nil).Once() 772 return runtimeContextRepo 773 }, 774 RuntimeRepoFn: func() *automock.RuntimeRepository { 775 runtimeRepo := &automock.RuntimeRepository{} 776 runtimeRepo.On("OwnerExistsByFiltersAndID", ctx, testScenarios[0].TargetTenantID, RuntimeID, runtimeLblFilters).Return(true, nil).Once() 777 runtimeRepo.On("OwnerExistsByFiltersAndID", ctx, testScenarios[1].TargetTenantID, RuntimeID, runtimeLblFilters).Return(false, nil).Once() 778 return runtimeRepo 779 }, 780 FormationRepoFn: func() *automock.FormationRepository { 781 formationRepo := &automock.FormationRepository{} 782 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 783 formationRepo.On("GetByName", ctx, ScenarioName2, testScenarios[1].Tenant).Return(formations[1], nil).Once() 784 return formationRepo 785 }, 786 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 787 formationTemplateRepo := &automock.FormationTemplateRepository{} 788 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 789 formationTemplateRepo.On("Get", ctx, formations[1].FormationTemplateID).Return(&formationTemplate, nil).Once() 790 return formationTemplateRepo 791 }, 792 ObjectID: RuntimeID, 793 ObjectType: graphql.FormationObjectTypeRuntime, 794 ExpectedErrorMessage: "", 795 ExpectedScenarios: []string{ScenarioName}, 796 }, 797 { 798 Name: "Success for runtime context", 799 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 800 repo := &automock.AutomaticFormationAssignmentRepository{} 801 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 802 return repo 803 }, 804 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 805 runtimeContextRepo := &automock.RuntimeContextRepository{} 806 runtimeContextRepo.On("GetByID", ctx, testScenarios[0].TargetTenantID, RuntimeContextID).Return(rtmCtx, nil).Once() 807 runtimeContextRepo.On("GetByID", ctx, testScenarios[1].TargetTenantID, RuntimeContextID).Return(rtmCtx2, nil).Once() 808 return runtimeContextRepo 809 }, 810 RuntimeRepoFn: func() *automock.RuntimeRepository { 811 runtimeRepo := &automock.RuntimeRepository{} 812 runtimeRepo.On("GetByFiltersAndIDUsingUnion", ctx, testScenarios[0].TargetTenantID, rtmCtx.RuntimeID, runtimeLblFilters).Return(&model.Runtime{}, nil).Once() 813 runtimeRepo.On("GetByFiltersAndIDUsingUnion", ctx, testScenarios[1].TargetTenantID, rtmCtx2.RuntimeID, runtimeLblFilters).Return(nil, notFoudErr).Once() 814 return runtimeRepo 815 }, 816 FormationRepoFn: func() *automock.FormationRepository { 817 formationRepo := &automock.FormationRepository{} 818 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 819 formationRepo.On("GetByName", ctx, ScenarioName2, testScenarios[1].Tenant).Return(formations[1], nil).Once() 820 return formationRepo 821 }, 822 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 823 formationTemplateRepo := &automock.FormationTemplateRepository{} 824 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 825 formationTemplateRepo.On("Get", ctx, formations[1].FormationTemplateID).Return(&formationTemplate, nil).Once() 826 return formationTemplateRepo 827 }, 828 ObjectID: RuntimeContextID, 829 ObjectType: graphql.FormationObjectTypeRuntimeContext, 830 ExpectedErrorMessage: "", 831 ExpectedScenarios: []string{ScenarioName}, 832 }, 833 { 834 Name: "Returns an error when getting runtime contexts", 835 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 836 repo := &automock.AutomaticFormationAssignmentRepository{} 837 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 838 return repo 839 }, 840 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 841 runtimeContextRepo := &automock.RuntimeContextRepository{} 842 runtimeContextRepo.On("GetByID", ctx, testScenarios[0].TargetTenantID, RuntimeContextID).Return(nil, testErr).Once() 843 return runtimeContextRepo 844 }, 845 FormationRepoFn: func() *automock.FormationRepository { 846 formationRepo := &automock.FormationRepository{} 847 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 848 return formationRepo 849 }, 850 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 851 formationTemplateRepo := &automock.FormationTemplateRepository{} 852 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 853 return formationTemplateRepo 854 }, 855 ObjectID: RuntimeContextID, 856 ObjectType: graphql.FormationObjectTypeRuntimeContext, 857 ExpectedErrorMessage: "while getting runtime contexts with ID", 858 ExpectedScenarios: nil, 859 }, 860 { 861 Name: "Returns an not found error when getting runtime contexts", 862 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 863 repo := &automock.AutomaticFormationAssignmentRepository{} 864 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 865 return repo 866 }, 867 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 868 runtimeContextRepo := &automock.RuntimeContextRepository{} 869 runtimeContextRepo.On("GetByID", ctx, testScenarios[0].TargetTenantID, RuntimeContextID).Return(nil, notFoudErr).Once() 870 runtimeContextRepo.On("GetByID", ctx, testScenarios[1].TargetTenantID, RuntimeContextID).Return(nil, notFoudErr).Once() 871 return runtimeContextRepo 872 }, 873 FormationRepoFn: func() *automock.FormationRepository { 874 formationRepo := &automock.FormationRepository{} 875 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 876 formationRepo.On("GetByName", ctx, ScenarioName2, testScenarios[1].Tenant).Return(formations[1], nil).Once() 877 return formationRepo 878 }, 879 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 880 formationTemplateRepo := &automock.FormationTemplateRepository{} 881 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 882 formationTemplateRepo.On("Get", ctx, formations[1].FormationTemplateID).Return(&formationTemplate, nil).Once() 883 return formationTemplateRepo 884 }, 885 ObjectID: RuntimeContextID, 886 ObjectType: graphql.FormationObjectTypeRuntimeContext, 887 ExpectedErrorMessage: "", 888 ExpectedScenarios: nil, 889 }, 890 { 891 Name: "Returns an error when getting runtime", 892 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 893 repo := &automock.AutomaticFormationAssignmentRepository{} 894 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 895 return repo 896 }, 897 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 898 runtimeContextRepo := &automock.RuntimeContextRepository{} 899 runtimeContextRepo.On("GetByID", ctx, testScenarios[0].TargetTenantID, RuntimeContextID).Return(rtmCtx, nil).Once() 900 return runtimeContextRepo 901 }, 902 RuntimeRepoFn: func() *automock.RuntimeRepository { 903 runtimeRepo := &automock.RuntimeRepository{} 904 runtimeRepo.On("GetByFiltersAndIDUsingUnion", ctx, testScenarios[0].TargetTenantID, rtmCtx.RuntimeID, runtimeLblFilters).Return(nil, testErr).Once() 905 return runtimeRepo 906 }, 907 FormationRepoFn: func() *automock.FormationRepository { 908 formationRepo := &automock.FormationRepository{} 909 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 910 return formationRepo 911 }, 912 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 913 formationTemplateRepo := &automock.FormationTemplateRepository{} 914 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 915 return formationTemplateRepo 916 }, 917 ObjectID: RuntimeContextID, 918 ObjectType: graphql.FormationObjectTypeRuntimeContext, 919 ExpectedErrorMessage: "while getting runtime with ID:", 920 ExpectedScenarios: nil, 921 }, 922 { 923 Name: "Returns an error when getting formations", 924 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 925 repo := &automock.AutomaticFormationAssignmentRepository{} 926 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 927 return repo 928 }, 929 FormationRepoFn: func() *automock.FormationRepository { 930 formationRepo := &automock.FormationRepository{} 931 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(nil, testErr).Once() 932 return formationRepo 933 }, 934 ObjectID: RuntimeContextID, 935 ObjectType: graphql.FormationObjectTypeRuntimeContext, 936 ExpectedErrorMessage: "while getting formation by name", 937 ExpectedScenarios: nil, 938 }, 939 { 940 Name: "Returns error for runtime when checking if the runtime has context fails", 941 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 942 repo := &automock.AutomaticFormationAssignmentRepository{} 943 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 944 return repo 945 }, 946 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 947 runtimeContextRepo := &automock.RuntimeContextRepository{} 948 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, RuntimeID).Return(false, testErr).Once() 949 return runtimeContextRepo 950 }, 951 RuntimeRepoFn: func() *automock.RuntimeRepository { 952 runtimeRepo := &automock.RuntimeRepository{} 953 runtimeRepo.On("OwnerExistsByFiltersAndID", ctx, testScenarios[0].TargetTenantID, RuntimeID, runtimeLblFilters).Return(true, nil).Once() 954 return runtimeRepo 955 }, 956 FormationRepoFn: func() *automock.FormationRepository { 957 formationRepo := &automock.FormationRepository{} 958 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 959 return formationRepo 960 }, 961 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 962 formationTemplateRepo := &automock.FormationTemplateRepository{} 963 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 964 return formationTemplateRepo 965 }, 966 ObjectID: RuntimeID, 967 ObjectType: graphql.FormationObjectTypeRuntime, 968 ExpectedErrorMessage: "while cheking runtime context existence for runtime with ID", 969 ExpectedScenarios: nil, 970 }, 971 { 972 Name: "Returns error for runtime when checking if runtime exists by filters and ID and has owner=true fails", 973 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 974 repo := &automock.AutomaticFormationAssignmentRepository{} 975 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 976 return repo 977 }, 978 RuntimeRepoFn: func() *automock.RuntimeRepository { 979 runtimeRepo := &automock.RuntimeRepository{} 980 runtimeRepo.On("OwnerExistsByFiltersAndID", ctx, testScenarios[0].TargetTenantID, RuntimeID, runtimeLblFilters).Return(false, testErr).Once() 981 return runtimeRepo 982 }, 983 FormationRepoFn: func() *automock.FormationRepository { 984 formationRepo := &automock.FormationRepository{} 985 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 986 return formationRepo 987 }, 988 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 989 formationTemplateRepo := &automock.FormationTemplateRepository{} 990 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 991 return formationTemplateRepo 992 }, 993 ObjectID: RuntimeID, 994 ObjectType: graphql.FormationObjectTypeRuntime, 995 ExpectedErrorMessage: "while checking if asa matches runtime with ID rt-id: while checking if runtime with id \"rt-id\" have owner=true: some error", 996 ExpectedScenarios: nil, 997 }, 998 { 999 Name: "Returns error for runtime when getting formation template runtime type fails", 1000 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 1001 repo := &automock.AutomaticFormationAssignmentRepository{} 1002 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 1003 return repo 1004 }, 1005 FormationRepoFn: func() *automock.FormationRepository { 1006 formationRepo := &automock.FormationRepository{} 1007 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 1008 return formationRepo 1009 }, 1010 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 1011 formationTemplateRepo := &automock.FormationTemplateRepository{} 1012 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(nil, testErr).Once() 1013 return formationTemplateRepo 1014 }, 1015 ObjectID: RuntimeID, 1016 ObjectType: graphql.FormationObjectTypeRuntime, 1017 ExpectedErrorMessage: "while checking if asa matches runtime with ID rt-id: while getting formation template by id \"bda5378d-caa1-4ee4-b8bf-f733e180fbf9\"", 1018 ExpectedScenarios: nil, 1019 }, 1020 { 1021 Name: "Returns error when listing ASAs fails", 1022 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 1023 repo := &automock.AutomaticFormationAssignmentRepository{} 1024 repo.On("ListAll", ctx, tenantID.String()).Return(nil, testErr) 1025 return repo 1026 }, 1027 ObjectID: RuntimeID, 1028 ObjectType: graphql.FormationObjectTypeRuntime, 1029 ExpectedErrorMessage: "while listing Automatic Scenario Assignments in tenant", 1030 ExpectedScenarios: nil, 1031 }, 1032 { 1033 Name: "Returns error when can't find matching func", 1034 ObjectID: "", 1035 ObjectType: "test", 1036 ExpectedErrorMessage: "unexpected formation object type \"test\"", 1037 ExpectedScenarios: nil, 1038 }, 1039 } 1040 for _, testCase := range testCases { 1041 t.Run(testCase.Name, func(t *testing.T) { 1042 // GIVEN 1043 asaRepo := unusedASARepo() 1044 if testCase.ScenarioAssignmentRepoFn != nil { 1045 asaRepo = testCase.ScenarioAssignmentRepoFn() 1046 } 1047 runtimeRepo := unusedRuntimeRepo() 1048 if testCase.RuntimeRepoFn != nil { 1049 runtimeRepo = testCase.RuntimeRepoFn() 1050 } 1051 runtimeContextRepo := unusedRuntimeContextRepo() 1052 if testCase.RuntimeContextRepoFn != nil { 1053 runtimeContextRepo = testCase.RuntimeContextRepoFn() 1054 } 1055 formationRepo := unusedFormationRepo() 1056 if testCase.FormationRepoFn != nil { 1057 formationRepo = testCase.FormationRepoFn() 1058 } 1059 formationTemplateRepo := unusedFormationTemplateRepo() 1060 if testCase.FormationTemplateRepoFn != nil { 1061 formationTemplateRepo = testCase.FormationTemplateRepoFn() 1062 } 1063 1064 svc := formation.NewASAEngine(asaRepo, runtimeRepo, runtimeContextRepo, formationRepo, formationTemplateRepo, runtimeType, applicationType) 1065 1066 // WHEN 1067 scenarios, err := svc.GetScenariosFromMatchingASAs(ctx, testCase.ObjectID, testCase.ObjectType) 1068 1069 // THEN 1070 if testCase.ExpectedErrorMessage == "" { 1071 require.NoError(t, err) 1072 require.ElementsMatch(t, scenarios, testCase.ExpectedScenarios) 1073 } else { 1074 require.Error(t, err) 1075 require.Contains(t, err.Error(), testCase.ExpectedErrorMessage) 1076 require.Nil(t, testCase.ExpectedScenarios) 1077 } 1078 1079 mock.AssertExpectationsForObjects(t, asaRepo, runtimeRepo, runtimeContextRepo, formationRepo, formationTemplateRepo) 1080 }) 1081 } 1082 } 1083 1084 func TestService_IsFormationComingFromASA(t *testing.T) { 1085 ctx := fixCtxWithTenant() 1086 testScenarios := []*model.AutomaticScenarioAssignment{ 1087 { 1088 ScenarioName: ScenarioName, 1089 Tenant: tenantID.String(), 1090 TargetTenantID: TargetTenantID, 1091 }, 1092 { 1093 ScenarioName: ScenarioName2, 1094 Tenant: TenantID2, 1095 TargetTenantID: TargetTenantID2, 1096 }, 1097 } 1098 1099 formations := []*model.Formation{ 1100 { 1101 ID: FormationID, 1102 TenantID: tenantID.String(), 1103 FormationTemplateID: FormationTemplateID, 1104 Name: ScenarioName, 1105 }, 1106 { 1107 ID: FormationID, 1108 TenantID: tenantID.String(), 1109 FormationTemplateID: FormationTemplateID, 1110 Name: ScenarioName2, 1111 }, 1112 } 1113 1114 testCases := []struct { 1115 Name string 1116 ScenarioAssignmentRepoFn func() *automock.AutomaticFormationAssignmentRepository 1117 RuntimeRepoFn func() *automock.RuntimeRepository 1118 RuntimeContextRepoFn func() *automock.RuntimeContextRepository 1119 FormationRepoFn func() *automock.FormationRepository 1120 FormationTemplateRepoFn func() *automock.FormationTemplateRepository 1121 FormationName string 1122 ObjectID string 1123 ObjectType graphql.FormationObjectType 1124 ExpectedErrorMessage string 1125 ExpectedResult bool 1126 }{ 1127 { 1128 Name: "Success formation is coming from ASA", 1129 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 1130 repo := &automock.AutomaticFormationAssignmentRepository{} 1131 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 1132 return repo 1133 }, 1134 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 1135 runtimeContextRepo := &automock.RuntimeContextRepository{} 1136 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, RuntimeID).Return(false, nil).Once() 1137 return runtimeContextRepo 1138 }, 1139 RuntimeRepoFn: func() *automock.RuntimeRepository { 1140 runtimeRepo := &automock.RuntimeRepository{} 1141 runtimeRepo.On("OwnerExistsByFiltersAndID", ctx, testScenarios[0].TargetTenantID, RuntimeID, runtimeLblFilters).Return(true, nil).Once() 1142 runtimeRepo.On("OwnerExistsByFiltersAndID", ctx, testScenarios[1].TargetTenantID, RuntimeID, runtimeLblFilters).Return(false, nil).Once() 1143 return runtimeRepo 1144 }, 1145 FormationRepoFn: func() *automock.FormationRepository { 1146 formationRepo := &automock.FormationRepository{} 1147 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 1148 formationRepo.On("GetByName", ctx, ScenarioName2, testScenarios[1].Tenant).Return(formations[1], nil).Once() 1149 return formationRepo 1150 }, 1151 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 1152 formationTemplateRepo := &automock.FormationTemplateRepository{} 1153 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 1154 formationTemplateRepo.On("Get", ctx, formations[1].FormationTemplateID).Return(&formationTemplate, nil).Once() 1155 return formationTemplateRepo 1156 }, 1157 FormationName: ScenarioName, 1158 ObjectID: RuntimeID, 1159 ObjectType: graphql.FormationObjectTypeRuntime, 1160 ExpectedErrorMessage: "", 1161 ExpectedResult: true, 1162 }, 1163 { 1164 Name: "Success formation is not coming from ASA", 1165 ScenarioAssignmentRepoFn: func() *automock.AutomaticFormationAssignmentRepository { 1166 repo := &automock.AutomaticFormationAssignmentRepository{} 1167 repo.On("ListAll", ctx, tenantID.String()).Return(testScenarios, nil) 1168 return repo 1169 }, 1170 RuntimeContextRepoFn: func() *automock.RuntimeContextRepository { 1171 runtimeContextRepo := &automock.RuntimeContextRepository{} 1172 runtimeContextRepo.On("ExistsByRuntimeID", ctx, TargetTenantID, RuntimeID).Return(false, nil).Once() 1173 return runtimeContextRepo 1174 }, 1175 RuntimeRepoFn: func() *automock.RuntimeRepository { 1176 runtimeRepo := &automock.RuntimeRepository{} 1177 runtimeRepo.On("OwnerExistsByFiltersAndID", ctx, testScenarios[0].TargetTenantID, RuntimeID, runtimeLblFilters).Return(true, nil).Once() 1178 runtimeRepo.On("OwnerExistsByFiltersAndID", ctx, testScenarios[1].TargetTenantID, RuntimeID, runtimeLblFilters).Return(false, nil).Once() 1179 return runtimeRepo 1180 }, 1181 FormationRepoFn: func() *automock.FormationRepository { 1182 formationRepo := &automock.FormationRepository{} 1183 formationRepo.On("GetByName", ctx, ScenarioName, testScenarios[0].Tenant).Return(formations[0], nil).Once() 1184 formationRepo.On("GetByName", ctx, ScenarioName2, testScenarios[1].Tenant).Return(formations[1], nil).Once() 1185 return formationRepo 1186 }, 1187 FormationTemplateRepoFn: func() *automock.FormationTemplateRepository { 1188 formationTemplateRepo := &automock.FormationTemplateRepository{} 1189 formationTemplateRepo.On("Get", ctx, formations[0].FormationTemplateID).Return(&formationTemplate, nil).Once() 1190 formationTemplateRepo.On("Get", ctx, formations[1].FormationTemplateID).Return(&formationTemplate, nil).Once() 1191 return formationTemplateRepo 1192 }, 1193 FormationName: ScenarioName2, 1194 ObjectID: RuntimeID, 1195 ObjectType: graphql.FormationObjectTypeRuntime, 1196 ExpectedErrorMessage: "", 1197 ExpectedResult: false, 1198 }, 1199 { 1200 Name: "Error when getting scenarios fails", 1201 ObjectID: "", 1202 ObjectType: "test", 1203 ExpectedErrorMessage: "unexpected formation object type \"test\"", 1204 ExpectedResult: false, 1205 }, 1206 } 1207 for _, testCase := range testCases { 1208 t.Run(testCase.Name, func(t *testing.T) { 1209 // GIVEN 1210 asaRepo := unusedASARepo() 1211 if testCase.ScenarioAssignmentRepoFn != nil { 1212 asaRepo = testCase.ScenarioAssignmentRepoFn() 1213 } 1214 runtimeRepo := unusedRuntimeRepo() 1215 if testCase.RuntimeRepoFn != nil { 1216 runtimeRepo = testCase.RuntimeRepoFn() 1217 } 1218 runtimeContextRepo := unusedRuntimeContextRepo() 1219 if testCase.RuntimeContextRepoFn != nil { 1220 runtimeContextRepo = testCase.RuntimeContextRepoFn() 1221 } 1222 formationRepo := unusedFormationRepo() 1223 if testCase.FormationRepoFn != nil { 1224 formationRepo = testCase.FormationRepoFn() 1225 } 1226 formationTemplateRepo := unusedFormationTemplateRepo() 1227 if testCase.FormationTemplateRepoFn != nil { 1228 formationTemplateRepo = testCase.FormationTemplateRepoFn() 1229 } 1230 1231 svc := formation.NewASAEngine(asaRepo, runtimeRepo, runtimeContextRepo, formationRepo, formationTemplateRepo, runtimeType, applicationType) 1232 1233 // WHEN 1234 comesFromASA, err := svc.IsFormationComingFromASA(ctx, testCase.ObjectID, testCase.FormationName, testCase.ObjectType) 1235 1236 // THEN 1237 if testCase.ExpectedErrorMessage == "" { 1238 require.NoError(t, err) 1239 require.Equal(t, testCase.ExpectedResult, comesFromASA) 1240 } else { 1241 require.Error(t, err) 1242 require.Contains(t, err.Error(), testCase.ExpectedErrorMessage) 1243 require.False(t, comesFromASA) 1244 } 1245 1246 mock.AssertExpectationsForObjects(t, asaRepo, runtimeRepo, runtimeContextRepo, formationRepo, formationTemplateRepo) 1247 }) 1248 } 1249 }