Make definition tags specific
[multicloud/k8s.git] / src / k8splugin / api / profilehandler_test.go
1 /*
2  * Copyright 2018 Intel Corporation, Inc
3  *
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
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16
17 package api
18
19 import (
20         "bytes"
21         "encoding/json"
22         "io"
23         "net/http"
24         "net/http/httptest"
25         "reflect"
26         "testing"
27
28         "github.com/onap/multicloud-k8s/src/k8splugin/internal/rb"
29
30         pkgerrors "github.com/pkg/errors"
31 )
32
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 {
37         rb.ProfileManager
38         // Items and err will be used to customize each test
39         // via a localized instantiation of mockRBProfile
40         Items []rb.Profile
41         Err   error
42 }
43
44 func (m *mockRBProfile) Create(inp rb.Profile) (rb.Profile, error) {
45         if m.Err != nil {
46                 return rb.Profile{}, m.Err
47         }
48
49         return m.Items[0], nil
50 }
51
52 func (m *mockRBProfile) Get(rbname, rbversion, prname string) (rb.Profile, error) {
53         if m.Err != nil {
54                 return rb.Profile{}, m.Err
55         }
56
57         return m.Items[0], nil
58 }
59
60 func (m *mockRBProfile) Delete(rbname, rbversion, prname string) error {
61         return m.Err
62 }
63
64 func (m *mockRBProfile) Upload(rbname, rbversion, prname string, inp []byte) error {
65         return m.Err
66 }
67
68 func TestRBProfileCreateHandler(t *testing.T) {
69         testCases := []struct {
70                 label        string
71                 reader       io.Reader
72                 expected     rb.Profile
73                 expectedCode int
74                 rbProClient  *mockRBProfile
75         }{
76                 {
77                         label:        "Missing Body Failure",
78                         expectedCode: http.StatusBadRequest,
79                         rbProClient:  &mockRBProfile{},
80                         reader:       nil,
81                 },
82                 {
83                         label:        "Create New Profile for Definition",
84                         expectedCode: http.StatusCreated,
85                         reader: bytes.NewBuffer([]byte(`{
86                                 "rb-name":"test-rbdef",
87                                 "rb-version":"v1",
88                                 "profile-name":"profile1",
89                                 "release-name":"testprofilereleasename",
90                                 "namespace":"default",
91                                 "kubernetes-version":"1.12.3"
92                                 }`)),
93                         expected: rb.Profile{
94                                 RBName:            "test-rbdef",
95                                 RBVersion:         "v1",
96                                 ProfileName:       "profile1",
97                                 ReleaseName:       "testprofilereleasename",
98                                 Namespace:         "default",
99                                 KubernetesVersion: "1.12.3",
100                         },
101                         rbProClient: &mockRBProfile{
102                                 //Items that will be returned by the mocked Client
103                                 Items: []rb.Profile{
104                                         {
105                                                 RBName:            "test-rbdef",
106                                                 RBVersion:         "v1",
107                                                 ProfileName:       "profile1",
108                                                 ReleaseName:       "testprofilereleasename",
109                                                 Namespace:         "default",
110                                                 KubernetesVersion: "1.12.3",
111                                         },
112                                 },
113                         },
114                 },
115         }
116
117         for _, testCase := range testCases {
118                 t.Run(testCase.label, func(t *testing.T) {
119                         request := httptest.NewRequest("POST", "/v1/rb/definition/test-rbdef/v1/profile",
120                                 testCase.reader)
121                         resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil, nil))
122
123                         //Check returned code
124                         if resp.StatusCode != testCase.expectedCode {
125                                 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, resp.StatusCode)
126                         }
127
128                         //Check returned body only if statusCreated
129                         if resp.StatusCode == http.StatusCreated {
130                                 got := rb.Profile{}
131                                 json.NewDecoder(resp.Body).Decode(&got)
132
133                                 if reflect.DeepEqual(testCase.expected, got) == false {
134                                         t.Errorf("createHandler returned unexpected body: got %v;"+
135                                                 " expected %v", got, testCase.expected)
136                                 }
137                         }
138                 })
139         }
140 }
141
142 func TestRBProfileGetHandler(t *testing.T) {
143
144         testCases := []struct {
145                 label        string
146                 expected     rb.Profile
147                 prname       string
148                 expectedCode int
149                 rbProClient  *mockRBProfile
150         }{
151                 {
152                         label:        "Get Bundle Profile",
153                         expectedCode: http.StatusOK,
154                         expected: rb.Profile{
155                                 RBName:            "test-rbdef",
156                                 RBVersion:         "v1",
157                                 ProfileName:       "profile1",
158                                 ReleaseName:       "testprofilereleasename",
159                                 Namespace:         "default",
160                                 KubernetesVersion: "1.12.3",
161                         },
162                         prname: "profile1",
163                         rbProClient: &mockRBProfile{
164                                 // Profile that will be returned by the mockclient
165                                 Items: []rb.Profile{
166                                         {
167                                                 RBName:            "test-rbdef",
168                                                 RBVersion:         "v1",
169                                                 ProfileName:       "profile1",
170                                                 ReleaseName:       "testprofilereleasename",
171                                                 Namespace:         "default",
172                                                 KubernetesVersion: "1.12.3",
173                                         },
174                                 },
175                         },
176                 },
177                 {
178                         label:        "Get Non-Exiting Bundle Profile",
179                         expectedCode: http.StatusInternalServerError,
180                         prname:       "non-existing-profile",
181                         rbProClient: &mockRBProfile{
182                                 // list of Profiles that will be returned by the mockclient
183                                 Items: []rb.Profile{},
184                                 Err:   pkgerrors.New("Internal Error"),
185                         },
186                 },
187         }
188
189         for _, testCase := range testCases {
190                 t.Run(testCase.label, func(t *testing.T) {
191                         request := httptest.NewRequest("GET", "/v1/rb/definition/test-rbdef/v1/profile/"+testCase.prname, nil)
192                         resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil, nil))
193
194                         //Check returned code
195                         if resp.StatusCode != testCase.expectedCode {
196                                 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, resp.StatusCode)
197                         }
198
199                         //Check returned body only if statusOK
200                         if resp.StatusCode == http.StatusOK {
201                                 got := rb.Profile{}
202                                 json.NewDecoder(resp.Body).Decode(&got)
203
204                                 if reflect.DeepEqual(testCase.expected, got) == false {
205                                         t.Errorf("listHandler returned unexpected body: got %v;"+
206                                                 " expected %v", got, testCase.expected)
207                                 }
208                         }
209                 })
210         }
211 }
212
213 func TestRBProfileDeleteHandler(t *testing.T) {
214
215         testCases := []struct {
216                 label        string
217                 prname       string
218                 expectedCode int
219                 rbProClient  *mockRBProfile
220         }{
221                 {
222                         label:        "Delete Bundle Profile",
223                         expectedCode: http.StatusNoContent,
224                         prname:       "profile1",
225                         rbProClient:  &mockRBProfile{},
226                 },
227                 {
228                         label:        "Delete Non-Exiting Bundle Profile",
229                         expectedCode: http.StatusInternalServerError,
230                         prname:       "non-existing",
231                         rbProClient: &mockRBProfile{
232                                 Err: pkgerrors.New("Internal Error"),
233                         },
234                 },
235         }
236
237         for _, testCase := range testCases {
238                 t.Run(testCase.label, func(t *testing.T) {
239                         request := httptest.NewRequest("DELETE", "/v1/rb/definition/test-rbdef/v1/profile/"+testCase.prname, nil)
240                         resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil, nil))
241
242                         //Check returned code
243                         if resp.StatusCode != testCase.expectedCode {
244                                 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, resp.StatusCode)
245                         }
246                 })
247         }
248 }
249
250 func TestRBProfileUploadHandler(t *testing.T) {
251
252         testCases := []struct {
253                 label        string
254                 prname       string
255                 body         io.Reader
256                 expectedCode int
257                 rbProClient  *mockRBProfile
258         }{
259                 {
260                         label:        "Upload Bundle Profile Content",
261                         expectedCode: http.StatusOK,
262                         prname:       "profile1",
263                         body: bytes.NewBuffer([]byte{
264                                 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
265                                 0x00, 0xff, 0xf2, 0x48, 0xcd,
266                         }),
267                         rbProClient: &mockRBProfile{},
268                 },
269                 {
270                         label:        "Upload Invalid Bundle Profile Content",
271                         expectedCode: http.StatusInternalServerError,
272                         prname:       "profile1",
273                         body: bytes.NewBuffer([]byte{
274                                 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00,
275                                 0x00, 0xff, 0xf2, 0x48, 0xcd,
276                         }),
277                         rbProClient: &mockRBProfile{
278                                 Err: pkgerrors.New("Internal Error"),
279                         },
280                 },
281                 {
282                         label:        "Upload Empty Body Content",
283                         expectedCode: http.StatusBadRequest,
284                         prname:       "profile1",
285                         rbProClient:  &mockRBProfile{},
286                 },
287         }
288
289         for _, testCase := range testCases {
290                 t.Run(testCase.label, func(t *testing.T) {
291                         request := httptest.NewRequest("POST",
292                                 "/v1/rb/definition/test-rbdef/v1/profile/"+testCase.prname+"/content", testCase.body)
293                         resp := executeRequest(request, NewRouter(nil, testCase.rbProClient, nil, nil, nil, nil))
294
295                         //Check returned code
296                         if resp.StatusCode != testCase.expectedCode {
297                                 t.Fatalf("Expected %d; Got: %d", testCase.expectedCode, resp.StatusCode)
298                         }
299                 })
300         }
301 }