Add generated file

This PR adds generated files under pkg/client and vendor folder.
This commit is contained in:
xing-yang
2018-07-12 10:55:15 -07:00
parent 36b1de0341
commit e213d1890d
17729 changed files with 5090889 additions and 0 deletions

View File

@@ -0,0 +1,70 @@
package(default_visibility = ["//visibility:public"])
load(
"@io_bazel_rules_go//go:def.bzl",
"go_test",
)
go_test(
name = "go_default_test",
size = "large",
srcs = [
"apiserver_test.go",
"main_test.go",
"patch_test.go",
"print_test.go",
],
tags = [
"etcd",
"integration",
],
deps = [
"//pkg/api/legacyscheme:go_default_library",
"//pkg/api/testapi:go_default_library",
"//pkg/apis/core:go_default_library",
"//pkg/kubectl/cmd/util:go_default_library",
"//pkg/kubectl/genericclioptions:go_default_library",
"//pkg/master:go_default_library",
"//pkg/printers:go_default_library",
"//pkg/printers/internalversion:go_default_library",
"//test/integration/framework:go_default_library",
"//vendor/github.com/golang/glog:go_default_library",
"//vendor/github.com/pborman/uuid:go_default_library",
"//vendor/k8s.io/api/batch/v2alpha1:go_default_library",
"//vendor/k8s.io/api/core/v1:go_default_library",
"//vendor/k8s.io/api/extensions/v1beta1:go_default_library",
"//vendor/k8s.io/api/rbac/v1alpha1:go_default_library",
"//vendor/k8s.io/api/scheduling/v1beta1:go_default_library",
"//vendor/k8s.io/api/settings/v1alpha1:go_default_library",
"//vendor/k8s.io/api/storage/v1alpha1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/errors:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/api/meta:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/apis/meta/v1beta1:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/runtime/schema:go_default_library",
"//vendor/k8s.io/apimachinery/pkg/types:go_default_library",
"//vendor/k8s.io/apiserver/pkg/features:go_default_library",
"//vendor/k8s.io/apiserver/pkg/util/feature:go_default_library",
"//vendor/k8s.io/client-go/discovery:go_default_library",
"//vendor/k8s.io/client-go/kubernetes:go_default_library",
"//vendor/k8s.io/client-go/rest:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd:go_default_library",
"//vendor/k8s.io/client-go/tools/clientcmd/api:go_default_library",
"//vendor/k8s.io/client-go/tools/pager:go_default_library",
"//vendor/k8s.io/gengo/examples/set-gen/sets:go_default_library",
],
)
filegroup(
name = "package-srcs",
srcs = glob(["**"]),
tags = ["automanaged"],
visibility = ["//visibility:private"],
)
filegroup(
name = "all-srcs",
srcs = [":package-srcs"],
tags = ["automanaged"],
)

View File

