mirror of
https://github.com/kyverno/kyverno.git
synced 2025-03-09 17:37:12 +00:00
983 lines
32 KiB
Go
983 lines
32 KiB
Go
|
/*
|
||
|
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 integration
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"reflect"
|
||
|
"sort"
|
||
|
"strings"
|
||
|
"testing"
|
||
|
"time"
|
||
|
|
||
|
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
|
||
|
"k8s.io/apiextensions-apiserver/test/integration/fixtures"
|
||
|
"k8s.io/apimachinery/pkg/api/errors"
|
||
|
"k8s.io/apimachinery/pkg/api/meta"
|
||
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
||
|
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
|
||
|
"k8s.io/apimachinery/pkg/runtime"
|
||
|
"k8s.io/apimachinery/pkg/types"
|
||
|
"k8s.io/apimachinery/pkg/util/wait"
|
||
|
"k8s.io/apimachinery/pkg/watch"
|
||
|
"k8s.io/client-go/dynamic"
|
||
|
)
|
||
|
|
||
|
func TestServerUp(t *testing.T) {
|
||
|
tearDown, _, _, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
}
|
||
|
|
||
|
func TestNamespaceScopedCRUD(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ns := "not-the-default"
|
||
|
|
||
|
testSimpleCRUD(t, ns, noxuDefinition, dynamicClient)
|
||
|
testFieldSelector(t, ns, noxuDefinition, dynamicClient)
|
||
|
}
|
||
|
|
||
|
func TestClusterScopedCRUD(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.ClusterScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ns := ""
|
||
|
testSimpleCRUD(t, ns, noxuDefinition, dynamicClient)
|
||
|
testFieldSelector(t, ns, noxuDefinition, dynamicClient)
|
||
|
}
|
||
|
|
||
|
func testSimpleCRUD(t *testing.T, ns string, noxuDefinition *apiextensionsv1beta1.CustomResourceDefinition, dynamicClient dynamic.Interface) {
|
||
|
noxuResourceClients := map[string]dynamic.ResourceInterface{}
|
||
|
noxuWatchs := map[string]watch.Interface{}
|
||
|
disabledVersions := map[string]bool{}
|
||
|
for _, v := range noxuDefinition.Spec.Versions {
|
||
|
disabledVersions[v.Name] = !v.Served
|
||
|
}
|
||
|
for _, v := range noxuDefinition.Spec.Versions {
|
||
|
noxuResourceClients[v.Name] = newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, v.Name)
|
||
|
|
||
|
noxuWatch, err := noxuResourceClients[v.Name].Watch(metav1.ListOptions{})
|
||
|
if disabledVersions[v.Name] {
|
||
|
if !errors.IsNotFound(err) {
|
||
|
t.Errorf("expected the watch operation fail with NotFound for disabled version %s, got error: %v", v.Name, err)
|
||
|
}
|
||
|
} else {
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
noxuWatchs[v.Name] = noxuWatch
|
||
|
}
|
||
|
}
|
||
|
defer func() {
|
||
|
for _, w := range noxuWatchs {
|
||
|
w.Stop()
|
||
|
}
|
||
|
}()
|
||
|
|
||
|
for version, noxuResourceClient := range noxuResourceClients {
|
||
|
createdNoxuInstance, err := instantiateVersionedCustomResource(t, fixtures.NewVersionedNoxuInstance(ns, "foo", version), noxuResourceClient, noxuDefinition, version)
|
||
|
if disabledVersions[version] {
|
||
|
if !errors.IsNotFound(err) {
|
||
|
t.Errorf("expected the CR creation fail with NotFound for disabled version %s, got error: %v", version, err)
|
||
|
}
|
||
|
continue
|
||
|
}
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to create noxu Instance:%v", err)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Group+"/"+version, createdNoxuInstance.GetAPIVersion(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
for watchVersion, noxuWatch := range noxuWatchs {
|
||
|
select {
|
||
|
case watchEvent := <-noxuWatch.ResultChan():
|
||
|
if e, a := watch.Added, watchEvent.Type; e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
break
|
||
|
}
|
||
|
createdObjectMeta, err := meta.Accessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
// it should have a UUID
|
||
|
if len(createdObjectMeta.GetUID()) == 0 {
|
||
|
t.Errorf("missing uuid: %#v", watchEvent.Object)
|
||
|
}
|
||
|
if e, a := ns, createdObjectMeta.GetNamespace(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
createdTypeMeta, err := meta.TypeAccessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Group+"/"+watchVersion, createdTypeMeta.GetAPIVersion(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Names.Kind, createdTypeMeta.GetKind(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
case <-time.After(5 * time.Second):
|
||
|
t.Errorf("missing watch event")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Check get for all versions
|
||
|
for version2, noxuResourceClient2 := range noxuResourceClients {
|
||
|
// Get test
|
||
|
gottenNoxuInstance, err := noxuResourceClient2.Get("foo", metav1.GetOptions{})
|
||
|
|
||
|
if disabledVersions[version2] {
|
||
|
if !errors.IsNotFound(err) {
|
||
|
t.Errorf("expected the get operation fail with NotFound for disabled version %s, got error: %v", version2, err)
|
||
|
|
||
|
}
|
||
|
} else {
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if e, a := version2, gottenNoxuInstance.GroupVersionKind().Version; !reflect.DeepEqual(e, a) {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// List test
|
||
|
listWithItem, err := noxuResourceClient2.List(metav1.ListOptions{})
|
||
|
if disabledVersions[version2] {
|
||
|
if !errors.IsNotFound(err) {
|
||
|
t.Errorf("expected the list operation fail with NotFound for disabled version %s, got error: %v", version2, err)
|
||
|
|
||
|
}
|
||
|
} else {
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := 1, len(listWithItem.Items); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := version2, listWithItem.GroupVersionKind().Version; !reflect.DeepEqual(e, a) {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := version2, listWithItem.Items[0].GroupVersionKind().Version; !reflect.DeepEqual(e, a) {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Update test
|
||
|
for version2, noxuResourceClient2 := range noxuResourceClients {
|
||
|
var gottenNoxuInstance *unstructured.Unstructured
|
||
|
if disabledVersions[version2] {
|
||
|
gottenNoxuInstance = &unstructured.Unstructured{}
|
||
|
gottenNoxuInstance.SetName("foo")
|
||
|
} else {
|
||
|
gottenNoxuInstance, err = noxuResourceClient2.Get("foo", metav1.GetOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
gottenNoxuInstance.Object["updated"] = version2
|
||
|
updatedNoxuInstance, err := noxuResourceClient2.Update(gottenNoxuInstance, metav1.UpdateOptions{})
|
||
|
if disabledVersions[version2] {
|
||
|
if !errors.IsNotFound(err) {
|
||
|
t.Errorf("expected the update operation fail with NotFound for disabled version %s, got error: %v", version2, err)
|
||
|
}
|
||
|
} else {
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if updated, ok := updatedNoxuInstance.Object["updated"]; !ok {
|
||
|
t.Errorf("expected string 'updated' field")
|
||
|
} else if updated, ok := updated.(string); !ok || updated != version2 {
|
||
|
t.Errorf("expected string 'updated' field to equal %q, got %q of type %T", version2, updated, updated)
|
||
|
}
|
||
|
|
||
|
if e, a := version2, updatedNoxuInstance.GroupVersionKind().Version; !reflect.DeepEqual(e, a) {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
for _, noxuWatch := range noxuWatchs {
|
||
|
select {
|
||
|
case watchEvent := <-noxuWatch.ResultChan():
|
||
|
eventMetadata, err := meta.Accessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if watchEvent.Type != watch.Modified {
|
||
|
t.Errorf("expected modified event, got %v", watchEvent.Type)
|
||
|
break
|
||
|
}
|
||
|
|
||
|
// it should have a UUID
|
||
|
createdMetadata, err := meta.Accessor(createdNoxuInstance)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := createdMetadata.GetUID(), eventMetadata.GetUID(); e != a {
|
||
|
t.Errorf("expected equal UID for (expected) %v, and (actual) %v", createdNoxuInstance, watchEvent.Object)
|
||
|
}
|
||
|
|
||
|
case <-time.After(5 * time.Second):
|
||
|
t.Errorf("missing watch event")
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Delete test
|
||
|
if err := noxuResourceClient.Delete("foo", metav1.NewDeleteOptions(0)); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
listWithoutItem, err := noxuResourceClient.List(metav1.ListOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := 0, len(listWithoutItem.Items); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
for _, noxuWatch := range noxuWatchs {
|
||
|
select {
|
||
|
case watchEvent := <-noxuWatch.ResultChan():
|
||
|
eventMetadata, err := meta.Accessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if watchEvent.Type != watch.Deleted {
|
||
|
t.Errorf("expected delete event, got %v", watchEvent.Type)
|
||
|
break
|
||
|
}
|
||
|
|
||
|
// it should have a UUID
|
||
|
createdMetadata, err := meta.Accessor(createdNoxuInstance)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := createdMetadata.GetUID(), eventMetadata.GetUID(); e != a {
|
||
|
t.Errorf("expected equal UID for (expected) %v, and (actual) %v", createdNoxuInstance, watchEvent.Object)
|
||
|
}
|
||
|
|
||
|
case <-time.After(5 * time.Second):
|
||
|
t.Errorf("missing watch event")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
// Delete test
|
||
|
if err := noxuResourceClient.DeleteCollection(metav1.NewDeleteOptions(0), metav1.ListOptions{}); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func testFieldSelector(t *testing.T, ns string, noxuDefinition *apiextensionsv1beta1.CustomResourceDefinition, dynamicClient dynamic.Interface) {
|
||
|
noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
|
||
|
initialList, err := noxuResourceClient.List(metav1.ListOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := 0, len(initialList.Items); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
initialListTypeMeta, err := meta.TypeAccessor(initialList)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Group+"/"+noxuDefinition.Spec.Versions[0].Name, initialListTypeMeta.GetAPIVersion(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Names.ListKind, initialListTypeMeta.GetKind(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
initialListListMeta, err := meta.ListAccessor(initialList)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
noxuWatch, err := noxuResourceClient.Watch(
|
||
|
metav1.ListOptions{
|
||
|
ResourceVersion: initialListListMeta.GetResourceVersion(),
|
||
|
FieldSelector: "metadata.name=foo",
|
||
|
},
|
||
|
)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer noxuWatch.Stop()
|
||
|
|
||
|
_, err = instantiateCustomResource(t, fixtures.NewNoxuInstance(ns, "bar"), noxuResourceClient, noxuDefinition)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to create noxu Instance:%v", err)
|
||
|
}
|
||
|
createdNoxuInstanceFoo, err := instantiateCustomResource(t, fixtures.NewNoxuInstance(ns, "foo"), noxuResourceClient, noxuDefinition)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to create noxu Instance:%v", err)
|
||
|
}
|
||
|
|
||
|
select {
|
||
|
case watchEvent := <-noxuWatch.ResultChan():
|
||
|
if e, a := watch.Added, watchEvent.Type; e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
break
|
||
|
}
|
||
|
createdObjectMeta, err := meta.Accessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
// it should have a UUID
|
||
|
if len(createdObjectMeta.GetUID()) == 0 {
|
||
|
t.Errorf("missing uuid: %#v", watchEvent.Object)
|
||
|
}
|
||
|
if e, a := ns, createdObjectMeta.GetNamespace(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := "foo", createdObjectMeta.GetName(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
createdTypeMeta, err := meta.TypeAccessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Group+"/"+noxuDefinition.Spec.Versions[0].Name, createdTypeMeta.GetAPIVersion(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Names.Kind, createdTypeMeta.GetKind(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
case <-time.After(5 * time.Second):
|
||
|
t.Errorf("missing watch event")
|
||
|
}
|
||
|
|
||
|
gottenNoxuInstance, err := noxuResourceClient.Get("foo", metav1.GetOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := createdNoxuInstanceFoo, gottenNoxuInstance; !reflect.DeepEqual(e, a) {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
listWithItem, err := noxuResourceClient.List(metav1.ListOptions{FieldSelector: "metadata.name=foo"})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := 1, len(listWithItem.Items); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := *createdNoxuInstanceFoo, listWithItem.Items[0]; !reflect.DeepEqual(e, a) {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
if err := noxuResourceClient.Delete("bar", nil); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if err := noxuResourceClient.Delete("foo", nil); err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
listWithoutItem, err := noxuResourceClient.List(metav1.ListOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := 0, len(listWithoutItem.Items); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
select {
|
||
|
case watchEvent := <-noxuWatch.ResultChan():
|
||
|
if e, a := watch.Deleted, watchEvent.Type; e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
break
|
||
|
}
|
||
|
deletedObjectMeta, err := meta.Accessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
// it should have a UUID
|
||
|
createdObjectMeta, err := meta.Accessor(createdNoxuInstanceFoo)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := createdObjectMeta.GetUID(), deletedObjectMeta.GetUID(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := ns, createdObjectMeta.GetNamespace(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := "foo", createdObjectMeta.GetName(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
case <-time.After(5 * time.Second):
|
||
|
t.Errorf("missing watch event")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestDiscovery(t *testing.T) {
|
||
|
group := "mygroup.example.com"
|
||
|
version := "v1beta1"
|
||
|
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
scope := apiextensionsv1beta1.NamespaceScoped
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(scope)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// check whether it shows up in discovery properly
|
||
|
resources, err := apiExtensionClient.Discovery().ServerResourcesForGroupVersion(group + "/" + version)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if len(resources.APIResources) != 1 {
|
||
|
t.Fatalf("Expected exactly the resource \"noxus\" in group version %v/%v via discovery, got: %v", group, version, resources.APIResources)
|
||
|
}
|
||
|
|
||
|
r := resources.APIResources[0]
|
||
|
if r.Name != "noxus" {
|
||
|
t.Fatalf("Expected exactly the resource \"noxus\" in group version %v/%v via discovery, got: %v", group, version, r.Name)
|
||
|
}
|
||
|
if r.Kind != "WishIHadChosenNoxu" {
|
||
|
t.Fatalf("Expected exactly the kind \"WishIHadChosenNoxu\" in group version %v/%v via discovery, got: %v", group, version, r.Kind)
|
||
|
}
|
||
|
|
||
|
s := []string{"foo", "bar", "abc", "def"}
|
||
|
if !reflect.DeepEqual(r.ShortNames, s) {
|
||
|
t.Fatalf("Expected exactly the shortnames `foo, bar, abc, def` in group version %v/%v via discovery, got: %v", group, version, r.ShortNames)
|
||
|
}
|
||
|
|
||
|
sort.Strings(r.Verbs)
|
||
|
expectedVerbs := []string{"create", "delete", "deletecollection", "get", "list", "patch", "update", "watch"}
|
||
|
if !reflect.DeepEqual([]string(r.Verbs), expectedVerbs) {
|
||
|
t.Fatalf("Unexpected verbs for resource \"noxus\" in group version %v/%v via discovery: expected=%v got=%v", group, version, expectedVerbs, r.Verbs)
|
||
|
}
|
||
|
|
||
|
if !reflect.DeepEqual(r.Categories, []string{"all"}) {
|
||
|
t.Fatalf("Expected exactly the category \"all\" in group version %v/%v via discovery, got: %v", group, version, r.Categories)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestNoNamespaceReject(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ns := ""
|
||
|
noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
|
||
|
initialList, err := noxuResourceClient.List(metav1.ListOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := 0, len(initialList.Items); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
initialListTypeMeta, err := meta.TypeAccessor(initialList)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Group+"/"+noxuDefinition.Spec.Version, initialListTypeMeta.GetAPIVersion(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Names.ListKind, initialListTypeMeta.GetKind(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
createdNoxuInstance, err := instantiateCustomResource(t, fixtures.NewNoxuInstance(ns, "foo"), noxuResourceClient, noxuDefinition)
|
||
|
if err == nil {
|
||
|
t.Fatalf("unexpected non-error: an empty namespace may not be set during creation while creating noxu instance: %v ", createdNoxuInstance)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestSameNameDiffNamespace(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ns1 := "namespace-1"
|
||
|
testSimpleCRUD(t, ns1, noxuDefinition, dynamicClient)
|
||
|
ns2 := "namespace-2"
|
||
|
testSimpleCRUD(t, ns2, noxuDefinition, dynamicClient)
|
||
|
|
||
|
}
|
||
|
|
||
|
func TestSelfLink(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
// namespace scoped
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ns := "not-the-default"
|
||
|
noxuNamespacedResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
|
||
|
|
||
|
noxuInstanceToCreate := fixtures.NewNoxuInstance(ns, "foo")
|
||
|
createdNoxuInstance, err := noxuNamespacedResourceClient.Create(noxuInstanceToCreate, metav1.CreateOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if e, a := "/apis/mygroup.example.com/v1beta1/namespaces/not-the-default/noxus/foo", createdNoxuInstance.GetSelfLink(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
// cluster scoped
|
||
|
curletDefinition := fixtures.NewCurletCustomResourceDefinition(apiextensionsv1beta1.ClusterScoped)
|
||
|
curletDefinition, err = fixtures.CreateNewCustomResourceDefinition(curletDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
curletResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, curletDefinition)
|
||
|
|
||
|
curletInstanceToCreate := fixtures.NewCurletInstance(ns, "foo")
|
||
|
createdCurletInstance, err := curletResourceClient.Create(curletInstanceToCreate, metav1.CreateOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if e, a := "/apis/mygroup.example.com/v1beta1/curlets/foo", createdCurletInstance.GetSelfLink(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestPreserveInt(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.ClusterScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ns := "not-the-default"
|
||
|
noxuNamespacedResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
|
||
|
|
||
|
noxuInstanceToCreate := fixtures.NewNoxuInstance(ns, "foo")
|
||
|
createdNoxuInstance, err := noxuNamespacedResourceClient.Create(noxuInstanceToCreate, metav1.CreateOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
originalJSON, err := runtime.Encode(unstructured.UnstructuredJSONScheme, createdNoxuInstance)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unexpected error: %v", err)
|
||
|
}
|
||
|
|
||
|
gottenNoxuInstance, err := runtime.Decode(unstructured.UnstructuredJSONScheme, originalJSON)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unexpected error: %v", err)
|
||
|
}
|
||
|
|
||
|
// Check if int is preserved.
|
||
|
unstructuredObj := gottenNoxuInstance.(*unstructured.Unstructured).Object
|
||
|
num := unstructuredObj["num"].(map[string]interface{})
|
||
|
num1 := num["num1"].(int64)
|
||
|
num2 := num["num2"].(int64)
|
||
|
if num1 != 9223372036854775807 || num2 != 1000000 {
|
||
|
t.Errorf("Expected %v, got %v, %v", `9223372036854775807, 1000000`, num1, num2)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestPatch(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.ClusterScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ns := "not-the-default"
|
||
|
noxuNamespacedResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
|
||
|
|
||
|
t.Logf("Creating foo")
|
||
|
noxuInstanceToCreate := fixtures.NewNoxuInstance(ns, "foo")
|
||
|
_, err = noxuNamespacedResourceClient.Create(noxuInstanceToCreate, metav1.CreateOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
t.Logf("Patching .num.num2 to 999")
|
||
|
patch := []byte(`{"num": {"num2":999}}`)
|
||
|
patchedNoxuInstance, err := noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, patch, metav1.PatchOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatalf("unexpected error: %v", err)
|
||
|
}
|
||
|
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "num", "num2")
|
||
|
rv, found, err := unstructured.NestedString(patchedNoxuInstance.UnstructuredContent(), "metadata", "resourceVersion")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if !found {
|
||
|
t.Fatalf("metadata.resourceVersion not found")
|
||
|
}
|
||
|
|
||
|
// a patch with no change
|
||
|
t.Logf("Patching .num.num2 again to 999")
|
||
|
patchedNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, patch, metav1.PatchOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatalf("unexpected error: %v", err)
|
||
|
}
|
||
|
// make sure no-op patch does not increment resourceVersion
|
||
|
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "num", "num2")
|
||
|
expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion")
|
||
|
|
||
|
// an empty patch
|
||
|
t.Logf("Applying empty patch")
|
||
|
patchedNoxuInstance, err = noxuNamespacedResourceClient.Patch("foo", types.MergePatchType, []byte(`{}`), metav1.PatchOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatalf("unexpected error: %v", err)
|
||
|
}
|
||
|
// an empty patch is a no-op patch. make sure it does not increment resourceVersion
|
||
|
expectInt64(t, patchedNoxuInstance.UnstructuredContent(), 999, "num", "num2")
|
||
|
expectString(t, patchedNoxuInstance.UnstructuredContent(), rv, "metadata", "resourceVersion")
|
||
|
|
||
|
originalJSON, err := runtime.Encode(unstructured.UnstructuredJSONScheme, patchedNoxuInstance)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unexpected error: %v", err)
|
||
|
}
|
||
|
|
||
|
gottenNoxuInstance, err := runtime.Decode(unstructured.UnstructuredJSONScheme, originalJSON)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unexpected error: %v", err)
|
||
|
}
|
||
|
|
||
|
// Check if int is preserved.
|
||
|
unstructuredObj := gottenNoxuInstance.(*unstructured.Unstructured).Object
|
||
|
num := unstructuredObj["num"].(map[string]interface{})
|
||
|
num1 := num["num1"].(int64)
|
||
|
num2 := num["num2"].(int64)
|
||
|
if num1 != 9223372036854775807 || num2 != 999 {
|
||
|
t.Errorf("Expected %v, got %v, %v", `9223372036854775807, 999`, num1, num2)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestCrossNamespaceListWatch(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
ns := ""
|
||
|
noxuResourceClient := newNamespacedCustomResourceClient(ns, dynamicClient, noxuDefinition)
|
||
|
initialList, err := noxuResourceClient.List(metav1.ListOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := 0, len(initialList.Items); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
initialListListMeta, err := meta.ListAccessor(initialList)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
noxuWatch, err := noxuResourceClient.Watch(metav1.ListOptions{ResourceVersion: initialListListMeta.GetResourceVersion()})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer noxuWatch.Stop()
|
||
|
|
||
|
instances := make(map[string]*unstructured.Unstructured)
|
||
|
ns1 := "namespace-1"
|
||
|
noxuNamespacedResourceClient1 := newNamespacedCustomResourceClient(ns1, dynamicClient, noxuDefinition)
|
||
|
instances[ns1] = createInstanceWithNamespaceHelper(t, ns1, "foo1", noxuNamespacedResourceClient1, noxuDefinition)
|
||
|
noxuNamespacesWatch1, err := noxuNamespacedResourceClient1.Watch(metav1.ListOptions{ResourceVersion: initialListListMeta.GetResourceVersion()})
|
||
|
defer noxuNamespacesWatch1.Stop()
|
||
|
|
||
|
ns2 := "namespace-2"
|
||
|
noxuNamespacedResourceClient2 := newNamespacedCustomResourceClient(ns2, dynamicClient, noxuDefinition)
|
||
|
instances[ns2] = createInstanceWithNamespaceHelper(t, ns2, "foo2", noxuNamespacedResourceClient2, noxuDefinition)
|
||
|
noxuNamespacesWatch2, err := noxuNamespacedResourceClient2.Watch(metav1.ListOptions{ResourceVersion: initialListListMeta.GetResourceVersion()})
|
||
|
defer noxuNamespacesWatch2.Stop()
|
||
|
|
||
|
createdList, err := noxuResourceClient.List(metav1.ListOptions{})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
if e, a := 2, len(createdList.Items); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
for _, a := range createdList.Items {
|
||
|
if e := instances[a.GetNamespace()]; !reflect.DeepEqual(e, &a) {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
addEvents := 0
|
||
|
for addEvents < 2 {
|
||
|
select {
|
||
|
case watchEvent := <-noxuWatch.ResultChan():
|
||
|
if e, a := watch.Added, watchEvent.Type; e != a {
|
||
|
t.Fatalf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
createdObjectMeta, err := meta.Accessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if len(createdObjectMeta.GetUID()) == 0 {
|
||
|
t.Errorf("missing uuid: %#v", watchEvent.Object)
|
||
|
}
|
||
|
createdTypeMeta, err := meta.TypeAccessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Group+"/"+noxuDefinition.Spec.Version, createdTypeMeta.GetAPIVersion(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
if e, a := noxuDefinition.Spec.Names.Kind, createdTypeMeta.GetKind(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
delete(instances, createdObjectMeta.GetNamespace())
|
||
|
addEvents++
|
||
|
case <-time.After(5 * time.Second):
|
||
|
t.Fatalf("missing watch event")
|
||
|
}
|
||
|
}
|
||
|
if e, a := 0, len(instances); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
|
||
|
checkNamespacesWatchHelper(t, ns1, noxuNamespacesWatch1)
|
||
|
checkNamespacesWatchHelper(t, ns2, noxuNamespacesWatch2)
|
||
|
}
|
||
|
|
||
|
func createInstanceWithNamespaceHelper(t *testing.T, ns string, name string, noxuNamespacedResourceClient dynamic.ResourceInterface, noxuDefinition *apiextensionsv1beta1.CustomResourceDefinition) *unstructured.Unstructured {
|
||
|
createdInstance, err := instantiateCustomResource(t, fixtures.NewNoxuInstance(ns, name), noxuNamespacedResourceClient, noxuDefinition)
|
||
|
if err != nil {
|
||
|
t.Fatalf("unable to create noxu Instance:%v", err)
|
||
|
}
|
||
|
return createdInstance
|
||
|
}
|
||
|
|
||
|
func checkNamespacesWatchHelper(t *testing.T, ns string, namespacedwatch watch.Interface) {
|
||
|
namespacedAddEvent := 0
|
||
|
for namespacedAddEvent < 2 {
|
||
|
select {
|
||
|
case watchEvent := <-namespacedwatch.ResultChan():
|
||
|
// Check that the namespaced watch only has one result
|
||
|
if namespacedAddEvent > 0 {
|
||
|
t.Fatalf("extra watch event")
|
||
|
}
|
||
|
if e, a := watch.Added, watchEvent.Type; e != a {
|
||
|
t.Fatalf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
createdObjectMeta, err := meta.Accessor(watchEvent.Object)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
if e, a := ns, createdObjectMeta.GetNamespace(); e != a {
|
||
|
t.Errorf("expected %v, got %v", e, a)
|
||
|
}
|
||
|
case <-time.After(5 * time.Second):
|
||
|
if namespacedAddEvent != 1 {
|
||
|
t.Fatalf("missing watch event")
|
||
|
}
|
||
|
}
|
||
|
namespacedAddEvent++
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestNameConflict(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
noxu2Definition := fixtures.NewNoxu2CustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||
|
_, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Create(noxu2Definition)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// A NameConflict occurs
|
||
|
err = wait.Poll(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
|
||
|
crd, err := apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(noxu2Definition.Name, metav1.GetOptions{})
|
||
|
if err != nil {
|
||
|
return false, err
|
||
|
}
|
||
|
|
||
|
for _, condition := range crd.Status.Conditions {
|
||
|
if condition.Type == apiextensionsv1beta1.NamesAccepted && condition.Status == apiextensionsv1beta1.ConditionFalse {
|
||
|
return true, nil
|
||
|
}
|
||
|
}
|
||
|
return false, nil
|
||
|
})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
err = fixtures.DeleteCustomResourceDefinition(noxuDefinition, apiExtensionClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// Names are now accepted
|
||
|
err = wait.Poll(500*time.Millisecond, wait.ForeverTestTimeout, func() (bool, error) {
|
||
|
crd, err := apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().Get(noxu2Definition.Name, metav1.GetOptions{})
|
||
|
if err != nil {
|
||
|
return false, err
|
||
|
}
|
||
|
|
||
|
for _, condition := range crd.Status.Conditions {
|
||
|
if condition.Type == apiextensionsv1beta1.NamesAccepted && condition.Status == apiextensionsv1beta1.ConditionTrue {
|
||
|
return true, nil
|
||
|
}
|
||
|
}
|
||
|
return false, nil
|
||
|
})
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func TestStatusGetAndPatch(t *testing.T) {
|
||
|
tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
defer tearDown()
|
||
|
|
||
|
noxuDefinition := fixtures.NewNoxuCustomResourceDefinition(apiextensionsv1beta1.NamespaceScoped)
|
||
|
noxuDefinition, err = fixtures.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// make sure we don't get 405 Method Not Allowed from Getting CRD/status subresource
|
||
|
result := &apiextensionsv1beta1.CustomResourceDefinition{}
|
||
|
err = apiExtensionClient.ApiextensionsV1beta1().RESTClient().Get().
|
||
|
Resource("customresourcedefinitions").
|
||
|
Name(noxuDefinition.Name).
|
||
|
SubResource("status").
|
||
|
Do().
|
||
|
Into(result)
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
|
||
|
// make sure we don't get 405 Method Not Allowed from Patching CRD/status subresource
|
||
|
_, err = apiExtensionClient.ApiextensionsV1beta1().CustomResourceDefinitions().
|
||
|
Patch(noxuDefinition.Name, types.StrategicMergePatchType,
|
||
|
[]byte(fmt.Sprintf(`{"labels":{"test-label":"dummy"}}`)),
|
||
|
"status")
|
||
|
if err != nil {
|
||
|
t.Fatal(err)
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func expectInt64(t *testing.T, obj map[string]interface{}, value int64, pth ...string) {
|
||
|
if v, found, err := unstructured.NestedInt64(obj, pth...); err != nil {
|
||
|
t.Fatalf("failed to access .%s: %v", strings.Join(pth, "."), err)
|
||
|
} else if !found {
|
||
|
t.Fatalf("failed to find .%s", strings.Join(pth, "."))
|
||
|
} else if v != value {
|
||
|
t.Fatalf("wanted %d at .%s, got %d", value, strings.Join(pth, "."), v)
|
||
|
}
|
||
|
}
|
||
|
func expectString(t *testing.T, obj map[string]interface{}, value string, pth ...string) {
|
||
|
if v, found, err := unstructured.NestedString(obj, pth...); err != nil {
|
||
|
t.Fatalf("failed to access .%s: %v", strings.Join(pth, "."), err)
|
||
|
} else if !found {
|
||
|
t.Fatalf("failed to find .%s", strings.Join(pth, "."))
|
||
|
} else if v != value {
|
||
|
t.Fatalf("wanted %q at .%s, got %q", value, strings.Join(pth, "."), v)
|
||
|
}
|
||
|
}
|