apiextensions: unify multi- and mono-versioned test helpers

This commit is contained in:
Dr. Stefan Schimanski 2018-05-23 16:53:13 +02:00
parent 818147d6fb
commit b01699b9f7
6 changed files with 162 additions and 335 deletions

View File

@ -81,124 +81,163 @@ func TestClusterScopedCRUD(t *testing.T) {
}
func testSimpleCRUD(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.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)
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)
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()
createdNoxuInstance, err := instantiateCustomResource(t, testserver.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
noxuWatch, err := noxuResourceClients[v.Name].Watch(metav1.ListOptions{})
if disabledVersions[v.Name] {
if err == nil {
t.Errorf("expected the watch creation fail for disabled version %s", v.Name)
}
} else {
if err != nil {
t.Fatal(err)
}
noxuWatchs[v.Name] = noxuWatch
}
createdObjectMeta, err := meta.Accessor(watchEvent.Object)
}
defer func() {
for _, w := range noxuWatchs {
w.Stop()
}
}()
for version, noxuResourceClient := range noxuResourceClients {
createdNoxuInstance, err := instantiateVersionedCustomResource(t, testserver.NewVersionedNoxuInstance(ns, "foo", version), noxuResourceClient, noxuDefinition, version)
if disabledVersions[version] {
if err == nil {
t.Errorf("expected the CR creation fail for disabled version %s", version)
}
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 err == nil {
t.Errorf("expected the get operation fail for disabled version %s", version2)
}
} 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 err == nil {
t.Errorf("expected the list operation fail for disabled version %s", version2)
}
} 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)
}
}
}
// 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)
}
// 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 {
if e, a := 0, len(listWithoutItem.Items); e != a {
t.Errorf("expected %v, got %v", e, a)
}
createdTypeMeta, err := meta.TypeAccessor(watchEvent.Object)
if err != nil {
for _, noxuWatch := range noxuWatchs {
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(createdNoxuInstance)
if err != nil {
t.Fatal(err)
}
if e, a := createdObjectMeta.GetUID(), deletedObjectMeta.GetUID(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
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)
}
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)
}
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 := createdNoxuInstance, gottenNoxuInstance; !reflect.DeepEqual(e, a) {
t.Errorf("expected %v, got %v", e, a)
}
listWithItem, err := noxuResourceClient.List(metav1.ListOptions{})
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 := *createdNoxuInstance, listWithItem.Items[0]; !reflect.DeepEqual(e, a) {
t.Errorf("expected %v, got %v", e, a)
}
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(createdNoxuInstance)
if err != nil {
t.Fatal(err)
}
if e, a := createdObjectMeta.GetUID(), deletedObjectMeta.GetUID(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
case <-time.After(5 * time.Second):
t.Errorf("missing watch event")
}
}

View File

