github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/apis/meta/v1/unstructured/helpers_test.go (about) 1 /* 2 Copyright 2017 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 unstructured 18 19 import ( 20 "io/ioutil" 21 "sync" 22 "testing" 23 24 runtimetesting "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/testing" 25 26 "github.com/stretchr/testify/assert" 27 ) 28 29 // TestCodecOfUnstructuredList tests that there are no data races in Encode(). 30 // i.e. that it does not mutate the object being encoded. 31 func TestCodecOfUnstructuredList(t *testing.T) { 32 var wg sync.WaitGroup 33 concurrency := 10 34 list := UnstructuredList{ 35 Object: map[string]interface{}{}, 36 } 37 wg.Add(concurrency) 38 for i := 0; i < concurrency; i++ { 39 go func() { 40 defer wg.Done() 41 assert.NoError(t, UnstructuredJSONScheme.Encode(&list, ioutil.Discard)) 42 }() 43 } 44 wg.Wait() 45 } 46 47 func TestRemoveNestedField(t *testing.T) { 48 obj := map[string]interface{}{ 49 "x": map[string]interface{}{ 50 "y": 1, 51 "a": "foo", 52 }, 53 } 54 RemoveNestedField(obj, "x", "a") 55 assert.Len(t, obj["x"], 1) 56 RemoveNestedField(obj, "x", "y") 57 assert.Empty(t, obj["x"]) 58 RemoveNestedField(obj, "x") 59 assert.Empty(t, obj) 60 RemoveNestedField(obj, "x") // Remove of a non-existent field 61 assert.Empty(t, obj) 62 } 63 64 func TestNestedFieldNoCopy(t *testing.T) { 65 target := map[string]interface{}{"foo": "bar"} 66 67 obj := map[string]interface{}{ 68 "a": map[string]interface{}{ 69 "b": target, 70 "c": nil, 71 "d": []interface{}{"foo"}, 72 "e": []interface{}{ 73 map[string]interface{}{ 74 "f": "bar", 75 }, 76 }, 77 }, 78 } 79 80 // case 1: field exists and is non-nil 81 res, exists, err := NestedFieldNoCopy(obj, "a", "b") 82 assert.True(t, exists) 83 assert.NoError(t, err) 84 assert.Equal(t, target, res) 85 target["foo"] = "baz" 86 assert.Equal(t, target["foo"], res.(map[string]interface{})["foo"], "result should be a reference to the expected item") 87 88 // case 2: field exists and is nil 89 res, exists, err = NestedFieldNoCopy(obj, "a", "c") 90 assert.True(t, exists) 91 assert.NoError(t, err) 92 assert.Nil(t, res) 93 94 // case 3: error traversing obj 95 res, exists, err = NestedFieldNoCopy(obj, "a", "d", "foo") 96 assert.False(t, exists) 97 assert.Error(t, err) 98 assert.Nil(t, res) 99 100 // case 4: field does not exist 101 res, exists, err = NestedFieldNoCopy(obj, "a", "g") 102 assert.False(t, exists) 103 assert.NoError(t, err) 104 assert.Nil(t, res) 105 106 // case 5: intermediate field does not exist 107 res, exists, err = NestedFieldNoCopy(obj, "a", "g", "f") 108 assert.False(t, exists) 109 assert.NoError(t, err) 110 assert.Nil(t, res) 111 112 // case 6: intermediate field is null 113 // (background: happens easily in YAML) 114 res, exists, err = NestedFieldNoCopy(obj, "a", "c", "f") 115 assert.False(t, exists) 116 assert.NoError(t, err) 117 assert.Nil(t, res) 118 119 // case 7: array/slice syntax is not supported 120 // (background: users may expect this to be supported) 121 res, exists, err = NestedFieldNoCopy(obj, "a", "e[0]") 122 assert.False(t, exists) 123 assert.NoError(t, err) 124 assert.Nil(t, res) 125 } 126 127 func TestNestedFieldCopy(t *testing.T) { 128 target := map[string]interface{}{"foo": "bar"} 129 130 obj := map[string]interface{}{ 131 "a": map[string]interface{}{ 132 "b": target, 133 "c": nil, 134 "d": []interface{}{"foo"}, 135 }, 136 } 137 138 // case 1: field exists and is non-nil 139 res, exists, err := NestedFieldCopy(obj, "a", "b") 140 assert.True(t, exists) 141 assert.NoError(t, err) 142 assert.Equal(t, target, res) 143 target["foo"] = "baz" 144 assert.NotEqual(t, target["foo"], res.(map[string]interface{})["foo"], "result should be a copy of the expected item") 145 146 // case 2: field exists and is nil 147 res, exists, err = NestedFieldCopy(obj, "a", "c") 148 assert.True(t, exists) 149 assert.NoError(t, err) 150 assert.Nil(t, res) 151 152 // case 3: error traversing obj 153 res, exists, err = NestedFieldCopy(obj, "a", "d", "foo") 154 assert.False(t, exists) 155 assert.Error(t, err) 156 assert.Nil(t, res) 157 158 // case 4: field does not exist 159 res, exists, err = NestedFieldCopy(obj, "a", "e") 160 assert.False(t, exists) 161 assert.NoError(t, err) 162 assert.Nil(t, res) 163 } 164 165 func TestCacheableObject(t *testing.T) { 166 runtimetesting.CacheableObjectTest(t, UnstructuredJSONScheme) 167 } 168 169 func TestSetNestedStringSlice(t *testing.T) { 170 obj := map[string]interface{}{ 171 "x": map[string]interface{}{ 172 "y": 1, 173 "a": "foo", 174 }, 175 } 176 177 err := SetNestedStringSlice(obj, []string{"bar"}, "x", "z") 178 assert.NoError(t, err) 179 assert.Len(t, obj["x"], 3) 180 assert.Len(t, obj["x"].(map[string]interface{})["z"], 1) 181 assert.Equal(t, obj["x"].(map[string]interface{})["z"].([]interface{})[0], "bar") 182 } 183 184 func TestSetNestedSlice(t *testing.T) { 185 obj := map[string]interface{}{ 186 "x": map[string]interface{}{ 187 "y": 1, 188 "a": "foo", 189 }, 190 } 191 192 err := SetNestedSlice(obj, []interface{}{"bar"}, "x", "z") 193 assert.NoError(t, err) 194 assert.Len(t, obj["x"], 3) 195 assert.Len(t, obj["x"].(map[string]interface{})["z"], 1) 196 assert.Equal(t, obj["x"].(map[string]interface{})["z"].([]interface{})[0], "bar") 197 } 198 199 func TestSetNestedStringMap(t *testing.T) { 200 obj := map[string]interface{}{ 201 "x": map[string]interface{}{ 202 "y": 1, 203 "a": "foo", 204 }, 205 } 206 207 err := SetNestedStringMap(obj, map[string]string{"b": "bar"}, "x", "z") 208 assert.NoError(t, err) 209 assert.Len(t, obj["x"], 3) 210 assert.Len(t, obj["x"].(map[string]interface{})["z"], 1) 211 assert.Equal(t, obj["x"].(map[string]interface{})["z"].(map[string]interface{})["b"], "bar") 212 } 213 214 func TestSetNestedMap(t *testing.T) { 215 obj := map[string]interface{}{ 216 "x": map[string]interface{}{ 217 "y": 1, 218 "a": "foo", 219 }, 220 } 221 222 err := SetNestedMap(obj, map[string]interface{}{"b": "bar"}, "x", "z") 223 assert.NoError(t, err) 224 assert.Len(t, obj["x"], 3) 225 assert.Len(t, obj["x"].(map[string]interface{})["z"], 1) 226 assert.Equal(t, obj["x"].(map[string]interface{})["z"].(map[string]interface{})["b"], "bar") 227 }