github.com/operator-framework/operator-lifecycle-manager@v0.30.0/pkg/lib/operatorstatus/csv_reporter_test.go (about)

     1  package operatorstatus
     2  
     3  import (
     4  	"testing"
     5  	"time"
     6  
     7  	"github.com/blang/semver/v4"
     8  	configv1 "github.com/openshift/api/config/v1"
     9  	"github.com/operator-framework/api/pkg/lib/version"
    10  	"github.com/operator-framework/api/pkg/operators/v1alpha1"
    11  	"github.com/operator-framework/operator-lifecycle-manager/pkg/lib/ownerutil"
    12  	"github.com/stretchr/testify/assert"
    13  	"github.com/stretchr/testify/require"
    14  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    15  	utilclock "k8s.io/utils/clock/testing"
    16  )
    17  
    18  func TestGetNewStatus(t *testing.T) {
    19  	fakeClock := utilclock.NewFakeClock(time.Now())
    20  
    21  	tests := []struct {
    22  		name     string
    23  		existing *configv1.ClusterOperatorStatus
    24  		context  *csvEventContext
    25  		expected *configv1.ClusterOperatorStatus
    26  	}{
    27  		// A CSV is being worked on. It has not succeeded or failed yet.
    28  		{
    29  			name: "WithCSVInProgress",
    30  			context: &csvEventContext{
    31  				Name:           "foo",
    32  				CurrentDeleted: false,
    33  				Current: &v1alpha1.ClusterServiceVersion{
    34  					ObjectMeta: metav1.ObjectMeta{
    35  						Name:      "foo",
    36  						Namespace: "foo-namespace",
    37  					},
    38  					Spec: v1alpha1.ClusterServiceVersionSpec{
    39  						Version: version.OperatorVersion{
    40  							Version: semver.Version{
    41  								Major: 1, Minor: 0, Patch: 0,
    42  							},
    43  						},
    44  					},
    45  					Status: v1alpha1.ClusterServiceVersionStatus{
    46  						Phase:   v1alpha1.CSVPhasePending,
    47  						Reason:  v1alpha1.CSVReasonWaiting,
    48  						Message: "Progressing towards 1.0.0",
    49  					},
    50  				},
    51  			},
    52  
    53  			expected: &configv1.ClusterOperatorStatus{
    54  				Conditions: []configv1.ClusterOperatorStatusCondition{
    55  					{
    56  						Type:               configv1.OperatorDegraded,
    57  						Status:             configv1.ConditionFalse,
    58  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
    59  					},
    60  					{
    61  						Type:               configv1.OperatorUpgradeable,
    62  						Status:             configv1.ConditionTrue,
    63  						Message:            "Safe to upgrade",
    64  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
    65  					},
    66  					{
    67  						Type:               configv1.OperatorProgressing,
    68  						Status:             configv1.ConditionTrue,
    69  						Message:            "Working toward 1.0.0",
    70  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
    71  					},
    72  				},
    73  				Versions: []configv1.OperandVersion{},
    74  				RelatedObjects: []configv1.ObjectReference{
    75  					{
    76  						Group:     "",
    77  						Resource:  "namespaces",
    78  						Namespace: "",
    79  						Name:      "foo-namespace",
    80  					},
    81  					{
    82  						Group:     v1alpha1.GroupName,
    83  						Resource:  clusterServiceVersionResource,
    84  						Namespace: "foo-namespace",
    85  						Name:      "foo",
    86  					},
    87  				},
    88  			},
    89  		},
    90  
    91  		{
    92  			name: "WithCSVInProgressAlreadyAvailableTrue",
    93  			context: &csvEventContext{
    94  				Name:           "foo",
    95  				CurrentDeleted: false,
    96  				Current: &v1alpha1.ClusterServiceVersion{
    97  					ObjectMeta: metav1.ObjectMeta{
    98  						Name:      "foo",
    99  						Namespace: "foo-namespace",
   100  					},
   101  					Spec: v1alpha1.ClusterServiceVersionSpec{
   102  						Version: version.OperatorVersion{
   103  							Version: semver.Version{
   104  								Major: 1, Minor: 0, Patch: 0,
   105  							},
   106  						},
   107  					},
   108  					Status: v1alpha1.ClusterServiceVersionStatus{
   109  						Phase:   v1alpha1.CSVPhasePending,
   110  						Reason:  v1alpha1.CSVReasonWaiting,
   111  						Message: "Progressing towards 1.0.0",
   112  					},
   113  				},
   114  			},
   115  			existing: &configv1.ClusterOperatorStatus{
   116  				Conditions: []configv1.ClusterOperatorStatusCondition{
   117  					{
   118  						Type:               configv1.OperatorAvailable,
   119  						Status:             configv1.ConditionTrue,
   120  						Message:            "test message",
   121  						Reason:             "test reason",
   122  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   123  					},
   124  				},
   125  			},
   126  
   127  			expected: &configv1.ClusterOperatorStatus{
   128  				Conditions: []configv1.ClusterOperatorStatusCondition{
   129  					{
   130  						Type:               configv1.OperatorAvailable,
   131  						Status:             configv1.ConditionTrue,
   132  						Message:            "test message",
   133  						Reason:             "test reason",
   134  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   135  					},
   136  					{
   137  						Type:               configv1.OperatorDegraded,
   138  						Status:             configv1.ConditionFalse,
   139  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   140  					},
   141  					{
   142  						Type:               configv1.OperatorUpgradeable,
   143  						Status:             configv1.ConditionTrue,
   144  						Message:            "Safe to upgrade",
   145  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   146  					},
   147  					{
   148  						Type:               configv1.OperatorProgressing,
   149  						Status:             configv1.ConditionTrue,
   150  						Message:            "Working toward 1.0.0",
   151  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   152  					},
   153  				},
   154  				RelatedObjects: []configv1.ObjectReference{
   155  					{
   156  						Group:     "",
   157  						Resource:  "namespaces",
   158  						Namespace: "",
   159  						Name:      "foo-namespace",
   160  					},
   161  					{
   162  						Group:     v1alpha1.GroupName,
   163  						Resource:  clusterServiceVersionResource,
   164  						Namespace: "foo-namespace",
   165  						Name:      "foo",
   166  					},
   167  				},
   168  			},
   169  		},
   170  
   171  		{
   172  			name: "WithCSVInProgressAlreadyAvailableFalse",
   173  			context: &csvEventContext{
   174  				Name:           "foo",
   175  				CurrentDeleted: false,
   176  				Current: &v1alpha1.ClusterServiceVersion{
   177  					ObjectMeta: metav1.ObjectMeta{
   178  						Name:      "foo",
   179  						Namespace: "foo-namespace",
   180  					},
   181  					Spec: v1alpha1.ClusterServiceVersionSpec{
   182  						Version: version.OperatorVersion{
   183  							Version: semver.Version{
   184  								Major: 1, Minor: 0, Patch: 0,
   185  							},
   186  						},
   187  					},
   188  					Status: v1alpha1.ClusterServiceVersionStatus{
   189  						Phase:   v1alpha1.CSVPhasePending,
   190  						Reason:  v1alpha1.CSVReasonWaiting,
   191  						Message: "Progressing towards 1.0.0",
   192  					},
   193  				},
   194  			},
   195  			existing: &configv1.ClusterOperatorStatus{
   196  				Conditions: []configv1.ClusterOperatorStatusCondition{
   197  					{
   198  						Type:               configv1.OperatorAvailable,
   199  						Status:             configv1.ConditionFalse,
   200  						Message:            "test message",
   201  						Reason:             "test reason",
   202  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   203  					},
   204  				},
   205  			},
   206  
   207  			expected: &configv1.ClusterOperatorStatus{
   208  				Conditions: []configv1.ClusterOperatorStatusCondition{
   209  					{
   210  						Type:               configv1.OperatorAvailable,
   211  						Status:             configv1.ConditionFalse,
   212  						Message:            "test message",
   213  						Reason:             "test reason",
   214  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   215  					},
   216  					{
   217  						Type:               configv1.OperatorDegraded,
   218  						Status:             configv1.ConditionFalse,
   219  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   220  					},
   221  					{
   222  						Type:               configv1.OperatorUpgradeable,
   223  						Status:             configv1.ConditionTrue,
   224  						Message:            "Safe to upgrade",
   225  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   226  					},
   227  					{
   228  						Type:               configv1.OperatorProgressing,
   229  						Status:             configv1.ConditionTrue,
   230  						Message:            "Working toward 1.0.0",
   231  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   232  					},
   233  				},
   234  				RelatedObjects: []configv1.ObjectReference{
   235  					{
   236  						Group:     "",
   237  						Resource:  "namespaces",
   238  						Namespace: "",
   239  						Name:      "foo-namespace",
   240  					},
   241  					{
   242  						Group:     v1alpha1.GroupName,
   243  						Resource:  clusterServiceVersionResource,
   244  						Namespace: "foo-namespace",
   245  						Name:      "foo",
   246  					},
   247  				},
   248  			},
   249  		},
   250  
   251  		{
   252  			name: "WithCSVSuccessfullyInstalled",
   253  			context: &csvEventContext{
   254  				Name:           "foo",
   255  				CurrentDeleted: false,
   256  				Current: &v1alpha1.ClusterServiceVersion{
   257  					ObjectMeta: metav1.ObjectMeta{
   258  						Name:      "foo",
   259  						Namespace: "foo-namespace",
   260  					},
   261  					Spec: v1alpha1.ClusterServiceVersionSpec{
   262  						Version: version.OperatorVersion{
   263  							Version: semver.Version{
   264  								Major: 1, Minor: 0, Patch: 0,
   265  							},
   266  						},
   267  					},
   268  					Status: v1alpha1.ClusterServiceVersionStatus{
   269  						Phase: v1alpha1.CSVPhaseSucceeded,
   270  					},
   271  				},
   272  			},
   273  
   274  			expected: &configv1.ClusterOperatorStatus{
   275  				Conditions: []configv1.ClusterOperatorStatusCondition{
   276  					{
   277  						Type:               configv1.OperatorDegraded,
   278  						Status:             configv1.ConditionFalse,
   279  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   280  					},
   281  					{
   282  						Type:               configv1.OperatorUpgradeable,
   283  						Status:             configv1.ConditionTrue,
   284  						Message:            "Safe to upgrade",
   285  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   286  					},
   287  					{
   288  						Type:               configv1.OperatorAvailable,
   289  						Status:             configv1.ConditionTrue,
   290  						Message:            "ClusterServiceVersion foo-namespace/foo observed in phase Succeeded",
   291  						Reason:             "ClusterServiceVersionSucceeded",
   292  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   293  					},
   294  					{
   295  						Type:               configv1.OperatorProgressing,
   296  						Status:             configv1.ConditionFalse,
   297  						Message:            "Deployed version 1.0.0",
   298  						LastTransitionTime: metav1.NewTime(fakeClock.Now()),
   299  					},
   300  				},
   301  				Versions: []configv1.OperandVersion{
   302  					{
   303  						Name:    "operator",
   304  						Version: "snapshot",
   305  					},
   306  					{
   307  						Name:    "foo",
   308  						Version: "1.0.0",
   309  					},
   310  				},
   311  				RelatedObjects: []configv1.ObjectReference{
   312  					{
   313  						Group:     "",
   314  						Resource:  "namespaces",
   315  						Namespace: "",
   316  						Name:      "foo-namespace",
   317  					},
   318  					{
   319  						Group:     v1alpha1.GroupName,
   320  						Resource:  clusterServiceVersionResource,
   321  						Namespace: "foo-namespace",
   322  						Name:      "foo",
   323  					},
   324  				},
   325  			},
   326  		},
   327  	}
   328  
   329  	for _, tt := range tests {
   330  		t.Run(tt.name, func(t *testing.T) {
   331  			reporter := &csvStatusReporter{
   332  				clock:          fakeClock,
   333  				releaseVersion: "snapshot",
   334  			}
   335  
   336  			err := ownerutil.InferGroupVersionKind(tt.context.Current)
   337  			require.NoError(t, err)
   338  
   339  			statusWant := tt.expected
   340  			statusGot := reporter.GetNewStatus(tt.existing, tt.context)
   341  
   342  			assert.Equal(t, statusWant, statusGot)
   343  		})
   344  	}
   345  }