@ -42,30 +42,7 @@ import (
)
func instantiateCustomResource(t *testing.T, instanceToCreate *unstructured.Unstructured, client dynamic.ResourceInterface, definition *apiextensionsv1beta1.CustomResourceDefinition) (*unstructured.Unstructured, error) {
createdInstance, err := client.Create(instanceToCreate)
if err != nil {
t.Logf("%#v", createdInstance)
return nil, err
}
createdObjectMeta, err := meta.Accessor(createdInstance)
if err != nil {
t.Fatal(err)
}
// it should have a UUID
if len(createdObjectMeta.GetUID()) == 0 {
t.Errorf("missing uuid: %#v", createdInstance)
}
createdTypeMeta, err := meta.TypeAccessor(createdInstance)
if err != nil {
t.Fatal(err)
}
if e, a := definition.Spec.Group+"/"+definition.Spec.Version, createdTypeMeta.GetAPIVersion(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
if e, a := definition.Spec.Names.Kind, createdTypeMeta.GetKind(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
return createdInstance, nil
return instantiateVersionedCustomResource(t, instanceToCreate, client, definition, definition.Spec.Versions[0].Name)
}
func instantiateVersionedCustomResource(t *testing.T, instanceToCreate *unstructured.Unstructured, client dynamic.ResourceInterface, definition *apiextensionsv1beta1.CustomResourceDefinition, version string) (*unstructured.Unstructured, error) {
@ -105,12 +82,7 @@ func NewNamespacedCustomResourceVersionedClient(ns string, client dynamic.Interf
}
func NewNamespacedCustomResourceClient(ns string, client dynamic.Interface, crd *apiextensionsv1beta1.CustomResourceDefinition) dynamic.ResourceInterface {
gvr := schema.GroupVersionResource{Group: crd.Spec.Group, Version: crd.Spec.Version, Resource: crd.Spec.Names.Plural}
if crd.Spec.Scope != apiextensionsv1beta1.ClusterScoped {
return client.Resource(gvr).Namespace(ns)
}
return client.Resource(gvr)
return NewNamespacedCustomResourceVersionedClient(ns, client, crd, crd.Spec.Versions[0].Name)
}
func TestMultipleResourceInstances(t *testing.T) {

View File

@ -342,7 +342,7 @@ func TestValidationSchema(t *testing.T) {
noxuDefinition.Spec.Subresources = &apiextensionsv1beta1.CustomResourceSubresources{
Status: &apiextensionsv1beta1.CustomResourceSubresourceStatus{},
}
noxuDefinition, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
_, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
if err == nil {
t.Fatalf(`unexpected non-error, expected: must only have "properties" or "required" at the root if the status subresource is enabled`)
}

View File

@ -80,10 +80,10 @@ func NewNoxuCustomResourceDefinition(scope apiextensionsv1beta1.ResourceScope) *
}
}
func NewNoxuInstance(namespace, name string) *unstructured.Unstructured {
func NewVersionedNoxuInstance(namespace, name, version string) *unstructured.Unstructured {
return &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "mygroup.example.com/v1beta1",
"apiVersion": "mygroup.example.com/" + version,
"kind": "WishIHadChosenNoxu",
"metadata": map[string]interface{}{
"namespace": namespace,
@ -100,6 +100,10 @@ func NewNoxuInstance(namespace, name string) *unstructured.Unstructured {
}
}
func NewNoxuInstance(namespace, name string) *unstructured.Unstructured {
return NewVersionedNoxuInstance(namespace, name, "v1beta1")
}
func NewMultipleVersionNoxuCRD(scope apiextensionsv1beta1.ResourceScope) *apiextensionsv1beta1.CustomResourceDefinition {
return &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{Name: "noxus.mygroup.example.com"},
@ -136,26 +140,6 @@ func NewMultipleVersionNoxuCRD(scope apiextensionsv1beta1.ResourceScope) *apiext
}
}
func NewVersionedNoxuInstance(namespace, name, version string) *unstructured.Unstructured {
return &unstructured.Unstructured{
Object: map[string]interface{}{
"apiVersion": "mygroup.example.com/" + version,
"kind": "WishIHadChosenNoxu",
"metadata": map[string]interface{}{
"namespace": namespace,
"name": name,
},
"content": map[string]interface{}{
"key": "value",
},
"num": map[string]interface{}{
"num1": noxuInstanceNum,
"num2": 1000000,
},
},
}
}
func NewNoxu2CustomResourceDefinition(scope apiextensionsv1beta1.ResourceScope) *apiextensionsv1beta1.CustomResourceDefinition {
return &apiextensionsv1beta1.CustomResourceDefinition{
ObjectMeta: metav1.ObjectMeta{Name: "noxus2.mygroup.example.com"},

View File

@ -54,8 +54,7 @@ func TestForProperValidationErrors(t *testing.T) {
{
name: "bad version",
instanceFn: func() *unstructured.Unstructured {
instance := testserver.NewNoxuInstance(ns, "foo")
instance.Object["apiVersion"] = "mygroup.example.com/v2"
instance := testserver.NewVersionedNoxuInstance(ns, "foo", "v2")
return instance
},
expectedError: "the API version in the data (mygroup.example.com/v2) does not match the expected API version (mygroup.example.com/v1beta1)",
@ -384,7 +383,7 @@ func TestForbiddenFieldsInSchema(t *testing.T) {
noxuDefinition := newNoxuValidationCRD(apiextensionsv1beta1.NamespaceScoped)
noxuDefinition.Spec.Validation.OpenAPIV3Schema.AdditionalProperties.Allows = false
noxuDefinition, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
_, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
if err == nil {
t.Fatalf("unexpected non-error: additionalProperties cannot be set to false")
}
@ -395,7 +394,7 @@ func TestForbiddenFieldsInSchema(t *testing.T) {
}
noxuDefinition.Spec.Validation.OpenAPIV3Schema.AdditionalProperties.Allows = true
noxuDefinition, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
_, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
if err == nil {
t.Fatalf("unexpected non-error: uniqueItems cannot be set to true")
}
@ -406,7 +405,7 @@ func TestForbiddenFieldsInSchema(t *testing.T) {
UniqueItems: false,
}
noxuDefinition, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
_, err = testserver.CreateNewCustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
if err == nil {
t.Fatal("unexpected non-error: $ref cannot be non-empty string")
}

View File

@ -19,14 +19,9 @@ package integration
import (
"reflect"
"testing"
"time"
apiextensionsv1beta1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1"
"k8s.io/apiextensions-apiserver/test/integration/testserver"
"k8s.io/apimachinery/pkg/api/meta"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/watch"
"k8s.io/client-go/dynamic"
)
func TestVersionedNamspacedScopedCRD(t *testing.T) {
@ -43,7 +38,7 @@ func TestVersionedNamspacedScopedCRD(t *testing.T) {
}
ns := "not-the-default"
testSimpleVersionedCRUD(t, ns, noxuDefinition, dynamicClient)
testSimpleCRUD(t, ns, noxuDefinition, dynamicClient)
}
func TestVersionedClusterScopedCRD(t *testing.T) {
@ -60,7 +55,7 @@ func TestVersionedClusterScopedCRD(t *testing.T) {
}
ns := ""
testSimpleVersionedCRUD(t, ns, noxuDefinition, dynamicClient)
testSimpleCRUD(t, ns, noxuDefinition, dynamicClient)
}
func TestStoragedVersionInNamespacedCRDStatus(t *testing.T) {
@ -140,165 +135,3 @@ func testStoragedVersionInCRDStatus(t *testing.T, ns string, noxuDefinition *api
t.Fatal(err)
}
}
func testSimpleVersionedCRUD(t *testing.T, ns string, noxuDefinition *apiextensionsv1beta1.CustomResourceDefinition, dynamicClient dynamic.Interface) {
noxuResourceClients := map[string]dynamic.ResourceInterface{}
noxuWatchs := map[string]watch.Interface{}
disbaledVersions := map[string]bool{}
for _, v := range noxuDefinition.Spec.Versions {
disbaledVersions[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 disbaledVersions[v.Name] {
if err == nil {
t.Errorf("expected the watch creation fail for disabled version %s", v.Name)
}
} 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, testserver.NewVersionedNoxuInstance(ns, "foo", version), noxuResourceClient, noxuDefinition, version)
if disbaledVersions[version] {
if err == nil {
t.Errorf("expected the CR creation fail for disabled version %s", version)
}
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 disbaledVersions[version2] {
if err == nil {
t.Errorf("expected the get operation fail for disabled version %s", version2)
}
} 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 disbaledVersions[version2] {
if err == nil {
t.Errorf("expected the list operation fail for disabled version %s", version2)
}
} 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)
}
}
}
// 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():
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(createdNoxuInstance)
if err != nil {
t.Fatal(err)
}
if e, a := createdObjectMeta.GetUID(), deletedObjectMeta.GetUID(); e != a {
t.Errorf("expected %v, got %v", e, a)
}
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)
}
}
}