func TestDecodeNumbers(t *testing.T) { // Start with a valid pod originalJSON := []byte(`{ "kind":"Pod", "apiVersion":"v1", "metadata":{"name":"pod","namespace":"foo"}, "spec":{ "containers":[{"name":"container","image":"container"}], "activeDeadlineSeconds":9223372036854775807 } }`) pod := &api.Pod{} // Decode with structured codec codec, err := testapi.GetCodecForObject(pod) if err != nil { t.Fatalf("unexpected error: %v", err) } err = codec.DecodeInto(originalJSON, pod) if err != nil { t.Fatalf("unexpected error: %v", err) } // ensure pod is valid if errs := validation.ValidatePod(pod); len(errs) > 0 { t.Fatalf("pod should be valid: %v", errs) } // Round-trip with unstructured codec unstructuredObj, err := runtime.UnstructuredJSONScheme.Decode(originalJSON) if err != nil { t.Fatalf("unexpected error: %v", err) } roundtripJSON, err := json.Marshal(unstructuredObj.(*runtime.Unstructured).Object) if err != nil { t.Fatalf("unexpected error: %v", err) } // Decode with structured codec again pod2 := &api.Pod{} err = codec.DecodeInto(roundtripJSON, pod2) if err != nil { t.Fatalf("unexpected error: %v", err) } // ensure pod is still valid if errs := validation.ValidatePod(pod2); len(errs) > 0 { t.Fatalf("pod should be valid: %v", errs) } // ensure round-trip preserved large integers if !reflect.DeepEqual(pod, pod2) { t.Fatalf("Expected\n\t%#v, got \n\t%#v", pod, pod2) } }
// roundTripSame verifies the same source object is tested in all API versions. func roundTripSame(t *testing.T, item runtime.Object, except ...string) { set := sets.NewString(except...) seed := rand.Int63() fuzzInternalObject(t, "", item, seed) codec, err := testapi.GetCodecForObject(item) if err != nil { t.Errorf("unexpected error: %v", err) } version := testapi.Default.Version() if !set.Has(version) { fuzzInternalObject(t, version, item, seed) roundTrip(t, codec, item) } }
"k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/meta" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/api/unversioned" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/runtime" "k8s.io/kubernetes/pkg/util/diff" "k8s.io/kubernetes/pkg/util/sets" ) var fuzzIters = flag.Int("fuzz-iters", 20, "How many fuzzing iterations to do.") var codecsToTest = []func(version unversioned.GroupVersion, item runtime.Object) (runtime.Codec, error){ func(version unversioned.GroupVersion, item runtime.Object) (runtime.Codec, error) { return testapi.GetCodecForObject(item) }, } func fuzzInternalObject(t *testing.T, forVersion unversioned.GroupVersion, item runtime.Object, seed int64) runtime.Object { apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed)).Fuzz(item) j, err := meta.TypeAccessor(item) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, item) } j.SetKind("") j.SetAPIVersion("") return item }
"k8s.io/apimachinery/pkg/watch" "k8s.io/kubernetes/pkg/api" "k8s.io/kubernetes/pkg/api/testapi" apitesting "k8s.io/kubernetes/pkg/api/testing" "k8s.io/kubernetes/pkg/api/v1" "k8s.io/kubernetes/pkg/apis/extensions" "k8s.io/kubernetes/pkg/apis/extensions/v1beta1" ) var fuzzIters = flag.Int("fuzz-iters", 20, "How many fuzzing iterations to do.") // codecsToTest is a list of functions that yield the codecs to use to test a // particular runtime object. var codecsToTest = []func(version schema.GroupVersion, item runtime.Object) (runtime.Codec, bool, error){ func(version schema.GroupVersion, item runtime.Object) (runtime.Codec, bool, error) { c, err := testapi.GetCodecForObject(item) return c, true, err }, } // fuzzInternalObject fuzzes an arbitrary runtime object using the appropriate // fuzzer registered with the apitesting package. func fuzzInternalObject(t *testing.T, forVersion schema.GroupVersion, item runtime.Object, seed int64) runtime.Object { apitesting.FuzzerFor(t, forVersion, rand.NewSource(seed)).Fuzz(item) j, err := meta.TypeAccessor(item) if err != nil { t.Fatalf("Unexpected error %v for %#v", err, item) } j.SetKind("") j.SetAPIVersion("")
func TestDecodeNumbers(t *testing.T) { // Start with a valid pod originalJSON := []byte(`{ "kind":"Pod", "apiVersion":"v1", "metadata":{"name":"pod","namespace":"foo"}, "spec":{ "containers":[{"name":"container","image":"container"}], "activeDeadlineSeconds":1000030003 } }`) pod := &api.Pod{} // Decode with structured codec codec, err := testapi.GetCodecForObject(pod) if err != nil { t.Fatalf("unexpected error: %v", err) } err = runtime.DecodeInto(codec, originalJSON, pod) if err != nil { t.Fatalf("unexpected error: %v", err) } // ensure pod is valid if errs := validation.ValidatePod(pod); len(errs) > 0 { t.Fatalf("pod should be valid: %v", errs) } // Round-trip with unstructured codec unstructuredObj, err := runtime.Decode(runtime.UnstructuredJSONScheme, originalJSON) if err != nil { t.Fatalf("unexpected error: %v", err) } roundtripJSON, err := runtime.Encode(runtime.UnstructuredJSONScheme, unstructuredObj) if err != nil { t.Fatalf("unexpected error: %v", err) } // Make sure we serialize back out in int form if !strings.Contains(string(roundtripJSON), `"activeDeadlineSeconds":1000030003`) { t.Errorf("Expected %s, got %s", `"activeDeadlineSeconds":1000030003`, string(roundtripJSON)) } // Decode with structured codec again obj2, err := runtime.Decode(codec, roundtripJSON) if err != nil { t.Fatalf("unexpected error: %v", err) } // ensure pod is still valid pod2, ok := obj2.(*api.Pod) if !ok { t.Fatalf("expected an *api.Pod, got %#v", obj2) } if errs := validation.ValidatePod(pod2); len(errs) > 0 { t.Fatalf("pod should be valid: %v", errs) } // ensure round-trip preserved large integers if !reflect.DeepEqual(pod, pod2) { t.Fatalf("Expected\n\t%#v, got \n\t%#v", pod, pod2) } }
func TestExampleObjectSchemas(t *testing.T) { cases := map[string]map[string]runtime.Object{ "../cmd/integration": { "v1-controller": &api.ReplicationController{}, }, "../examples/guestbook": { "frontend-controller": &api.ReplicationController{}, "redis-slave-controller": &api.ReplicationController{}, "redis-master-controller": &api.ReplicationController{}, "frontend-service": &api.Service{}, "redis-master-service": &api.Service{}, "redis-slave-service": &api.Service{}, }, "../examples/guestbook-go": { "guestbook-controller": &api.ReplicationController{}, "redis-slave-controller": &api.ReplicationController{}, "redis-master-controller": &api.ReplicationController{}, "guestbook-service": &api.Service{}, "redis-master-service": &api.Service{}, "redis-slave-service": &api.Service{}, }, "../docs/user-guide/walkthrough": { "pod-nginx": &api.Pod{}, "pod-nginx-with-label": &api.Pod{}, "pod-redis": &api.Pod{}, "pod-with-http-healthcheck": &api.Pod{}, "service": &api.Service{}, "replication-controller": &api.ReplicationController{}, "podtemplate": &api.PodTemplate{}, }, "../docs/user-guide/update-demo": { "kitten-rc": &api.ReplicationController{}, "nautilus-rc": &api.ReplicationController{}, }, "../docs/user-guide/persistent-volumes/volumes": { "local-01": &api.PersistentVolume{}, "local-02": &api.PersistentVolume{}, "gce": &api.PersistentVolume{}, "nfs": &api.PersistentVolume{}, }, "../docs/user-guide/persistent-volumes/claims": { "claim-01": &api.PersistentVolumeClaim{}, "claim-02": &api.PersistentVolumeClaim{}, "claim-03": &api.PersistentVolumeClaim{}, }, "../docs/user-guide/persistent-volumes/simpletest": { "namespace": &api.Namespace{}, "pod": &api.Pod{}, "service": &api.Service{}, }, "../examples/iscsi": { "iscsi": &api.Pod{}, }, "../examples/glusterfs": { "glusterfs-pod": &api.Pod{}, "glusterfs-endpoints": &api.Endpoints{}, "glusterfs-service": &api.Service{}, }, "../docs/user-guide/liveness": { "exec-liveness": &api.Pod{}, "http-liveness": &api.Pod{}, }, "../docs/user-guide": { "multi-pod": nil, "pod": &api.Pod{}, "job": &extensions.Job{}, "ingress": &extensions.Ingress{}, "nginx-deployment": &extensions.Deployment{}, "new-nginx-deployment": &extensions.Deployment{}, }, "../docs/admin": { "daemon": &extensions.DaemonSet{}, }, "../examples": { "scheduler-policy-config": &schedulerapi.Policy{}, "scheduler-policy-config-with-extender": &schedulerapi.Policy{}, }, "../examples/rbd/secret": { "ceph-secret": &api.Secret{}, }, "../examples/rbd": { "rbd": &api.Pod{}, "rbd-with-secret": &api.Pod{}, }, "../examples/cassandra": { "cassandra-daemonset": &extensions.DaemonSet{}, "cassandra-controller": &api.ReplicationController{}, "cassandra-service": &api.Service{}, "cassandra": &api.Pod{}, }, "../examples/celery-rabbitmq": { "celery-controller": &api.ReplicationController{}, "flower-controller": &api.ReplicationController{}, "flower-service": &api.Service{}, "rabbitmq-controller": &api.ReplicationController{}, "rabbitmq-service": &api.Service{}, }, "../examples/cluster-dns": { "dns-backend-rc": &api.ReplicationController{}, "dns-backend-service": &api.Service{}, "dns-frontend-pod": &api.Pod{}, "namespace-dev": &api.Namespace{}, "namespace-prod": &api.Namespace{}, }, "../docs/user-guide/downward-api": { "dapi-pod": &api.Pod{}, }, "../docs/user-guide/downward-api/volume/": { "dapi-volume": &api.Pod{}, }, "../examples/elasticsearch": { "es-rc": &api.ReplicationController{}, "es-svc": &api.Service{}, "service-account": nil, }, "../examples/explorer": { "pod": &api.Pod{}, }, "../examples/hazelcast": { "hazelcast-controller": &api.ReplicationController{}, "hazelcast-service": &api.Service{}, }, "../docs/admin/namespaces": { "namespace-dev": &api.Namespace{}, "namespace-prod": &api.Namespace{}, }, "../docs/admin/limitrange": { "invalid-pod": &api.Pod{}, "limits": &api.LimitRange{}, "namespace": &api.Namespace{}, "valid-pod": &api.Pod{}, }, "../docs/user-guide/logging-demo": { "synthetic_0_25lps": &api.Pod{}, "synthetic_10lps": &api.Pod{}, }, "../examples/meteor": { "meteor-controller": &api.ReplicationController{}, "meteor-service": &api.Service{}, "mongo-pod": &api.Pod{}, "mongo-service": &api.Service{}, }, "../examples/mysql-wordpress-pd": { "mysql-service": &api.Service{}, "mysql": &api.Pod{}, "wordpress-service": &api.Service{}, "wordpress": &api.Pod{}, }, "../examples/nfs": { "nfs-busybox-rc": &api.ReplicationController{}, "nfs-server-rc": &api.ReplicationController{}, "nfs-server-service": &api.Service{}, "nfs-pv": &api.PersistentVolume{}, "nfs-pvc": &api.PersistentVolumeClaim{}, "nfs-web-rc": &api.ReplicationController{}, "nfs-web-service": &api.Service{}, }, "../docs/user-guide/node-selection": { "pod": &api.Pod{}, "pod-with-node-affinity": &api.Pod{}, }, "../examples/openshift-origin": { "openshift-origin-namespace": &api.Namespace{}, "openshift-controller": &api.ReplicationController{}, "openshift-service": &api.Service{}, "etcd-controller": &api.ReplicationController{}, "etcd-service": &api.Service{}, "etcd-discovery-controller": &api.ReplicationController{}, "etcd-discovery-service": &api.Service{}, "secret": nil, }, "../examples/phabricator": { "phabricator-controller": &api.ReplicationController{}, "phabricator-service": &api.Service{}, }, "../examples/redis": { "redis-controller": &api.ReplicationController{}, "redis-master": &api.Pod{}, "redis-proxy": &api.Pod{}, "redis-sentinel-controller": &api.ReplicationController{}, "redis-sentinel-service": &api.Service{}, }, "../docs/admin/resourcequota": { "namespace": &api.Namespace{}, "limits": &api.LimitRange{}, "quota": &api.ResourceQuota{}, }, "../examples/rethinkdb": { "admin-pod": &api.Pod{}, "admin-service": &api.Service{}, "driver-service": &api.Service{}, "rc": &api.ReplicationController{}, }, "../docs/user-guide/secrets": { "secret-pod": &api.Pod{}, "secret": &api.Secret{}, "secret-env-pod": &api.Pod{}, }, "../examples/spark": { "spark-master-controller": &api.ReplicationController{}, "spark-master-service": &api.Service{}, "spark-webui": &api.Service{}, "spark-worker-controller": &api.ReplicationController{}, "zeppelin-controller": &api.ReplicationController{}, "zeppelin-service": &api.Service{}, }, "../examples/spark/spark-gluster": { "spark-master-service": &api.Service{}, "spark-master-controller": &api.ReplicationController{}, "spark-worker-controller": &api.ReplicationController{}, "glusterfs-endpoints": &api.Endpoints{}, }, "../examples/storm": { "storm-nimbus-service": &api.Service{}, "storm-nimbus": &api.Pod{}, "storm-worker-controller": &api.ReplicationController{}, "zookeeper-service": &api.Service{}, "zookeeper": &api.Pod{}, }, "../examples/cephfs/": { "cephfs": &api.Pod{}, "cephfs-with-secret": &api.Pod{}, }, "../examples/fibre_channel": { "fc": &api.Pod{}, }, "../examples/extensions": { "deployment": &extensions.Deployment{}, }, "../examples/javaweb-tomcat-sidecar": { "javaweb": &api.Pod{}, "javaweb-2": &api.Pod{}, }, "../examples/job/work-queue-1": { "job": &extensions.Job{}, }, "../examples/job/work-queue-2": { "redis-pod": &api.Pod{}, "redis-service": &api.Service{}, "job": &extensions.Job{}, }, } capabilities.SetForTests(capabilities.Capabilities{ AllowPrivileged: true, }) for path, expected := range cases { tested := 0 err := walkJSONFiles(path, func(name, path string, data []byte) { expectedType, found := expected[name] if !found { t.Errorf("%s: %s does not have a test case defined", path, name) return } tested++ if expectedType == nil { t.Logf("skipping : %s/%s\n", path, name) return } if strings.Contains(name, "scheduler-policy-config") { if err := runtime.DecodeInto(schedulerapilatest.Codec, data, expectedType); err != nil { t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data)) return } //TODO: Add validate method for &schedulerapi.Policy } else { codec, err := testapi.GetCodecForObject(expectedType) if err != nil { t.Errorf("Could not get codec for %s: %s", expectedType, err) } if err := runtime.DecodeInto(codec, data, expectedType); err != nil { t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data)) return } if errors := validateObject(expectedType); len(errors) > 0 { t.Errorf("%s did not validate correctly: %v", path, errors) } } }) if err != nil { t.Errorf("Expected no error, Got %v", err) } if tested != len(expected) { t.Errorf("Directory %v: Expected %d examples, Got %d", path, len(expected), tested) } } }
func TestExampleObjectSchemas(t *testing.T) { cases := map[string]map[string]runtime.Object{ "../examples/guestbook": { "frontend-deployment": &extensions.Deployment{}, "redis-slave-deployment": &extensions.Deployment{}, "redis-master-deployment": &extensions.Deployment{}, "frontend-service": &api.Service{}, "redis-master-service": &api.Service{}, "redis-slave-service": &api.Service{}, }, "../examples/guestbook/legacy": { "frontend-controller": &api.ReplicationController{}, "redis-slave-controller": &api.ReplicationController{}, "redis-master-controller": &api.ReplicationController{}, }, "../examples/guestbook-go": { "guestbook-controller": &api.ReplicationController{}, "redis-slave-controller": &api.ReplicationController{}, "redis-master-controller": &api.ReplicationController{}, "guestbook-service": &api.Service{}, "redis-master-service": &api.Service{}, "redis-slave-service": &api.Service{}, }, "../examples/volumes/iscsi": { "iscsi": &api.Pod{}, }, "../examples/volumes/glusterfs": { "glusterfs-pod": &api.Pod{}, "glusterfs-endpoints": &api.Endpoints{}, "glusterfs-service": &api.Service{}, }, "../examples": { "scheduler-policy-config": &schedulerapi.Policy{}, "scheduler-policy-config-with-extender": &schedulerapi.Policy{}, }, "../examples/volumes/rbd/secret": { "ceph-secret": &api.Secret{}, }, "../examples/volumes/rbd": { "rbd": &api.Pod{}, "rbd-with-secret": &api.Pod{}, }, "../examples/storage/cassandra": { "cassandra-daemonset": &extensions.DaemonSet{}, "cassandra-controller": &api.ReplicationController{}, "cassandra-service": &api.Service{}, "cassandra-petset": &apps.PetSet{}, }, "../examples/cluster-dns": { "dns-backend-rc": &api.ReplicationController{}, "dns-backend-service": &api.Service{}, "dns-frontend-pod": &api.Pod{}, "namespace-dev": &api.Namespace{}, "namespace-prod": &api.Namespace{}, }, "../examples/elasticsearch": { "es-rc": &api.ReplicationController{}, "es-svc": &api.Service{}, "service-account": nil, }, "../examples/explorer": { "pod": &api.Pod{}, }, "../examples/storage/hazelcast": { "hazelcast-controller": &api.ReplicationController{}, "hazelcast-service": &api.Service{}, }, "../examples/meteor": { "meteor-controller": &api.ReplicationController{}, "meteor-service": &api.Service{}, "mongo-pod": &api.Pod{}, "mongo-service": &api.Service{}, }, "../examples/mysql-wordpress-pd": { "gce-volumes": &api.PersistentVolume{}, "local-volumes": &api.PersistentVolume{}, "mysql-deployment": &api.Service{}, "wordpress-deployment": &api.Service{}, }, "../examples/volumes/nfs": { "nfs-busybox-rc": &api.ReplicationController{}, "nfs-server-rc": &api.ReplicationController{}, "nfs-server-service": &api.Service{}, "nfs-pv": &api.PersistentVolume{}, "nfs-pvc": &api.PersistentVolumeClaim{}, "nfs-web-rc": &api.ReplicationController{}, "nfs-web-service": &api.Service{}, }, "../examples/openshift-origin": { "openshift-origin-namespace": &api.Namespace{}, "openshift-controller": &api.ReplicationController{}, "openshift-service": &api.Service{}, "etcd-controller": &api.ReplicationController{}, "etcd-service": &api.Service{}, "etcd-discovery-controller": &api.ReplicationController{}, "etcd-discovery-service": &api.Service{}, "secret": nil, }, "../examples/phabricator": { "phabricator-controller": &api.ReplicationController{}, "phabricator-service": &api.Service{}, }, "../examples/storage/redis": { "redis-controller": &api.ReplicationController{}, "redis-master": &api.Pod{}, "redis-proxy": &api.Pod{}, "redis-sentinel-controller": &api.ReplicationController{}, "redis-sentinel-service": &api.Service{}, }, "../examples/storage/rethinkdb": { "admin-pod": &api.Pod{}, "admin-service": &api.Service{}, "driver-service": &api.Service{}, "rc": &api.ReplicationController{}, }, "../examples/spark": { "namespace-spark-cluster": &api.Namespace{}, "spark-master-controller": &api.ReplicationController{}, "spark-master-service": &api.Service{}, "spark-webui": &api.Service{}, "spark-worker-controller": &api.ReplicationController{}, "zeppelin-controller": &api.ReplicationController{}, "zeppelin-service": &api.Service{}, }, "../examples/spark/spark-gluster": { "spark-master-service": &api.Service{}, "spark-master-controller": &api.ReplicationController{}, "spark-worker-controller": &api.ReplicationController{}, "glusterfs-endpoints": &api.Endpoints{}, }, "../examples/storm": { "storm-nimbus-service": &api.Service{}, "storm-nimbus": &api.Pod{}, "storm-worker-controller": &api.ReplicationController{}, "zookeeper-service": &api.Service{}, "zookeeper": &api.Pod{}, }, "../examples/volumes/cephfs/": { "cephfs": &api.Pod{}, "cephfs-with-secret": &api.Pod{}, }, "../examples/volumes/fibre_channel": { "fc": &api.Pod{}, }, "../examples/javaweb-tomcat-sidecar": { "javaweb": &api.Pod{}, "javaweb-2": &api.Pod{}, }, "../examples/volumes/azure_file": { "azure": &api.Pod{}, }, "../examples/volumes/azure_disk": { "azure": &api.Pod{}, }, } capabilities.SetForTests(capabilities.Capabilities{ AllowPrivileged: true, }) for path, expected := range cases { tested := 0 err := walkJSONFiles(path, func(name, path string, data []byte) { expectedType, found := expected[name] if !found { t.Errorf("%s: %s does not have a test case defined", path, name) return } tested++ if expectedType == nil { t.Logf("skipping : %s/%s\n", path, name) return } if strings.Contains(name, "scheduler-policy-config") { if err := runtime.DecodeInto(schedulerapilatest.Codec, data, expectedType); err != nil { t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data)) return } //TODO: Add validate method for &schedulerapi.Policy } else { codec, err := testapi.GetCodecForObject(expectedType) if err != nil { t.Errorf("Could not get codec for %s: %s", expectedType, err) } if err := runtime.DecodeInto(codec, data, expectedType); err != nil { t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data)) return } if errors := validateObject(expectedType); len(errors) > 0 { t.Errorf("%s did not validate correctly: %v", path, errors) } } }) if err != nil { t.Errorf("Expected no error, Got %v", err) } if tested != len(expected) { t.Errorf("Directory %v: Expected %d examples, Got %d", path, len(expected), tested) } } }
func TestExampleObjectSchemas(t *testing.T) { cases := map[string]map[string][]runtime.Object{ "../docs/user-guide/walkthrough": { "deployment": {&extensions.Deployment{}}, "deployment-update": {&extensions.Deployment{}}, "pod-nginx": {&api.Pod{}}, "pod-nginx-with-label": {&api.Pod{}}, "pod-redis": {&api.Pod{}}, "pod-with-http-healthcheck": {&api.Pod{}}, "podtemplate": {&api.PodTemplate{}}, "service": {&api.Service{}}, }, "../docs/user-guide/update-demo": { "kitten-rc": {&api.ReplicationController{}}, "nautilus-rc": {&api.ReplicationController{}}, }, "../docs/user-guide/persistent-volumes/volumes": { "local-01": {&api.PersistentVolume{}}, "local-02": {&api.PersistentVolume{}}, "gce": {&api.PersistentVolume{}}, "nfs": {&api.PersistentVolume{}}, }, "../docs/user-guide/persistent-volumes/claims": { "claim-01": {&api.PersistentVolumeClaim{}}, "claim-02": {&api.PersistentVolumeClaim{}}, "claim-03": {&api.PersistentVolumeClaim{}}, }, "../docs/user-guide/persistent-volumes/simpletest": { "namespace": {&api.Namespace{}}, "pod": {&api.Pod{}}, "service": {&api.Service{}}, }, "../docs/user-guide/liveness": { "exec-liveness": {&api.Pod{}}, "http-liveness": {&api.Pod{}}, "http-liveness-named-port": {&api.Pod{}}, }, "../docs/user-guide/jobs/work-queue-1": { "job": {&batch.Job{}}, }, "../docs/user-guide/jobs/work-queue-2": { "job": {&batch.Job{}}, "redis-pod": {&api.Pod{}}, "redis-service": {&api.Service{}}, }, "../docs/user-guide": { "bad-nginx-deployment": {&extensions.Deployment{}}, "counter-pod": {&api.Pod{}}, "curlpod": {&extensions.Deployment{}}, "deployment": {&extensions.Deployment{}}, "ingress": {&extensions.Ingress{}}, "job": {&batch.Job{}}, "multi-pod": {&api.Pod{}, &api.Pod{}}, "new-nginx-deployment": {&extensions.Deployment{}}, "nginx-app": {&api.Service{}, &extensions.Deployment{}}, "nginx-deployment": {&extensions.Deployment{}}, "nginx-init-containers": {&api.Pod{}}, "nginx-lifecycle-deployment": {&extensions.Deployment{}}, "nginx-probe-deployment": {&extensions.Deployment{}}, "nginx-secure-app": {&api.Service{}, &extensions.Deployment{}}, "nginx-svc": {&api.Service{}}, "petset": {&api.Service{}, nil}, "pod": {&api.Pod{}}, "pod-w-message": {&api.Pod{}}, "redis-deployment": {&extensions.Deployment{}}, "redis-resource-deployment": {&extensions.Deployment{}}, "redis-secret-deployment": {&extensions.Deployment{}}, "run-my-nginx": {&extensions.Deployment{}}, "cronjob": {&batch.CronJob{}}, }, "../docs/admin": { "daemon": {&extensions.DaemonSet{}}, }, "../docs/user-guide/downward-api": { "dapi-pod": {&api.Pod{}}, "dapi-container-resources": {&api.Pod{}}, }, "../docs/user-guide/downward-api/volume/": { "dapi-volume": {&api.Pod{}}, "dapi-volume-resources": {&api.Pod{}}, }, "../docs/admin/namespaces": { "namespace-dev": {&api.Namespace{}}, "namespace-prod": {&api.Namespace{}}, }, "../docs/admin/limitrange": { "invalid-pod": {&api.Pod{}}, "limits": {&api.LimitRange{}}, "namespace": {&api.Namespace{}}, "valid-pod": {&api.Pod{}}, }, "../docs/user-guide/logging-demo": { "synthetic_0_25lps": {&api.Pod{}}, "synthetic_10lps": {&api.Pod{}}, }, "../docs/user-guide/node-selection": { "pod": {&api.Pod{}}, "pod-with-node-affinity": {&api.Pod{}}, "pod-with-pod-affinity": {&api.Pod{}}, }, "../docs/admin/resourcequota": { "best-effort": {&api.ResourceQuota{}}, "compute-resources": {&api.ResourceQuota{}}, "limits": {&api.LimitRange{}}, "namespace": {&api.Namespace{}}, "not-best-effort": {&api.ResourceQuota{}}, "object-counts": {&api.ResourceQuota{}}, }, "../docs/user-guide/secrets": { "secret-pod": {&api.Pod{}}, "secret": {&api.Secret{}}, "secret-env-pod": {&api.Pod{}}, }, "../docs/tutorials/stateful-application": { "gce-volume": {&api.PersistentVolume{}}, "mysql-deployment": {&api.Service{}, &api.PersistentVolumeClaim{}, &extensions.Deployment{}}, "mysql-services": {&api.Service{}, &api.Service{}}, "mysql-configmap": {&api.ConfigMap{}}, "mysql-statefulset": {&apps.StatefulSet{}}, "web": {&api.Service{}, &apps.StatefulSet{}}, "zookeeper": {&api.Service{}, &api.ConfigMap{}, &policy.PodDisruptionBudget{}, &apps.StatefulSet{}}, }, } capabilities.SetForTests(capabilities.Capabilities{ AllowPrivileged: true, }) for path, expected := range cases { tested := 0 numExpected := 0 err := walkConfigFiles(path, func(name, path string, docs [][]byte) { expectedTypes, found := expected[name] if !found { t.Errorf("%s: %s does not have a test case defined", path, name) return } numExpected += len(expectedTypes) if len(expectedTypes) != len(docs) { t.Errorf("%s: number of expected types (%v) doesn't match number of docs in YAML (%v)", path, len(expectedTypes), len(docs)) return } for i, data := range docs { expectedType := expectedTypes[i] tested++ if expectedType == nil { t.Logf("skipping : %s/%s\n", path, name) return } if strings.Contains(name, "scheduler-policy-config") { if err := runtime.DecodeInto(schedulerapilatest.Codec, data, expectedType); err != nil { t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data)) return } // TODO: Add validate method for // &schedulerapi.Policy, and remove this // special case } else { codec, err := testapi.GetCodecForObject(expectedType) if err != nil { t.Errorf("Could not get codec for %s: %s", expectedType, err) } if err := runtime.DecodeInto(codec, data, expectedType); err != nil { t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(data)) return } if errors := validateObject(expectedType); len(errors) > 0 { t.Errorf("%s did not validate correctly: %v", path, errors) } } } }) if err != nil { t.Errorf("Expected no error, Got %v on Path %v", err, path) } if tested != numExpected { t.Errorf("Directory %v: Expected %d examples, Got %d", path, len(expected), tested) } } }