]> git.apps.os.sepia.ceph.com Git - ceph.git/blob
b2c965ee71b96a2d185ffe010175c715f35da83f
[ceph.git] /
1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, TestBed } from '@angular/core/testing';
3 import { ReactiveFormsModule } from '@angular/forms';
4 import { By } from '@angular/platform-browser';
5 import { RouterTestingModule } from '@angular/router/testing';
6
7 import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
8 import _ from 'lodash';
9 import { ToastrModule } from 'ngx-toastr';
10 import { of } from 'rxjs';
11
12 import { CephServiceService } from '~/app/shared/api/ceph-service.service';
13 import { PaginateObservable } from '~/app/shared/api/paginate.model';
14 import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
15 import { SharedModule } from '~/app/shared/shared.module';
16 import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
17 import { ServiceFormComponent } from './service-form.component';
18
19 describe('ServiceFormComponent', () => {
20   let component: ServiceFormComponent;
21   let fixture: ComponentFixture<ServiceFormComponent>;
22   let cephServiceService: CephServiceService;
23   let form: CdFormGroup;
24   let formHelper: FormHelper;
25
26   configureTestBed({
27     declarations: [ServiceFormComponent],
28     providers: [NgbActiveModal],
29     imports: [
30       HttpClientTestingModule,
31       NgbTypeaheadModule,
32       ReactiveFormsModule,
33       RouterTestingModule,
34       SharedModule,
35       ToastrModule.forRoot()
36     ]
37   });
38
39   beforeEach(() => {
40     fixture = TestBed.createComponent(ServiceFormComponent);
41     component = fixture.componentInstance;
42     component.ngOnInit();
43     form = component.serviceForm;
44     formHelper = new FormHelper(form);
45     fixture.detectChanges();
46   });
47
48   it('should create', () => {
49     expect(component).toBeTruthy();
50   });
51
52   describe('should test form', () => {
53     beforeEach(() => {
54       cephServiceService = TestBed.inject(CephServiceService);
55       spyOn(cephServiceService, 'create').and.stub();
56     });
57
58     it('should test placement (host)', () => {
59       formHelper.setValue('service_type', 'crash');
60       formHelper.setValue('placement', 'hosts');
61       formHelper.setValue('hosts', ['mgr0', 'mon0', 'osd0']);
62       formHelper.setValue('count', 2);
63       component.onSubmit();
64       expect(cephServiceService.create).toHaveBeenCalledWith({
65         service_type: 'crash',
66         placement: {
67           hosts: ['mgr0', 'mon0', 'osd0'],
68           count: 2
69         },
70         unmanaged: false
71       });
72     });
73
74     it('should test placement (label)', () => {
75       formHelper.setValue('service_type', 'mgr');
76       formHelper.setValue('placement', 'label');
77       formHelper.setValue('label', 'foo');
78       component.onSubmit();
79       expect(cephServiceService.create).toHaveBeenCalledWith({
80         service_type: 'mgr',
81         placement: {
82           label: 'foo'
83         },
84         unmanaged: false
85       });
86     });
87
88     it('should submit valid count', () => {
89       formHelper.setValue('count', 1);
90       component.onSubmit();
91       formHelper.expectValid('count');
92     });
93
94     it('should submit invalid count (1)', () => {
95       formHelper.setValue('count', 0);
96       component.onSubmit();
97       formHelper.expectError('count', 'min');
98     });
99
100     it('should submit invalid count (2)', () => {
101       formHelper.setValue('count', 'abc');
102       component.onSubmit();
103       formHelper.expectError('count', 'pattern');
104     });
105
106     it('should test unmanaged', () => {
107       formHelper.setValue('service_type', 'mgr');
108       formHelper.setValue('service_id', 'svc');
109       formHelper.setValue('placement', 'label');
110       formHelper.setValue('label', 'bar');
111       formHelper.setValue('unmanaged', true);
112       component.onSubmit();
113       expect(cephServiceService.create).toHaveBeenCalledWith({
114         service_type: 'mgr',
115         service_id: 'svc',
116         placement: {},
117         unmanaged: true
118       });
119     });
120
121     it('should test various services', () => {
122       _.forEach(
123         ['alertmanager', 'crash', 'mds', 'mgr', 'mon', 'node-exporter', 'prometheus', 'rbd-mirror'],
124         (serviceType) => {
125           formHelper.setValue('service_type', serviceType);
126           component.onSubmit();
127           expect(cephServiceService.create).toHaveBeenCalledWith({
128             service_type: serviceType,
129             placement: {},
130             unmanaged: false
131           });
132         }
133       );
134     });
135
136     describe('should test service grafana', () => {
137       beforeEach(() => {
138         formHelper.setValue('service_type', 'grafana');
139       });
140
141       it('should sumbit grafana', () => {
142         component.onSubmit();
143         expect(cephServiceService.create).toHaveBeenCalledWith({
144           service_type: 'grafana',
145           placement: {},
146           unmanaged: false,
147           initial_admin_password: null,
148           port: null
149         });
150       });
151
152       it('should sumbit grafana with custom port and initial password', () => {
153         formHelper.setValue('grafana_port', 1234);
154         formHelper.setValue('grafana_admin_password', 'foo');
155         component.onSubmit();
156         expect(cephServiceService.create).toHaveBeenCalledWith({
157           service_type: 'grafana',
158           placement: {},
159           unmanaged: false,
160           initial_admin_password: 'foo',
161           port: 1234
162         });
163       });
164     });
165
166     describe('should test service nfs', () => {
167       beforeEach(() => {
168         formHelper.setValue('service_type', 'nfs');
169       });
170
171       it('should submit nfs', () => {
172         component.onSubmit();
173         expect(cephServiceService.create).toHaveBeenCalledWith({
174           service_type: 'nfs',
175           placement: {},
176           unmanaged: false
177         });
178       });
179     });
180
181     describe('should test service rgw', () => {
182       beforeEach(() => {
183         formHelper.setValue('service_type', 'rgw');
184         formHelper.setValue('service_id', 'svc');
185       });
186
187       it('should test rgw valid service id', () => {
188         formHelper.setValue('service_id', 'svc.realm.zone');
189         formHelper.expectValid('service_id');
190         formHelper.setValue('service_id', 'svc');
191         formHelper.expectValid('service_id');
192       });
193
194       it('should test rgw invalid service id', () => {
195         formHelper.setValue('service_id', '.');
196         formHelper.expectError('service_id', 'rgwPattern');
197         formHelper.setValue('service_id', 'svc.');
198         formHelper.expectError('service_id', 'rgwPattern');
199         formHelper.setValue('service_id', 'svc.realm');
200         formHelper.expectError('service_id', 'rgwPattern');
201         formHelper.setValue('service_id', 'svc.realm.');
202         formHelper.expectError('service_id', 'rgwPattern');
203         formHelper.setValue('service_id', '.svc.realm');
204         formHelper.expectError('service_id', 'rgwPattern');
205         formHelper.setValue('service_id', 'svc.realm.zone.');
206         formHelper.expectError('service_id', 'rgwPattern');
207       });
208
209       it('should submit rgw with realm and zone', () => {
210         formHelper.setValue('service_id', 'svc.my-realm.my-zone');
211         component.onSubmit();
212         expect(cephServiceService.create).toHaveBeenCalledWith({
213           service_type: 'rgw',
214           service_id: 'svc',
215           rgw_realm: 'my-realm',
216           rgw_zone: 'my-zone',
217           placement: {},
218           unmanaged: false,
219           ssl: false
220         });
221       });
222
223       it('should submit rgw with port and ssl enabled', () => {
224         formHelper.setValue('rgw_frontend_port', 1234);
225         formHelper.setValue('ssl', true);
226         component.onSubmit();
227         expect(cephServiceService.create).toHaveBeenCalledWith({
228           service_type: 'rgw',
229           service_id: 'svc',
230           placement: {},
231           unmanaged: false,
232           rgw_frontend_port: 1234,
233           rgw_frontend_ssl_certificate: '',
234           ssl: true
235         });
236       });
237
238       it('should submit valid rgw port (1)', () => {
239         formHelper.setValue('rgw_frontend_port', 1);
240         component.onSubmit();
241         formHelper.expectValid('rgw_frontend_port');
242       });
243
244       it('should submit valid rgw port (2)', () => {
245         formHelper.setValue('rgw_frontend_port', 65535);
246         component.onSubmit();
247         formHelper.expectValid('rgw_frontend_port');
248       });
249
250       it('should submit invalid rgw port (1)', () => {
251         formHelper.setValue('rgw_frontend_port', 0);
252         fixture.detectChanges();
253         formHelper.expectError('rgw_frontend_port', 'min');
254       });
255
256       it('should submit invalid rgw port (2)', () => {
257         formHelper.setValue('rgw_frontend_port', 65536);
258         fixture.detectChanges();
259         formHelper.expectError('rgw_frontend_port', 'max');
260       });
261
262       it('should submit invalid rgw port (3)', () => {
263         formHelper.setValue('rgw_frontend_port', 'abc');
264         component.onSubmit();
265         formHelper.expectError('rgw_frontend_port', 'pattern');
266       });
267
268       it('should submit rgw w/o port', () => {
269         formHelper.setValue('ssl', false);
270         component.onSubmit();
271         expect(cephServiceService.create).toHaveBeenCalledWith({
272           service_type: 'rgw',
273           service_id: 'svc',
274           placement: {},
275           unmanaged: false,
276           ssl: false
277         });
278       });
279
280       it('should not show private key field', () => {
281         formHelper.setValue('ssl', true);
282         fixture.detectChanges();
283         const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
284         expect(ssl_key).toBeNull();
285       });
286
287       it('should test .pem file', () => {
288         const pemCert = `
289 -----BEGIN CERTIFICATE-----
290 iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
291 -----END CERTIFICATE-----
292 -----BEGIN CERTIFICATE-----
293 mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
294 -----END CERTIFICATE-----
295 -----BEGIN RSA PRIVATE KEY-----
296 x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
297 -----END RSA PRIVATE KEY-----`;
298         formHelper.setValue('ssl', true);
299         formHelper.setValue('ssl_cert', pemCert);
300         fixture.detectChanges();
301         formHelper.expectValid('ssl_cert');
302       });
303     });
304
305     describe('should test service iscsi', () => {
306       beforeEach(() => {
307         formHelper.setValue('service_type', 'iscsi');
308         formHelper.setValue('pool', 'xyz');
309         formHelper.setValue('api_user', 'user');
310         formHelper.setValue('api_password', 'password');
311         formHelper.setValue('ssl', false);
312       });
313
314       it('should submit iscsi', () => {
315         component.onSubmit();
316         expect(cephServiceService.create).toHaveBeenCalledWith({
317           service_type: 'iscsi',
318           placement: {},
319           unmanaged: false,
320           pool: 'xyz',
321           api_user: 'user',
322           api_password: 'password',
323           api_secure: false
324         });
325       });
326
327       it('should submit iscsi with trusted ips', () => {
328         formHelper.setValue('ssl', true);
329         formHelper.setValue('trusted_ip_list', ' 172.16.0.5, 192.1.1.10  ');
330         component.onSubmit();
331         expect(cephServiceService.create).toHaveBeenCalledWith({
332           service_type: 'iscsi',
333           placement: {},
334           unmanaged: false,
335           pool: 'xyz',
336           api_user: 'user',
337           api_password: 'password',
338           api_secure: true,
339           ssl_cert: '',
340           ssl_key: '',
341           trusted_ip_list: '172.16.0.5, 192.1.1.10'
342         });
343       });
344
345       it('should submit iscsi with port', () => {
346         formHelper.setValue('api_port', 456);
347         component.onSubmit();
348         expect(cephServiceService.create).toHaveBeenCalledWith({
349           service_type: 'iscsi',
350           placement: {},
351           unmanaged: false,
352           pool: 'xyz',
353           api_user: 'user',
354           api_password: 'password',
355           api_secure: false,
356           api_port: 456
357         });
358       });
359
360       it('should submit valid iscsi port (1)', () => {
361         formHelper.setValue('api_port', 1);
362         component.onSubmit();
363         formHelper.expectValid('api_port');
364       });
365
366       it('should submit valid iscsi port (2)', () => {
367         formHelper.setValue('api_port', 65535);
368         component.onSubmit();
369         formHelper.expectValid('api_port');
370       });
371
372       it('should submit invalid iscsi port (1)', () => {
373         formHelper.setValue('api_port', 0);
374         fixture.detectChanges();
375         formHelper.expectError('api_port', 'min');
376       });
377
378       it('should submit invalid iscsi port (2)', () => {
379         formHelper.setValue('api_port', 65536);
380         fixture.detectChanges();
381         formHelper.expectError('api_port', 'max');
382       });
383
384       it('should submit invalid iscsi port (3)', () => {
385         formHelper.setValue('api_port', 'abc');
386         component.onSubmit();
387         formHelper.expectError('api_port', 'pattern');
388       });
389
390       it('should throw error when there is no pool', () => {
391         formHelper.expectErrorChange('pool', '', 'required');
392       });
393     });
394
395     describe('should test service ingress', () => {
396       beforeEach(() => {
397         formHelper.setValue('service_type', 'ingress');
398         formHelper.setValue('backend_service', 'rgw.foo');
399         formHelper.setValue('virtual_ip', '192.168.20.1/24');
400         formHelper.setValue('ssl', false);
401       });
402
403       it('should submit ingress', () => {
404         component.onSubmit();
405         expect(cephServiceService.create).toHaveBeenCalledWith({
406           service_type: 'ingress',
407           placement: {},
408           unmanaged: false,
409           backend_service: 'rgw.foo',
410           service_id: 'rgw.foo',
411           virtual_ip: '192.168.20.1/24',
412           virtual_interface_networks: null,
413           ssl: false
414         });
415       });
416
417       it('should pre-populate the service id', () => {
418         component.prePopulateId();
419         const prePopulatedID = component.serviceForm.getValue('service_id');
420         expect(prePopulatedID).toBe('rgw.foo');
421       });
422
423       it('should submit valid frontend and monitor port', () => {
424         // min value
425         formHelper.setValue('frontend_port', 1);
426         formHelper.setValue('monitor_port', 1);
427         fixture.detectChanges();
428         formHelper.expectValid('frontend_port');
429         formHelper.expectValid('monitor_port');
430
431         // max value
432         formHelper.setValue('frontend_port', 65535);
433         formHelper.setValue('monitor_port', 65535);
434         fixture.detectChanges();
435         formHelper.expectValid('frontend_port');
436         formHelper.expectValid('monitor_port');
437       });
438
439       it('should submit invalid frontend and monitor port', () => {
440         // min
441         formHelper.setValue('frontend_port', 0);
442         formHelper.setValue('monitor_port', 0);
443         fixture.detectChanges();
444         formHelper.expectError('frontend_port', 'min');
445         formHelper.expectError('monitor_port', 'min');
446
447         // max
448         formHelper.setValue('frontend_port', 65536);
449         formHelper.setValue('monitor_port', 65536);
450         fixture.detectChanges();
451         formHelper.expectError('frontend_port', 'max');
452         formHelper.expectError('monitor_port', 'max');
453
454         // pattern
455         formHelper.setValue('frontend_port', 'abc');
456         formHelper.setValue('monitor_port', 'abc');
457         component.onSubmit();
458         formHelper.expectError('frontend_port', 'pattern');
459         formHelper.expectError('monitor_port', 'pattern');
460       });
461
462       it('should not show private key field with ssl enabled', () => {
463         formHelper.setValue('ssl', true);
464         fixture.detectChanges();
465         const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
466         expect(ssl_key).toBeNull();
467       });
468
469       it('should test .pem file with ssl enabled', () => {
470         const pemCert = `
471 -----BEGIN CERTIFICATE-----
472 iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
473 -----END CERTIFICATE-----
474 -----BEGIN CERTIFICATE-----
475 mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
476 -----END CERTIFICATE-----
477 -----BEGIN RSA PRIVATE KEY-----
478 x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
479 -----END RSA PRIVATE KEY-----`;
480         formHelper.setValue('ssl', true);
481         formHelper.setValue('ssl_cert', pemCert);
482         fixture.detectChanges();
483         formHelper.expectValid('ssl_cert');
484       });
485     });
486
487     describe('should test service snmp-gateway', () => {
488       beforeEach(() => {
489         formHelper.setValue('service_type', 'snmp-gateway');
490         formHelper.setValue('snmp_destination', '192.168.20.1:8443');
491       });
492
493       it('should test snmp-gateway service with V2c', () => {
494         formHelper.setValue('snmp_version', 'V2c');
495         formHelper.setValue('snmp_community', 'public');
496         component.onSubmit();
497         expect(cephServiceService.create).toHaveBeenCalledWith({
498           service_type: 'snmp-gateway',
499           placement: {},
500           unmanaged: false,
501           snmp_version: 'V2c',
502           snmp_destination: '192.168.20.1:8443',
503           credentials: {
504             snmp_community: 'public'
505           }
506         });
507       });
508
509       it('should test snmp-gateway service with V3', () => {
510         formHelper.setValue('snmp_version', 'V3');
511         formHelper.setValue('engine_id', '800C53F00000');
512         formHelper.setValue('auth_protocol', 'SHA');
513         formHelper.setValue('privacy_protocol', 'DES');
514         formHelper.setValue('snmp_v3_auth_username', 'testuser');
515         formHelper.setValue('snmp_v3_auth_password', 'testpass');
516         formHelper.setValue('snmp_v3_priv_password', 'testencrypt');
517         component.onSubmit();
518         expect(cephServiceService.create).toHaveBeenCalledWith({
519           service_type: 'snmp-gateway',
520           placement: {},
521           unmanaged: false,
522           snmp_version: 'V3',
523           snmp_destination: '192.168.20.1:8443',
524           engine_id: '800C53F00000',
525           auth_protocol: 'SHA',
526           privacy_protocol: 'DES',
527           credentials: {
528             snmp_v3_auth_username: 'testuser',
529             snmp_v3_auth_password: 'testpass',
530             snmp_v3_priv_password: 'testencrypt'
531           }
532         });
533       });
534
535       it('should submit invalid snmp destination', () => {
536         formHelper.setValue('snmp_version', 'V2c');
537         formHelper.setValue('snmp_destination', '192.168.20.1');
538         formHelper.setValue('snmp_community', 'public');
539         formHelper.expectError('snmp_destination', 'snmpDestinationPattern');
540       });
541
542       it('should submit invalid snmp engine id', () => {
543         formHelper.setValue('snmp_version', 'V3');
544         formHelper.setValue('snmp_destination', '192.168.20.1');
545         formHelper.setValue('engine_id', 'AABBCCDDE');
546         formHelper.setValue('auth_protocol', 'SHA');
547         formHelper.setValue('privacy_protocol', 'DES');
548         formHelper.setValue('snmp_v3_auth_username', 'testuser');
549         formHelper.setValue('snmp_v3_auth_password', 'testpass');
550
551         formHelper.expectError('engine_id', 'snmpEngineIdPattern');
552       });
553     });
554
555     describe('should test service mds', () => {
556       beforeEach(() => {
557         formHelper.setValue('service_type', 'mds');
558         const paginate_obs = new PaginateObservable<any>(of({}));
559         spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
560       });
561
562       it('should test mds valid service id', () => {
563         formHelper.setValue('service_id', 'svc123');
564         formHelper.expectValid('service_id');
565         formHelper.setValue('service_id', 'svc_id-1');
566         formHelper.expectValid('service_id');
567       });
568
569       it('should test mds invalid service id', () => {
570         formHelper.setValue('service_id', '123');
571         formHelper.expectError('service_id', 'mdsPattern');
572         formHelper.setValue('service_id', '123svc');
573         formHelper.expectError('service_id', 'mdsPattern');
574         formHelper.setValue('service_id', 'svc#1');
575         formHelper.expectError('service_id', 'mdsPattern');
576       });
577     });
578
579     describe('check edit fields', () => {
580       beforeEach(() => {
581         component.editing = true;
582       });
583
584       it('should check whether edit field is correctly loaded', () => {
585         const paginate_obs = new PaginateObservable<any>(of({}));
586         const cephServiceSpy = spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
587         component.ngOnInit();
588         expect(cephServiceSpy).toBeCalledTimes(2);
589         expect(component.action).toBe('Edit');
590         const serviceType = fixture.debugElement.query(By.css('#service_type')).nativeElement;
591         const serviceId = fixture.debugElement.query(By.css('#service_id')).nativeElement;
592         expect(serviceType.disabled).toBeTruthy();
593         expect(serviceId.disabled).toBeTruthy();
594       });
595     });
596   });
597 });