1 package kclient
2
3 import (
4 "errors"
5 "fmt"
6 "testing"
7
8 "github.com/google/go-cmp/cmp"
9
10 "github.com/redhat-developer/odo/pkg/testingutil"
11
12 corev1 "k8s.io/api/core/v1"
13 metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
14 ktesting "k8s.io/client-go/testing"
15
16 "k8s.io/apimachinery/pkg/api/resource"
17 "k8s.io/apimachinery/pkg/runtime"
18
19 "github.com/devfile/library/v2/pkg/devfile/generator"
20
21 "github.com/redhat-developer/odo/pkg/util"
22 )
23
24 func TestCreatePVC(t *testing.T) {
25
26 tests := []struct {
27 name string
28 pvcName string
29 size string
30 namespace string
31 labels map[string]string
32 wantErr bool
33 }{
34 {
35 name: "Case 1: Valid pvc name",
36 pvcName: "mypvc",
37 size: "1Gi",
38 namespace: "default",
39 labels: map[string]string{
40 "testpvc": "testpvc",
41 },
42 wantErr: false,
43 },
44 {
45 name: "Case 2: Invalid pvc name",
46 pvcName: "",
47 size: "1Gi",
48 namespace: "default",
49 labels: map[string]string{
50 "testpvc": "testpvc",
51 },
52 wantErr: true,
53 },
54 {
55 name: "Case 3: Invalid pvc size",
56 pvcName: "mypvc",
57 size: "garbage",
58 namespace: "default",
59 labels: map[string]string{
60 "testpvc": "testpvc",
61 },
62 wantErr: true,
63 },
64 }
65
66 for _, tt := range tests {
67 t.Run(tt.name, func(t *testing.T) {
68
69 fkclient, fkclientset := FakeNew()
70 fkclient.Namespace = tt.namespace
71
72 quantity, err := resource.ParseQuantity(tt.size)
73 if err != nil && tt.size != "garbage" {
74 t.Errorf("resource.ParseQuantity unexpected error %v", err)
75 } else if err != nil && tt.size == "garbage" {
76 return
77 }
78
79 objectMeta := generator.GetObjectMeta(tt.pvcName, tt.namespace, tt.labels, nil)
80
81 fkclientset.Kubernetes.PrependReactor("create", "persistentvolumeclaims", func(action ktesting.Action) (bool, runtime.Object, error) {
82 if tt.pvcName == "" {
83 return true, nil, errors.New("pvc name is empty")
84 }
85 pvc := corev1.PersistentVolumeClaim{
86 TypeMeta: metav1.TypeMeta{
87 Kind: PersistentVolumeClaimKind,
88 APIVersion: PersistentVolumeClaimAPIVersion,
89 },
90 ObjectMeta: metav1.ObjectMeta{
91 Name: tt.pvcName,
92 },
93 }
94 return true, &pvc, nil
95 })
96
97 pvcParams := generator.PVCParams{
98 ObjectMeta: objectMeta,
99 Quantity: quantity,
100 }
101 pvc := generator.GetPVC(pvcParams)
102
103 createdPVC, err := fkclient.CreatePVC(*pvc)
104
105
106 if !tt.wantErr == (err != nil) {
107 t.Errorf("fkclient.CreatePVC unexpected error %v, wantErr %v", err, tt.wantErr)
108 }
109
110 if err == nil {
111 if len(fkclientset.Kubernetes.Actions()) != 1 {
112 t.Errorf("expected 1 action in StartPVC got: %v", fkclientset.Kubernetes.Actions())
113 } else {
114 if createdPVC.Name != tt.pvcName {
115 t.Errorf("deployment name does not match the expected name, expected: %s, got %s", tt.pvcName, createdPVC.Name)
116 }
117 }
118 }
119 })
120 }
121 }
122
123 func TestDeletePVC(t *testing.T) {
124 tests := []struct {
125 name string
126 pvcName string
127 wantErr bool
128 }{
129 {
130 name: "storage 10Gi",
131 pvcName: "postgresql",
132 wantErr: false,
133 },
134 }
135 for _, tt := range tests {
136 t.Run(tt.name, func(t *testing.T) {
137 fakeClient, fakeClientSet := FakeNew()
138
139 fakeClientSet.Kubernetes.PrependReactor("delete", "persistentvolumeclaims", func(action ktesting.Action) (bool, runtime.Object, error) {
140 return true, nil, nil
141 })
142
143 err := fakeClient.DeletePVC(tt.pvcName)
144
145
146 if !tt.wantErr == (err != nil) {
147 t.Errorf(" client.DeletePVC(name) unexpected error %v, wantErr %v", err, tt.wantErr)
148 }
149
150
151 if (len(fakeClientSet.Kubernetes.Actions()) != 1) && (tt.wantErr != true) {
152 t.Errorf("expected 1 action in DeletePVC got: %v", fakeClientSet.Kubernetes.Actions())
153 }
154
155
156 DeletedPVC := fakeClientSet.Kubernetes.Actions()[0].(ktesting.DeleteAction).GetName()
157 if DeletedPVC != tt.pvcName {
158 t.Errorf("Delete action is performed with wrong pvcName, expected: %s, got %s", tt.pvcName, DeletedPVC)
159
160 }
161 })
162 }
163 }
164
165 func TestListPVCs(t *testing.T) {
166 tests := []struct {
167 name string
168 pvcName string
169 size string
170 namespace string
171 labels map[string]string
172 wantErr bool
173 }{
174 {
175 name: "Case: Valid pvc name",
176 pvcName: "mypvc",
177 size: "1Gi",
178 namespace: "default",
179 labels: map[string]string{
180 "mylabel1": "testpvc1",
181 "mylabel2": "testpvc2",
182 },
183 wantErr: false,
184 },
185 {
186 name: "Case: Wrong Label Selector",
187 pvcName: "mypvc",
188 size: "1Gi",
189 namespace: "default",
190 labels: map[string]string{
191 "mylabel1": "testpvc1",
192 "mylabel2": "testpvc2",
193 },
194 wantErr: true,
195 },
196 }
197
198 for _, tt := range tests {
199 t.Run(tt.name, func(t *testing.T) {
200
201 fkclient, fkclientset := FakeNew()
202 fkclient.Namespace = tt.namespace
203
204 selector := util.ConvertLabelsToSelector(tt.labels)
205
206 listOfPVC := corev1.PersistentVolumeClaimList{
207 Items: []corev1.PersistentVolumeClaim{
208 {
209 ObjectMeta: metav1.ObjectMeta{
210 Name: tt.pvcName,
211 Labels: tt.labels,
212 },
213 },
214 },
215 }
216
217 fkclientset.Kubernetes.PrependReactor("list", "persistentvolumeclaims", func(action ktesting.Action) (bool, runtime.Object, error) {
218 if tt.name == "Case: Wrong Label Selector" {
219 return true, nil, fmt.Errorf("TestGetPVCsFromSelector: Labels do not match with expected values, expected:%s, got:%s", selector, selector+",garbage=true")
220 }
221 return true, &listOfPVC, nil
222 })
223
224 PVCs, err := fkclient.ListPVCs(selector)
225 if !tt.wantErr && err != nil {
226 t.Errorf("TestGetPVCsFromSelector: Error listing PVCs with selector: %v", err)
227 }
228
229 if len(PVCs) == 0 || len(PVCs) > 1 {
230 if !tt.wantErr {
231 t.Errorf("TestGetPVCsFromSelector: Incorrect amount of PVC found with selector %s", selector)
232 }
233 } else {
234 for _, PVC := range PVCs {
235 if PVC.Name != tt.pvcName {
236 t.Errorf("TestGetPVCsFromSelector: PVC found with incorrect name, expected: %s actual: %s", tt.pvcName, PVC.Name)
237 }
238 if diff := cmp.Diff(tt.labels, PVC.Labels); diff != "" {
239 t.Errorf("Client.ListPVCs() labels mismatch (-want +got):\n%s", diff)
240 }
241 }
242 }
243 })
244 }
245 }
246
247 func TestGetPVCFromName(t *testing.T) {
248 tests := []struct {
249 name string
250 pvcName string
251 wantPVC *corev1.PersistentVolumeClaim
252 wantErr bool
253 }{
254 {
255 name: "storage 10Gi",
256 pvcName: "postgresql",
257 wantPVC: &corev1.PersistentVolumeClaim{
258 ObjectMeta: metav1.ObjectMeta{
259 Name: "postgresql",
260 },
261 },
262 wantErr: false,
263 },
264 }
265 for _, tt := range tests {
266 t.Run(tt.name, func(t *testing.T) {
267 fakeClient, fakeClientSet := FakeNew()
268
269 fakeClientSet.Kubernetes.PrependReactor("get", "persistentvolumeclaims", func(action ktesting.Action) (bool, runtime.Object, error) {
270 return true, tt.wantPVC, nil
271 })
272
273 returnPVC, err := fakeClient.GetPVCFromName(tt.pvcName)
274
275
276 if !tt.wantErr == (err != nil) {
277 t.Errorf(" client.GetPVCFromName(name) unexpected error %v, wantErr %v", err, tt.wantErr)
278 }
279
280 if (len(fakeClientSet.Kubernetes.Actions()) != 1) && (tt.wantErr != true) {
281 t.Errorf("expected 1 action in GetPVCFromName got: %v", fakeClientSet.Kubernetes.Actions())
282 }
283
284 PVCname := fakeClientSet.Kubernetes.Actions()[0].(ktesting.GetAction).GetName()
285 if PVCname != tt.pvcName {
286 t.Errorf("Get action is performed with wrong pvcName, expected: %s, got %s", tt.pvcName, PVCname)
287
288 }
289
290 if returnPVC != tt.wantPVC {
291 t.Errorf("Get action has returned pvc with wrong name, expected: %s, got %s", tt.wantPVC, returnPVC)
292 }
293 })
294 }
295 }
296
297 func TestListPVCNames(t *testing.T) {
298 type args struct {
299 selector string
300 }
301 tests := []struct {
302 name string
303 args args
304 returnedPVCs *corev1.PersistentVolumeClaimList
305 want []string
306 wantErr bool
307 }{
308 {
309 name: "case 1: two pvcs returned",
310 args: args{
311 "component-name=nodejs",
312 },
313 returnedPVCs: &corev1.PersistentVolumeClaimList{
314 Items: []corev1.PersistentVolumeClaim{
315 *testingutil.FakePVC("storage-1", "1Gi", map[string]string{"component-name": "nodejs"}),
316 *testingutil.FakePVC("storage-2", "1Gi", map[string]string{"component-name": "nodejs"}),
317 },
318 },
319 want: []string{"storage-1", "storage-2"},
320 },
321 {
322 name: "case 2: no pvcs returned",
323 args: args{
324 "component-name=nodejs",
325 },
326 returnedPVCs: &corev1.PersistentVolumeClaimList{
327 Items: []corev1.PersistentVolumeClaim{},
328 },
329 want: nil,
330 },
331 }
332 for _, tt := range tests {
333 t.Run(tt.name, func(t *testing.T) {
334
335 fkclient, fkclientset := FakeNew()
336
337 fkclientset.Kubernetes.PrependReactor("list", "persistentvolumeclaims", func(action ktesting.Action) (bool, runtime.Object, error) {
338 return true, tt.returnedPVCs, nil
339 })
340
341 got, err := fkclient.ListPVCNames(tt.args.selector)
342 if (err != nil) != tt.wantErr {
343 t.Errorf("ListPVCNames() error = %v, wantErr %v", err, tt.wantErr)
344 return
345 }
346 if diff := cmp.Diff(tt.want, got); diff != "" {
347 t.Errorf("Client.ListPVCNames() mismatch (-want +got):\n%s", diff)
348 }
349 })
350 }
351 }
352
View as plain text