1
16
17 package integration
18
19 import (
20 "context"
21 "fmt"
22 "net/http"
23 "reflect"
24 "testing"
25 "time"
26
27 "github.com/stretchr/testify/assert"
28 apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1"
29 "k8s.io/apiextensions-apiserver/test/integration/fixtures"
30 "k8s.io/apimachinery/pkg/api/errors"
31 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
32 "k8s.io/apimachinery/pkg/types"
33 "k8s.io/apimachinery/pkg/util/wait"
34 )
35
36 func TestInternalVersionIsHandlerVersion(t *testing.T) {
37 tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
38 if err != nil {
39 t.Fatal(err)
40 }
41 defer tearDown()
42
43 noxuDefinition := fixtures.NewMultipleVersionNoxuCRD(apiextensionsv1.NamespaceScoped)
44
45 assert.Equal(t, "v1beta1", noxuDefinition.Spec.Versions[0].Name)
46 assert.Equal(t, "v1beta2", noxuDefinition.Spec.Versions[1].Name)
47 assert.True(t, noxuDefinition.Spec.Versions[1].Storage)
48
49 noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
50 if err != nil {
51 t.Fatal(err)
52 }
53
54 ns := "not-the-default"
55
56 noxuNamespacedResourceClientV1beta1 := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, "v1beta1")
57
58 t.Logf("Creating foo")
59 noxuInstanceToCreate := fixtures.NewNoxuInstance(ns, "foo")
60 _, err = noxuNamespacedResourceClientV1beta1.Create(context.TODO(), noxuInstanceToCreate, metav1.CreateOptions{})
61 if err != nil {
62 t.Fatal(err)
63 }
64
65
66 t.Logf("Updating CRD to validate apiVersion")
67 noxuDefinition, err = UpdateCustomResourceDefinitionWithRetry(apiExtensionClient, noxuDefinition.Name, func(crd *apiextensionsv1.CustomResourceDefinition) {
68 for i := range crd.Spec.Versions {
69 crd.Spec.Versions[i].Schema = &apiextensionsv1.CustomResourceValidation{
70 OpenAPIV3Schema: &apiextensionsv1.JSONSchemaProps{
71 Type: "object",
72 Properties: map[string]apiextensionsv1.JSONSchemaProps{
73 "apiVersion": {
74 Pattern: "^mygroup.example.com/v1beta1$",
75 Type: "string",
76 },
77 },
78 Required: []string{"apiVersion"},
79 },
80 }
81 }
82 })
83 assert.NoError(t, err)
84
85 time.Sleep(time.Second)
86
87
88 {
89 t.Logf("patch of handler version v1beta1 (non-storage version) should succeed")
90 i := 0
91 err = wait.PollImmediate(time.Millisecond*100, wait.ForeverTestTimeout, func() (bool, error) {
92 patch := []byte(fmt.Sprintf(`{"i": %d}`, i))
93 i++
94
95 _, err := noxuNamespacedResourceClientV1beta1.Patch(context.TODO(), "foo", types.MergePatchType, patch, metav1.PatchOptions{})
96 if err != nil {
97
98
99 if err, ok := err.(*errors.StatusError); ok && err.Status().Code == http.StatusInternalServerError {
100 return false, nil
101 }
102 return false, err
103 }
104 return true, nil
105 })
106 assert.NoError(t, err)
107 }
108
109
110 {
111 t.Logf("patch of handler version v1beta2 (storage version) should fail")
112 i := 0
113 noxuNamespacedResourceClientV1beta2 := newNamespacedCustomResourceVersionedClient(ns, dynamicClient, noxuDefinition, "v1beta2")
114 err = wait.PollImmediate(time.Millisecond*100, wait.ForeverTestTimeout, func() (bool, error) {
115 patch := []byte(fmt.Sprintf(`{"i": %d}`, i))
116 i++
117
118 _, err := noxuNamespacedResourceClientV1beta2.Patch(context.TODO(), "foo", types.MergePatchType, patch, metav1.PatchOptions{})
119 assert.Error(t, err)
120
121
122
123 if err, ok := err.(*errors.StatusError); ok && err.Status().Code == http.StatusInternalServerError {
124 return false, nil
125 }
126
127 assert.Contains(t, err.Error(), "apiVersion")
128 return true, nil
129 })
130 assert.NoError(t, err)
131 }
132 }
133
134 func TestVersionedNamespacedScopedCRD(t *testing.T) {
135 tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
136 if err != nil {
137 t.Fatal(err)
138 }
139 defer tearDown()
140
141 noxuDefinition := fixtures.NewMultipleVersionNoxuCRD(apiextensionsv1.NamespaceScoped)
142 noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
143 if err != nil {
144 t.Fatal(err)
145 }
146
147 ns := "not-the-default"
148 testSimpleCRUD(t, ns, noxuDefinition, dynamicClient)
149 }
150
151 func TestVersionedClusterScopedCRD(t *testing.T) {
152 tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
153 if err != nil {
154 t.Fatal(err)
155 }
156 defer tearDown()
157
158 noxuDefinition := fixtures.NewMultipleVersionNoxuCRD(apiextensionsv1.ClusterScoped)
159 noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
160 if err != nil {
161 t.Fatal(err)
162 }
163
164 ns := ""
165 testSimpleCRUD(t, ns, noxuDefinition, dynamicClient)
166 }
167
168 func TestStoragedVersionInNamespacedCRDStatus(t *testing.T) {
169 noxuDefinition := fixtures.NewMultipleVersionNoxuCRD(apiextensionsv1.NamespaceScoped)
170 ns := "not-the-default"
171 testStoragedVersionInCRDStatus(t, ns, noxuDefinition)
172 }
173
174 func TestStoragedVersionInClusterScopedCRDStatus(t *testing.T) {
175 noxuDefinition := fixtures.NewMultipleVersionNoxuCRD(apiextensionsv1.ClusterScoped)
176 ns := ""
177 testStoragedVersionInCRDStatus(t, ns, noxuDefinition)
178 }
179
180 func testStoragedVersionInCRDStatus(t *testing.T, ns string, noxuDefinition *apiextensionsv1.CustomResourceDefinition) {
181 versionsV1Beta1Storage := []apiextensionsv1.CustomResourceDefinitionVersion{
182 {
183 Name: "v1beta1",
184 Served: true,
185 Storage: true,
186 Schema: fixtures.AllowAllSchema(),
187 },
188 {
189 Name: "v1beta2",
190 Served: true,
191 Storage: false,
192 Schema: fixtures.AllowAllSchema(),
193 },
194 }
195 versionsV1Beta2Storage := []apiextensionsv1.CustomResourceDefinitionVersion{
196 {
197 Name: "v1beta1",
198 Served: true,
199 Storage: false,
200 Schema: fixtures.AllowAllSchema(),
201 },
202 {
203 Name: "v1beta2",
204 Served: true,
205 Storage: true,
206 Schema: fixtures.AllowAllSchema(),
207 },
208 }
209 tearDown, apiExtensionClient, dynamicClient, err := fixtures.StartDefaultServerWithClients(t)
210 if err != nil {
211 t.Fatal(err)
212 }
213 defer tearDown()
214
215 noxuDefinition.Spec.Versions = versionsV1Beta1Storage
216 noxuDefinition, err = fixtures.CreateNewV1CustomResourceDefinition(noxuDefinition, apiExtensionClient, dynamicClient)
217 if err != nil {
218 t.Fatal(err)
219 }
220
221
222 crd, err := apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), noxuDefinition.Name, metav1.GetOptions{})
223 if err != nil {
224 t.Fatal(err)
225 }
226 if e, a := []string{"v1beta1"}, crd.Status.StoredVersions; !reflect.DeepEqual(e, a) {
227 t.Errorf("expected %v, got %v", e, a)
228 }
229
230
231 crd.Spec.Versions = versionsV1Beta2Storage
232 _, err = apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Update(context.TODO(), crd, metav1.UpdateOptions{})
233 if err != nil {
234 t.Fatal(err)
235 }
236 crd, err = apiExtensionClient.ApiextensionsV1().CustomResourceDefinitions().Get(context.TODO(), noxuDefinition.Name, metav1.GetOptions{})
237 if err != nil {
238 t.Fatal(err)
239 }
240 if e, a := []string{"v1beta1", "v1beta2"}, crd.Status.StoredVersions; !reflect.DeepEqual(e, a) {
241 t.Errorf("expected %v, got %v", e, a)
242 }
243
244 err = fixtures.DeleteV1CustomResourceDefinition(crd, apiExtensionClient)
245 if err != nil {
246 t.Fatal(err)
247 }
248 }
249
View as plain text