@@ -2,12 +2,12 @@ package atlasdeployment
2
2
3
3
import (
4
4
"context"
5
+ "errors"
5
6
"fmt"
6
7
"net/http"
7
8
"testing"
8
9
9
- internal "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/searchindex"
10
-
10
+ "github.com/stretchr/testify/assert"
11
11
"github.com/stretchr/testify/mock"
12
12
"go.mongodb.org/atlas-sdk/v20231115008/admin"
13
13
"go.mongodb.org/atlas-sdk/v20231115008/mockadmin"
@@ -18,14 +18,11 @@ import (
18
18
"sigs.k8s.io/controller-runtime/pkg/client/fake"
19
19
20
20
"github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/pointer"
21
+ internal "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/searchindex"
22
+ akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1"
21
23
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common"
22
- "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/workflow"
23
-
24
24
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/status"
25
-
26
- "github.com/stretchr/testify/assert"
27
-
28
- akov2 "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1"
25
+ "github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/workflow"
29
26
)
30
27
31
28
func Test_verifyAllIndexesNamesAreUnique (t * testing.T ) {
@@ -316,6 +313,182 @@ func Test_SearchIndexesReconcile(t *testing.T) {
316
313
assert .False (t , result .IsOk ())
317
314
})
318
315
316
+ t .Run ("Should proceed with index Type Search if it cannot be found: CREATE INDEX" , func (t * testing.T ) {
317
+ mockSearchAPI := mockadmin .NewAtlasSearchApi (t )
318
+
319
+ nestMock := func (f func (nestedMock * mockadmin.AtlasSearchApi )) {
320
+ nested := mockadmin .NewAtlasSearchApi (t )
321
+ f (nested )
322
+ }
323
+
324
+ searchIndexConfig := & akov2.AtlasSearchIndexConfig {
325
+ TypeMeta : metav1.TypeMeta {},
326
+ ObjectMeta : metav1.ObjectMeta {
327
+ Name : "testConfig" ,
328
+ Namespace : "testNamespace" ,
329
+ },
330
+ Spec : akov2.AtlasSearchIndexConfigSpec {
331
+ Analyzer : pointer .MakePtr ("testAnalyzer" ),
332
+ },
333
+ Status : status.AtlasSearchIndexConfigStatus {},
334
+ }
335
+
336
+ deployment := & akov2.AtlasDeployment {
337
+ TypeMeta : metav1.TypeMeta {},
338
+ ObjectMeta : metav1.ObjectMeta {},
339
+ Spec : akov2.AtlasDeploymentSpec {
340
+ DeploymentSpec : & akov2.AdvancedDeploymentSpec {
341
+ Name : "testDeployment" ,
342
+ SearchIndexes : []akov2.SearchIndex {
343
+ {
344
+ Name : "Index1" ,
345
+ Type : IndexTypeSearch ,
346
+ Search : & akov2.Search {
347
+ SearchConfigurationRef : common.ResourceRefNamespaced {
348
+ Name : searchIndexConfig .Name ,
349
+ Namespace : searchIndexConfig .Namespace ,
350
+ },
351
+ },
352
+ },
353
+ },
354
+ },
355
+ },
356
+ Status : status.AtlasDeploymentStatus {},
357
+ }
358
+
359
+ sch := runtime .NewScheme ()
360
+ assert .Nil (t , akov2 .AddToScheme (sch ))
361
+ assert .Nil (t , corev1 .AddToScheme (sch ))
362
+
363
+ k8sClient := fake .NewClientBuilder ().
364
+ WithScheme (sch ).
365
+ WithObjects (deployment , searchIndexConfig ).
366
+ Build ()
367
+
368
+ reconciler := searchIndexesReconciler {
369
+ ctx : & workflow.Context {
370
+ Log : zap .S (),
371
+ OrgID : "testOrgID" ,
372
+ Client : nil ,
373
+ SdkClient : & admin.APIClient {AtlasSearchApi : mockSearchAPI },
374
+ Context : context .Background (),
375
+ },
376
+ deployment : deployment ,
377
+ k8sClient : k8sClient ,
378
+ projectID : "testProjectID" ,
379
+ }
380
+
381
+ // mock GET for Index1
382
+ nestMock (func (n * mockadmin.AtlasSearchApi ) {
383
+ mockSearchAPI .EXPECT ().
384
+ GetAtlasSearchIndex (context .Background (), mock .Anything , mock .Anything , "123" ).
385
+ Return (admin.GetAtlasSearchIndexApiRequest {ApiService : n })
386
+ n .EXPECT ().
387
+ GetAtlasSearchIndexExecute (admin.GetAtlasSearchIndexApiRequest {ApiService : n }).
388
+ Return (
389
+ & admin.ClusterSearchIndex {
390
+ IndexID : pointer .MakePtr ("123" ),
391
+ Name : "Index1" ,
392
+ Status : pointer .MakePtr (IndexStatusActive ),
393
+ Type : pointer .MakePtr (IndexTypeSearch ),
394
+ Analyzer : pointer .MakePtr ("testAnalyzer" ),
395
+ },
396
+ & http.Response {StatusCode : http .StatusOK }, nil ,
397
+ )
398
+ })
399
+
400
+ // mock CREATE for Index1
401
+ atlasIdx , err := internal .NewSearchIndexFromAKO (& deployment .Spec .DeploymentSpec .SearchIndexes [0 ], & searchIndexConfig .Spec ).ToAtlas ()
402
+ assert .NoError (t , err )
403
+
404
+ nestMock (func (n * mockadmin.AtlasSearchApi ) {
405
+ mockSearchAPI .EXPECT ().
406
+ CreateAtlasSearchIndex (context .Background (), mock .Anything , mock .Anything , atlasIdx ).
407
+ Return (admin.CreateAtlasSearchIndexApiRequest {ApiService : n })
408
+ n .EXPECT ().
409
+ CreateAtlasSearchIndexExecute (admin.CreateAtlasSearchIndexApiRequest {ApiService : n }).
410
+ Return (
411
+ & admin.ClusterSearchIndex {Name : "Index1" , IndexID : pointer .MakePtr ("123" ), Status : pointer .MakePtr ("NOT STARTED" )},
412
+ & http.Response {StatusCode : http .StatusCreated }, nil ,
413
+ )
414
+ })
415
+
416
+ // first reconcile succeeds, creation succeeds
417
+ result := reconciler .Reconcile ()
418
+ deployment .UpdateStatus (reconciler .ctx .Conditions (), reconciler .ctx .StatusOptions ()... )
419
+ assert .False (t , result .IsOk ())
420
+ assert .Equal (t , []status.DeploymentSearchIndexStatus {
421
+ {
422
+ Name : "Index1" ,
423
+ ID : "123" ,
424
+ Status : "InProgress" ,
425
+ Message : "Atlas search index status: NOT STARTED" ,
426
+ },
427
+ }, deployment .Status .SearchIndexes )
428
+
429
+ // Add another search Index2 which is a copy of Index1
430
+ deployment .Spec .DeploymentSpec .SearchIndexes = append (deployment .Spec .DeploymentSpec .SearchIndexes , akov2.SearchIndex {
431
+ Name : "Index2" ,
432
+ Type : IndexTypeSearch ,
433
+ Search : & akov2.Search {
434
+ SearchConfigurationRef : common.ResourceRefNamespaced {
435
+ Name : searchIndexConfig .Name ,
436
+ Namespace : searchIndexConfig .Namespace ,
437
+ },
438
+ },
439
+ })
440
+
441
+ // mock CREATE for Index2
442
+ atlasIdx , err = internal .NewSearchIndexFromAKO (& deployment .Spec .DeploymentSpec .SearchIndexes [1 ], & searchIndexConfig .Spec ).ToAtlas ()
443
+ assert .NoError (t , err )
444
+
445
+ nestMock (func (n * mockadmin.AtlasSearchApi ) {
446
+ mockSearchAPI .EXPECT ().CreateAtlasSearchIndex (context .Background (), mock .Anything , mock .Anything , atlasIdx ).
447
+ Return (admin.CreateAtlasSearchIndexApiRequest {ApiService : n })
448
+ n .EXPECT ().
449
+ CreateAtlasSearchIndexExecute (admin.CreateAtlasSearchIndexApiRequest {ApiService : n }).
450
+ Return (
451
+ nil ,
452
+ & http.Response {StatusCode : http .StatusBadRequest }, errors .New ("conflict" ),
453
+ )
454
+ })
455
+
456
+ // create fails
457
+ result = reconciler .Reconcile ()
458
+ deployment .UpdateStatus (reconciler .ctx .Conditions (), reconciler .ctx .StatusOptions ()... )
459
+ assert .False (t , result .IsOk ())
460
+ assert .Equal (t , []status.DeploymentSearchIndexStatus {
461
+ {
462
+ Name : "Index1" ,
463
+ ID : "123" ,
464
+ Status : "Ready" ,
465
+ Message : "Atlas search index status: STEADY" ,
466
+ },
467
+ {
468
+ Name : "Index2" ,
469
+ ID : "" ,
470
+ Status : "Error" ,
471
+ Message : "error with processing index Index2. err: failed to create index: conflict, status: 400" ,
472
+ },
473
+ }, deployment .Status .SearchIndexes )
474
+
475
+ // remove Index2 from the spec
476
+ deployment .Spec .DeploymentSpec .SearchIndexes = []akov2.SearchIndex {deployment .Spec .DeploymentSpec .SearchIndexes [0 ]}
477
+
478
+ // third reconcile succeeds, creation succeeds
479
+ result = reconciler .Reconcile ()
480
+ deployment .UpdateStatus (reconciler .ctx .Conditions (), reconciler .ctx .StatusOptions ()... )
481
+ assert .True (t , result .IsOk ())
482
+ assert .Equal (t , []status.DeploymentSearchIndexStatus {
483
+ {
484
+ Name : "Index1" ,
485
+ ID : "123" ,
486
+ Status : "Ready" ,
487
+ Message : "Atlas search index status: STEADY" ,
488
+ },
489
+ }, deployment .Status .SearchIndexes )
490
+ })
491
+
319
492
t .Run ("Should proceed with the index Type Search: UPDATE INDEX" , func (t * testing.T ) {
320
493
mockSearchAPI := mockadmin .NewAtlasSearchApi (t )
321
494
0 commit comments