@@ -0,0 +1,323 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apiserver
import (
"bytes"
"context"
"fmt"
"io/ioutil"
"net/http"
"net/http/httptest"
"reflect"
"testing"
"github.com/golang/glog"
"k8s.io/api/core/v1"
"k8s.io/api/extensions/v1beta1"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/apimachinery/pkg/runtime/schema"
genericfeatures "k8s.io/apiserver/pkg/features"
utilfeature "k8s.io/apiserver/pkg/util/feature"
clientset "k8s.io/client-go/kubernetes"
restclient "k8s.io/client-go/rest"
"k8s.io/client-go/tools/pager"
"k8s.io/kubernetes/pkg/api/testapi"
api "k8s.io/kubernetes/pkg/apis/core"
"k8s.io/kubernetes/pkg/master"
"k8s.io/kubernetes/test/integration/framework"
)
func setup(t *testing.T, groupVersions ...schema.GroupVersion) (*httptest.Server, clientset.Interface, framework.CloseFunc) {
masterConfig := framework.NewIntegrationTestMasterConfig()
if len(groupVersions) > 0 {
resourceConfig := master.DefaultAPIResourceConfigSource()
resourceConfig.EnableVersions(groupVersions...)
masterConfig.ExtraConfig.APIResourceConfigSource = resourceConfig
}
_, s, closeFn := framework.RunAMaster(masterConfig)
clientSet, err := clientset.NewForConfig(&restclient.Config{Host: s.URL})
if err != nil {
t.Fatalf("Error in create clientset: %v", err)
}
return s, clientSet, closeFn
}
func verifyStatusCode(t *testing.T, verb, URL, body string, expectedStatusCode int) {
// We dont use the typed Go client to send this request to be able to verify the response status code.
bodyBytes := bytes.NewReader([]byte(body))
req, err := http.NewRequest(verb, URL, bodyBytes)
if err != nil {
t.Fatalf("unexpected error: %v in sending req with verb: %s, URL: %s and body: %s", err, verb, URL, body)
}
transport := http.DefaultTransport
glog.Infof("Sending request: %v", req)
resp, err := transport.RoundTrip(req)
if err != nil {
t.Fatalf("unexpected error: %v in req: %v", err, req)
}
defer resp.Body.Close()
b, _ := ioutil.ReadAll(resp.Body)
if resp.StatusCode != expectedStatusCode {
t.Errorf("Expected status %v, but got %v", expectedStatusCode, resp.StatusCode)
t.Errorf("Body: %v", string(b))
}
}
func path(resource, namespace, name string) string {
return testapi.Extensions.ResourcePath(resource, namespace, name)
}
func newRS(namespace string) *v1beta1.ReplicaSet {
return &v1beta1.ReplicaSet{
TypeMeta: metav1.TypeMeta{
Kind: "ReplicaSet",
APIVersion: "extensions/v1beta1",
},
ObjectMeta: metav1.ObjectMeta{
Namespace: namespace,
GenerateName: "apiserver-test",
},
Spec: v1beta1.ReplicaSetSpec{
Template: v1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{"name": "test"},
},
Spec: v1.PodSpec{
Containers: []v1.Container{
{
Name: "fake-name",
Image: "fakeimage",
},
},
},
},
},
}
}
var cascDel = `
{
"kind": "DeleteOptions",
"apiVersion": "` + testapi.Groups[api.GroupName].GroupVersion().String() + `",
"orphanDependents": false
}
`
// Tests that the apiserver returns 202 status code as expected.
func Test202StatusCode(t *testing.T) {
s, clientSet, closeFn := setup(t)
defer closeFn()
ns := framework.CreateTestingNamespace("status-code", s, t)
defer framework.DeleteTestingNamespace(ns, s, t)
rsClient := clientSet.ExtensionsV1beta1().ReplicaSets(ns.Name)
// 1. Create the resource without any finalizer and then delete it without setting DeleteOptions.
// Verify that server returns 200 in this case.
rs, err := rsClient.Create(newRS(ns.Name))
if err != nil {
t.Fatalf("Failed to create rs: %v", err)
}
verifyStatusCode(t, "DELETE", s.URL+path("replicasets", ns.Name, rs.Name), "", 200)
// 2. Create the resource with a finalizer so that the resource is not immediately deleted and then delete it without setting DeleteOptions.
// Verify that the apiserver still returns 200 since DeleteOptions.OrphanDependents is not set.
rs = newRS(ns.Name)
rs.ObjectMeta.Finalizers = []string{"kube.io/dummy-finalizer"}
rs, err = rsClient.Create(rs)
if err != nil {
t.Fatalf("Failed to create rs: %v", err)
}
verifyStatusCode(t, "DELETE", s.URL+path("replicasets", ns.Name, rs.Name), "", 200)
// 3. Create the resource and then delete it with DeleteOptions.OrphanDependents=false.
// Verify that the server still returns 200 since the resource is immediately deleted.
rs = newRS(ns.Name)
rs, err = rsClient.Create(rs)
if err != nil {
t.Fatalf("Failed to create rs: %v", err)
}
verifyStatusCode(t, "DELETE", s.URL+path("replicasets", ns.Name, rs.Name), cascDel, 200)
// 4. Create the resource with a finalizer so that the resource is not immediately deleted and then delete it with DeleteOptions.OrphanDependents=false.
// Verify that the server returns 202 in this case.
rs = newRS(ns.Name)
rs.ObjectMeta.Finalizers = []string{"kube.io/dummy-finalizer"}
rs, err = rsClient.Create(rs)
if err != nil {
t.Fatalf("Failed to create rs: %v", err)
}
verifyStatusCode(t, "DELETE", s.URL+path("replicasets", ns.Name, rs.Name), cascDel, 202)
}
func TestAPIListChunking(t *testing.T) {
if err := utilfeature.DefaultFeatureGate.Set(string(genericfeatures.APIListChunking) + "=true"); err != nil {
t.Fatal(err)
}
s, clientSet, closeFn := setup(t)
defer closeFn()
ns := framework.CreateTestingNamespace("list-paging", s, t)
defer framework.DeleteTestingNamespace(ns, s, t)
rsClient := clientSet.ExtensionsV1beta1().ReplicaSets(ns.Name)
for i := 0; i < 4; i++ {
rs := newRS(ns.Name)
rs.Name = fmt.Sprintf("test-%d", i)
if _, err := rsClient.Create(rs); err != nil {
t.Fatal(err)
}
}
calls := 0
firstRV := ""
p := &pager.ListPager{
PageSize: 1,
PageFn: pager.SimplePageFunc(func(opts metav1.ListOptions) (runtime.Object, error) {
calls++
list, err := rsClient.List(opts)
if err != nil {
return nil, err
}
if calls == 1 {
firstRV = list.ResourceVersion
}
if calls == 2 {
rs := newRS(ns.Name)
rs.Name = "test-5"
if _, err := rsClient.Create(rs); err != nil {
t.Fatal(err)
}
}
return list, err
}),
}
listObj, err := p.List(context.Background(), metav1.ListOptions{})
if err != nil {
t.Fatal(err)
}
if calls != 4 {
t.Errorf("unexpected list invocations: %d", calls)
}
list := listObj.(metav1.ListInterface)
if len(list.GetContinue()) != 0 {
t.Errorf("unexpected continue: %s", list.GetContinue())
}
if list.GetResourceVersion() != firstRV {
t.Errorf("unexpected resource version: %s instead of %s", list.GetResourceVersion(), firstRV)
}
var names []string
if err := meta.EachListItem(listObj, func(obj runtime.Object) error {
rs := obj.(*v1beta1.ReplicaSet)
names = append(names, rs.Name)
return nil
}); err != nil {
t.Fatal(err)
}
if !reflect.DeepEqual(names, []string{"test-0", "test-1", "test-2", "test-3"}) {
t.Errorf("unexpected items: %#v", list)
}
}
func makeSecret(name string) *v1.Secret {
return &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: name,
},
Data: map[string][]byte{
"key": []byte("value"),
},
}
}
func TestNameInFieldSelector(t *testing.T) {
s, clientSet, closeFn := setup(t)
defer closeFn()
numNamespaces := 3
namespaces := make([]*v1.Namespace, 0, numNamespaces)
for i := 0; i < 3; i++ {
ns := framework.CreateTestingNamespace(fmt.Sprintf("ns%d", i), s, t)
defer framework.DeleteTestingNamespace(ns, s, t)
namespaces = append(namespaces, ns)
_, err := clientSet.CoreV1().Secrets(ns.Name).Create(makeSecret("foo"))
if err != nil {
t.Errorf("Couldn't create secret: %v", err)
}
_, err = clientSet.CoreV1().Secrets(ns.Name).Create(makeSecret("bar"))
if err != nil {
t.Errorf("Couldn't create secret: %v", err)
}
}
testcases := []struct {
namespace string
selector string
expectedSecrets int
}{
{
namespace: "",
selector: "metadata.name=foo",
expectedSecrets: numNamespaces,
},
{
namespace: "",
selector: "metadata.name=foo,metadata.name=bar",
expectedSecrets: 0,
},
{
namespace: "",
selector: "metadata.name=foo,metadata.namespace=ns1",
expectedSecrets: 1,
},
{
namespace: "ns1",
selector: "metadata.name=foo,metadata.namespace=ns1",
expectedSecrets: 1,
},
{
namespace: "ns1",
selector: "metadata.name=foo,metadata.namespace=ns2",
expectedSecrets: 0,
},
{
namespace: "ns1",
selector: "metadata.name=foo,metadata.namespace=",
expectedSecrets: 0,
},
}
for _, tc := range testcases {
opts := metav1.ListOptions{
FieldSelector: tc.selector,
}
secrets, err := clientSet.CoreV1().Secrets(tc.namespace).List(opts)
if err != nil {
t.Errorf("%s: Unexpected error: %v", tc.selector, err)
}
if len(secrets.Items) != tc.expectedSecrets {
t.Errorf("%s: Unexpected number of secrets: %d, expected: %d", tc.selector, len(secrets.Items), tc.expectedSecrets)
}
}
}

