mirror of
https://github.com/k3s-io/kubernetes.git
synced 2025-08-05 10:19:50 +00:00
move third party resource tests
This commit is contained in:
parent
1c667e4fc5
commit
1123f6788b
@ -17,7 +17,6 @@ limitations under the License.
|
|||||||
package master
|
package master
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
|
||||||
"crypto/tls"
|
"crypto/tls"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
@ -30,7 +29,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"k8s.io/kubernetes/pkg/api"
|
"k8s.io/kubernetes/pkg/api"
|
||||||
"k8s.io/kubernetes/pkg/api/meta"
|
|
||||||
"k8s.io/kubernetes/pkg/api/testapi"
|
"k8s.io/kubernetes/pkg/api/testapi"
|
||||||
"k8s.io/kubernetes/pkg/api/unversioned"
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
apiv1 "k8s.io/kubernetes/pkg/api/v1"
|
apiv1 "k8s.io/kubernetes/pkg/api/v1"
|
||||||
@ -50,13 +48,8 @@ import (
|
|||||||
"k8s.io/kubernetes/pkg/genericapiserver"
|
"k8s.io/kubernetes/pkg/genericapiserver"
|
||||||
"k8s.io/kubernetes/pkg/kubelet/client"
|
"k8s.io/kubernetes/pkg/kubelet/client"
|
||||||
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
ipallocator "k8s.io/kubernetes/pkg/registry/core/service/ipallocator"
|
||||||
extensionsrest "k8s.io/kubernetes/pkg/registry/extensions/rest"
|
|
||||||
"k8s.io/kubernetes/pkg/registry/extensions/thirdpartyresourcedata"
|
|
||||||
"k8s.io/kubernetes/pkg/registry/generic"
|
|
||||||
"k8s.io/kubernetes/pkg/registry/registrytest"
|
"k8s.io/kubernetes/pkg/registry/registrytest"
|
||||||
"k8s.io/kubernetes/pkg/runtime"
|
"k8s.io/kubernetes/pkg/runtime"
|
||||||
"k8s.io/kubernetes/pkg/storage"
|
|
||||||
"k8s.io/kubernetes/pkg/storage/etcd/etcdtest"
|
|
||||||
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
etcdtesting "k8s.io/kubernetes/pkg/storage/etcd/testing"
|
||||||
utilnet "k8s.io/kubernetes/pkg/util/net"
|
utilnet "k8s.io/kubernetes/pkg/util/net"
|
||||||
"k8s.io/kubernetes/pkg/util/sets"
|
"k8s.io/kubernetes/pkg/util/sets"
|
||||||
@ -67,7 +60,6 @@ import (
|
|||||||
"github.com/go-openapi/strfmt"
|
"github.com/go-openapi/strfmt"
|
||||||
"github.com/go-openapi/validate"
|
"github.com/go-openapi/validate"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"golang.org/x/net/context"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// setUp is a convience function for setting up for (most) tests.
|
// setUp is a convience function for setting up for (most) tests.
|
||||||
@ -289,6 +281,19 @@ func TestGetNodeAddresses(t *testing.T) {
|
|||||||
assert.Equal([]string{"127.0.0.2", "127.0.0.2"}, addrs)
|
assert.Equal([]string{"127.0.0.2", "127.0.0.2"}, addrs)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func decodeResponse(resp *http.Response, obj interface{}) error {
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if err := json.Unmarshal(data, obj); err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Because we need to be backwards compatible with release 1.1, at endpoints
|
// Because we need to be backwards compatible with release 1.1, at endpoints
|
||||||
// that exist in release 1.1, the responses should have empty APIVersion.
|
// that exist in release 1.1, the responses should have empty APIVersion.
|
||||||
func TestAPIVersionOfDiscoveryEndpoints(t *testing.T) {
|
func TestAPIVersionOfDiscoveryEndpoints(t *testing.T) {
|
||||||
@ -477,613 +482,6 @@ func TestDiscoveryAtAPIS(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var versionsToTest = []string{"v1", "v3"}
|
|
||||||
|
|
||||||
type Foo struct {
|
|
||||||
unversioned.TypeMeta `json:",inline"`
|
|
||||||
api.ObjectMeta `json:"metadata,omitempty" description:"standard object metadata"`
|
|
||||||
|
|
||||||
SomeField string `json:"someField"`
|
|
||||||
OtherField int `json:"otherField"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type FooList struct {
|
|
||||||
unversioned.TypeMeta `json:",inline"`
|
|
||||||
unversioned.ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata"`
|
|
||||||
|
|
||||||
Items []Foo `json:"items"`
|
|
||||||
}
|
|
||||||
|
|
||||||
func initThirdParty(t *testing.T, version, name string) (*Master, *etcdtesting.EtcdTestServer, *httptest.Server, *assert.Assertions) {
|
|
||||||
return initThirdPartyMultiple(t, []string{version}, []string{name})
|
|
||||||
}
|
|
||||||
|
|
||||||
func initThirdPartyMultiple(t *testing.T, versions, names []string) (*Master, *etcdtesting.EtcdTestServer, *httptest.Server, *assert.Assertions) {
|
|
||||||
master, etcdserver, _, assert := newMaster(t)
|
|
||||||
_, master.ServiceClusterIPRange, _ = net.ParseCIDR("10.0.0.0/24")
|
|
||||||
|
|
||||||
for ix := range names {
|
|
||||||
api := &extensions.ThirdPartyResource{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: names[ix],
|
|
||||||
},
|
|
||||||
Versions: []extensions.APIVersion{
|
|
||||||
{
|
|
||||||
Name: versions[ix],
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
hasRsrc, err := master.HasThirdPartyResource(api)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
if !hasRsrc {
|
|
||||||
err := master.InstallThirdPartyResource(api)
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
t.Errorf("Failed to install API: %v", err)
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
t.Errorf("Expected %s: %v not to be present!", names[ix], api)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
server := httptest.NewServer(master.HandlerContainer.ServeMux)
|
|
||||||
return master, etcdserver, server, assert
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInstallMultipleAPIs(t *testing.T) {
|
|
||||||
names := []string{"foo.company.com", "bar.company.com"}
|
|
||||||
versions := []string{"v1", "v1"}
|
|
||||||
|
|
||||||
_, etcdserver, server, assert := initThirdPartyMultiple(t, versions, names)
|
|
||||||
defer server.Close()
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
for ix := range names {
|
|
||||||
kind, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(
|
|
||||||
&extensions.ThirdPartyResource{ObjectMeta: api.ObjectMeta{Name: names[ix]}})
|
|
||||||
assert.NoError(err, "Failed to extract group & kind")
|
|
||||||
|
|
||||||
plural, _ := meta.KindToResource(unversioned.GroupVersionKind{
|
|
||||||
Group: group,
|
|
||||||
Version: versions[ix],
|
|
||||||
Kind: kind,
|
|
||||||
})
|
|
||||||
|
|
||||||
resp, err := http.Get(
|
|
||||||
fmt.Sprintf("%s/apis/%s/%s/namespaces/default/%s", server.URL, group, versions[ix], plural.Resource))
|
|
||||||
if !assert.NoError(err, "Failed to do HTTP GET") {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
|
||||||
assert.NoError(err)
|
|
||||||
|
|
||||||
obj := map[string]interface{}{}
|
|
||||||
if err = json.Unmarshal(data, &obj); err != nil {
|
|
||||||
assert.NoError(err, fmt.Sprintf("unexpected error: %v", err))
|
|
||||||
}
|
|
||||||
kindOut, found := obj["kind"]
|
|
||||||
if !found {
|
|
||||||
t.Errorf("Missing 'kind' in %v", obj)
|
|
||||||
}
|
|
||||||
assert.Equal(kindOut, kind+"List")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInstallThirdPartyAPIList(t *testing.T) {
|
|
||||||
for _, version := range versionsToTest {
|
|
||||||
testInstallThirdPartyAPIListVersion(t, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInstallThirdPartyAPIListVersion(t *testing.T, version string) {
|
|
||||||
tests := []struct {
|
|
||||||
items []Foo
|
|
||||||
name string
|
|
||||||
test string
|
|
||||||
}{
|
|
||||||
{
|
|
||||||
name: "foo.company.com",
|
|
||||||
test: "null",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
items: []Foo{},
|
|
||||||
name: "foo.company.com",
|
|
||||||
test: "empty",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
items: []Foo{},
|
|
||||||
name: "policy.company.com",
|
|
||||||
test: "plurals",
|
|
||||||
},
|
|
||||||
{
|
|
||||||
items: []Foo{
|
|
||||||
{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "test",
|
|
||||||
},
|
|
||||||
TypeMeta: unversioned.TypeMeta{
|
|
||||||
Kind: "Foo",
|
|
||||||
APIVersion: version,
|
|
||||||
},
|
|
||||||
SomeField: "test field",
|
|
||||||
OtherField: 10,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "bar",
|
|
||||||
},
|
|
||||||
TypeMeta: unversioned.TypeMeta{
|
|
||||||
Kind: "Foo",
|
|
||||||
APIVersion: version,
|
|
||||||
},
|
|
||||||
SomeField: "test field another",
|
|
||||||
OtherField: 20,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
name: "foo.company.com",
|
|
||||||
test: "real list",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
for _, test := range tests {
|
|
||||||
func() {
|
|
||||||
master, etcdserver, server, assert := initThirdParty(t, version, test.name)
|
|
||||||
defer server.Close()
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
kind, group, err := thirdpartyresourcedata.ExtractApiGroupAndKind(
|
|
||||||
&extensions.ThirdPartyResource{ObjectMeta: api.ObjectMeta{Name: test.name}})
|
|
||||||
assert.NoError(err, test.test)
|
|
||||||
|
|
||||||
plural, _ := meta.KindToResource(unversioned.GroupVersionKind{
|
|
||||||
Group: group,
|
|
||||||
Version: version,
|
|
||||||
Kind: kind,
|
|
||||||
})
|
|
||||||
|
|
||||||
if test.items != nil {
|
|
||||||
s, destroyFunc := generic.NewRawStorage(master.thirdPartyStorageConfig)
|
|
||||||
defer destroyFunc()
|
|
||||||
err := createThirdPartyList(
|
|
||||||
s,
|
|
||||||
fmt.Sprintf("/ThirdPartyResourceData/%s/%s/default", group, plural.Resource),
|
|
||||||
test.items)
|
|
||||||
if !assert.NoError(err, test.test) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(
|
|
||||||
fmt.Sprintf("%s/apis/%s/%s/namespaces/default/%s", server.URL, group, version, plural.Resource))
|
|
||||||
if !assert.NoError(err, test.test) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
assert.Equal(http.StatusOK, resp.StatusCode, test.test)
|
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
|
||||||
assert.NoError(err, test.test)
|
|
||||||
|
|
||||||
list := FooList{}
|
|
||||||
if err = json.Unmarshal(data, &list); err != nil {
|
|
||||||
assert.NoError(err, "unexpected error: %v %s", err, test.test)
|
|
||||||
}
|
|
||||||
|
|
||||||
if test.items == nil {
|
|
||||||
if len(list.Items) != 0 {
|
|
||||||
assert.NoError(err, "expected no items, saw: %v %s", err, list.Items, test.test)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if len(list.Items) != len(test.items) {
|
|
||||||
t.Fatalf("(%s) unexpected length: %d vs %d", test.name, len(list.Items), len(test.items))
|
|
||||||
}
|
|
||||||
// The order of elements in LIST is not guaranteed.
|
|
||||||
mapping := make(map[string]int)
|
|
||||||
for ix := range test.items {
|
|
||||||
mapping[test.items[ix].Name] = ix
|
|
||||||
}
|
|
||||||
for ix := range list.Items {
|
|
||||||
// Copy things that are set dynamically on the server
|
|
||||||
expectedObj := test.items[mapping[list.Items[ix].Name]]
|
|
||||||
expectedObj.SelfLink = list.Items[ix].SelfLink
|
|
||||||
expectedObj.ResourceVersion = list.Items[ix].ResourceVersion
|
|
||||||
expectedObj.Namespace = list.Items[ix].Namespace
|
|
||||||
expectedObj.UID = list.Items[ix].UID
|
|
||||||
expectedObj.CreationTimestamp = list.Items[ix].CreationTimestamp
|
|
||||||
|
|
||||||
// We endure the order of items by sorting them (using 'mapping')
|
|
||||||
// so that this function passes.
|
|
||||||
if !reflect.DeepEqual(list.Items[ix], expectedObj) {
|
|
||||||
t.Errorf("(%s) expected:\n%#v\nsaw:\n%#v\n", test.name, expectedObj, list.Items[ix])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func encodeToThirdParty(name string, obj interface{}) (runtime.Object, error) {
|
|
||||||
serial, err := json.Marshal(obj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
thirdPartyData := extensions.ThirdPartyResourceData{
|
|
||||||
ObjectMeta: api.ObjectMeta{Name: name},
|
|
||||||
Data: serial,
|
|
||||||
}
|
|
||||||
return &thirdPartyData, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func createThirdPartyObject(s storage.Interface, path, name string, obj interface{}) error {
|
|
||||||
data, err := encodeToThirdParty(name, obj)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return s.Create(context.TODO(), etcdtest.AddPrefix(path), data, nil, 0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func createThirdPartyList(s storage.Interface, path string, list []Foo) error {
|
|
||||||
for _, obj := range list {
|
|
||||||
if err := createThirdPartyObject(s, path+"/"+obj.Name, obj.Name, obj); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func decodeResponse(resp *http.Response, obj interface{}) error {
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
if err := json.Unmarshal(data, obj); err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func writeResponseToFile(resp *http.Response, filename string) error {
|
|
||||||
defer resp.Body.Close()
|
|
||||||
|
|
||||||
data, err := ioutil.ReadAll(resp.Body)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
return ioutil.WriteFile(filename, data, 0755)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInstallThirdPartyAPIGet(t *testing.T) {
|
|
||||||
for _, version := range versionsToTest {
|
|
||||||
testInstallThirdPartyAPIGetVersion(t, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInstallThirdPartyAPIGetVersion(t *testing.T, version string) {
|
|
||||||
master, etcdserver, server, assert := initThirdParty(t, version, "foo.company.com")
|
|
||||||
defer server.Close()
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
expectedObj := Foo{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "test",
|
|
||||||
},
|
|
||||||
TypeMeta: unversioned.TypeMeta{
|
|
||||||
Kind: "Foo",
|
|
||||||
APIVersion: version,
|
|
||||||
},
|
|
||||||
SomeField: "test field",
|
|
||||||
OtherField: 10,
|
|
||||||
}
|
|
||||||
s, destroyFunc := generic.NewRawStorage(master.thirdPartyStorageConfig)
|
|
||||||
defer destroyFunc()
|
|
||||||
if !assert.NoError(createThirdPartyObject(s, "/ThirdPartyResourceData/company.com/foos/default/test", "test", expectedObj)) {
|
|
||||||
t.FailNow()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test")
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
|
||||||
|
|
||||||
item := Foo{}
|
|
||||||
assert.NoError(decodeResponse(resp, &item))
|
|
||||||
if !assert.False(reflect.DeepEqual(item, expectedObj)) {
|
|
||||||
t.Errorf("expected objects to not be equal:\n%v\nsaw:\n%v\n", expectedObj, item)
|
|
||||||
}
|
|
||||||
// Fill in data that the apiserver injects
|
|
||||||
expectedObj.SelfLink = item.SelfLink
|
|
||||||
expectedObj.ResourceVersion = item.ResourceVersion
|
|
||||||
if !assert.True(reflect.DeepEqual(item, expectedObj)) {
|
|
||||||
t.Errorf("expected:\n%#v\nsaw:\n%#v\n", expectedObj, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInstallThirdPartyAPIPost(t *testing.T) {
|
|
||||||
registered.AddThirdPartyAPIGroupVersions(unversioned.GroupVersion{Group: "company.com", Version: "v1"}, unversioned.GroupVersion{Group: "company.com", Version: "v3"})
|
|
||||||
|
|
||||||
for _, version := range versionsToTest {
|
|
||||||
testInstallThirdPartyAPIPostForVersion(t, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInstallThirdPartyAPIPostForVersion(t *testing.T, version string) {
|
|
||||||
master, etcdserver, server, assert := initThirdParty(t, version, "foo.company.com")
|
|
||||||
defer server.Close()
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
inputObj := Foo{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "test",
|
|
||||||
},
|
|
||||||
TypeMeta: unversioned.TypeMeta{
|
|
||||||
Kind: "Foo",
|
|
||||||
APIVersion: "company.com/" + version,
|
|
||||||
},
|
|
||||||
SomeField: "test field",
|
|
||||||
OtherField: 10,
|
|
||||||
}
|
|
||||||
data, err := json.Marshal(inputObj)
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Post(server.URL+"/apis/company.com/"+version+"/namespaces/default/foos", "application/json", bytes.NewBuffer(data))
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(http.StatusCreated, resp.StatusCode)
|
|
||||||
|
|
||||||
item := Foo{}
|
|
||||||
assert.NoError(decodeResponse(resp, &item))
|
|
||||||
|
|
||||||
// fill in fields set by the apiserver
|
|
||||||
expectedObj := inputObj
|
|
||||||
expectedObj.SelfLink = item.SelfLink
|
|
||||||
expectedObj.ResourceVersion = item.ResourceVersion
|
|
||||||
expectedObj.Namespace = item.Namespace
|
|
||||||
expectedObj.UID = item.UID
|
|
||||||
expectedObj.CreationTimestamp = item.CreationTimestamp
|
|
||||||
if !assert.True(reflect.DeepEqual(item, expectedObj)) {
|
|
||||||
t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
thirdPartyObj := extensions.ThirdPartyResourceData{}
|
|
||||||
s, destroyFunc := generic.NewRawStorage(master.thirdPartyStorageConfig)
|
|
||||||
defer destroyFunc()
|
|
||||||
err = s.Get(context.TODO(), etcdtest.AddPrefix("/ThirdPartyResourceData/company.com/foos/default/test"), &thirdPartyObj, false)
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
t.FailNow()
|
|
||||||
}
|
|
||||||
|
|
||||||
item = Foo{}
|
|
||||||
assert.NoError(json.Unmarshal(thirdPartyObj.Data, &item))
|
|
||||||
|
|
||||||
if !assert.True(reflect.DeepEqual(item, inputObj)) {
|
|
||||||
t.Errorf("expected:\n%v\nsaw:\n%v\n", inputObj, item)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInstallThirdPartyAPIDelete(t *testing.T) {
|
|
||||||
for _, version := range versionsToTest {
|
|
||||||
testInstallThirdPartyAPIDeleteVersion(t, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInstallThirdPartyAPIDeleteVersion(t *testing.T, version string) {
|
|
||||||
master, etcdserver, server, assert := initThirdParty(t, version, "foo.company.com")
|
|
||||||
defer server.Close()
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
expectedObj := Foo{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "test",
|
|
||||||
Namespace: "default",
|
|
||||||
},
|
|
||||||
TypeMeta: unversioned.TypeMeta{
|
|
||||||
Kind: "Foo",
|
|
||||||
},
|
|
||||||
SomeField: "test field",
|
|
||||||
OtherField: 10,
|
|
||||||
}
|
|
||||||
s, destroyFunc := generic.NewRawStorage(master.thirdPartyStorageConfig)
|
|
||||||
defer destroyFunc()
|
|
||||||
if !assert.NoError(createThirdPartyObject(s, "/ThirdPartyResourceData/company.com/foos/default/test", "test", expectedObj)) {
|
|
||||||
t.FailNow()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test")
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
|
||||||
|
|
||||||
item := Foo{}
|
|
||||||
assert.NoError(decodeResponse(resp, &item))
|
|
||||||
|
|
||||||
// Fill in fields set by the apiserver
|
|
||||||
expectedObj.SelfLink = item.SelfLink
|
|
||||||
expectedObj.ResourceVersion = item.ResourceVersion
|
|
||||||
expectedObj.Namespace = item.Namespace
|
|
||||||
if !assert.True(reflect.DeepEqual(item, expectedObj)) {
|
|
||||||
t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err = httpDelete(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test")
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
|
||||||
|
|
||||||
resp, err = http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test")
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(http.StatusNotFound, resp.StatusCode)
|
|
||||||
|
|
||||||
expectedDeletedKey := etcdtest.AddPrefix("ThirdPartyResourceData/company.com/foos/default/test")
|
|
||||||
thirdPartyObj := extensions.ThirdPartyResourceData{}
|
|
||||||
err = s.Get(context.TODO(), expectedDeletedKey, &thirdPartyObj, false)
|
|
||||||
if !storage.IsNotFound(err) {
|
|
||||||
t.Errorf("expected deletion didn't happen: %v", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpDelete(url string) (*http.Response, error) {
|
|
||||||
req, err := http.NewRequest("DELETE", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
client := &http.Client{}
|
|
||||||
return client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInstallThirdPartyAPIListOptions(t *testing.T) {
|
|
||||||
for _, version := range versionsToTest {
|
|
||||||
testInstallThirdPartyAPIListOptionsForVersion(t, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInstallThirdPartyAPIListOptionsForVersion(t *testing.T, version string) {
|
|
||||||
_, etcdserver, server, assert := initThirdParty(t, version, "foo.company.com")
|
|
||||||
defer server.Close()
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
// send a GET request with query parameter
|
|
||||||
resp, err := httpGetWithRV(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos")
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
t.Fatalf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
func httpGetWithRV(url string) (*http.Response, error) {
|
|
||||||
req, err := http.NewRequest("GET", url, nil)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
q := req.URL.Query()
|
|
||||||
// resourceversion is part of a ListOptions
|
|
||||||
q.Add("resourceversion", "0")
|
|
||||||
req.URL.RawQuery = q.Encode()
|
|
||||||
client := &http.Client{}
|
|
||||||
return client.Do(req)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestInstallThirdPartyResourceRemove(t *testing.T) {
|
|
||||||
for _, version := range versionsToTest {
|
|
||||||
testInstallThirdPartyResourceRemove(t, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func testInstallThirdPartyResourceRemove(t *testing.T, version string) {
|
|
||||||
master, etcdserver, server, assert := initThirdParty(t, version, "foo.company.com")
|
|
||||||
defer server.Close()
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
expectedObj := Foo{
|
|
||||||
ObjectMeta: api.ObjectMeta{
|
|
||||||
Name: "test",
|
|
||||||
},
|
|
||||||
TypeMeta: unversioned.TypeMeta{
|
|
||||||
Kind: "Foo",
|
|
||||||
},
|
|
||||||
SomeField: "test field",
|
|
||||||
OtherField: 10,
|
|
||||||
}
|
|
||||||
s, destroyFunc := generic.NewRawStorage(master.thirdPartyStorageConfig)
|
|
||||||
defer destroyFunc()
|
|
||||||
if !assert.NoError(createThirdPartyObject(s, "/ThirdPartyResourceData/company.com/foos/default/test", "test", expectedObj)) {
|
|
||||||
t.FailNow()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
secondObj := expectedObj
|
|
||||||
secondObj.Name = "bar"
|
|
||||||
if !assert.NoError(createThirdPartyObject(s, "/ThirdPartyResourceData/company.com/foos/default/bar", "bar", secondObj)) {
|
|
||||||
t.FailNow()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
resp, err := http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test")
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
t.FailNow()
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusOK {
|
|
||||||
t.Errorf("unexpected status: %v", resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
item := Foo{}
|
|
||||||
if err := decodeResponse(resp, &item); err != nil {
|
|
||||||
t.Errorf("unexpected error: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: validate etcd set things here
|
|
||||||
item.ObjectMeta = expectedObj.ObjectMeta
|
|
||||||
|
|
||||||
if !assert.True(reflect.DeepEqual(item, expectedObj)) {
|
|
||||||
t.Errorf("expected:\n%v\nsaw:\n%v\n", expectedObj, item)
|
|
||||||
}
|
|
||||||
|
|
||||||
path := extensionsrest.MakeThirdPartyPath("company.com")
|
|
||||||
master.RemoveThirdPartyResource(path + "/foos")
|
|
||||||
|
|
||||||
resp, err = http.Get(server.URL + "/apis/company.com/" + version + "/namespaces/default/foos/test")
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if resp.StatusCode != http.StatusNotFound {
|
|
||||||
t.Errorf("unexpected status: %v", resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
expectedDeletedKeys := []string{
|
|
||||||
etcdtest.AddPrefix("/ThirdPartyResourceData/company.com/foos/default/test"),
|
|
||||||
etcdtest.AddPrefix("/ThirdPartyResourceData/company.com/foos/default/bar"),
|
|
||||||
}
|
|
||||||
for _, key := range expectedDeletedKeys {
|
|
||||||
thirdPartyObj := extensions.ThirdPartyResourceData{}
|
|
||||||
s, destroyFunc := generic.NewRawStorage(master.thirdPartyStorageConfig)
|
|
||||||
err := s.Get(context.TODO(), key, &thirdPartyObj, false)
|
|
||||||
if !storage.IsNotFound(err) {
|
|
||||||
t.Errorf("expected deletion didn't happen: %v", err)
|
|
||||||
}
|
|
||||||
destroyFunc()
|
|
||||||
}
|
|
||||||
installed := master.ListThirdPartyResources()
|
|
||||||
if len(installed) != 0 {
|
|
||||||
t.Errorf("Resource(s) still installed: %v", installed)
|
|
||||||
}
|
|
||||||
services := master.HandlerContainer.RegisteredWebServices()
|
|
||||||
for ix := range services {
|
|
||||||
if strings.HasPrefix(services[ix].RootPath(), "/apis/company.com") {
|
|
||||||
t.Errorf("Web service still installed at %s: %#v", services[ix].RootPath(), services[ix])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestThirdPartyDiscovery(t *testing.T) {
|
|
||||||
for _, version := range versionsToTest {
|
|
||||||
testThirdPartyDiscovery(t, version)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
type FakeTunneler struct {
|
type FakeTunneler struct {
|
||||||
SecondsSinceSyncValue int64
|
SecondsSinceSyncValue int64
|
||||||
SecondsSinceSSHKeySyncValue int64
|
SecondsSinceSSHKeySyncValue int64
|
||||||
@ -1116,48 +514,14 @@ func TestIsTunnelSyncHealthy(t *testing.T) {
|
|||||||
assert.Error(err, "IsTunnelSyncHealthy() should have returned an error.")
|
assert.Error(err, "IsTunnelSyncHealthy() should have returned an error.")
|
||||||
}
|
}
|
||||||
|
|
||||||
func testThirdPartyDiscovery(t *testing.T, version string) {
|
func writeResponseToFile(resp *http.Response, filename string) error {
|
||||||
_, etcdserver, server, assert := initThirdParty(t, version, "foo.company.com")
|
defer resp.Body.Close()
|
||||||
defer server.Close()
|
|
||||||
defer etcdserver.Terminate(t)
|
|
||||||
|
|
||||||
resp, err := http.Get(server.URL + "/apis/company.com/")
|
data, err := ioutil.ReadAll(resp.Body)
|
||||||
if !assert.NoError(err) {
|
if err != nil {
|
||||||
return
|
return err
|
||||||
}
|
}
|
||||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
return ioutil.WriteFile(filename, data, 0755)
|
||||||
|
|
||||||
group := unversioned.APIGroup{}
|
|
||||||
assert.NoError(decodeResponse(resp, &group))
|
|
||||||
assert.Equal(group.APIVersion, "v1")
|
|
||||||
assert.Equal(group.Kind, "APIGroup")
|
|
||||||
assert.Equal(group.Name, "company.com")
|
|
||||||
expectedVersion := unversioned.GroupVersionForDiscovery{
|
|
||||||
GroupVersion: "company.com/" + version,
|
|
||||||
Version: version,
|
|
||||||
}
|
|
||||||
|
|
||||||
assert.Equal(group.Versions, []unversioned.GroupVersionForDiscovery{expectedVersion})
|
|
||||||
assert.Equal(group.PreferredVersion, expectedVersion)
|
|
||||||
|
|
||||||
resp, err = http.Get(server.URL + "/apis/company.com/" + version)
|
|
||||||
if !assert.NoError(err) {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
assert.Equal(http.StatusOK, resp.StatusCode)
|
|
||||||
|
|
||||||
resourceList := unversioned.APIResourceList{}
|
|
||||||
assert.NoError(decodeResponse(resp, &resourceList))
|
|
||||||
assert.Equal(resourceList.APIVersion, "v1")
|
|
||||||
assert.Equal(resourceList.Kind, "APIResourceList")
|
|
||||||
assert.Equal(resourceList.GroupVersion, "company.com/"+version)
|
|
||||||
assert.Equal(resourceList.APIResources, []unversioned.APIResource{
|
|
||||||
{
|
|
||||||
Name: "foos",
|
|
||||||
Namespaced: true,
|
|
||||||
Kind: "Foo",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// TestValidOpenAPISpec verifies that the open api is added
|
// TestValidOpenAPISpec verifies that the open api is added
|
||||||
|
229
test/integration/thirdparty/thirdparty_test.go
vendored
Normal file
229
test/integration/thirdparty/thirdparty_test.go
vendored
Normal file
@ -0,0 +1,229 @@
|
|||||||
|
// +build integration,!no-etcd
|
||||||
|
|
||||||
|
/*
|
||||||
|
Copyright 2015 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 thirdparty
|
||||||
|
|
||||||
|
// This file contains tests for the storage classes API resource.
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"k8s.io/kubernetes/pkg/api"
|
||||||
|
apierrors "k8s.io/kubernetes/pkg/api/errors"
|
||||||
|
"k8s.io/kubernetes/pkg/api/unversioned"
|
||||||
|
"k8s.io/kubernetes/pkg/apis/extensions"
|
||||||
|
"k8s.io/kubernetes/pkg/client/clientset_generated/internalclientset"
|
||||||
|
"k8s.io/kubernetes/pkg/client/restclient"
|
||||||
|
"k8s.io/kubernetes/pkg/util/diff"
|
||||||
|
"k8s.io/kubernetes/pkg/util/wait"
|
||||||
|
"k8s.io/kubernetes/test/integration/framework"
|
||||||
|
)
|
||||||
|
|
||||||
|
// TODO these tests will eventually be runnable in a single test
|
||||||
|
func TestThirdPartyDelete(t *testing.T) {
|
||||||
|
_, s := framework.RunAMaster(framework.NewIntegrationTestMasterConfig())
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
clientConfig := &restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{NegotiatedSerializer: api.Codecs}}
|
||||||
|
client := internalclientset.NewForConfigOrDie(clientConfig)
|
||||||
|
|
||||||
|
DoTestInstallThirdPartyAPIDelete(t, client, clientConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestThirdPartyMultiple(t *testing.T) {
|
||||||
|
_, s := framework.RunAMaster(framework.NewIntegrationTestMasterConfig())
|
||||||
|
defer s.Close()
|
||||||
|
|
||||||
|
clientConfig := &restclient.Config{Host: s.URL, ContentConfig: restclient.ContentConfig{NegotiatedSerializer: api.Codecs}}
|
||||||
|
client := internalclientset.NewForConfigOrDie(clientConfig)
|
||||||
|
|
||||||
|
DoTestInstallMultipleAPIs(t, client, clientConfig)
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO make multiple versions work. they've been broken
|
||||||
|
var versionsToTest = []string{"v1"}
|
||||||
|
|
||||||
|
type Foo struct {
|
||||||
|
unversioned.TypeMeta `json:",inline"`
|
||||||
|
api.ObjectMeta `json:"metadata,omitempty" description:"standard object metadata"`
|
||||||
|
|
||||||
|
SomeField string `json:"someField"`
|
||||||
|
OtherField int `json:"otherField"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type FooList struct {
|
||||||
|
unversioned.TypeMeta `json:",inline"`
|
||||||
|
unversioned.ListMeta `json:"metadata,omitempty" description:"standard list metadata; see http://releases.k8s.io/HEAD/docs/devel/api-conventions.md#metadata"`
|
||||||
|
|
||||||
|
Items []Foo `json:"items"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// installThirdParty installs a third party resoure and returns a defer func
|
||||||
|
func installThirdParty(t *testing.T, client internalclientset.Interface, clientConfig *restclient.Config, tpr *extensions.ThirdPartyResource, group, version, resource string) func() {
|
||||||
|
var err error
|
||||||
|
_, err = client.Extensions().ThirdPartyResources().Create(tpr)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fooClientConfig := *clientConfig
|
||||||
|
fooClientConfig.APIPath = "apis"
|
||||||
|
fooClientConfig.GroupVersion = &unversioned.GroupVersion{Group: group, Version: version}
|
||||||
|
fooClient, err := restclient.RESTClientFor(&fooClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = wait.Poll(100*time.Millisecond, 60*time.Second, func() (bool, error) {
|
||||||
|
_, err := fooClient.Get().Namespace("default").Resource(resource).DoRaw()
|
||||||
|
if err == nil {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
|
return false, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return func() {
|
||||||
|
client.Extensions().ThirdPartyResources().Delete(tpr.Name, nil)
|
||||||
|
err = wait.Poll(100*time.Millisecond, 60*time.Second, func() (bool, error) {
|
||||||
|
_, err := fooClient.Get().Namespace("default").Resource(resource).DoRaw()
|
||||||
|
if apierrors.IsNotFound(err) {
|
||||||
|
return true, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return false, err
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func DoTestInstallMultipleAPIs(t *testing.T, client internalclientset.Interface, clientConfig *restclient.Config) {
|
||||||
|
group := "company.com"
|
||||||
|
version := "v1"
|
||||||
|
|
||||||
|
defer installThirdParty(t, client, clientConfig,
|
||||||
|
&extensions.ThirdPartyResource{
|
||||||
|
ObjectMeta: api.ObjectMeta{Name: "foo.company.com"},
|
||||||
|
Versions: []extensions.APIVersion{{Name: version}},
|
||||||
|
}, group, version, "foos",
|
||||||
|
)()
|
||||||
|
|
||||||
|
// TODO make multiple resources in one version work
|
||||||
|
// defer installThirdParty(t, client, clientConfig,
|
||||||
|
// &extensions.ThirdPartyResource{
|
||||||
|
// ObjectMeta: api.ObjectMeta{Name: "bar.company.com"},
|
||||||
|
// Versions: []extensions.APIVersion{{Name: version}},
|
||||||
|
// }, group, version, "bars",
|
||||||
|
// )()
|
||||||
|
}
|
||||||
|
|
||||||
|
func DoTestInstallThirdPartyAPIDelete(t *testing.T, client internalclientset.Interface, clientConfig *restclient.Config) {
|
||||||
|
for _, version := range versionsToTest {
|
||||||
|
testInstallThirdPartyAPIDeleteVersion(t, client, clientConfig, version)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func testInstallThirdPartyAPIDeleteVersion(t *testing.T, client internalclientset.Interface, clientConfig *restclient.Config, version string) {
|
||||||
|
group := "company.com"
|
||||||
|
|
||||||
|
defer installThirdParty(t, client, clientConfig,
|
||||||
|
&extensions.ThirdPartyResource{
|
||||||
|
ObjectMeta: api.ObjectMeta{Name: "foo.company.com"},
|
||||||
|
Versions: []extensions.APIVersion{{Name: version}},
|
||||||
|
}, group, version, "foos",
|
||||||
|
)()
|
||||||
|
|
||||||
|
fooClientConfig := *clientConfig
|
||||||
|
fooClientConfig.APIPath = "apis"
|
||||||
|
fooClientConfig.GroupVersion = &unversioned.GroupVersion{Group: group, Version: version}
|
||||||
|
fooClient, err := restclient.RESTClientFor(&fooClientConfig)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
expectedObj := Foo{
|
||||||
|
ObjectMeta: api.ObjectMeta{
|
||||||
|
Name: "test",
|
||||||
|
Namespace: "default",
|
||||||
|
},
|
||||||
|
TypeMeta: unversioned.TypeMeta{
|
||||||
|
Kind: "Foo",
|
||||||
|
},
|
||||||
|
SomeField: "test field",
|
||||||
|
OtherField: 10,
|
||||||
|
}
|
||||||
|
objBytes, err := json.Marshal(&expectedObj)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := fooClient.Post().Namespace("default").Resource("foos").Body(objBytes).DoRaw(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
apiBytes, err := fooClient.Get().Namespace("default").Resource("foos").Name("test").DoRaw()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
item := Foo{}
|
||||||
|
err = json.Unmarshal(apiBytes, &item)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Fill in fields set by the apiserver
|
||||||
|
item.SelfLink = expectedObj.SelfLink
|
||||||
|
item.ResourceVersion = expectedObj.ResourceVersion
|
||||||
|
item.Namespace = expectedObj.Namespace
|
||||||
|
item.UID = expectedObj.UID
|
||||||
|
item.CreationTimestamp = expectedObj.CreationTimestamp
|
||||||
|
if !reflect.DeepEqual(item, expectedObj) {
|
||||||
|
t.Fatalf("expected:\n%v\n", diff.ObjectGoPrintSideBySide(expectedObj, item))
|
||||||
|
}
|
||||||
|
|
||||||
|
listBytes, err := fooClient.Get().Namespace("default").Resource("foos").DoRaw()
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
list := FooList{}
|
||||||
|
err = json.Unmarshal(listBytes, &list)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if len(list.Items) != 1 {
|
||||||
|
t.Fatalf("wrong item: %v", list)
|
||||||
|
}
|
||||||
|
|
||||||
|
if _, err := fooClient.Delete().Namespace("default").Resource("foos").Name("test").DoRaw(); err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
if _, err := fooClient.Get().Namespace("default").Resource("foos").Name("test").DoRaw(); !apierrors.IsNotFound(err) {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user