]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
faf35d0295c7bcbfaa570e0fab6760e3c27cfa03
[ceph-ci.git] /
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 { RouterTestingModule } from '@angular/router/testing';
5
6 import { ToastModule } from 'ng2-toastr';
7
8 import { configureTestBed, i18nProviders } from '../../../../testing/unit-test-helper';
9 import { SharedModule } from '../../../shared/shared.module';
10 import { IscsiTargetFormComponent } from './iscsi-target-form.component';
11
12 describe('IscsiTargetFormComponent', () => {
13   let component: IscsiTargetFormComponent;
14   let fixture: ComponentFixture<IscsiTargetFormComponent>;
15   let httpTesting: HttpTestingController;
16
17   const SETTINGS = {
18     config: { minimum_gateways: 2 },
19     disk_default_controls: {
20       hw_max_sectors: 1024,
21       osd_op_timeout: 30,
22       qfull_timeout: 5
23     },
24     target_default_controls: {
25       cmdsn_depth: 128,
26       dataout_timeout: 20,
27       immediate_data: 'Yes'
28     }
29   };
30
31   const LIST_TARGET = [
32     {
33       target_iqn: 'iqn.2003-01.com.redhat.iscsi-gw:iscsi-igw',
34       portals: [{ host: 'node1', ip: '192.168.100.201' }],
35       disks: [{ pool: 'rbd', image: 'disk_1', controls: {} }],
36       clients: [
37         {
38           client_iqn: 'iqn.1994-05.com.redhat:rh7-client',
39           luns: [{ pool: 'rbd', image: 'disk_1' }],
40           auth: {
41             user: 'myiscsiusername',
42             password: 'myiscsipassword',
43             mutual_user: null,
44             mutual_password: null
45           }
46         }
47       ],
48       groups: [],
49       target_controls: {}
50     }
51   ];
52
53   const PORTALS = [
54     { name: 'node1', ip_addresses: ['192.168.100.201', '10.0.2.15'] },
55     { name: 'node2', ip_addresses: ['192.168.100.202'] }
56   ];
57
58   const RBD_LIST = [
59     { status: 0, value: [], pool_name: 'ganesha' },
60     {
61       status: 0,
62       value: [
63         {
64           size: 96636764160,
65           obj_size: 4194304,
66           num_objs: 23040,
67           order: 22,
68           block_name_prefix: 'rbd_data.148162fb31a8',
69           name: 'disk_1',
70           id: '148162fb31a8',
71           pool_name: 'rbd',
72           features: 61,
73           features_name: ['deep-flatten', 'exclusive-lock', 'fast-diff', 'layering', 'object-map'],
74           timestamp: '2019-01-18T10:44:26Z',
75           stripe_count: 1,
76           stripe_unit: 4194304,
77           data_pool: null,
78           parent: null,
79           snapshots: [],
80           total_disk_usage: 0,
81           disk_usage: 0
82         },
83         {
84           size: 119185342464,
85           obj_size: 4194304,
86           num_objs: 28416,
87           order: 22,
88           block_name_prefix: 'rbd_data.14b292cee6cb',
89           name: 'disk_2',
90           id: '14b292cee6cb',
91           pool_name: 'rbd',
92           features: 61,
93           features_name: ['deep-flatten', 'exclusive-lock', 'fast-diff', 'layering', 'object-map'],
94           timestamp: '2019-01-18T10:45:56Z',
95           stripe_count: 1,
96           stripe_unit: 4194304,
97           data_pool: null,
98           parent: null,
99           snapshots: [],
100           total_disk_usage: 0,
101           disk_usage: 0
102         }
103       ],
104       pool_name: 'rbd'
105     }
106   ];
107
108   configureTestBed(
109     {
110       declarations: [IscsiTargetFormComponent],
111       imports: [
112         SharedModule,
113         ReactiveFormsModule,
114         HttpClientTestingModule,
115         RouterTestingModule,
116         ToastModule.forRoot()
117       ],
118       providers: [i18nProviders]
119     },
120     true
121   );
122
123   beforeEach(() => {
124     fixture = TestBed.createComponent(IscsiTargetFormComponent);
125     component = fixture.componentInstance;
126     httpTesting = TestBed.get(HttpTestingController);
127     fixture.detectChanges();
128
129     httpTesting.expectOne('ui-api/iscsi/settings').flush(SETTINGS);
130     httpTesting.expectOne('ui-api/iscsi/portals').flush(PORTALS);
131     httpTesting.expectOne('api/summary').flush({});
132     httpTesting.expectOne('api/block/image').flush(RBD_LIST);
133     httpTesting.expectOne('api/iscsi/target').flush(LIST_TARGET);
134     httpTesting.verify();
135   });
136
137   it('should create', () => {
138     expect(component).toBeTruthy();
139   });
140
141   it('should only show images not used in other targets', () => {
142     expect(component.imagesAll).toEqual(['rbd/disk_2']);
143     expect(component.imagesSelections).toEqual([
144       { description: '', name: 'rbd/disk_2', selected: false }
145     ]);
146   });
147
148   it('should generate portals selectOptions', () => {
149     expect(component.portalsSelections).toEqual([
150       { description: '', name: 'node1:192.168.100.201', selected: false },
151       { description: '', name: 'node1:10.0.2.15', selected: false },
152       { description: '', name: 'node2:192.168.100.202', selected: false }
153     ]);
154   });
155
156   it('should create the form', () => {
157     expect(component.targetForm.value).toEqual({
158       disks: [],
159       groups: [],
160       initiators: [],
161       portals: [],
162       target_controls: {},
163       target_iqn: component.targetForm.value.target_iqn
164     });
165   });
166
167   it('should prepare data when selecting an image', () => {
168     expect(component.imagesInitiatorSelections).toEqual([]);
169     expect(component.groupDiskSelections).toEqual([]);
170     expect(component.imagesSettings).toEqual({});
171
172     component.onImageSelection({ option: { name: 'rbd/disk_1', selected: true } });
173
174     expect(component.imagesInitiatorSelections).toEqual([
175       { description: '', name: 'rbd/disk_1', selected: false }
176     ]);
177     expect(component.groupDiskSelections).toEqual([
178       { description: '', name: 'rbd/disk_1', selected: false }
179     ]);
180     expect(component.imagesSettings).toEqual({ 'rbd/disk_1': {} });
181   });
182
183   it('should clean data when removing an image', () => {
184     component.onImageSelection({ option: { name: 'rbd/disk_1', selected: true } });
185     component.addGroup();
186     component.groups.controls[0].patchValue({
187       group_id: 'foo',
188       disks: ['rbd/disk_1']
189     });
190
191     expect(component.groups.controls[0].value).toEqual({
192       disks: ['rbd/disk_1'],
193       group_id: 'foo',
194       members: []
195     });
196
197     component.onImageSelection({ option: { name: 'rbd/disk_1', selected: false } });
198
199     expect(component.groups.controls[0].value).toEqual({ disks: [], group_id: 'foo', members: [] });
200     expect(component.imagesInitiatorSelections).toEqual([]);
201     expect(component.groupDiskSelections).toEqual([]);
202     expect(component.imagesSettings).toEqual({ 'rbd/disk_1': {} });
203   });
204
205   describe('should test initiators', () => {
206     beforeEach(() => {
207       component.addInitiator();
208       component.initiators.controls[0].patchValue({
209         client_iqn: 'iqn.initiator'
210       });
211       component.updatedInitiatorSelector();
212     });
213
214     it('should prepare data when creating an initiator', () => {
215       expect(component.initiators.controls.length).toBe(1);
216       expect(component.initiators.controls[0].value).toEqual({
217         auth: { mutual_password: '', mutual_user: '', password: '', user: '' },
218         cdIsInGroup: false,
219         client_iqn: 'iqn.initiator',
220         luns: []
221       });
222       expect(component.groupMembersSelections).toEqual([
223         { description: '', name: 'iqn.initiator', selected: false }
224       ]);
225     });
226
227     it('should update data when changing an initiator name', () => {
228       expect(component.groupMembersSelections).toEqual([
229         { description: '', name: 'iqn.initiator', selected: false }
230       ]);
231
232       component.initiators.controls[0].patchValue({
233         client_iqn: 'iqn.initiator_new'
234       });
235       component.updatedInitiatorSelector();
236
237       expect(component.groupMembersSelections).toEqual([
238         { description: '', name: 'iqn.initiator_new', selected: false }
239       ]);
240     });
241
242     it('should clean data when removing an initiator', () => {
243       component.addGroup();
244       component.groups.controls[0].patchValue({
245         group_id: 'foo',
246         members: ['iqn.initiator']
247       });
248
249       expect(component.groups.controls[0].value).toEqual({
250         disks: [],
251         group_id: 'foo',
252         members: ['iqn.initiator']
253       });
254
255       component.removeInitiator(0);
256
257       expect(component.groups.controls[0].value).toEqual({
258         disks: [],
259         group_id: 'foo',
260         members: []
261       });
262       expect(component.groupMembersSelections).toEqual([]);
263     });
264
265     it('should remove images in the initiator when added in a group', () => {
266       component.initiators.controls[0].patchValue({
267         luns: ['rbd/disk_1']
268       });
269       expect(component.initiators.controls[0].value).toEqual({
270         auth: { mutual_password: '', mutual_user: '', password: '', user: '' },
271         cdIsInGroup: false,
272         client_iqn: 'iqn.initiator',
273         luns: ['rbd/disk_1']
274       });
275
276       component.addGroup();
277       component.groups.controls[0].patchValue({
278         group_id: 'foo',
279         members: ['iqn.initiator']
280       });
281       component.onGroupMemberSelection({
282         option: {
283           name: 'iqn.initiator',
284           selected: true
285         }
286       });
287
288       expect(component.initiators.controls[0].value).toEqual({
289         auth: { mutual_password: '', mutual_user: '', password: '', user: '' },
290         cdIsInGroup: true,
291         client_iqn: 'iqn.initiator',
292         luns: []
293       });
294     });
295   });
296
297   it('should generate the request data', () => {
298     component.onImageSelection({ option: { name: 'rbd/disk_1', selected: true } });
299     component.portals.setValue(['node1:192.168.100.201', 'node2:192.168.100.202']);
300     component.addInitiator();
301     component.initiators.controls[0].patchValue({
302       client_iqn: 'iqn.initiator'
303     });
304     component.addGroup();
305     component.groups.controls[0].patchValue({
306       group_id: 'foo',
307       members: ['iqn.initiator'],
308       disks: ['rbd/disk_1']
309     });
310
311     component.submit();
312
313     const req = httpTesting.expectOne('api/iscsi/target');
314     expect(req.request.method).toBe('POST');
315     expect(req.request.body).toEqual({
316       clients: [
317         {
318           auth: { mutual_password: null, mutual_user: null, password: null, user: null },
319           cdIsInGroup: false,
320           client_iqn: 'iqn.initiator',
321           luns: []
322         }
323       ],
324       disks: [],
325       groups: [
326         { disks: [{ image: 'disk_1', pool: 'rbd' }], group_id: 'foo', members: ['iqn.initiator'] }
327       ],
328       portals: [{ host: 'node1', ip: '192.168.100.201' }, { host: 'node2', ip: '192.168.100.202' }],
329       target_controls: {},
330       target_iqn: component.targetForm.value.target_iqn
331     });
332   });
333 });