github.com/spotmaxtech/k8s-apimachinery-v0260@v0.0.1/pkg/apis/meta/v1/unstructured/unstructured_test.go (about)

     1  /*
     2  Copyright 2018 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_test
    18  
    19  import (
    20  	"math/rand"
    21  	"reflect"
    22  	"testing"
    23  
    24  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/api/apitesting/fuzzer"
    25  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/api/equality"
    26  	metafuzzer "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/apis/meta/fuzzer"
    27  	metav1 "github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/apis/meta/v1"
    28  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/apis/meta/v1/unstructured"
    29  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime"
    30  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/runtime/serializer"
    31  	"github.com/spotmaxtech/k8s-apimachinery-v0260/pkg/util/diff"
    32  	"github.com/stretchr/testify/assert"
    33  )
    34  
    35  func TestNilUnstructuredContent(t *testing.T) {
    36  	var u unstructured.Unstructured
    37  	uCopy := u.DeepCopy()
    38  	content := u.UnstructuredContent()
    39  	expContent := make(map[string]interface{})
    40  	assert.EqualValues(t, expContent, content)
    41  	assert.Equal(t, uCopy, &u)
    42  }
    43  
    44  // TestUnstructuredMetadataRoundTrip checks that metadata accessors
    45  // correctly set the metadata for unstructured objects.
    46  // First, it fuzzes an empty ObjectMeta and sets this value as the metadata for an unstructured object.
    47  // Next, it uses metadata accessor methods to set these fuzzed values to another unstructured object.
    48  // Finally, it checks that both the unstructured objects are equal.
    49  func TestUnstructuredMetadataRoundTrip(t *testing.T) {
    50  	scheme := runtime.NewScheme()
    51  	codecs := serializer.NewCodecFactory(scheme)
    52  	seed := rand.Int63()
    53  	fuzzer := fuzzer.FuzzerFor(metafuzzer.Funcs, rand.NewSource(seed), codecs)
    54  
    55  	N := 1000
    56  	for i := 0; i < N; i++ {
    57  		u := &unstructured.Unstructured{Object: map[string]interface{}{}}
    58  		uCopy := u.DeepCopy()
    59  		metadata := &metav1.ObjectMeta{}
    60  		fuzzer.Fuzz(metadata)
    61  
    62  		if err := setObjectMeta(u, metadata); err != nil {
    63  			t.Fatalf("unexpected error setting fuzzed ObjectMeta: %v", err)
    64  		}
    65  		setObjectMetaUsingAccessors(u, uCopy)
    66  
    67  		if !equality.Semantic.DeepEqual(u, uCopy) {
    68  			t.Errorf("diff: %v", diff.ObjectReflectDiff(u, uCopy))
    69  		}
    70  	}
    71  }
    72  
    73  // TestUnstructuredMetadataOmitempty checks that ObjectMeta omitempty
    74  // semantics are enforced for unstructured objects.
    75  // The fuzzing test above should catch these cases but this is here just to be safe.
    76  // Example: the metadata.clusterName field has the omitempty json tag
    77  // so if it is set to it's zero value (""), it should be removed from the metadata map.
    78  func TestUnstructuredMetadataOmitempty(t *testing.T) {
    79  	scheme := runtime.NewScheme()
    80  	codecs := serializer.NewCodecFactory(scheme)
    81  	seed := rand.Int63()
    82  	fuzzer := fuzzer.FuzzerFor(metafuzzer.Funcs, rand.NewSource(seed), codecs)
    83  
    84  	// fuzz to make sure we don't miss any function calls below
    85  	u := &unstructured.Unstructured{Object: map[string]interface{}{}}
    86  	metadata := &metav1.ObjectMeta{}
    87  	fuzzer.Fuzz(metadata)
    88  	if err := setObjectMeta(u, metadata); err != nil {
    89  		t.Fatalf("unexpected error setting fuzzed ObjectMeta: %v", err)
    90  	}
    91  
    92  	// set zero values for all fields in metadata explicitly
    93  	// to check that omitempty fields having zero values are never set
    94  	u.SetName("")
    95  	u.SetGenerateName("")
    96  	u.SetNamespace("")
    97  	u.SetSelfLink("")
    98  	u.SetUID("")
    99  	u.SetResourceVersion("")
   100  	u.SetGeneration(0)
   101  	u.SetCreationTimestamp(metav1.Time{})
   102  	u.SetDeletionTimestamp(nil)
   103  	u.SetDeletionGracePeriodSeconds(nil)
   104  	u.SetLabels(nil)
   105  	u.SetAnnotations(nil)
   106  	u.SetOwnerReferences(nil)
   107  	u.SetFinalizers(nil)
   108  	u.SetManagedFields(nil)
   109  
   110  	gotMetadata, _, err := unstructured.NestedFieldNoCopy(u.UnstructuredContent(), "metadata")
   111  	if err != nil {
   112  		t.Error(err)
   113  	}
   114  	emptyMetadata := make(map[string]interface{})
   115  
   116  	if !reflect.DeepEqual(gotMetadata, emptyMetadata) {
   117  		t.Errorf("expected %v, got %v", emptyMetadata, gotMetadata)
   118  	}
   119  }
   120  
   121  func setObjectMeta(u *unstructured.Unstructured, objectMeta *metav1.ObjectMeta) error {
   122  	if objectMeta == nil {
   123  		unstructured.RemoveNestedField(u.UnstructuredContent(), "metadata")
   124  		return nil
   125  	}
   126  	metadata, err := runtime.DefaultUnstructuredConverter.ToUnstructured(objectMeta)
   127  	if err != nil {
   128  		return err
   129  	}
   130  	u.UnstructuredContent()["metadata"] = metadata
   131  	return nil
   132  }
   133  
   134  func setObjectMetaUsingAccessors(u, uCopy *unstructured.Unstructured) {
   135  	uCopy.SetName(u.GetName())
   136  	uCopy.SetGenerateName(u.GetGenerateName())
   137  	uCopy.SetNamespace(u.GetNamespace())
   138  	uCopy.SetSelfLink(u.GetSelfLink())
   139  	uCopy.SetUID(u.GetUID())
   140  	uCopy.SetResourceVersion(u.GetResourceVersion())
   141  	uCopy.SetGeneration(u.GetGeneration())
   142  	uCopy.SetCreationTimestamp(u.GetCreationTimestamp())
   143  	uCopy.SetDeletionTimestamp(u.GetDeletionTimestamp())
   144  	uCopy.SetDeletionGracePeriodSeconds(u.GetDeletionGracePeriodSeconds())
   145  	uCopy.SetLabels(u.GetLabels())
   146  	uCopy.SetAnnotations(u.GetAnnotations())
   147  	uCopy.SetOwnerReferences(u.GetOwnerReferences())
   148  	uCopy.SetFinalizers(u.GetFinalizers())
   149  	uCopy.SetManagedFields(u.GetManagedFields())
   150  }