Skip to content

Commit 81e09c9

Browse files
CLOUDP-221979: add additional unit tests (#1568)
Added unit test --------- Co-authored-by: Igor Karpukhin <karpukhinigor@gmail.com>
1 parent b51b081 commit 81e09c9

File tree

2 files changed

+182
-9
lines changed

2 files changed

+182
-9
lines changed

internal/searchindex/searchindex.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ type indexCleaner func(s *SearchIndex)
240240
func cleanConfigRef() indexCleaner {
241241
return func(s *SearchIndex) {
242242
if s.Search == nil {
243-
return
243+
s.Search = &akov2.Search{}
244244
}
245245
s.Search.SearchConfigurationRef.Name = ""
246246
s.Search.SearchConfigurationRef.Namespace = ""

pkg/controller/atlasdeployment/searchindexes_test.go

Lines changed: 181 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,12 @@ package atlasdeployment
22

33
import (
44
"context"
5+
"errors"
56
"fmt"
67
"net/http"
78
"testing"
89

9-
internal "github.com/mongodb/mongodb-atlas-kubernetes/v2/internal/searchindex"
10-
10+
"github.com/stretchr/testify/assert"
1111
"github.com/stretchr/testify/mock"
1212
"go.mongodb.org/atlas-sdk/v20231115008/admin"
1313
"go.mongodb.org/atlas-sdk/v20231115008/mockadmin"
@@ -18,14 +18,11 @@ import (
1818
"sigs.k8s.io/controller-runtime/pkg/client/fake"
1919

2020
"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"
2123
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/api/v1/common"
22-
"github.com/mongodb/mongodb-atlas-kubernetes/v2/pkg/controller/workflow"
23-
2424
"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"
2926
)
3027

3128
func Test_verifyAllIndexesNamesAreUnique(t *testing.T) {
@@ -316,6 +313,182 @@ func Test_SearchIndexesReconcile(t *testing.T) {
316313
assert.False(t, result.IsOk())
317314
})
318315

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+
319492
t.Run("Should proceed with the index Type Search: UPDATE INDEX", func(t *testing.T) {
320493
mockSearchAPI := mockadmin.NewAtlasSearchApi(t)
321494

0 commit comments

Comments
 (0)