// roundTripSame verifies the same source object is tested in all API versions // yielded by codecsToTest func roundTripSame(t *testing.T, group testapi.TestGroup, item runtime.Object, except ...string) { set := sets.NewString(except...) seed := rand.Int63() fuzzInternalObject(t, group.InternalGroupVersion(), item, seed) version := *group.GroupVersion() codecs := []runtime.Codec{} for _, fn := range codecsToTest { codec, ok, err := fn(version, item) if err != nil { t.Errorf("unable to get codec: %v", err) return } if !ok { continue } codecs = append(codecs, codec) } if !set.Has(version.String()) { fuzzInternalObject(t, version, item, seed) for _, codec := range codecs { roundTrip(t, codec, item) } } }
func testListJob(t *testing.T, group testapi.TestGroup, resourceGroup string) { ns := api.NamespaceAll c := &simple.Client{ Request: simple.Request{ Method: "GET", Path: group.ResourcePath(getJobsResourceName(), ns, ""), }, Response: simple.Response{StatusCode: 200, Body: &extensions.JobList{ Items: []extensions.Job{ { ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ "foo": "bar", "name": "baz", }, }, Spec: extensions.JobSpec{ Template: api.PodTemplateSpec{}, }, }, }, }, }, ResourceGroup: resourceGroup, } receivedJobList, err := getJobClient(t, c, ns, resourceGroup).List(api.ListOptions{}) defer c.Close() c.Validate(t, receivedJobList, err) }
func testGetJob(t *testing.T, group testapi.TestGroup, resourceGroup string) { ns := api.NamespaceDefault c := &simple.Client{ Request: simple.Request{ Method: "GET", Path: group.ResourcePath(getJobsResourceName(), ns, "foo"), Query: simple.BuildQueryValues(nil), }, Response: simple.Response{ StatusCode: 200, Body: &extensions.Job{ ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ "foo": "bar", "name": "baz", }, }, Spec: extensions.JobSpec{ Template: api.PodTemplateSpec{}, }, }, }, ResourceGroup: resourceGroup, } receivedJob, err := getJobClient(t, c, ns, resourceGroup).Get("foo") defer c.Close() c.Validate(t, receivedJob, err) }
func testHorizontalPodAutoscalerList(t *testing.T, group testapi.TestGroup, resourceGroup string) { ns := api.NamespaceDefault horizontalPodAutoscalerList := &extensions.HorizontalPodAutoscalerList{ Items: []extensions.HorizontalPodAutoscaler{ { ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: ns, }, }, }, } c := &simple.Client{ Request: simple.Request{ Method: "GET", Path: group.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, ""), Query: simple.BuildQueryValues(nil), Body: nil, }, Response: simple.Response{StatusCode: 200, Body: horizontalPodAutoscalerList}, ResourceGroup: resourceGroup, } response, err := getHPAClient(t, c, ns, resourceGroup).List(api.ListOptions{}) defer c.Close() c.Validate(t, response, err) }
func testHorizontalPodAutoscalerCreate(t *testing.T, group testapi.TestGroup, resourceGroup string) { ns := api.NamespaceDefault horizontalPodAutoscaler := extensions.HorizontalPodAutoscaler{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: ns, }, } c := &simple.Client{ Request: simple.Request{ Method: "POST", Path: group.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, ""), Query: simple.BuildQueryValues(nil), Body: &horizontalPodAutoscaler, }, Response: simple.Response{StatusCode: 200, Body: &horizontalPodAutoscaler}, ResourceGroup: resourceGroup, } response, err := getHPAClient(t, c, ns, resourceGroup).Create(&horizontalPodAutoscaler) defer c.Close() if err != nil { t.Fatalf("unexpected error: %v", err) } c.Validate(t, response, err) }
func testHorizontalPodAutoscalerDelete(t *testing.T, group testapi.TestGroup, resourceGroup string) { ns := api.NamespaceDefault c := &simple.Client{ Request: simple.Request{Method: "DELETE", Path: group.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "foo"), Query: simple.BuildQueryValues(nil)}, Response: simple.Response{StatusCode: 200}, ResourceGroup: resourceGroup, } err := getHPAClient(t, c, ns, resourceGroup).Delete("foo", nil) defer c.Close() c.Validate(t, nil, err) }
func testHorizontalPodAutoscalerWatch(t *testing.T, group testapi.TestGroup, resourceGroup string) { c := &simple.Client{ Request: simple.Request{ Method: "GET", Path: group.ResourcePathWithPrefix("watch", getHorizontalPodAutoscalersResoureName(), "", ""), Query: url.Values{"resourceVersion": []string{}}}, Response: simple.Response{StatusCode: 200}, ResourceGroup: resourceGroup, } _, err := getHPAClient(t, c, api.NamespaceAll, resourceGroup).Watch(api.ListOptions{}) defer c.Close() c.Validate(t, nil, err) }
func doRoundTripTest(group testapi.TestGroup, kind string, t *testing.T) { item, err := api.Scheme.New(group.InternalGroupVersion().WithKind(kind)) if err != nil { t.Fatalf("Couldn't make a %v? %v", kind, err) } if _, err := meta.TypeAccessor(item); err != nil { t.Fatalf("%q is not a TypeMeta and cannot be tested - add it to nonRoundTrippableTypes: %v", kind, err) } if api.Scheme.Recognizes(group.GroupVersion().WithKind(kind)) { roundTripSame(t, group, item, nonRoundTrippableTypesByVersion[kind]...) } if !nonInternalRoundTrippableTypes.Has(kind) && api.Scheme.Recognizes(group.GroupVersion().WithKind(kind)) { roundTrip(t, group.Codec(), fuzzInternalObject(t, group.InternalGroupVersion(), item, rand.Int63())) } }
func testHorizontalPodAutoscalerUpdateStatus(t *testing.T, group testapi.TestGroup, resourceGroup string) { ns := api.NamespaceDefault horizontalPodAutoscaler := &extensions.HorizontalPodAutoscaler{ ObjectMeta: api.ObjectMeta{ Name: "abc", Namespace: ns, ResourceVersion: "1", }, } c := &simple.Client{ Request: simple.Request{Method: "PUT", Path: group.ResourcePath(getHorizontalPodAutoscalersResoureName(), ns, "abc") + "/status", Query: simple.BuildQueryValues(nil)}, Response: simple.Response{StatusCode: 200, Body: horizontalPodAutoscaler}, ResourceGroup: resourceGroup, } response, err := getHPAClient(t, c, ns, resourceGroup).UpdateStatus(horizontalPodAutoscaler) defer c.Close() c.Validate(t, response, err) }
func testCreateJob(t *testing.T, group testapi.TestGroup, resourceGroup string) { ns := api.NamespaceDefault requestJob := &extensions.Job{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: ns, }, } c := &simple.Client{ Request: simple.Request{ Method: "POST", Path: group.ResourcePath(getJobsResourceName(), ns, ""), Body: requestJob, Query: simple.BuildQueryValues(nil), }, Response: simple.Response{ StatusCode: 200, Body: &extensions.Job{ ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ "foo": "bar", "name": "baz", }, }, Spec: extensions.JobSpec{ Template: api.PodTemplateSpec{}, }, }, }, ResourceGroup: resourceGroup, } receivedJob, err := getJobClient(t, c, ns, resourceGroup).Create(requestJob) defer c.Close() if err != nil { t.Fatalf("unexpected error: %v", err) } c.Validate(t, receivedJob, err) }
func testUpdateJobStatus(t *testing.T, group testapi.TestGroup, resourceGroup string) { ns := api.NamespaceDefault requestJob := &batch.Job{ ObjectMeta: api.ObjectMeta{ Name: "foo", Namespace: ns, ResourceVersion: "1", }, } c := &simple.Client{ Request: simple.Request{ Method: "PUT", Path: group.ResourcePath(getJobsResourceName(), ns, "foo") + "/status", Query: simple.BuildQueryValues(nil), }, Response: simple.Response{ StatusCode: 200, Body: &batch.Job{ ObjectMeta: api.ObjectMeta{ Name: "foo", Labels: map[string]string{ "foo": "bar", "name": "baz", }, }, Spec: batch.JobSpec{ Template: api.PodTemplateSpec{}, }, Status: batch.JobStatus{ Active: 1, }, }, }, ResourceGroup: resourceGroup, } receivedJob, err := getJobClient(t, c, ns, resourceGroup).UpdateStatus(requestJob) defer c.Close() c.Validate(t, receivedJob, err) }
func readSwaggerApiFile(group testapi.TestGroup) ([]byte, error) { // TODO: Figure out a better way of finding these files var pathToSwaggerSpec string if group.GroupVersion().Group == "" { pathToSwaggerSpec = "../../../api/swagger-spec/" + group.GroupVersion().Version + ".json" } else { pathToSwaggerSpec = "../../../api/swagger-spec/" + group.GroupVersion().Group + "_" + group.GroupVersion().Version + ".json" } return ioutil.ReadFile(pathToSwaggerSpec) }
func doRoundTrip(t *testing.T, group testapi.TestGroup, kind string) { // We do fuzzing on the internal version of the object, and only then // convert to the external version. This is because custom fuzzing // function are only supported for internal objects. internalObj, err := api.Scheme.New(group.InternalGroupVersion().WithKind(kind)) if err != nil { t.Fatalf("Couldn't create internal object %v: %v", kind, err) } seed := rand.Int63() apitesting.FuzzerFor(t, group.InternalGroupVersion(), rand.NewSource(seed)). // We are explicitly overwriting custom fuzzing functions, to ensure // that InitContainers and their statuses are not generated. This is // because in thise test we are simply doing json operations, in which // those disappear. Funcs( func(s *api.PodSpec, c fuzz.Continue) { c.FuzzNoCustom(s) s.InitContainers = nil }, func(s *api.PodStatus, c fuzz.Continue) { c.FuzzNoCustom(s) s.InitContainerStatuses = nil }, ).Fuzz(internalObj) item, err := api.Scheme.New(group.GroupVersion().WithKind(kind)) if err != nil { t.Fatalf("Couldn't create external object %v: %v", kind, err) } if err := api.Scheme.Convert(internalObj, item, nil); err != nil { t.Fatalf("Conversion for %v failed: %v", kind, err) } data, err := json.Marshal(item) if err != nil { t.Errorf("Error when marshaling object: %v", err) return } unstr := make(map[string]interface{}) err = json.Unmarshal(data, &unstr) if err != nil { t.Errorf("Error when unmarshaling to unstructured: %v", err) return } data, err = json.Marshal(unstr) if err != nil { t.Errorf("Error when marshaling unstructured: %v", err) return } unmarshalledObj := reflect.New(reflect.TypeOf(item).Elem()).Interface() err = json.Unmarshal(data, &unmarshalledObj) if err != nil { t.Errorf("Error when unmarshaling to object: %v", err) return } if !api.Semantic.DeepEqual(item, unmarshalledObj) { t.Errorf("Object changed during JSON operations, diff: %v", diff.ObjectReflectDiff(item, unmarshalledObj)) return } // TODO; Enable the following part of test once to/from unstructured // format conversions are implemented. /* newUnstr := make(map[string]interface{}) err = unstructured.NewConverter().ToUnstructured(item, &newUnstr) if err != nil { t.Errorf("ToUnstructured failed: %v", err) return } newObj := reflect.New(reflect.TypeOf(item).Elem()).Interface().(runtime.Object) err = unstructured.NewConverter().FromUnstructured(newUnstr, newObj) if err != nil { t.Errorf("FromUnstructured failed: %v", err) return } if !api.Semantic.DeepEqual(item, newObj) { t.Errorf("Object changed, diff: %v", diff.ObjectReflectDiff(item, newObj)) } */ }