2 * Copyright 2018 Intel Corporation, Inc
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
23 "k8splugin/internal/rb"
30 pkgerrors "github.com/pkg/errors"
33 //Creating an embedded interface via anonymous variable
34 //This allows us to make mockDB satisfy the DatabaseConnection
35 //interface even if we are not implementing all the methods in it
36 type mockRBProfile struct {
38 // Items and err will be used to customize each test
39 // via a localized instantiation of mockRBProfile
44 func (m *mockRBProfile) Create(inp rb.Profile) (rb.Profile, error) {
46 return rb.Profile{}, m.Err
49 return m.Items[0], nil
52 func (m *mockRBProfile) List() ([]rb.Profile, error) {
54 return []rb.Profile{}, m.Err
60 func (m *mockRBProfile) Get(id string) (rb.Profile, error) {
62 return rb.Profile{}, m.Err
65 return m.Items[0], nil
68 func (m *mockRBProfile) Delete(id string) error {
72 func (m *mockRBProfile) Upload(id string, inp []byte) error {
76 func TestRBProfileCreateHandler(t *testing.T) {
77 testCases := []struct {
82 rbDefClient *mockRBProfile
85 label: "Missing Body Failure",
86 expectedCode: http.StatusBadRequest,
87 rbDefClient: &mockRBProfile{},
90 label: "Create without UUID",
91 expectedCode: http.StatusCreated,
92 reader: bytes.NewBuffer([]byte(`{
93 "rbdid":"abcde123-e89b-8888-a456-986655447236",
95 "namespace":"default",
96 "kubernetesversion":"1.12.3"
99 UUID: "123e4567-e89b-12d3-a456-426655440000",
100 RBDID: "abcde123-e89b-8888-a456-986655447236",
101 Name: "testresourcebundle",
102 Namespace: "default",
103 KubernetesVersion: "1.12.3",
105 rbDefClient: &mockRBProfile{
106 //Items that will be returned by the mocked Client
109 UUID: "123e4567-e89b-12d3-a456-426655440000",
110 RBDID: "abcde123-e89b-8888-a456-986655447236",
111 Name: "testresourcebundle",
112 Namespace: "default",
113 KubernetesVersion: "1.12.3",
120 for _, testCase := range testCases {
121 t.Run(testCase.label, func(t *testing.T) {
122 vh := rbProfileHandler{client: testCase.rbDefClient}
123 req, err := http.NewRequest("POST", "/v1/rb/profile", testCase.reader)
129 rr := httptest.NewRecorder()
130 hr := http.HandlerFunc(vh.createHandler)
131 hr.ServeHTTP(rr, req)
133 //Check returned code
134 if rr.Code != testCase.expectedCode {
135 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code)
138 //Check returned body only if statusCreated
139 if rr.Code == http.StatusCreated {
141 json.NewDecoder(rr.Body).Decode(&got)
143 if reflect.DeepEqual(testCase.expected, got) == false {
144 t.Errorf("createHandler returned unexpected body: got %v;"+
145 " expected %v", got, testCase.expected)
152 func TestRBProfileListHandler(t *testing.T) {
154 testCases := []struct {
156 expected []rb.Profile
158 rbDefClient *mockRBProfile
161 label: "List Bundle Profiles",
162 expectedCode: http.StatusOK,
163 expected: []rb.Profile{
165 UUID: "123e4567-e89b-12d3-a456-426655440000",
166 RBDID: "abcde123-e89b-8888-a456-986655447236",
167 Name: "testresourcebundle",
168 Namespace: "default",
169 KubernetesVersion: "1.12.3",
172 UUID: "123e4567-e89b-12d3-a456-426655441111",
173 RBDID: "abcde123-e89b-8888-a456-986655441111",
174 Name: "testresourcebundle2",
175 Namespace: "default",
176 KubernetesVersion: "1.12.3",
179 rbDefClient: &mockRBProfile{
180 // list of Profiles that will be returned by the mockclient
183 UUID: "123e4567-e89b-12d3-a456-426655440000",
184 RBDID: "abcde123-e89b-8888-a456-986655447236",
185 Name: "testresourcebundle",
186 Namespace: "default",
187 KubernetesVersion: "1.12.3",
190 UUID: "123e4567-e89b-12d3-a456-426655441111",
191 RBDID: "abcde123-e89b-8888-a456-986655441111",
192 Name: "testresourcebundle2",
193 Namespace: "default",
194 KubernetesVersion: "1.12.3",
201 for _, testCase := range testCases {
202 t.Run(testCase.label, func(t *testing.T) {
203 vh := rbProfileHandler{client: testCase.rbDefClient}
204 req, err := http.NewRequest("GET", "/v1/rb/profile", nil)
209 rr := httptest.NewRecorder()
210 hr := http.HandlerFunc(vh.listHandler)
212 hr.ServeHTTP(rr, req)
213 //Check returned code
214 if rr.Code != testCase.expectedCode {
215 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code)
218 //Check returned body only if statusOK
219 if rr.Code == http.StatusOK {
220 got := []rb.Profile{}
221 json.NewDecoder(rr.Body).Decode(&got)
223 // Since the order of returned slice is not guaranteed
224 // Check both and return error if both don't match
225 sort.Slice(got, func(i, j int) bool {
226 return got[i].UUID < got[j].UUID
228 // Sort both as it is not expected that testCase.expected
230 sort.Slice(testCase.expected, func(i, j int) bool {
231 return testCase.expected[i].UUID < testCase.expected[j].UUID
234 if reflect.DeepEqual(testCase.expected, got) == false {
235 t.Errorf("listHandler returned unexpected body: got %v;"+
236 " expected %v", got, testCase.expected)
243 func TestRBProfileGetHandler(t *testing.T) {
245 testCases := []struct {
250 rbDefClient *mockRBProfile
253 label: "Get Bundle Profile",
254 expectedCode: http.StatusOK,
255 expected: rb.Profile{
256 UUID: "123e4567-e89b-12d3-a456-426655441111",
257 RBDID: "abcde123-e89b-8888-a456-986655447236",
258 Name: "testresourcebundle2",
259 Namespace: "default",
260 KubernetesVersion: "1.12.3",
262 inpUUID: "123e4567-e89b-12d3-a456-426655441111",
263 rbDefClient: &mockRBProfile{
264 // list of Profiles that will be returned by the mockclient
267 UUID: "123e4567-e89b-12d3-a456-426655441111",
268 RBDID: "abcde123-e89b-8888-a456-986655447236",
269 Name: "testresourcebundle2",
270 Namespace: "default",
271 KubernetesVersion: "1.12.3",
277 label: "Get Non-Exiting Bundle Profile",
278 expectedCode: http.StatusInternalServerError,
279 inpUUID: "123e4567-e89b-12d3-a456-426655440000",
280 rbDefClient: &mockRBProfile{
281 // list of Profiles that will be returned by the mockclient
282 Items: []rb.Profile{},
283 Err: pkgerrors.New("Internal Error"),
288 for _, testCase := range testCases {
289 t.Run(testCase.label, func(t *testing.T) {
290 vh := rbProfileHandler{client: testCase.rbDefClient}
291 req, err := http.NewRequest("GET", "/v1/rb/profile/"+testCase.inpUUID, nil)
296 rr := httptest.NewRecorder()
297 hr := http.HandlerFunc(vh.getHandler)
299 hr.ServeHTTP(rr, req)
300 //Check returned code
301 if rr.Code != testCase.expectedCode {
302 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code)
305 //Check returned body only if statusOK
306 if rr.Code == http.StatusOK {
308 json.NewDecoder(rr.Body).Decode(&got)
310 if reflect.DeepEqual(testCase.expected, got) == false {
311 t.Errorf("listHandler returned unexpected body: got %v;"+
312 " expected %v", got, testCase.expected)
319 func TestRBProfileDeleteHandler(t *testing.T) {
321 testCases := []struct {
325 rbDefClient *mockRBProfile
328 label: "Delete Bundle Profile",
329 expectedCode: http.StatusNoContent,
330 inpUUID: "123e4567-e89b-12d3-a456-426655441111",
331 rbDefClient: &mockRBProfile{},
334 label: "Delete Non-Exiting Bundle Profile",
335 expectedCode: http.StatusInternalServerError,
336 inpUUID: "123e4567-e89b-12d3-a456-426655440000",
337 rbDefClient: &mockRBProfile{
338 Err: pkgerrors.New("Internal Error"),
343 for _, testCase := range testCases {
344 t.Run(testCase.label, func(t *testing.T) {
345 vh := rbProfileHandler{client: testCase.rbDefClient}
346 req, err := http.NewRequest("GET", "/v1/rb/profile/"+testCase.inpUUID, nil)
351 rr := httptest.NewRecorder()
352 hr := http.HandlerFunc(vh.deleteHandler)
354 hr.ServeHTTP(rr, req)
355 //Check returned code
356 if rr.Code != testCase.expectedCode {
357 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code)
363 func TestRBProfileUploadHandler(t *testing.T) {
365 testCases := []struct {
370 rbDefClient *mockRBProfile
373 label: "Upload Bundle Profile Content",
374 expectedCode: http.StatusOK,
375 inpUUID: "123e4567-e89b-12d3-a456-426655441111",
376 body: bytes.NewBuffer([]byte{
377 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
378 0x00, 0xff, 0xf2, 0x48, 0xcd,
380 rbDefClient: &mockRBProfile{},
383 label: "Upload Invalid Bundle Profile Content",
384 expectedCode: http.StatusInternalServerError,
385 inpUUID: "123e4567-e89b-12d3-a456-426655440000",
386 body: bytes.NewBuffer([]byte{
387 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
388 0x00, 0xff, 0xf2, 0x48, 0xcd,
390 rbDefClient: &mockRBProfile{
391 Err: pkgerrors.New("Internal Error"),
395 label: "Upload Empty Body Content",
396 expectedCode: http.StatusBadRequest,
397 inpUUID: "123e4567-e89b-12d3-a456-426655440000",
398 rbDefClient: &mockRBProfile{},
402 for _, testCase := range testCases {
403 t.Run(testCase.label, func(t *testing.T) {
404 vh := rbProfileHandler{client: testCase.rbDefClient}
405 req, err := http.NewRequest("POST",
406 "/v1/rb/profile/"+testCase.inpUUID+"/content", testCase.body)
412 rr := httptest.NewRecorder()
413 hr := http.HandlerFunc(vh.uploadHandler)
415 hr.ServeHTTP(rr, req)
416 //Check returned code
417 if rr.Code != testCase.expectedCode {
418 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, rr.Code)