]>
Commit | Line | Data |
---|---|---|
11fdf7f2 TL |
1 | import { HttpClientTestingModule, HttpTestingController } from '@angular/common/http/testing'; |
2 | import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
3 | import { ReactiveFormsModule } from '@angular/forms'; | |
4 | import { ActivatedRoute } from '@angular/router'; | |
5 | import { RouterTestingModule } from '@angular/router/testing'; | |
6 | ||
494da23a | 7 | import { ToastrModule } from 'ngx-toastr'; |
11fdf7f2 TL |
8 | |
9 | import { ActivatedRouteStub } from '../../../../testing/activated-route-stub'; | |
10 | import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper'; | |
11 | import { SharedModule } from '../../../shared/shared.module'; | |
12 | import { IscsiTargetFormComponent } from './iscsi-target-form.component'; | |
13 | ||
14 | describe('IscsiTargetFormComponent', () => { | |
15 | let component: IscsiTargetFormComponent; | |
16 | let fixture: ComponentFixture<IscsiTargetFormComponent>; | |
17 | let httpTesting: HttpTestingController; | |
18 | let activatedRoute: ActivatedRouteStub; | |
19 | ||
20 | const SETTINGS = { | |
21 | config: { minimum_gateways: 2 }, | |
22 | disk_default_controls: { | |
23 | 'backstore:1': { | |
24 | hw_max_sectors: 1024, | |
25 | osd_op_timeout: 30 | |
26 | }, | |
27 | 'backstore:2': { | |
28 | qfull_timeout: 5 | |
29 | } | |
30 | }, | |
31 | target_default_controls: { | |
32 | cmdsn_depth: 128, | |
33 | dataout_timeout: 20, | |
34 | immediate_data: 'Yes' | |
35 | }, | |
36 | required_rbd_features: { | |
37 | 'backstore:1': 0, | |
38 | 'backstore:2': 0 | |
39 | }, | |
81eedcae TL |
40 | unsupported_rbd_features: { |
41 | 'backstore:1': 0, | |
42 | 'backstore:2': 0 | |
11fdf7f2 TL |
43 | }, |
44 | backstores: ['backstore:1', 'backstore:2'], | |
45 | default_backstore: 'backstore:1' | |
46 | }; | |
47 | ||
48 | const LIST_TARGET = [ | |
49 | { | |
50 | target_iqn: 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw', | |
51 | portals: [{ host: 'node1', ip: '192.168.100.201' }], | |
52 | disks: [{ pool: 'rbd', image: 'disk_1', controls: {}, backstore: 'backstore:1' }], | |
53 | clients: [ | |
54 | { | |
55 | client_iqn: 'iqn.1994-05.com.redhat:rh7-client', | |
56 | luns: [{ pool: 'rbd', image: 'disk_1' }], | |
57 | auth: { | |
58 | user: 'myiscsiusername', | |
59 | password: 'myiscsipassword', | |
60 | mutual_user: null, | |
61 | mutual_password: null | |
62 | } | |
63 | } | |
64 | ], | |
65 | groups: [], | |
66 | target_controls: {} | |
67 | } | |
68 | ]; | |
69 | ||
70 | const PORTALS = [ | |
71 | { name: 'node1', ip_addresses: ['192.168.100.201', '10.0.2.15'] }, | |
72 | { name: 'node2', ip_addresses: ['192.168.100.202'] } | |
73 | ]; | |
74 | ||
75 | const RBD_LIST = [ | |
76 | { status: 0, value: [], pool_name: 'ganesha' }, | |
77 | { | |
78 | status: 0, | |
79 | value: [ | |
80 | { | |
81 | size: 96636764160, | |
82 | obj_size: 4194304, | |
83 | num_objs: 23040, | |
84 | order: 22, | |
85 | block_name_prefix: 'rbd_data.148162fb31a8', | |
86 | name: 'disk_1', | |
87 | id: '148162fb31a8', | |
88 | pool_name: 'rbd', | |
89 | features: 61, | |
90 | features_name: ['deep-flatten', 'exclusive-lock', 'fast-diff', 'layering', 'object-map'], | |
91 | timestamp: '2019-01-18T10:44:26Z', | |
92 | stripe_count: 1, | |
93 | stripe_unit: 4194304, | |
94 | data_pool: null, | |
95 | parent: null, | |
96 | snapshots: [], | |
97 | total_disk_usage: 0, | |
98 | disk_usage: 0 | |
99 | }, | |
100 | { | |
101 | size: 119185342464, | |
102 | obj_size: 4194304, | |
103 | num_objs: 28416, | |
104 | order: 22, | |
105 | block_name_prefix: 'rbd_data.14b292cee6cb', | |
106 | name: 'disk_2', | |
107 | id: '14b292cee6cb', | |
108 | pool_name: 'rbd', | |
109 | features: 61, | |
110 | features_name: ['deep-flatten', 'exclusive-lock', 'fast-diff', 'layering', 'object-map'], | |
111 | timestamp: '2019-01-18T10:45:56Z', | |
112 | stripe_count: 1, | |
113 | stripe_unit: 4194304, | |
114 | data_pool: null, | |
115 | parent: null, | |
116 | snapshots: [], | |
117 | total_disk_usage: 0, | |
118 | disk_usage: 0 | |
119 | } | |
120 | ], | |
121 | pool_name: 'rbd' | |
122 | } | |
123 | ]; | |
124 | ||
125 | configureTestBed( | |
126 | { | |
127 | declarations: [IscsiTargetFormComponent], | |
128 | imports: [ | |
129 | SharedModule, | |
130 | ReactiveFormsModule, | |
131 | HttpClientTestingModule, | |
132 | RouterTestingModule, | |
494da23a | 133 | ToastrModule.forRoot() |
11fdf7f2 TL |
134 | ], |
135 | providers: [ | |
136 | i18nProviders, | |
137 | { | |
138 | provide: ActivatedRoute, | |
139 | useValue: new ActivatedRouteStub({ target_iqn: undefined }) | |
140 | } | |
141 | ] | |
142 | }, | |
143 | true | |
144 | ); | |
145 | ||
146 | beforeEach(() => { | |
147 | fixture = TestBed.createComponent(IscsiTargetFormComponent); | |
148 | component = fixture.componentInstance; | |
149 | httpTesting = TestBed.get(HttpTestingController); | |
150 | activatedRoute = TestBed.get(ActivatedRoute); | |
151 | fixture.detectChanges(); | |
152 | ||
153 | httpTesting.expectOne('ui-api/iscsi/settings').flush(SETTINGS); | |
154 | httpTesting.expectOne('ui-api/iscsi/portals').flush(PORTALS); | |
155 | httpTesting.expectOne('api/summary').flush({}); | |
156 | httpTesting.expectOne('api/block/image').flush(RBD_LIST); | |
157 | httpTesting.expectOne('api/iscsi/target').flush(LIST_TARGET); | |
158 | httpTesting.verify(); | |
159 | }); | |
160 | ||
161 | it('should create', () => { | |
162 | expect(component).toBeTruthy(); | |
163 | }); | |
164 | ||
165 | it('should only show images not used in other targets', () => { | |
166 | expect(component.imagesAll).toEqual([RBD_LIST[1]['value'][1]]); | |
167 | expect(component.imagesSelections).toEqual([ | |
81eedcae | 168 | { description: '', name: 'rbd/disk_2', selected: false, enabled: true } |
11fdf7f2 TL |
169 | ]); |
170 | }); | |
171 | ||
172 | it('should generate portals selectOptions', () => { | |
173 | expect(component.portalsSelections).toEqual([ | |
81eedcae TL |
174 | { description: '', name: 'node1:192.168.100.201', selected: false, enabled: true }, |
175 | { description: '', name: 'node1:10.0.2.15', selected: false, enabled: true }, | |
176 | { description: '', name: 'node2:192.168.100.202', selected: false, enabled: true } | |
11fdf7f2 TL |
177 | ]); |
178 | }); | |
179 | ||
180 | it('should create the form', () => { | |
181 | expect(component.targetForm.value).toEqual({ | |
182 | disks: [], | |
183 | groups: [], | |
184 | initiators: [], | |
185 | acl_enabled: false, | |
186 | portals: [], | |
187 | target_controls: {}, | |
188 | target_iqn: component.targetForm.value.target_iqn | |
189 | }); | |
190 | }); | |
191 | ||
192 | it('should prepare data when selecting an image', () => { | |
193 | expect(component.imagesSettings).toEqual({}); | |
194 | component.onImageSelection({ option: { name: 'rbd/disk_2', selected: true } }); | |
195 | expect(component.imagesSettings).toEqual({ | |
196 | 'rbd/disk_2': { | |
197 | backstore: 'backstore:1', | |
198 | 'backstore:1': {} | |
199 | } | |
200 | }); | |
201 | }); | |
202 | ||
203 | it('should clean data when removing an image', () => { | |
204 | component.onImageSelection({ option: { name: 'rbd/disk_2', selected: true } }); | |
205 | component.addGroup(); | |
206 | component.groups.controls[0].patchValue({ | |
207 | group_id: 'foo', | |
208 | disks: ['rbd/disk_2'] | |
209 | }); | |
210 | ||
211 | expect(component.groups.controls[0].value).toEqual({ | |
212 | disks: ['rbd/disk_2'], | |
213 | group_id: 'foo', | |
214 | members: [] | |
215 | }); | |
216 | ||
217 | component.onImageSelection({ option: { name: 'rbd/disk_2', selected: false } }); | |
218 | ||
219 | expect(component.groups.controls[0].value).toEqual({ disks: [], group_id: 'foo', members: [] }); | |
220 | expect(component.imagesSettings).toEqual({ | |
221 | 'rbd/disk_2': { | |
222 | backstore: 'backstore:1', | |
223 | 'backstore:1': {} | |
224 | } | |
225 | }); | |
226 | }); | |
227 | ||
228 | describe('should test initiators', () => { | |
229 | beforeEach(() => { | |
230 | component.targetForm.patchValue({ disks: ['rbd/disk_2'], acl_enabled: true }); | |
231 | component.addGroup().patchValue({ name: 'group_1' }); | |
81eedcae | 232 | component.addGroup().patchValue({ name: 'group_2' }); |
11fdf7f2 TL |
233 | component.onImageSelection({ option: { name: 'rbd/disk_2', selected: true } }); |
234 | ||
235 | component.addInitiator(); | |
236 | component.initiators.controls[0].patchValue({ | |
237 | client_iqn: 'iqn.initiator' | |
238 | }); | |
239 | component.updatedInitiatorSelector(); | |
240 | }); | |
241 | ||
242 | it('should prepare data when creating an initiator', () => { | |
243 | expect(component.initiators.controls.length).toBe(1); | |
244 | expect(component.initiators.controls[0].value).toEqual({ | |
245 | auth: { mutual_password: '', mutual_user: '', password: '', user: '' }, | |
246 | cdIsInGroup: false, | |
247 | client_iqn: 'iqn.initiator', | |
248 | luns: [] | |
249 | }); | |
250 | expect(component.imagesInitiatorSelections).toEqual([ | |
81eedcae | 251 | [{ description: '', name: 'rbd/disk_2', selected: false, enabled: true }] |
11fdf7f2 TL |
252 | ]); |
253 | expect(component.groupMembersSelections).toEqual([ | |
81eedcae TL |
254 | [{ description: '', name: 'iqn.initiator', selected: false, enabled: true }], |
255 | [{ description: '', name: 'iqn.initiator', selected: false, enabled: true }] | |
11fdf7f2 TL |
256 | ]); |
257 | }); | |
258 | ||
259 | it('should update data when changing an initiator name', () => { | |
260 | expect(component.groupMembersSelections).toEqual([ | |
81eedcae TL |
261 | [{ description: '', name: 'iqn.initiator', selected: false, enabled: true }], |
262 | [{ description: '', name: 'iqn.initiator', selected: false, enabled: true }] | |
11fdf7f2 TL |
263 | ]); |
264 | ||
265 | component.initiators.controls[0].patchValue({ | |
266 | client_iqn: 'iqn.initiator_new' | |
267 | }); | |
268 | component.updatedInitiatorSelector(); | |
269 | ||
270 | expect(component.groupMembersSelections).toEqual([ | |
81eedcae TL |
271 | [{ description: '', name: 'iqn.initiator_new', selected: false, enabled: true }], |
272 | [{ description: '', name: 'iqn.initiator_new', selected: false, enabled: true }] | |
11fdf7f2 TL |
273 | ]); |
274 | }); | |
275 | ||
276 | it('should clean data when removing an initiator', () => { | |
277 | component.groups.controls[0].patchValue({ | |
278 | group_id: 'foo', | |
279 | members: ['iqn.initiator'] | |
280 | }); | |
281 | ||
282 | expect(component.groups.controls[0].value).toEqual({ | |
283 | disks: [], | |
284 | group_id: 'foo', | |
285 | members: ['iqn.initiator'] | |
286 | }); | |
287 | ||
288 | component.removeInitiator(0); | |
289 | ||
290 | expect(component.groups.controls[0].value).toEqual({ | |
291 | disks: [], | |
292 | group_id: 'foo', | |
293 | members: [] | |
294 | }); | |
81eedcae | 295 | expect(component.groupMembersSelections).toEqual([[], []]); |
11fdf7f2 TL |
296 | expect(component.imagesInitiatorSelections).toEqual([]); |
297 | }); | |
298 | ||
299 | it('should remove images in the initiator when added in a group', () => { | |
300 | component.initiators.controls[0].patchValue({ | |
301 | luns: ['rbd/disk_2'] | |
302 | }); | |
303 | expect(component.initiators.controls[0].value).toEqual({ | |
304 | auth: { mutual_password: '', mutual_user: '', password: '', user: '' }, | |
305 | cdIsInGroup: false, | |
306 | client_iqn: 'iqn.initiator', | |
307 | luns: ['rbd/disk_2'] | |
308 | }); | |
309 | ||
310 | component.addGroup(); | |
311 | component.groups.controls[0].patchValue({ | |
312 | group_id: 'foo', | |
313 | members: ['iqn.initiator'] | |
314 | }); | |
315 | component.onGroupMemberSelection({ | |
316 | option: { | |
317 | name: 'iqn.initiator', | |
318 | selected: true | |
319 | } | |
320 | }); | |
321 | ||
322 | expect(component.initiators.controls[0].value).toEqual({ | |
323 | auth: { mutual_password: '', mutual_user: '', password: '', user: '' }, | |
324 | cdIsInGroup: true, | |
325 | client_iqn: 'iqn.initiator', | |
326 | luns: [] | |
327 | }); | |
328 | }); | |
81eedcae TL |
329 | |
330 | it('should disabled the initiator when selected', () => { | |
331 | expect(component.groupMembersSelections).toEqual([ | |
332 | [{ description: '', enabled: true, name: 'iqn.initiator', selected: false }], | |
333 | [{ description: '', enabled: true, name: 'iqn.initiator', selected: false }] | |
334 | ]); | |
335 | ||
336 | component.groupMembersSelections[0][0].selected = true; | |
337 | component.onGroupMemberSelection({ option: { name: 'iqn.initiator', selected: true } }); | |
338 | ||
339 | expect(component.groupMembersSelections).toEqual([ | |
340 | [{ description: '', enabled: false, name: 'iqn.initiator', selected: true }], | |
341 | [{ description: '', enabled: false, name: 'iqn.initiator', selected: false }] | |
342 | ]); | |
343 | }); | |
11fdf7f2 TL |
344 | }); |
345 | ||
346 | describe('should submit request', () => { | |
347 | beforeEach(() => { | |
348 | component.targetForm.patchValue({ disks: ['rbd/disk_2'], acl_enabled: true }); | |
349 | component.onImageSelection({ option: { name: 'rbd/disk_2', selected: true } }); | |
350 | component.portals.setValue(['node1:192.168.100.201', 'node2:192.168.100.202']); | |
351 | component.addInitiator().patchValue({ | |
352 | client_iqn: 'iqn.initiator' | |
353 | }); | |
354 | component.addGroup().patchValue({ | |
355 | group_id: 'foo', | |
356 | members: ['iqn.initiator'], | |
357 | disks: ['rbd/disk_2'] | |
358 | }); | |
359 | }); | |
360 | ||
361 | it('should call update', () => { | |
362 | activatedRoute.setParams({ target_iqn: 'iqn.iscsi' }); | |
363 | component.isEdit = true; | |
364 | component.target_iqn = 'iqn.iscsi'; | |
365 | ||
366 | component.submit(); | |
367 | ||
368 | const req = httpTesting.expectOne('api/iscsi/target/iqn.iscsi'); | |
369 | expect(req.request.method).toBe('PUT'); | |
370 | expect(req.request.body).toEqual({ | |
371 | clients: [ | |
372 | { | |
373 | auth: { mutual_password: '', mutual_user: '', password: '', user: '' }, | |
374 | client_iqn: 'iqn.initiator', | |
375 | luns: [] | |
376 | } | |
377 | ], | |
378 | disks: [{ backstore: 'backstore:1', controls: {}, image: 'disk_2', pool: 'rbd' }], | |
379 | groups: [ | |
380 | { disks: [{ image: 'disk_2', pool: 'rbd' }], group_id: 'foo', members: ['iqn.initiator'] } | |
381 | ], | |
382 | new_target_iqn: component.targetForm.value.target_iqn, | |
383 | portals: [ | |
384 | { host: 'node1', ip: '192.168.100.201' }, | |
385 | { host: 'node2', ip: '192.168.100.202' } | |
386 | ], | |
387 | target_controls: {}, | |
388 | target_iqn: component.target_iqn, | |
389 | acl_enabled: true | |
390 | }); | |
391 | }); | |
392 | ||
393 | it('should call create', () => { | |
394 | component.submit(); | |
395 | ||
396 | const req = httpTesting.expectOne('api/iscsi/target'); | |
397 | expect(req.request.method).toBe('POST'); | |
398 | expect(req.request.body).toEqual({ | |
399 | clients: [ | |
400 | { | |
401 | auth: { mutual_password: '', mutual_user: '', password: '', user: '' }, | |
402 | client_iqn: 'iqn.initiator', | |
403 | luns: [] | |
404 | } | |
405 | ], | |
406 | disks: [{ backstore: 'backstore:1', controls: {}, image: 'disk_2', pool: 'rbd' }], | |
407 | groups: [ | |
408 | { | |
409 | disks: [{ image: 'disk_2', pool: 'rbd' }], | |
410 | group_id: 'foo', | |
411 | members: ['iqn.initiator'] | |
412 | } | |
413 | ], | |
414 | portals: [ | |
415 | { host: 'node1', ip: '192.168.100.201' }, | |
416 | { host: 'node2', ip: '192.168.100.202' } | |
417 | ], | |
418 | target_controls: {}, | |
419 | target_iqn: component.targetForm.value.target_iqn, | |
420 | acl_enabled: true | |
421 | }); | |
422 | }); | |
423 | ||
424 | it('should call create with acl_enabled disabled', () => { | |
425 | component.targetForm.patchValue({ acl_enabled: false }); | |
426 | component.submit(); | |
427 | ||
428 | const req = httpTesting.expectOne('api/iscsi/target'); | |
429 | expect(req.request.method).toBe('POST'); | |
430 | expect(req.request.body).toEqual({ | |
431 | clients: [], | |
432 | disks: [{ backstore: 'backstore:1', controls: {}, image: 'disk_2', pool: 'rbd' }], | |
433 | groups: [], | |
434 | acl_enabled: false, | |
435 | portals: [ | |
436 | { host: 'node1', ip: '192.168.100.201' }, | |
437 | { host: 'node2', ip: '192.168.100.202' } | |
438 | ], | |
439 | target_controls: {}, | |
440 | target_iqn: component.targetForm.value.target_iqn | |
441 | }); | |
442 | }); | |
443 | }); | |
444 | }); |