github.com/GoogleContainerTools/kpt@v1.0.0-beta.50.0.20240520170205-c25345ffcbee/pkg/status/rollout_test.go (about)

     1  // Copyright 2021 The kpt Authors
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //      http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  package status
    16  
    17  import (
    18  	"context"
    19  	"testing"
    20  
    21  	"github.com/stretchr/testify/assert"
    22  	"k8s.io/apimachinery/pkg/runtime/schema"
    23  	"sigs.k8s.io/cli-utils/pkg/kstatus/polling/testutil"
    24  	"sigs.k8s.io/cli-utils/pkg/kstatus/status"
    25  	"sigs.k8s.io/cli-utils/pkg/object"
    26  	fakemapper "sigs.k8s.io/cli-utils/pkg/testutil"
    27  )
    28  
    29  func TestRolloutSupports(t *testing.T) {
    30  	testCases := map[string]struct {
    31  		gk       schema.GroupKind
    32  		supports bool
    33  	}{
    34  		"matches rollout group": {
    35  			gk: schema.GroupKind{
    36  				Group: "argoproj.io",
    37  				Kind:  "Rollout",
    38  			},
    39  			supports: true,
    40  		},
    41  		"doesn't match other resources": {
    42  			gk: schema.GroupKind{
    43  				Group: "apps",
    44  				Kind:  "StatefulSet",
    45  			},
    46  			supports: false,
    47  		},
    48  	}
    49  
    50  	for tn, tc := range testCases {
    51  		t.Run(tn, func(t *testing.T) {
    52  			fakeMapper := fakemapper.NewFakeRESTMapper()
    53  
    54  			statusReader := &RolloutStatusReader{
    55  				Mapper: fakeMapper,
    56  			}
    57  
    58  			supports := statusReader.Supports(tc.gk)
    59  
    60  			assert.Equal(t, tc.supports, supports)
    61  		})
    62  	}
    63  }
    64  
    65  func TestRolloutReadStatus(t *testing.T) {
    66  	testCases := map[string]struct {
    67  		resource       string
    68  		gvk            schema.GroupVersionKind
    69  		expectedStatus status.Status
    70  		expectedMsg    string
    71  	}{
    72  		"Resource where observedGeneration doesn't match generation is InProgress": {
    73  			resource: `
    74  apiVersion: argoproj.io/v1alpha1
    75  kind: Rollout
    76  metadata:
    77    name: pubsub.googleapis.com
    78    namespace: cnrm
    79    generation: 42
    80  status:
    81    observedGeneration: "41"
    82  `,
    83  			gvk: schema.GroupVersionKind{
    84  				Group:   "argoproj.io",
    85  				Version: "v1alpha1",
    86  				Kind:    "Rollout",
    87  			},
    88  			expectedStatus: status.InProgressStatus,
    89  			expectedMsg:    "Rollout generation is 42, but latest observed generation is 41",
    90  		},
    91  		"Resource when spec.replicas more than status.replicas is InProgress": {
    92  			resource: `
    93  apiVersion: argoproj.io/v1alpha1
    94  kind: Rollout
    95  metadata:
    96    name: pubsub.googleapis.com
    97    namespace: cnrm
    98    generation: 42
    99  spec:
   100    replicas: 2
   101  status:
   102    observedGeneration: "42"
   103    replicas: 1
   104    phase: Progressing
   105  `,
   106  			gvk: schema.GroupVersionKind{
   107  				Group:   "argoproj.io",
   108  				Kind:    "Rollout",
   109  				Version: "v1alpha1",
   110  			},
   111  			expectedStatus: status.InProgressStatus,
   112  			expectedMsg:    "replicas: 1/2",
   113  		},
   114  		"Resource when status.replicas more than spec.replicas is InProgress": {
   115  			resource: `
   116  apiVersion: argoproj.io/v1alpha1
   117  kind: Rollout
   118  metadata:
   119    name: pubsub.googleapis.com
   120    namespace: cnrm
   121    generation: 42
   122  spec:
   123    replicas: 1
   124  status:
   125    observedGeneration: "42"
   126    replicas: 2
   127    phase: Progressing
   128  `,
   129  			gvk: schema.GroupVersionKind{
   130  				Group:   "argoproj.io",
   131  				Kind:    "Rollout",
   132  				Version: "v1alpha1",
   133  			},
   134  			expectedStatus: status.InProgressStatus,
   135  			expectedMsg:    "Pending termination: 1",
   136  		},
   137  		"Resource when status.updatedReplicas more than spec.availableReplicas is InProgress": {
   138  			resource: `
   139  apiVersion: argoproj.io/v1alpha1
   140  kind: Rollout
   141  metadata:
   142    name: pubsub.googleapis.com
   143    namespace: cnrm
   144    generation: 42
   145  spec:
   146    replicas: 2
   147  status:
   148    observedGeneration: "42"
   149    replicas: 2
   150    updatedReplicas: 2
   151    availableReplicas: 1
   152    phase: Progressing
   153  `,
   154  			gvk: schema.GroupVersionKind{
   155  				Group:   "argoproj.io",
   156  				Kind:    "Rollout",
   157  				Version: "v1alpha1",
   158  			},
   159  			expectedStatus: status.InProgressStatus,
   160  			expectedMsg:    "Available: 1/2",
   161  		},
   162  		"Resource when spec.replicas more than spec.readyReplicas is InProgress": {
   163  			resource: `
   164  apiVersion: argoproj.io/v1alpha1
   165  kind: Rollout
   166  metadata:
   167    name: pubsub.googleapis.com
   168    namespace: cnrm
   169    generation: 42
   170  spec:
   171    replicas: 2
   172  status:
   173    observedGeneration: "42"
   174    replicas: 2
   175    updatedReplicas: 2
   176    availableReplicas: 2
   177    readyReplicas: 1
   178    phase: Progressing
   179  `,
   180  			gvk: schema.GroupVersionKind{
   181  				Group:   "argoproj.io",
   182  				Kind:    "Rollout",
   183  				Version: "v1alpha1",
   184  			},
   185  			expectedStatus: status.InProgressStatus,
   186  			expectedMsg:    "Ready: 1/2",
   187  		},
   188  		"Resource when status.phase is Degraded is Failed": {
   189  			resource: `
   190  apiVersion: argoproj.io/v1alpha1
   191  kind: Rollout
   192  metadata:
   193    name: pubsub.googleapis.com
   194    namespace: cnrm
   195    generation: 42
   196  spec:
   197    replicas: 2
   198  status:
   199    observedGeneration: "42"
   200    replicas: 2
   201    updatedReplicas: 2
   202    availableReplicas: 2
   203    readyReplicas: 2
   204    phase: Degraded
   205  `,
   206  			gvk: schema.GroupVersionKind{
   207  				Group:   "argoproj.io",
   208  				Kind:    "Rollout",
   209  				Version: "v1alpha1",
   210  			},
   211  			expectedStatus: status.FailedStatus,
   212  			expectedMsg:    "Ready Replicas: 2, Updated Replicas: 2",
   213  		},
   214  		"Resource when status.phase is Failed is Failed": {
   215  			resource: `
   216  apiVersion: argoproj.io/v1alpha1
   217  kind: Rollout
   218  metadata:
   219    name: pubsub.googleapis.com
   220    namespace: cnrm
   221    generation: 42
   222  spec:
   223    replicas: 2
   224  status:
   225    observedGeneration: "42"
   226    replicas: 2
   227    updatedReplicas: 2
   228    availableReplicas: 2
   229    readyReplicas: 2
   230    phase: Failed
   231  `,
   232  			gvk: schema.GroupVersionKind{
   233  				Group:   "argoproj.io",
   234  				Kind:    "Rollout",
   235  				Version: "v1alpha1",
   236  			},
   237  			expectedStatus: status.FailedStatus,
   238  			expectedMsg:    "Ready Replicas: 2, Updated Replicas: 2",
   239  		},
   240  		"Resource when status.phase is Healthy is Current": {
   241  			resource: `
   242  apiVersion: argoproj.io/v1alpha1
   243  kind: Rollout
   244  metadata:
   245    name: pubsub.googleapis.com
   246    namespace: cnrm
   247    generation: 42
   248  spec:
   249    replicas: 2
   250  status:
   251    observedGeneration: "42"
   252    replicas: 2
   253    updatedReplicas: 2
   254    availableReplicas: 2
   255    readyReplicas: 2
   256    phase: Healthy
   257  `,
   258  			gvk: schema.GroupVersionKind{
   259  				Group:   "argoproj.io",
   260  				Kind:    "Rollout",
   261  				Version: "v1alpha1",
   262  			},
   263  			expectedStatus: status.CurrentStatus,
   264  			expectedMsg:    "Ready Replicas: 2, Updated Replicas: 2",
   265  		},
   266  		"Resource when status.phase is Paused is InProgress": {
   267  			resource: `
   268  apiVersion: argoproj.io/v1alpha1
   269  kind: Rollout
   270  metadata:
   271    name: pubsub.googleapis.com
   272    namespace: cnrm
   273    generation: 42
   274  spec:
   275    replicas: 2
   276  status:
   277    observedGeneration: "42"
   278    replicas: 2
   279    updatedReplicas: 2
   280    availableReplicas: 2
   281    readyReplicas: 2
   282    phase: Paused
   283  `,
   284  			gvk: schema.GroupVersionKind{
   285  				Group:   "argoproj.io",
   286  				Kind:    "Rollout",
   287  				Version: "v1alpha1",
   288  			},
   289  			expectedStatus: status.InProgressStatus,
   290  			expectedMsg:    "Ready Replicas: 2, Updated Replicas: 2",
   291  		},
   292  		"Resource when status.phase is Progressing is InProgress": {
   293  			resource: `
   294  apiVersion: argoproj.io/v1alpha1
   295  kind: Rollout
   296  metadata:
   297    name: pubsub.googleapis.com
   298    namespace: cnrm
   299    generation: 42
   300  spec:
   301    replicas: 2
   302  status:
   303    observedGeneration: "42"
   304    replicas: 2
   305    updatedReplicas: 2
   306    availableReplicas: 2
   307    readyReplicas: 2
   308    phase: Progressing
   309  `,
   310  			gvk: schema.GroupVersionKind{
   311  				Group:   "argoproj.io",
   312  				Kind:    "Rollout",
   313  				Version: "v1alpha1",
   314  			},
   315  			expectedStatus: status.InProgressStatus,
   316  			expectedMsg:    "Ready Replicas: 2, Updated Replicas: 2",
   317  		},
   318  	}
   319  
   320  	for tn, tc := range testCases {
   321  		t.Run(tn, func(t *testing.T) {
   322  			obj := testutil.YamlToUnstructured(t, tc.resource)
   323  
   324  			fakeClusterReader := &fakeClusterReader{
   325  				getResource: obj,
   326  			}
   327  
   328  			fakeMapper := fakemapper.NewFakeRESTMapper(tc.gvk)
   329  			statusReader := &RolloutStatusReader{
   330  				Mapper: fakeMapper,
   331  			}
   332  
   333  			res, err := statusReader.ReadStatus(context.Background(), fakeClusterReader, object.UnstructuredToObjMetadata(obj))
   334  			assert.NoError(t, err)
   335  			assert.Equal(t, tc.expectedStatus, res.Status)
   336  			assert.Equal(t, tc.expectedMsg, res.Message)
   337  		})
   338  	}
   339  }