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  }