...

Source file src/github.com/openshift/api/pkg/testing/deepcopy_test.go

Documentation: github.com/openshift/api/pkg/testing

     1  package testing
     2  
     3  import (
     4  	"math/rand"
     5  	"testing"
     6  
     7  	"k8s.io/apimachinery/pkg/api/apitesting/fuzzer"
     8  	"k8s.io/apimachinery/pkg/api/apitesting/roundtrip"
     9  	genericfuzzer "k8s.io/apimachinery/pkg/apis/meta/fuzzer"
    10  	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
    11  	"k8s.io/apimachinery/pkg/runtime"
    12  	"k8s.io/apimachinery/pkg/runtime/schema"
    13  	"k8s.io/apimachinery/pkg/runtime/serializer"
    14  	"k8s.io/apimachinery/pkg/util/sets"
    15  
    16  	apps "github.com/openshift/api/apps/v1"
    17  	authorization "github.com/openshift/api/authorization/v1"
    18  	build "github.com/openshift/api/build/v1"
    19  	image "github.com/openshift/api/image/v1"
    20  	network "github.com/openshift/api/network/v1"
    21  	oauth "github.com/openshift/api/oauth/v1"
    22  	project "github.com/openshift/api/project/v1"
    23  	quota "github.com/openshift/api/quota/v1"
    24  	route "github.com/openshift/api/route/v1"
    25  	security "github.com/openshift/api/security/v1"
    26  	template "github.com/openshift/api/template/v1"
    27  	user "github.com/openshift/api/user/v1"
    28  )
    29  
    30  var groups = map[schema.GroupVersion]func(*runtime.Scheme) error{
    31  	apps.GroupVersion:          apps.Install,
    32  	authorization.GroupVersion: authorization.Install,
    33  	build.GroupVersion:         build.Install,
    34  	image.GroupVersion:         image.Install,
    35  	network.GroupVersion:       network.Install,
    36  	oauth.GroupVersion:         oauth.Install,
    37  	project.GroupVersion:       project.Install,
    38  	quota.GroupVersion:         quota.Install,
    39  	route.GroupVersion:         route.Install,
    40  	security.GroupVersion:      security.Install,
    41  	template.GroupVersion:      template.Install,
    42  	user.GroupVersion:          user.Install,
    43  }
    44  
    45  // TestRoundTripTypesWithoutProtobuf applies the round-trip test to all round-trippable Kinds
    46  // in the scheme.
    47  func TestRoundTripTypesWithoutProtobuf(t *testing.T) {
    48  	// TODO upstream this loop
    49  	for gv, install := range groups {
    50  		t.Logf("starting group %q", gv)
    51  		scheme := runtime.NewScheme()
    52  		codecs := serializer.NewCodecFactory(scheme)
    53  
    54  		install(scheme)
    55  		seed := rand.Int63()
    56  		// I'm only using the generic fuzzer funcs, but at some point in time we might need to
    57  		// switch to specialized. For now we're happy with the current serialization test.
    58  		fuzzer := fuzzer.FuzzerFor(genericfuzzer.Funcs, rand.NewSource(seed), codecs)
    59  		kinds := scheme.KnownTypes(gv)
    60  
    61  		for kind := range kinds {
    62  			if globalNonRoundTrippableTypes.Has(kind) {
    63  				continue
    64  			}
    65  			gvk := gv.WithKind(kind)
    66  			// FIXME: this is explicitly testing w/o protobuf which was failing
    67  			// The RoundTripSpecificKindWithoutProtobuf performs the following sequence of actions:
    68  			// 1. object := original.DeepCopyObject()
    69  			// 2. obj3 := Decode(Encode(object)
    70  			// 3. Fuzz(object)
    71  			// 4. check semantic.DeepEqual(original, obj3)
    72  			roundtrip.RoundTripSpecificKindWithoutProtobuf(t, gvk, scheme, codecs, fuzzer, nil)
    73  		}
    74  		t.Logf("finished group %q", gv)
    75  	}
    76  }
    77  
    78  func TestFailRoundTrip(t *testing.T) {
    79  	scheme := runtime.NewScheme()
    80  	codecs := serializer.NewCodecFactory(scheme)
    81  	groupVersion := schema.GroupVersion{Group: "broken", Version: "v1"}
    82  	builder := runtime.NewSchemeBuilder(func(scheme *runtime.Scheme) error {
    83  		scheme.AddKnownTypes(groupVersion, &BrokenType{})
    84  		metav1.AddToGroupVersion(scheme, groupVersion)
    85  		return nil
    86  	})
    87  	builder.AddToScheme(scheme)
    88  	seed := rand.Int63()
    89  	fuzzer := fuzzer.FuzzerFor(genericfuzzer.Funcs, rand.NewSource(seed), codecs)
    90  	gvk := groupVersion.WithKind("BrokenType")
    91  	tmpT := new(testing.T)
    92  	roundtrip.RoundTripSpecificKindWithoutProtobuf(tmpT, gvk, scheme, codecs, fuzzer, nil)
    93  	// It's very hacky way of making sure the DeepCopy is actually invoked inside RoundTripSpecificKindWithoutProtobuf
    94  	// used in the other test. If for some reason this tests starts passing we need to fail b/c we're not testing
    95  	// the DeepCopy in the other method which we care so much about.
    96  	if !tmpT.Failed() {
    97  		t.Log("RoundTrip should've failed on DeepCopy but it did not!")
    98  		t.FailNow()
    99  	}
   100  }
   101  
   102  // TODO: externalize this upstream
   103  var globalNonRoundTrippableTypes = sets.NewString(
   104  	"ExportOptions",
   105  	"GetOptions",
   106  	// WatchEvent does not include kind and version and can only be deserialized
   107  	// implicitly (if the caller expects the specific object). The watch call defines
   108  	// the schema by content type, rather than via kind/version included in each
   109  	// object.
   110  	"WatchEvent",
   111  	// ListOptions is now part of the meta group
   112  	"ListOptions",
   113  	// Delete options is only read in metav1
   114  	"DeleteOptions",
   115  )
   116  
   117  type BrokenType struct {
   118  	metav1.TypeMeta   `json:",inline"`
   119  	metav1.ObjectMeta `json:"metadata,omitempty"`
   120  
   121  	Field1 string `json:"field1,omitempty"`
   122  	Field2 string `json:"field2,omitempty"`
   123  }
   124  
   125  func (in *BrokenType) DeepCopy() *BrokenType {
   126  	return new(BrokenType)
   127  }
   128  
   129  func (in *BrokenType) DeepCopyObject() runtime.Object {
   130  	if c := in.DeepCopy(); c != nil {
   131  		return c
   132  	} else {
   133  		return nil
   134  	}
   135  }
   136  

View as plain text