github.com/argoproj/argo-cd/v3@v3.2.1/notification_controller/controller/controller_test.go (about)

     1  package controller
     2  
     3  import (
     4  	"context"
     5  	"testing"
     6  	"time"
     7  
     8  	"github.com/sirupsen/logrus/hooks/test"
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/stretchr/testify/require"
    11  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    12  	"k8s.io/apimachinery/pkg/runtime"
    13  	"k8s.io/client-go/dynamic/fake"
    14  	k8sfake "k8s.io/client-go/kubernetes/fake"
    15  	"k8s.io/client-go/tools/cache"
    16  
    17  	"github.com/argoproj/argo-cd/v3/pkg/apis/application/v1alpha1"
    18  )
    19  
    20  func TestIsAppSyncStatusRefreshed(t *testing.T) {
    21  	logger, _ := test.NewNullLogger()
    22  	logEntry := logger.WithField("", "")
    23  
    24  	tests := []struct {
    25  		name          string
    26  		app           *unstructured.Unstructured
    27  		expectedValue bool
    28  	}{
    29  		{
    30  			name: "No OperationState",
    31  			app: &unstructured.Unstructured{
    32  				Object: map[string]any{
    33  					"status": map[string]any{},
    34  				},
    35  			},
    36  			expectedValue: true,
    37  		},
    38  		{
    39  			name: "No FinishedAt, Completed Phase",
    40  			app: &unstructured.Unstructured{
    41  				Object: map[string]any{
    42  					"status": map[string]any{
    43  						"operationState": map[string]any{
    44  							"phase": "Succeeded",
    45  						},
    46  					},
    47  				},
    48  			},
    49  			expectedValue: false,
    50  		},
    51  		{
    52  			name: "FinishedAt After ReconciledAt & ObservedAt",
    53  			app: &unstructured.Unstructured{
    54  				Object: map[string]any{
    55  					"status": map[string]any{
    56  						"operationState": map[string]any{
    57  							"finishedAt": "2021-01-01T01:05:00Z",
    58  							"phase":      "Succeeded",
    59  						},
    60  						"reconciledAt": "2021-01-01T01:02:00Z",
    61  						"observedAt":   "2021-01-01T01:04:00Z",
    62  					},
    63  				},
    64  			},
    65  			expectedValue: false,
    66  		},
    67  		{
    68  			name: "FinishedAt Before ReconciledAt & ObservedAt",
    69  			app: &unstructured.Unstructured{
    70  				Object: map[string]any{
    71  					"status": map[string]any{
    72  						"operationState": map[string]any{
    73  							"finishedAt": "2021-01-01T01:02:00Z",
    74  							"phase":      "Succeeded",
    75  						},
    76  						"reconciledAt": "2021-01-01T01:04:00Z",
    77  						"observedAt":   "2021-01-01T01:06:00Z",
    78  					},
    79  				},
    80  			},
    81  			expectedValue: true,
    82  		},
    83  	}
    84  
    85  	for _, test := range tests {
    86  		t.Run(test.name, func(t *testing.T) {
    87  			actualValue := isAppSyncStatusRefreshed(test.app, logEntry)
    88  			assert.Equal(t, test.expectedValue, actualValue)
    89  		})
    90  	}
    91  }
    92  
    93  func TestGetAppProj_invalidProjectNestedString(t *testing.T) {
    94  	app := &unstructured.Unstructured{
    95  		Object: map[string]any{
    96  			"spec": map[string]any{},
    97  		},
    98  	}
    99  	informer := cache.NewSharedIndexInformer(nil, nil, 0, nil)
   100  	proj := getAppProj(app, informer)
   101  
   102  	assert.Nil(t, proj)
   103  }
   104  
   105  func TestInit(t *testing.T) {
   106  	scheme := runtime.NewScheme()
   107  	err := v1alpha1.SchemeBuilder.AddToScheme(scheme)
   108  	require.NoErrorf(t, err, "Error registering the resource")
   109  	dynamicClient := fake.NewSimpleDynamicClient(scheme)
   110  	k8sClient := k8sfake.NewSimpleClientset()
   111  	appLabelSelector := "app=test"
   112  
   113  	selfServiceNotificationEnabledFlags := []bool{false, true}
   114  	for _, selfServiceNotificationEnabled := range selfServiceNotificationEnabledFlags {
   115  		nc := NewController(
   116  			k8sClient,
   117  			dynamicClient,
   118  			nil,
   119  			"default",
   120  			[]string{},
   121  			appLabelSelector,
   122  			nil,
   123  			"my-secret",
   124  			"my-configmap",
   125  			selfServiceNotificationEnabled,
   126  		)
   127  
   128  		assert.NotNil(t, nc)
   129  
   130  		ctx, cancel := context.WithTimeout(t.Context(), 10*time.Second)
   131  		defer cancel()
   132  
   133  		err = nc.Init(ctx)
   134  
   135  		require.NoError(t, err)
   136  	}
   137  }
   138  
   139  func TestInitTimeout(t *testing.T) {
   140  	scheme := runtime.NewScheme()
   141  	err := v1alpha1.SchemeBuilder.AddToScheme(scheme)
   142  	require.NoErrorf(t, err, "Error registering the resource")
   143  	dynamicClient := fake.NewSimpleDynamicClient(scheme)
   144  	k8sClient := k8sfake.NewSimpleClientset()
   145  	appLabelSelector := "app=test"
   146  
   147  	nc := NewController(
   148  		k8sClient,
   149  		dynamicClient,
   150  		nil,
   151  		"default",
   152  		[]string{},
   153  		appLabelSelector,
   154  		nil,
   155  		"my-secret",
   156  		"my-configmap",
   157  		false,
   158  	)
   159  
   160  	assert.NotNil(t, nc)
   161  
   162  	// Use a short timeout to simulate a timeout during cache synchronization
   163  	ctx, cancel := context.WithTimeout(t.Context(), 1*time.Millisecond)
   164  	defer cancel()
   165  
   166  	err = nc.Init(ctx)
   167  
   168  	// Expect an error & add assertion for the error message
   169  	assert.EqualError(t, err, "timed out waiting for caches to sync")
   170  }
   171  
   172  func TestCheckAppNotInAdditionalNamespaces(t *testing.T) {
   173  	app := &unstructured.Unstructured{
   174  		Object: map[string]any{
   175  			"spec": map[string]any{},
   176  		},
   177  	}
   178  	namespace := "argocd"
   179  	var applicationNamespaces []string
   180  	applicationNamespaces = append(applicationNamespaces, "namespace1")
   181  	applicationNamespaces = append(applicationNamespaces, "namespace2")
   182  
   183  	// app is in same namespace as controller's namespace
   184  	app.SetNamespace(namespace)
   185  	assert.False(t, checkAppNotInAdditionalNamespaces(app, namespace, applicationNamespaces))
   186  
   187  	// app is not in the namespace as controller's namespace, but it is in one of the applicationNamespaces
   188  	app.SetNamespace("namespace2")
   189  	assert.False(t, checkAppNotInAdditionalNamespaces(app, "", applicationNamespaces))
   190  
   191  	// app is not in the namespace as controller's namespace, and it is not in any of the applicationNamespaces
   192  	app.SetNamespace("namespace3")
   193  	assert.True(t, checkAppNotInAdditionalNamespaces(app, "", applicationNamespaces))
   194  }