@@ -5,7 +5,10 @@ import (
55 "errors"
66 "reflect"
77 "testing"
8+ "time"
89
10+ "github.com/google/go-cmp/cmp"
11+ "github.com/google/go-cmp/cmp/cmpopts"
912 "github.com/stretchr/testify/assert"
1013 "github.com/stretchr/testify/mock"
1114 "go.mongodb.org/atlas-sdk/v20231115008/admin"
@@ -283,6 +286,172 @@ func TestTerminate(t *testing.T) {
283286 }
284287}
285288
289+ func TestReady (t * testing.T ) {
290+ tests := map [string ]struct {
291+ dbUser * akov2.AtlasDatabaseUser
292+ passwordVersion string
293+ interceptors interceptor.Funcs
294+
295+ expectedResult ctrl.Result
296+ expectedConditions []api.Condition
297+ }{
298+ "fail to set finalizer" : {
299+ dbUser : & akov2.AtlasDatabaseUser {
300+ ObjectMeta : metav1.ObjectMeta {
301+ Name : "user1" ,
302+ Namespace : "default" ,
303+ },
304+ Spec : akov2.AtlasDatabaseUserSpec {
305+ Project : & common.ResourceRefNamespaced {
306+ Name : "my-project" ,
307+ Namespace : "default" ,
308+ },
309+ Username : "user1" ,
310+ PasswordSecret : & common.ResourceRef {
311+ Name : "user-pass" ,
312+ },
313+ DatabaseName : "admin" ,
314+ },
315+ },
316+ passwordVersion : "1" ,
317+ interceptors : interceptor.Funcs {
318+ Patch : func (ctx context.Context , client client.WithWatch , obj client.Object , patch client.Patch , opts ... client.PatchOption ) error {
319+ return errors .New ("failed to set finalizer" )
320+ },
321+ },
322+ expectedResult : workflow .Terminate (workflow .AtlasFinalizerNotSet , "" ).ReconcileResult (),
323+ expectedConditions : []api.Condition {
324+ api .FalseCondition (api .DatabaseUserReadyType ).
325+ WithReason (string (workflow .AtlasFinalizerNotSet )).
326+ WithMessageRegexp ("failed to set finalizer" ),
327+ },
328+ },
329+ "fail to set last applied config" : {
330+ dbUser : & akov2.AtlasDatabaseUser {
331+ ObjectMeta : metav1.ObjectMeta {
332+ Name : "user1" ,
333+ Namespace : "default" ,
334+ },
335+ Spec : akov2.AtlasDatabaseUserSpec {
336+ Project : & common.ResourceRefNamespaced {
337+ Name : "my-project" ,
338+ Namespace : "default" ,
339+ },
340+ Username : "user1" ,
341+ PasswordSecret : & common.ResourceRef {
342+ Name : "user-pass" ,
343+ },
344+ DatabaseName : "admin" ,
345+ },
346+ },
347+ passwordVersion : "1" ,
348+ interceptors : interceptor.Funcs {
349+ Patch : func (ctx context.Context , client client.WithWatch , obj client.Object , patch client.Patch , opts ... client.PatchOption ) error {
350+ if patch .Type () == types .JSONPatchType {
351+ return nil
352+ }
353+
354+ return errors .New ("failed to set last applied config" )
355+ },
356+ },
357+ expectedResult : workflow .Terminate (workflow .Internal , "" ).ReconcileResult (),
358+ expectedConditions : []api.Condition {
359+ api .FalseCondition (api .DatabaseUserReadyType ).
360+ WithReason (string (workflow .Internal )).
361+ WithMessageRegexp ("failed to set last applied config" ),
362+ },
363+ },
364+ "don't requeue when it's a linked resource" : {
365+ dbUser : & akov2.AtlasDatabaseUser {
366+ ObjectMeta : metav1.ObjectMeta {
367+ Name : "user1" ,
368+ Namespace : "default" ,
369+ },
370+ Spec : akov2.AtlasDatabaseUserSpec {
371+ Project : & common.ResourceRefNamespaced {
372+ Name : "my-project" ,
373+ Namespace : "default" ,
374+ },
375+ Username : "user1" ,
376+ PasswordSecret : & common.ResourceRef {
377+ Name : "user-pass" ,
378+ },
379+ DatabaseName : "admin" ,
380+ },
381+ },
382+ passwordVersion : "1" ,
383+ expectedResult : workflow .OK ().ReconcileResult (),
384+ expectedConditions : []api.Condition {
385+ api .TrueCondition (api .ReadyType ),
386+ api .TrueCondition (api .DatabaseUserReadyType ),
387+ },
388+ },
389+ "don't requeue when it's a standalone resource" : {
390+ dbUser : & akov2.AtlasDatabaseUser {
391+ ObjectMeta : metav1.ObjectMeta {
392+ Name : "user1" ,
393+ Namespace : "default" ,
394+ },
395+ Spec : akov2.AtlasDatabaseUserSpec {
396+ ExternalProjectRef : & akov2.ExternalProjectReference {
397+ ID : "project-id" ,
398+ },
399+ LocalCredentialHolder : api.LocalCredentialHolder {
400+ ConnectionSecret : & api.LocalObjectReference {
401+ Name : "user-creds" ,
402+ },
403+ },
404+ Username : "user1" ,
405+ PasswordSecret : & common.ResourceRef {
406+ Name : "user-pass" ,
407+ },
408+ DatabaseName : "admin" ,
409+ },
410+ },
411+ passwordVersion : "1" ,
412+ expectedResult : workflow .Requeue (15 * time .Minute ).ReconcileResult (),
413+ expectedConditions : []api.Condition {
414+ api .TrueCondition (api .ReadyType ),
415+ api .TrueCondition (api .DatabaseUserReadyType ),
416+ },
417+ },
418+ }
419+
420+ for name , tt := range tests {
421+ t .Run (name , func (t * testing.T ) {
422+ testScheme := runtime .NewScheme ()
423+ assert .NoError (t , akov2 .AddToScheme (testScheme ))
424+ assert .NoError (t , corev1 .AddToScheme (testScheme ))
425+ k8sClient := fake .NewClientBuilder ().
426+ WithScheme (testScheme ).
427+ WithObjects (tt .dbUser ).
428+ WithStatusSubresource (tt .dbUser ).
429+ WithInterceptorFuncs (tt .interceptors ).
430+ Build ()
431+
432+ logger := zaptest .NewLogger (t ).Sugar ()
433+ c := & AtlasDatabaseUserReconciler {
434+ Client : k8sClient ,
435+ Log : logger ,
436+ }
437+ ctx := & workflow.Context {
438+ Context : context .Background (),
439+ Log : logger ,
440+ }
441+
442+ assert .Equal (t , tt .expectedResult , c .ready (ctx , tt .dbUser , tt .passwordVersion ))
443+ assert .True (
444+ t ,
445+ cmp .Equal (
446+ tt .expectedConditions ,
447+ ctx .Conditions (),
448+ cmpopts .IgnoreFields (api.Condition {}, "LastTransitionTime" ),
449+ ),
450+ )
451+ })
452+ }
453+ }
454+
286455func TestFindAtlasDatabaseUserForSecret (t * testing.T ) {
287456 for _ , tc := range []struct {
288457 name string
0 commit comments