diff --git a/.travis.yml b/.travis.yml index 384edc5f5c..73ee995c16 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,6 +1,6 @@ language: go go: - - 1.9.3 + - 1.10.2 # Don't want default ./... here: install: @@ -10,7 +10,7 @@ install: # Fetch dependencies for us to run the tests in test/examples_test.go - go get -t -v k8s.io/website/test # Make sure we are testing against the correct branch -- pushd $GOPATH/src/k8s.io/kubernetes && git checkout release-1.10 && popd +- pushd $GOPATH/src/k8s.io/kubernetes && git checkout release-1.11 && popd # Simplified deduplication of dependencies. - cp -L -R $GOPATH/src/k8s.io/kubernetes/vendor/ $GOPATH/src/ diff --git a/test/examples_test.go b/test/examples_test.go index 577a6b82ae..2acc2ebb69 100644 --- a/test/examples_test.go +++ b/test/examples_test.go @@ -24,7 +24,6 @@ import ( "io/ioutil" "os" "path/filepath" - "regexp" "strings" "testing" @@ -33,6 +32,7 @@ import ( "k8s.io/apimachinery/pkg/util/validation/field" "k8s.io/apimachinery/pkg/util/yaml" utilfeature "k8s.io/apiserver/pkg/util/feature" + "k8s.io/kubernetes/pkg/api/legacyscheme" "k8s.io/kubernetes/pkg/api/testapi" "k8s.io/kubernetes/pkg/apis/admissionregistration" ar_validation "k8s.io/kubernetes/pkg/apis/admissionregistration/validation" @@ -59,6 +59,33 @@ import ( schedulerapilatest "k8s.io/kubernetes/pkg/scheduler/api/latest" ) +func getCodecForObject(obj runtime.Object) (runtime.Codec, error) { + kinds, _, err := legacyscheme.Scheme.ObjectKinds(obj) + if err != nil { + return nil, fmt.Errorf("unexpected encoding error: %v", err) + } + kind := kinds[0] + + for _, group := range testapi.Groups { + if group.GroupVersion().Group != kind.Group { + continue + } + + if legacyscheme.Scheme.Recognizes(kind) { + return group.Codec(), nil + } + } + // Codec used for unversioned types + if legacyscheme.Scheme.Recognizes(kind) { + serializer, ok := runtime.SerializerInfoForMediaType(legacyscheme.Codecs.SupportedMediaTypes(), runtime.ContentTypeJSON) + if !ok { + return nil, fmt.Errorf("no serializer registered for json") + } + return serializer.Serializer, nil + } + return nil, fmt.Errorf("unexpected kind: %v", kind) +} + func validateObject(obj runtime.Object) (errors field.ErrorList) { // Enable CustomPodDNS for testing utilfeature.DefaultFeatureGate.Set("CustomPodDNS=true") @@ -173,8 +200,8 @@ func validateObject(obj runtime.Object) (errors field.ErrorList) { t.Namespace = api.NamespaceDefault } errors = ext_validation.ValidateIngress(t) - case *extensions.PodSecurityPolicy: - errors = ext_validation.ValidatePodSecurityPolicy(t) + case *policy.PodSecurityPolicy: + errors = policy_validation.ValidatePodSecurityPolicy(t) case *extensions.ReplicaSet: if t.Namespace == "" { t.Namespace = api.NamespaceDefault @@ -289,9 +316,9 @@ func TestExampleObjectSchemas(t *testing.T) { "nginx-deployment": {&extensions.Deployment{}}, }, "docs/concepts/policy": { - "privileged-psp": {&extensions.PodSecurityPolicy{}}, - "restricted-psp": {&extensions.PodSecurityPolicy{}}, - "example-psp": {&extensions.PodSecurityPolicy{}}, + "privileged-psp": {&policy.PodSecurityPolicy{}}, + "restricted-psp": {&policy.PodSecurityPolicy{}}, + "example-psp": {&policy.PodSecurityPolicy{}}, }, "docs/concepts/services-networking": { "curlpod": {&extensions.Deployment{}}, @@ -308,8 +335,8 @@ func TestExampleObjectSchemas(t *testing.T) { "frontend": {&extensions.ReplicaSet{}}, "hpa-rs": {&autoscaling.HorizontalPodAutoscaler{}}, "job": {&batch.Job{}}, - "my-repset": {&extensions.ReplicaSet{}}, "nginx-deployment": {&extensions.Deployment{}}, + "my-repset": {&extensions.ReplicaSet{}}, "replication": {&api.ReplicationController{}}, }, "docs/tasks/access-application-cluster": { @@ -540,7 +567,7 @@ func TestExampleObjectSchemas(t *testing.T) { // &schedulerapi.Policy, and remove this // special case } else { - codec, err := testapi.GetCodecForObject(expectedType) + codec, err := getCodecForObject(expectedType) if err != nil { t.Errorf("Could not get codec for %s: %s", expectedType, err) } @@ -562,92 +589,3 @@ func TestExampleObjectSchemas(t *testing.T) { } } } - -// This regex is tricky, but it works. For future me, here is the decode: -// -// Flags: (?ms) = multiline match, allow . to match \n -// 1) Look for a line that starts with ``` (a markdown code block) -// 2) (?: ... ) = non-capturing group -// 3) (P) = capture group as "name" -// 4) Look for #1 followed by either: -// 4a) "yaml" followed by any word-characters followed by a newline (e.g. ```yamlfoo\n) -// 4b) "any word-characters followed by a newline (e.g. ```json\n) -// 5) Look for either: -// 5a) #4a followed by one or more characters (non-greedy) -// 5b) #4b followed by { followed by one or more characters (non-greedy) followed by } -// 6) Look for #5 followed by a newline followed by ``` (end of the code block) -// -// This could probably be simplified, but is already too delicate. Before any -// real changes, we should have a test case that just tests this regex. -var sampleRegexp = regexp.MustCompile("(?ms)^```(?:(?Pyaml)\\w*\\n(?P.+?)|\\w*\\n(?P\\{.+?\\}))\\n^```") -var subsetRegexp = regexp.MustCompile("(?ms)\\.{3}") - -// Validates examples embedded in Markdown files. -func TestReadme(t *testing.T) { - // BlockVolume required for local volume example - utilfeature.DefaultFeatureGate.Set("BlockVolume=true") - - paths := []struct { - file string - expectedType []runtime.Object // List of all valid types for the whole doc - }{ - {"../content/en/docs/concepts/storage/volumes.md", []runtime.Object{ - &api.Pod{}, - &api.PersistentVolume{}, - }}, - } - - for _, path := range paths { - data, err := ioutil.ReadFile(path.file) - if err != nil { - t.Errorf("Unable to read file %s: %v", path, err) - continue - } - - matches := sampleRegexp.FindAllStringSubmatch(string(data), -1) - if matches == nil { - continue - } - for _, match := range matches { - var content, subtype string - for i, name := range sampleRegexp.SubexpNames() { - if name == "type" { - subtype = match[i] - } - if name == "content" && match[i] != "" { - content = match[i] - } - } - if subtype == "yaml" && subsetRegexp.FindString(content) != "" { - t.Logf("skipping (%s): \n%s", subtype, content) - continue - } - - json, err := yaml.ToJSON([]byte(content)) - if err != nil { - t.Errorf("%s could not be converted to JSON: %v\n%s", path, err, string(content)) - } - - var expectedType runtime.Object - for _, expectedType = range path.expectedType { - err = runtime.DecodeInto(testapi.Default.Codec(), json, expectedType) - if err == nil { - break - } - } - if err != nil { - t.Errorf("%s did not decode correctly: %v\n%s", path, err, string(content)) - continue - } - - if errors := validateObject(expectedType); len(errors) > 0 { - t.Errorf("%s did not validate correctly: %v", path, errors) - } - _, err = runtime.Encode(testapi.Default.Codec(), expectedType) - if err != nil { - t.Errorf("Could not encode object: %v", err) - continue - } - } - } -}