View File

@@ -0,0 +1,27 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apiserver
import (
"testing"
"k8s.io/kubernetes/test/integration/framework"
)
func TestMain(m *testing.M) {
framework.EtcdMain(m.Run)
}

View File

@@ -0,0 +1,138 @@
/*
Copyright 2017 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apiserver
import (
"fmt"
"sync"
"sync/atomic"
"testing"
"github.com/pborman/uuid"
"k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/types"
"k8s.io/kubernetes/test/integration/framework"
)
// Tests that the apiserver retries patches
func TestPatchConflicts(t *testing.T) {
s, clientSet, closeFn := setup(t)
defer closeFn()
ns := framework.CreateTestingNamespace("status-code", s, t)
defer framework.DeleteTestingNamespace(ns, s, t)
numOfConcurrentPatches := 100
UIDs := make([]types.UID, numOfConcurrentPatches)
ownerRefs := []metav1.OwnerReference{}
for i := 0; i < numOfConcurrentPatches; i++ {
uid := types.UID(uuid.NewRandom().String())
ownerName := fmt.Sprintf("owner-%d", i)
UIDs[i] = uid
ownerRefs = append(ownerRefs, metav1.OwnerReference{
APIVersion: "example.com/v1",
Kind: "Foo",
Name: ownerName,
UID: uid,
})
}
secret := &v1.Secret{
ObjectMeta: metav1.ObjectMeta{
Name: "test",
OwnerReferences: ownerRefs,
},
}
// Create the object we're going to conflict on
clientSet.CoreV1().Secrets(ns.Name).Create(secret)
client := clientSet.CoreV1().RESTClient()
successes := int32(0)
// Run a lot of simultaneous patch operations to exercise internal API server retry of application of patches that do not specify resourceVersion.
// They should all succeed.
wg := sync.WaitGroup{}
for i := 0; i < numOfConcurrentPatches; i++ {
wg.Add(1)
go func(i int) {
defer wg.Done()
labelName := fmt.Sprintf("label-%d", i)
value := uuid.NewRandom().String()
obj, err := client.Patch(types.StrategicMergePatchType).
Namespace(ns.Name).
Resource("secrets").
Name("test").
Body([]byte(fmt.Sprintf(`{"metadata":{"labels":{"%s":"%s"}, "ownerReferences":[{"$patch":"delete","uid":"%s"}]}}`, labelName, value, UIDs[i]))).
Do().
Get()
if errors.IsConflict(err) {
t.Logf("tolerated conflict error patching %s: %v", "secrets", err)
return
}
if err != nil {
t.Errorf("error patching %s: %v", "secrets", err)
return
}
accessor, err := meta.Accessor(obj)
if err != nil {
t.Errorf("error getting object from %s: %v", "secrets", err)
return
}
// make sure the label we wanted was effective
if accessor.GetLabels()[labelName] != value {
t.Errorf("patch of %s was ineffective, expected %s=%s, got labels %#v", "secrets", labelName, value, accessor.GetLabels())
return
}
// make sure the patch directive didn't get lost, and that an entry in the ownerReference list was deleted.
found := findOwnerRefByUID(accessor.GetOwnerReferences(), UIDs[i])
if err != nil {
t.Errorf("%v", err)
return
}
if found {
t.Errorf("patch of %s with $patch directive was ineffective, didn't delete the entry in the ownerReference slice: %#v", "secrets", UIDs[i])
}
atomic.AddInt32(&successes, 1)
}(i)
}
wg.Wait()
if successes < int32(numOfConcurrentPatches) {
t.Errorf("Expected at least %d successful patches for %s, got %d", numOfConcurrentPatches, "secrets", successes)
} else {
t.Logf("Got %d successful patches for %s", successes, "secrets")
}
}
func findOwnerRefByUID(ownerRefs []metav1.OwnerReference, uid types.UID) bool {
for _, of := range ownerRefs {
if of.UID == uid {
return true
}
}
return false
}

View File

@@ -0,0 +1,304 @@
/*
Copyright 2018 The Kubernetes Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package apiserver
import (
"encoding/json"
"fmt"
"io/ioutil"
"os"
"reflect"
"strings"
"testing"
"time"
batchv2alpha1 "k8s.io/api/batch/v2alpha1"
rbacv1alpha1 "k8s.io/api/rbac/v1alpha1"
schedulerapi "k8s.io/api/scheduling/v1beta1"
settingsv1alpha1 "k8s.io/api/settings/v1alpha1"
storagev1alpha1 "k8s.io/api/storage/v1alpha1"
"k8s.io/apimachinery/pkg/api/meta"
metav1beta1 "k8s.io/apimachinery/pkg/apis/meta/v1beta1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/discovery"
"k8s.io/client-go/tools/clientcmd"
clientcmdapi "k8s.io/client-go/tools/clientcmd/api"
"k8s.io/gengo/examples/set-gen/sets"
"k8s.io/kubernetes/pkg/api/legacyscheme"
"k8s.io/kubernetes/pkg/kubectl/cmd/util"
"k8s.io/kubernetes/pkg/kubectl/genericclioptions"
"k8s.io/kubernetes/pkg/printers"
printersinternal "k8s.io/kubernetes/pkg/printers/internalversion"
"k8s.io/kubernetes/test/integration/framework"
)
var kindWhiteList = sets.NewString(
// k8s.io/api/core
"APIGroup",
"APIVersions",
"Binding",
"DeleteOptions",
"ExportOptions",
"GetOptions",
"ListOptions",
"NodeProxyOptions",
"PodAttachOptions",
"PodExecOptions",
"PodPortForwardOptions",
"PodLogOptions",
"PodProxyOptions",
"PodStatusResult",
"RangeAllocation",
"ServiceProxyOptions",
"SerializedReference",
// --
// k8s.io/api/admission
"AdmissionReview",
// --
// k8s.io/api/admissionregistration
"InitializerConfiguration",
// --
// k8s.io/api/authentication
"TokenRequest",
"TokenReview",
// --
// k8s.io/api/authorization
"LocalSubjectAccessReview",
"SelfSubjectAccessReview",
"SelfSubjectRulesReview",
"SubjectAccessReview",
// --
// k8s.io/api/autoscaling
"Scale",
// --
// k8s.io/api/apps
"DeploymentRollback",
// --
// k8s.io/api/batch
"JobTemplate",
// --
// k8s.io/api/extensions
"ReplicationControllerDummy",
// --
// k8s.io/api/imagepolicy
"ImageReview",
// --
// k8s.io/api/policy
"Eviction",
// --
// k8s.io/kubernetes/pkg/apis/componentconfig
"KubeSchedulerConfiguration",
// --
// k8s.io/apimachinery/pkg/apis/meta
"WatchEvent",
"Status",
// --
)
// TODO (soltysh): this list has to go down to 0!
var missingHanlders = sets.NewString(
"ClusterRole",
"LimitRange",
"MutatingWebhookConfiguration",
"ResourceQuota",
"Role",
"ValidatingWebhookConfiguration",
"VolumeAttachment",
"PriorityClass",
"PodPreset",
)
func TestServerSidePrint(t *testing.T) {
s, _, closeFn := setup(t,
// additional groupversions needed for the test to run
batchv2alpha1.SchemeGroupVersion,
rbacv1alpha1.SchemeGroupVersion,
settingsv1alpha1.SchemeGroupVersion,
schedulerapi.SchemeGroupVersion,
storagev1alpha1.SchemeGroupVersion)
defer closeFn()
ns := framework.CreateTestingNamespace("server-print", s, t)
defer framework.DeleteTestingNamespace(ns, s, t)
tableParam := fmt.Sprintf("application/json;as=Table;g=%s;v=%s, application/json", metav1beta1.GroupName, metav1beta1.SchemeGroupVersion.Version)
printer := newFakePrinter(printersinternal.AddHandlers)
configFlags := genericclioptions.NewTestConfigFlags().
WithClientConfig(clientcmd.NewDefaultClientConfig(*createKubeConfig(s.URL), &clientcmd.ConfigOverrides{}))
restConfig, err := configFlags.ToRESTConfig()
if err != nil {
t.Errorf("unexpected error: %v", err)
}
cacheDir, err := ioutil.TempDir(os.TempDir(), "test-integration-apiserver-print")
if err != nil {
t.Errorf("unexpected error: %v", err)
}
defer func() {
os.Remove(cacheDir)
}()
cachedClient, err := discovery.NewCachedDiscoveryClientForConfig(restConfig, cacheDir, "", time.Duration(10*time.Minute))
if err != nil {
t.Errorf("unexpected error: %v", err)
}
configFlags.WithDiscoveryClient(cachedClient)
factory := util.NewFactory(configFlags)
mapper, err := factory.ToRESTMapper()
if err != nil {
t.Errorf("unexpected error getting mapper: %v", err)
return
}
for gvk, apiType := range legacyscheme.Scheme.AllKnownTypes() {
// we do not care about internal objects or lists // TODO make sure this is always true
if gvk.Version == runtime.APIVersionInternal || strings.HasSuffix(apiType.Name(), "List") {
continue
}
if kindWhiteList.Has(gvk.Kind) || missingHanlders.Has(gvk.Kind) {
continue
}
t.Logf("Checking %s", gvk)
// read table definition as returned by the server
mapping, err := mapper.RESTMapping(gvk.GroupKind(), gvk.Version)
if err != nil {
t.Errorf("unexpected error getting mapping for GVK %s: %v", gvk, err)
continue
}
client, err := factory.ClientForMapping(mapping)
if err != nil {
t.Errorf("unexpected error getting client for GVK %s: %v", gvk, err)
continue
}
req := client.Get()
if mapping.Scope.Name() == meta.RESTScopeNameNamespace {
req = req.Namespace(ns.Name)
}
body, err := req.Resource(mapping.Resource.Resource).SetHeader("Accept", tableParam).Do().Raw()
if err != nil {
t.Errorf("unexpected error getting %s: %v", gvk, err)
continue
}
actual, err := decodeIntoTable(body)
if err != nil {
t.Errorf("unexpected error decoding %s: %v", gvk, err)
continue
}
// get table definition used in printers
obj, err := legacyscheme.Scheme.New(gvk)
if err != nil {
t.Errorf("unexpected error creating %s: %v", gvk, err)
continue
}
intGV := gvk.GroupKind().WithVersion(runtime.APIVersionInternal).GroupVersion()
intObj, err := legacyscheme.Scheme.ConvertToVersion(obj, intGV)
if err != nil {
t.Errorf("unexpected error converting %s to internal: %v", gvk, err)
continue
}
expectedColumnDefinitions, ok := printer.handlers[reflect.TypeOf(intObj)]
if !ok {
t.Errorf("missing handler for type %v", gvk)
continue
}
for _, e := range expectedColumnDefinitions {
for _, a := range actual.ColumnDefinitions {
if a.Name == e.Name && !reflect.DeepEqual(a, e) {
t.Errorf("unexpected difference in column definition %s for %s:\nexpected:\n%#v\nactual:\n%#v\n", e.Name, gvk, e, a)
}
}
}
}
}
type fakePrinter struct {
handlers map[reflect.Type][]metav1beta1.TableColumnDefinition
}
var _ printers.PrintHandler = &fakePrinter{}
func (f *fakePrinter) Handler(columns, columnsWithWide []string, printFunc interface{}) error {
return nil
}
func (f *fakePrinter) TableHandler(columns []metav1beta1.TableColumnDefinition, printFunc interface{}) error {
printFuncValue := reflect.ValueOf(printFunc)
objType := printFuncValue.Type().In(0)
f.handlers[objType] = columns
return nil
}
func (f *fakePrinter) DefaultTableHandler(columns []metav1beta1.TableColumnDefinition, printFunc interface{}) error {
return nil
}
func newFakePrinter(fns ...func(printers.PrintHandler)) *fakePrinter {
handlers := make(map[reflect.Type][]metav1beta1.TableColumnDefinition, len(fns))
p := &fakePrinter{handlers: handlers}
for _, fn := range fns {
fn(p)
}
return p
}
func decodeIntoTable(body []byte) (*metav1beta1.Table, error) {
table := &metav1beta1.Table{}
err := json.Unmarshal(body, table)
if err != nil {
return nil, err
}
return table, nil
}
func createKubeConfig(url string) *clientcmdapi.Config {
clusterNick := "cluster"
userNick := "user"
contextNick := "context"
config := clientcmdapi.NewConfig()
cluster := clientcmdapi.NewCluster()
cluster.Server = url
cluster.InsecureSkipTLSVerify = true
config.Clusters[clusterNick] = cluster
context := clientcmdapi.NewContext()
context.Cluster = clusterNick
context.AuthInfo = userNick
config.Contexts[contextNick] = context
config.CurrentContext = contextNick
return config
}