github.com/verrazzano/verrazzano@v1.7.0/pkg/k8s/ready/daemonset_ready_test.go (about)

     1  // Copyright (c) 2022, Oracle and/or its affiliates.
     2  // Licensed under the Universal Permissive License v 1.0 as shown at https://oss.oracle.com/licenses/upl.
     3  
     4  package ready
     5  
     6  import (
     7  	"testing"
     8  
     9  	"github.com/stretchr/testify/assert"
    10  	"github.com/verrazzano/verrazzano/pkg/log/vzlog"
    11  	appsv1 "k8s.io/api/apps/v1"
    12  	corev1 "k8s.io/api/core/v1"
    13  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    14  	"k8s.io/apimachinery/pkg/types"
    15  	k8scheme "k8s.io/client-go/kubernetes/scheme"
    16  	"sigs.k8s.io/controller-runtime/pkg/client"
    17  	"sigs.k8s.io/controller-runtime/pkg/client/fake"
    18  )
    19  
    20  func TestDaemonSetsReady(t *testing.T) {
    21  
    22  	selector := &metav1.LabelSelector{
    23  		MatchLabels: map[string]string{
    24  			"app": "foo",
    25  		},
    26  	}
    27  	enoughReplicas := &appsv1.DaemonSet{
    28  		ObjectMeta: metav1.ObjectMeta{
    29  			Name:      "foo",
    30  			Namespace: "bar",
    31  		},
    32  		Spec: appsv1.DaemonSetSpec{
    33  			Selector: selector,
    34  		},
    35  		Status: appsv1.DaemonSetStatus{
    36  			NumberAvailable:        1,
    37  			UpdatedNumberScheduled: 1,
    38  		},
    39  	}
    40  	enoughReplicasMultiple := &appsv1.DaemonSet{
    41  		ObjectMeta: metav1.ObjectMeta{
    42  			Name:      "foo",
    43  			Namespace: "bar",
    44  		},
    45  		Spec: appsv1.DaemonSetSpec{
    46  			Selector: selector,
    47  		},
    48  		Status: appsv1.DaemonSetStatus{
    49  			NumberAvailable:        2,
    50  			UpdatedNumberScheduled: 2,
    51  		},
    52  	}
    53  	notEnoughReadyReplicas := &appsv1.DaemonSet{
    54  		ObjectMeta: metav1.ObjectMeta{
    55  			Name:      "foo",
    56  			Namespace: "bar",
    57  		},
    58  		Spec: appsv1.DaemonSetSpec{
    59  			Selector: selector,
    60  		},
    61  		Status: appsv1.DaemonSetStatus{
    62  			NumberAvailable:        0,
    63  			UpdatedNumberScheduled: 1,
    64  		},
    65  	}
    66  	notEnoughUpdatedReplicas := &appsv1.DaemonSet{
    67  		ObjectMeta: metav1.ObjectMeta{
    68  			Name:      "foo",
    69  			Namespace: "bar",
    70  		},
    71  		Spec: appsv1.DaemonSetSpec{
    72  			Selector: selector,
    73  		},
    74  		Status: appsv1.DaemonSetStatus{
    75  			NumberAvailable:        1,
    76  			UpdatedNumberScheduled: 0,
    77  		},
    78  	}
    79  
    80  	readyPod := &corev1.Pod{
    81  		ObjectMeta: metav1.ObjectMeta{
    82  			Name:      "foo-95d8c5d96-m6mbr",
    83  			Namespace: "bar",
    84  			Labels: map[string]string{
    85  				controllerRevisionHashLabel: "95d8c5d96",
    86  				"app":                       "foo",
    87  			},
    88  		},
    89  		Status: corev1.PodStatus{
    90  			ContainerStatuses: []corev1.ContainerStatus{
    91  				{
    92  					Ready: true,
    93  				},
    94  			},
    95  		},
    96  	}
    97  	notReadyContainerPod := &corev1.Pod{
    98  		ObjectMeta: metav1.ObjectMeta{
    99  			Name:      "foo-95d8c5d96-m6y76",
   100  			Namespace: "bar",
   101  			Labels: map[string]string{
   102  				controllerRevisionHashLabel: "95d8c5d96",
   103  				"app":                       "foo",
   104  			},
   105  		},
   106  		Status: corev1.PodStatus{
   107  			ContainerStatuses: []corev1.ContainerStatus{
   108  				{
   109  					Ready: false,
   110  				},
   111  			},
   112  		},
   113  	}
   114  	notReadyInitContainerPod := &corev1.Pod{
   115  		ObjectMeta: metav1.ObjectMeta{
   116  			Name:      "foo-95d8c5d96-m6mbr",
   117  			Namespace: "bar",
   118  			Labels: map[string]string{
   119  				controllerRevisionHashLabel: "95d8c5d96",
   120  				"app":                       "foo",
   121  			},
   122  		},
   123  		Status: corev1.PodStatus{
   124  			InitContainerStatuses: []corev1.ContainerStatus{
   125  				{
   126  					Ready: false,
   127  				},
   128  			},
   129  		},
   130  	}
   131  	noPodHashLabel := &corev1.Pod{
   132  		ObjectMeta: metav1.ObjectMeta{
   133  			Name:      "foo-95d8c5d96-m6mbr",
   134  			Namespace: "bar",
   135  			Labels: map[string]string{
   136  				"app": "foo",
   137  			},
   138  		},
   139  		Status: corev1.PodStatus{
   140  			ContainerStatuses: []corev1.ContainerStatus{
   141  				{
   142  					Ready: true,
   143  				},
   144  			},
   145  		},
   146  	}
   147  
   148  	controllerRevision := &appsv1.ControllerRevision{
   149  		ObjectMeta: metav1.ObjectMeta{
   150  			Name:      "foo-95d8c5d96",
   151  			Namespace: "bar",
   152  		},
   153  		Revision: 1,
   154  	}
   155  
   156  	namespacedName := []types.NamespacedName{
   157  		{
   158  			Name:      "foo",
   159  			Namespace: "bar",
   160  		},
   161  	}
   162  
   163  	var tests = []struct {
   164  		name     string
   165  		c        client.Client
   166  		n        []types.NamespacedName
   167  		ready    bool
   168  		expected int32
   169  	}{
   170  		{
   171  			"should be ready when daemonset has enough replicas and pod is ready",
   172  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(enoughReplicas, readyPod, controllerRevision).Build(),
   173  			namespacedName,
   174  			true,
   175  			1,
   176  		},
   177  		{
   178  			"should be ready when daemonset has enough replicas and one pod of two pods is ready",
   179  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(enoughReplicasMultiple, notReadyContainerPod, readyPod, controllerRevision).Build(),
   180  			namespacedName,
   181  			true,
   182  			1,
   183  		},
   184  		{
   185  			"should be not ready when expected pods ready not reached",
   186  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(enoughReplicasMultiple, readyPod, controllerRevision).Build(),
   187  			namespacedName,
   188  			false,
   189  			2,
   190  		},
   191  		{
   192  			"should be not ready when daemonset has enough replicas but pod init container pods is not ready",
   193  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(enoughReplicas, notReadyInitContainerPod, controllerRevision).Build(),
   194  			namespacedName,
   195  			false,
   196  			1,
   197  		},
   198  		{
   199  			"should be not ready when daemonset has enough replicas but pod container pods is not ready",
   200  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(enoughReplicas, notReadyContainerPod, controllerRevision).Build(),
   201  			namespacedName,
   202  			false,
   203  			1,
   204  		},
   205  		{
   206  			"should be not ready when pod not found for daemonset",
   207  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(enoughReplicas).Build(),
   208  			namespacedName,
   209  			false,
   210  			1,
   211  		},
   212  		{
   213  			"should be not ready when daemonset not found",
   214  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).Build(),
   215  			namespacedName,
   216  			false,
   217  			1,
   218  		},
   219  		{
   220  			"should be not ready when controller-revision-hash label not found",
   221  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(enoughReplicas, noPodHashLabel).Build(),
   222  			namespacedName,
   223  			false,
   224  			1,
   225  		},
   226  		{
   227  			"should be not ready when controllerrevision resource not found",
   228  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(enoughReplicas, readyPod).Build(),
   229  			namespacedName,
   230  			false,
   231  			1,
   232  		},
   233  		{
   234  			"should be not ready when daemonset doesn't have enough ready replicas",
   235  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(notEnoughReadyReplicas).Build(),
   236  			namespacedName,
   237  			false,
   238  			1,
   239  		},
   240  		{
   241  			"should be not ready when daemonset doesn't have enough updated replicas",
   242  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).WithObjects(notEnoughUpdatedReplicas).Build(),
   243  			namespacedName,
   244  			false,
   245  			1,
   246  		},
   247  		{
   248  			"should be ready when no PodReadyCheck provided",
   249  			fake.NewClientBuilder().WithScheme(k8scheme.Scheme).Build(),
   250  			[]types.NamespacedName{},
   251  			true,
   252  			1,
   253  		},
   254  	}
   255  
   256  	for _, tt := range tests {
   257  		t.Run(tt.name, func(t *testing.T) {
   258  			assert.Equal(t, tt.ready, DaemonSetsAreReady(vzlog.DefaultLogger(), tt.c, tt.n, tt.expected, ""))
   259  		})
   260  	}
   261  }