github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/apis/meta/v1/helpers_test.go (about) 1 /* 2 Copyright 2016 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 v1 18 19 import ( 20 "fmt" 21 "reflect" 22 "strings" 23 "testing" 24 25 "github.com/google/gofuzz" 26 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/labels" 27 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/types" 28 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/diff" 29 ) 30 31 func TestLabelSelectorAsSelector(t *testing.T) { 32 matchLabels := map[string]string{"foo": "bar"} 33 matchExpressions := []LabelSelectorRequirement{{ 34 Key: "baz", 35 Operator: LabelSelectorOpIn, 36 Values: []string{"qux", "norf"}, 37 }} 38 mustParse := func(s string) labels.Selector { 39 out, e := labels.Parse(s) 40 if e != nil { 41 panic(e) 42 } 43 return out 44 } 45 tc := []struct { 46 in *LabelSelector 47 out labels.Selector 48 expectErr bool 49 }{ 50 {in: nil, out: labels.Nothing()}, 51 {in: &LabelSelector{}, out: labels.Everything()}, 52 { 53 in: &LabelSelector{MatchLabels: matchLabels}, 54 out: mustParse("foo=bar"), 55 }, 56 { 57 in: &LabelSelector{MatchExpressions: matchExpressions}, 58 out: mustParse("baz in (norf,qux)"), 59 }, 60 { 61 in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions}, 62 out: mustParse("baz in (norf,qux),foo=bar"), 63 }, 64 { 65 in: &LabelSelector{ 66 MatchExpressions: []LabelSelectorRequirement{{ 67 Key: "baz", 68 Operator: LabelSelectorOpExists, 69 Values: []string{"qux", "norf"}, 70 }}, 71 }, 72 expectErr: true, 73 }, 74 } 75 76 for i, tc := range tc { 77 inCopy := tc.in.DeepCopy() 78 out, err := LabelSelectorAsSelector(tc.in) 79 // after calling LabelSelectorAsSelector, tc.in shouldn't be modified 80 if !reflect.DeepEqual(inCopy, tc.in) { 81 t.Errorf("[%v]expected:\n\t%#v\nbut got:\n\t%#v", i, inCopy, tc.in) 82 } 83 if err == nil && tc.expectErr { 84 t.Errorf("[%v]expected error but got none.", i) 85 } 86 if err != nil && !tc.expectErr { 87 t.Errorf("[%v]did not expect error but got: %v", i, err) 88 } 89 // fmt.Sprint() over String() as nil.String() will panic 90 if fmt.Sprint(out) != fmt.Sprint(tc.out) { 91 t.Errorf("[%v]expected:\n\t%s\nbut got:\n\t%s", i, fmt.Sprint(tc.out), fmt.Sprint(out)) 92 } 93 } 94 } 95 96 func BenchmarkLabelSelectorAsSelector(b *testing.B) { 97 selector := &LabelSelector{ 98 MatchLabels: map[string]string{ 99 "foo": "foo", 100 "bar": "bar", 101 }, 102 MatchExpressions: []LabelSelectorRequirement{{ 103 Key: "baz", 104 Operator: LabelSelectorOpExists, 105 }}, 106 } 107 b.StartTimer() 108 for i := 0; i < b.N; i++ { 109 _, err := LabelSelectorAsSelector(selector) 110 if err != nil { 111 b.Fatal(err) 112 } 113 } 114 } 115 116 func TestLabelSelectorAsMap(t *testing.T) { 117 matchLabels := map[string]string{"foo": "bar"} 118 matchExpressions := func(operator LabelSelectorOperator, values []string) []LabelSelectorRequirement { 119 return []LabelSelectorRequirement{{ 120 Key: "baz", 121 Operator: operator, 122 Values: values, 123 }} 124 } 125 126 tests := []struct { 127 in *LabelSelector 128 out map[string]string 129 errString string 130 }{ 131 {in: nil, out: nil}, 132 { 133 in: &LabelSelector{MatchLabels: matchLabels}, 134 out: map[string]string{"foo": "bar"}, 135 }, 136 { 137 in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf"})}, 138 out: map[string]string{"foo": "bar", "baz": "norf"}, 139 }, 140 { 141 in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf"})}, 142 out: map[string]string{"baz": "norf"}, 143 }, 144 { 145 in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpIn, []string{"norf", "qux"})}, 146 out: map[string]string{"foo": "bar"}, 147 errString: "without a single value cannot be converted", 148 }, 149 { 150 in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpNotIn, []string{"norf", "qux"})}, 151 out: map[string]string{}, 152 errString: "cannot be converted", 153 }, 154 { 155 in: &LabelSelector{MatchLabels: matchLabels, MatchExpressions: matchExpressions(LabelSelectorOpExists, []string{})}, 156 out: map[string]string{"foo": "bar"}, 157 errString: "cannot be converted", 158 }, 159 { 160 in: &LabelSelector{MatchExpressions: matchExpressions(LabelSelectorOpDoesNotExist, []string{})}, 161 out: map[string]string{}, 162 errString: "cannot be converted", 163 }, 164 } 165 166 for i, tc := range tests { 167 out, err := LabelSelectorAsMap(tc.in) 168 if err == nil && len(tc.errString) > 0 { 169 t.Errorf("[%v]expected error but got none.", i) 170 continue 171 } 172 if err != nil && len(tc.errString) == 0 { 173 t.Errorf("[%v]did not expect error but got: %v", i, err) 174 continue 175 } 176 if err != nil && len(tc.errString) > 0 && !strings.Contains(err.Error(), tc.errString) { 177 t.Errorf("[%v]expected error with %q but got: %v", i, tc.errString, err) 178 continue 179 } 180 if !reflect.DeepEqual(out, tc.out) { 181 t.Errorf("[%v]expected:\n\t%+v\nbut got:\n\t%+v", i, tc.out, out) 182 } 183 } 184 } 185 186 func TestResetObjectMetaForStatus(t *testing.T) { 187 meta := &ObjectMeta{} 188 existingMeta := &ObjectMeta{} 189 190 // fuzz the existingMeta to set every field, no nils 191 f := fuzz.New().NilChance(0).NumElements(1, 1).MaxDepth(10) 192 f.Fuzz(existingMeta) 193 ResetObjectMetaForStatus(meta, existingMeta) 194 195 // not all fields are stomped during the reset. These fields should not have been set. False 196 // set them all to their zero values. Before you add anything to this list, consider whether or not 197 // you're enforcing immutability (those are fine) and whether /status should be able to update 198 // these values (these are usually not fine). 199 200 // generateName doesn't do anything after create 201 existingMeta.SetGenerateName("") 202 // resourceVersion is enforced in validation and used during the storage update 203 existingMeta.SetResourceVersion("") 204 // fields made immutable in validation 205 existingMeta.SetUID(types.UID("")) 206 existingMeta.SetName("") 207 existingMeta.SetNamespace("") 208 existingMeta.SetCreationTimestamp(Time{}) 209 existingMeta.SetDeletionTimestamp(nil) 210 existingMeta.SetDeletionGracePeriodSeconds(nil) 211 existingMeta.SetManagedFields(nil) 212 213 if !reflect.DeepEqual(meta, existingMeta) { 214 t.Error(diff.ObjectDiff(meta, existingMeta)) 215 } 216 } 217 218 func TestSetMetaDataLabel(t *testing.T) { 219 tests := []struct { 220 obj *ObjectMeta 221 label string 222 value string 223 want map[string]string 224 }{ 225 { 226 obj: &ObjectMeta{}, 227 label: "foo", 228 value: "bar", 229 want: map[string]string{"foo": "bar"}, 230 }, 231 { 232 obj: &ObjectMeta{Labels: map[string]string{"foo": "bar"}}, 233 label: "foo", 234 value: "baz", 235 want: map[string]string{"foo": "baz"}, 236 }, 237 { 238 obj: &ObjectMeta{Labels: map[string]string{"foo": "bar"}}, 239 label: "version", 240 value: "1.0.0", 241 want: map[string]string{"foo": "bar", "version": "1.0.0"}, 242 }, 243 } 244 245 for _, tc := range tests { 246 SetMetaDataLabel(tc.obj, tc.label, tc.value) 247 if !reflect.DeepEqual(tc.obj.Labels, tc.want) { 248 t.Errorf("got %v, want %v", tc.obj.Labels, tc.want) 249 } 250 } 251 }