sigs.k8s.io/cluster-api@v1.7.1/util/annotations/helpers_test.go (about)

     1  /*
     2  Copyright 2020 The Kubernetes Authors.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8      http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  
    17  package annotations
    18  
    19  import (
    20  	"testing"
    21  
    22  	. "github.com/onsi/gomega"
    23  	corev1 "k8s.io/api/core/v1"
    24  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    25  	"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
    26  )
    27  
    28  func TestAddAnnotations(t *testing.T) {
    29  	g := NewWithT(t)
    30  
    31  	testcases := []struct {
    32  		name     string
    33  		obj      metav1.Object
    34  		input    map[string]string
    35  		expected map[string]string
    36  		changed  bool
    37  	}{
    38  		{
    39  			name: "should return false if no changes are made",
    40  			obj: &corev1.Node{
    41  				ObjectMeta: metav1.ObjectMeta{
    42  					Annotations: map[string]string{
    43  						"foo": "bar",
    44  					},
    45  				},
    46  				Spec:   corev1.NodeSpec{},
    47  				Status: corev1.NodeStatus{},
    48  			},
    49  			input: map[string]string{
    50  				"foo": "bar",
    51  			},
    52  			expected: map[string]string{
    53  				"foo": "bar",
    54  			},
    55  			changed: false,
    56  		},
    57  		{
    58  			name: "should do nothing if no annotations are provided",
    59  			obj: &corev1.Node{
    60  				ObjectMeta: metav1.ObjectMeta{
    61  					Annotations: map[string]string{
    62  						"foo": "bar",
    63  					},
    64  				},
    65  				Spec:   corev1.NodeSpec{},
    66  				Status: corev1.NodeStatus{},
    67  			},
    68  			input: map[string]string{},
    69  			expected: map[string]string{
    70  				"foo": "bar",
    71  			},
    72  			changed: false,
    73  		},
    74  		{
    75  			name: "should do nothing if no annotations are provided and have been nil before",
    76  			obj: &corev1.Node{
    77  				ObjectMeta: metav1.ObjectMeta{
    78  					Annotations: nil,
    79  				},
    80  				Spec:   corev1.NodeSpec{},
    81  				Status: corev1.NodeStatus{},
    82  			},
    83  			input:    map[string]string{},
    84  			expected: nil,
    85  			changed:  false,
    86  		},
    87  		{
    88  			name: "should return true if annotations are added",
    89  			obj: &corev1.Node{
    90  				ObjectMeta: metav1.ObjectMeta{
    91  					Annotations: map[string]string{
    92  						"foo": "bar",
    93  					},
    94  				},
    95  				Spec:   corev1.NodeSpec{},
    96  				Status: corev1.NodeStatus{},
    97  			},
    98  			input: map[string]string{
    99  				"thing1": "thing2",
   100  				"buzz":   "blah",
   101  			},
   102  			expected: map[string]string{
   103  				"foo":    "bar",
   104  				"thing1": "thing2",
   105  				"buzz":   "blah",
   106  			},
   107  			changed: true,
   108  		},
   109  		{
   110  			name: "should return true if annotations are changed",
   111  			obj: &corev1.Node{
   112  				ObjectMeta: metav1.ObjectMeta{
   113  					Annotations: map[string]string{
   114  						"foo": "bar",
   115  					},
   116  				},
   117  				Spec:   corev1.NodeSpec{},
   118  				Status: corev1.NodeStatus{},
   119  			},
   120  			input: map[string]string{
   121  				"foo": "buzz",
   122  			},
   123  			expected: map[string]string{
   124  				"foo": "buzz",
   125  			},
   126  			changed: true,
   127  		},
   128  		{
   129  			name: "should return true if annotations are changed and have been nil before",
   130  			obj: &corev1.Node{
   131  				ObjectMeta: metav1.ObjectMeta{
   132  					Annotations: nil,
   133  				},
   134  				Spec:   corev1.NodeSpec{},
   135  				Status: corev1.NodeStatus{},
   136  			},
   137  			input: map[string]string{
   138  				"foo": "buzz",
   139  			},
   140  			expected: map[string]string{
   141  				"foo": "buzz",
   142  			},
   143  			changed: true,
   144  		},
   145  		{
   146  			name: "should add annotations to an empty unstructured",
   147  			obj:  &unstructured.Unstructured{},
   148  			input: map[string]string{
   149  				"foo": "buzz",
   150  			},
   151  			expected: map[string]string{
   152  				"foo": "buzz",
   153  			},
   154  			changed: true,
   155  		},
   156  		{
   157  			name: "should add annotations to a non empty unstructured",
   158  			obj: &unstructured.Unstructured{
   159  				Object: map[string]interface{}{
   160  					"metadata": map[string]interface{}{
   161  						"annotations": map[string]interface{}{
   162  							"foo": "bar",
   163  						},
   164  					},
   165  				},
   166  			},
   167  			input: map[string]string{
   168  				"thing1": "thing2",
   169  				"buzz":   "blah",
   170  			},
   171  			expected: map[string]string{
   172  				"foo":    "bar",
   173  				"thing1": "thing2",
   174  				"buzz":   "blah",
   175  			},
   176  			changed: true,
   177  		},
   178  	}
   179  
   180  	for _, tc := range testcases {
   181  		t.Run(tc.name, func(*testing.T) {
   182  			res := AddAnnotations(tc.obj, tc.input)
   183  			g.Expect(res).To(Equal(tc.changed))
   184  			g.Expect(tc.obj.GetAnnotations()).To(Equal(tc.expected))
   185  		})
   186  	}
   187  }
   188  
   189  func TestHasTruthyAnnotationValue(t *testing.T) {
   190  	tests := []struct {
   191  		name          string
   192  		obj           metav1.Object
   193  		annotationKey string
   194  		expected      bool
   195  	}{
   196  		{
   197  			name: "annotation does not exist",
   198  			obj: &corev1.Node{
   199  				ObjectMeta: metav1.ObjectMeta{
   200  					Annotations: map[string]string{
   201  						"cluster.x-k8s.io/some-other-annotation": "",
   202  					},
   203  				},
   204  				Spec:   corev1.NodeSpec{},
   205  				Status: corev1.NodeStatus{},
   206  			},
   207  			annotationKey: "cluster.x-k8s.io/replicas-managed-by",
   208  			expected:      false,
   209  		},
   210  		{
   211  			name: "no val",
   212  			obj: &corev1.Node{
   213  				ObjectMeta: metav1.ObjectMeta{
   214  					Annotations: map[string]string{
   215  						"cluster.x-k8s.io/replicas-managed-by": "",
   216  					},
   217  				},
   218  				Spec:   corev1.NodeSpec{},
   219  				Status: corev1.NodeStatus{},
   220  			},
   221  			annotationKey: "cluster.x-k8s.io/replicas-managed-by",
   222  			expected:      true,
   223  		},
   224  		{
   225  			name: "annotation exists, true value",
   226  			obj: &corev1.Node{
   227  				ObjectMeta: metav1.ObjectMeta{
   228  					Annotations: map[string]string{
   229  						"cluster.x-k8s.io/replicas-managed-by": "true",
   230  					},
   231  				},
   232  				Spec:   corev1.NodeSpec{},
   233  				Status: corev1.NodeStatus{},
   234  			},
   235  			annotationKey: "cluster.x-k8s.io/replicas-managed-by",
   236  			expected:      true,
   237  		},
   238  		{
   239  			name: "annotation exists, random string value",
   240  			obj: &corev1.Node{
   241  				ObjectMeta: metav1.ObjectMeta{
   242  					Annotations: map[string]string{
   243  						"cluster.x-k8s.io/replicas-managed-by": "foo",
   244  					},
   245  				},
   246  				Spec:   corev1.NodeSpec{},
   247  				Status: corev1.NodeStatus{},
   248  			},
   249  			annotationKey: "cluster.x-k8s.io/replicas-managed-by",
   250  			expected:      true,
   251  		},
   252  		{
   253  			name: "annotation exists, false value",
   254  			obj: &corev1.Node{
   255  				ObjectMeta: metav1.ObjectMeta{
   256  					Annotations: map[string]string{
   257  						"cluster.x-k8s.io/replicas-managed-by": "false",
   258  					},
   259  				},
   260  				Spec:   corev1.NodeSpec{},
   261  				Status: corev1.NodeStatus{},
   262  			},
   263  			annotationKey: "cluster.x-k8s.io/replicas-managed-by",
   264  			expected:      false,
   265  		},
   266  	}
   267  	for _, tt := range tests {
   268  		tt := tt
   269  		t.Run(tt.name, func(t *testing.T) {
   270  			g := NewWithT(t)
   271  			ret := hasTruthyAnnotationValue(tt.obj, tt.annotationKey)
   272  			if tt.expected {
   273  				g.Expect(ret).To(BeTrue())
   274  			} else {
   275  				g.Expect(ret).To(BeFalse())
   276  			}
   277  		})
   278  	}
   279  }