]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
4f71abcec7a7d3f2e1db2923e250baddd4103bbf
[ceph-ci.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 submit rgw with realm, zonegroup and zone', () => {
195         formHelper.setValue('service_id', 'svc');
196         formHelper.setValue('realm_name', 'my-realm');
197         formHelper.setValue('zone_name', 'my-zone');
198         formHelper.setValue('zonegroup_name', 'my-zonegroup');
199         component.onSubmit();
200         expect(cephServiceService.create).toHaveBeenCalledWith({
201           service_type: 'rgw',
202           service_id: 'svc',
203           rgw_realm: 'my-realm',
204           rgw_zone: 'my-zone',
205           rgw_zonegroup: 'my-zonegroup',
206           placement: {},
207           unmanaged: false,
208           ssl: false
209         });
210       });
211
212       it('should submit rgw with port and ssl enabled', () => {
213         formHelper.setValue('rgw_frontend_port', 1234);
214         formHelper.setValue('ssl', true);
215         component.onSubmit();
216         expect(cephServiceService.create).toHaveBeenCalledWith({
217           service_type: 'rgw',
218           service_id: 'svc',
219           rgw_realm: null,
220           rgw_zone: null,
221           rgw_zonegroup: null,
222           placement: {},
223           unmanaged: false,
224           rgw_frontend_port: 1234,
225           rgw_frontend_ssl_certificate: '',
226           ssl: true
227         });
228       });
229
230       it('should submit valid rgw port (1)', () => {
231         formHelper.setValue('rgw_frontend_port', 1);
232         component.onSubmit();
233         formHelper.expectValid('rgw_frontend_port');
234       });
235
236       it('should submit valid rgw port (2)', () => {
237         formHelper.setValue('rgw_frontend_port', 65535);
238         component.onSubmit();
239         formHelper.expectValid('rgw_frontend_port');
240       });
241
242       it('should submit invalid rgw port (1)', () => {
243         formHelper.setValue('rgw_frontend_port', 0);
244         fixture.detectChanges();
245         formHelper.expectError('rgw_frontend_port', 'min');
246       });
247
248       it('should submit invalid rgw port (2)', () => {
249         formHelper.setValue('rgw_frontend_port', 65536);
250         fixture.detectChanges();
251         formHelper.expectError('rgw_frontend_port', 'max');
252       });
253
254       it('should submit invalid rgw port (3)', () => {
255         formHelper.setValue('rgw_frontend_port', 'abc');
256         component.onSubmit();
257         formHelper.expectError('rgw_frontend_port', 'pattern');
258       });
259
260       it('should submit rgw w/o port', () => {
261         formHelper.setValue('ssl', false);
262         component.onSubmit();
263         expect(cephServiceService.create).toHaveBeenCalledWith({
264           service_type: 'rgw',
265           service_id: 'svc',
266           rgw_realm: null,
267           rgw_zone: null,
268           rgw_zonegroup: null,
269           placement: {},
270           unmanaged: false,
271           ssl: false
272         });
273       });
274
275       it('should not show private key field', () => {
276         formHelper.setValue('ssl', true);
277         fixture.detectChanges();
278         const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
279         expect(ssl_key).toBeNull();
280       });
281
282       it('should test .pem file', () => {
283         const pemCert = `
284 -----BEGIN CERTIFICATE-----
285 iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
286 -----END CERTIFICATE-----
287 -----BEGIN CERTIFICATE-----
288 mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
289 -----END CERTIFICATE-----
290 -----BEGIN RSA PRIVATE KEY-----
291 x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
292 -----END RSA PRIVATE KEY-----`;
293         formHelper.setValue('ssl', true);
294         formHelper.setValue('ssl_cert', pemCert);
295         fixture.detectChanges();
296         formHelper.expectValid('ssl_cert');
297       });
298     });
299
300     describe('should test service iscsi', () => {
301       beforeEach(() => {
302         formHelper.setValue('service_type', 'iscsi');
303         formHelper.setValue('pool', 'xyz');
304         formHelper.setValue('api_user', 'user');
305         formHelper.setValue('api_password', 'password');
306         formHelper.setValue('ssl', false);
307       });
308
309       it('should submit iscsi', () => {
310         component.onSubmit();
311         expect(cephServiceService.create).toHaveBeenCalledWith({
312           service_type: 'iscsi',
313           placement: {},
314           unmanaged: false,
315           pool: 'xyz',
316           api_user: 'user',
317           api_password: 'password',
318           api_secure: false
319         });
320       });
321
322       it('should submit iscsi with trusted ips', () => {
323         formHelper.setValue('ssl', true);
324         formHelper.setValue('trusted_ip_list', ' 172.16.0.5, 192.1.1.10  ');
325         component.onSubmit();
326         expect(cephServiceService.create).toHaveBeenCalledWith({
327           service_type: 'iscsi',
328           placement: {},
329           unmanaged: false,
330           pool: 'xyz',
331           api_user: 'user',
332           api_password: 'password',
333           api_secure: true,
334           ssl_cert: '',
335           ssl_key: '',
336           trusted_ip_list: '172.16.0.5, 192.1.1.10'
337         });
338       });
339
340       it('should submit iscsi with port', () => {
341         formHelper.setValue('api_port', 456);
342         component.onSubmit();
343         expect(cephServiceService.create).toHaveBeenCalledWith({
344           service_type: 'iscsi',
345           placement: {},
346           unmanaged: false,
347           pool: 'xyz',
348           api_user: 'user',
349           api_password: 'password',
350           api_secure: false,
351           api_port: 456
352         });
353       });
354
355       it('should submit valid iscsi port (1)', () => {
356         formHelper.setValue('api_port', 1);
357         component.onSubmit();
358         formHelper.expectValid('api_port');
359       });
360
361       it('should submit valid iscsi port (2)', () => {
362         formHelper.setValue('api_port', 65535);
363         component.onSubmit();
364         formHelper.expectValid('api_port');
365       });
366
367       it('should submit invalid iscsi port (1)', () => {
368         formHelper.setValue('api_port', 0);
369         fixture.detectChanges();
370         formHelper.expectError('api_port', 'min');
371       });
372
373       it('should submit invalid iscsi port (2)', () => {
374         formHelper.setValue('api_port', 65536);
375         fixture.detectChanges();
376         formHelper.expectError('api_port', 'max');
377       });
378
379       it('should submit invalid iscsi port (3)', () => {
380         formHelper.setValue('api_port', 'abc');
381         component.onSubmit();
382         formHelper.expectError('api_port', 'pattern');
383       });
384
385       it('should throw error when there is no pool', () => {
386         formHelper.expectErrorChange('pool', '', 'required');
387       });
388     });
389
390     describe('should test service smb', () => {
391       beforeEach(() => {
392         formHelper.setValue('service_type', 'smb');
393         formHelper.setValue('service_id', 'foo');
394         formHelper.setValue('cluster_id', 'cluster_foo');
395         formHelper.setValue('config_uri', 'rados://.smb/foo/scc.toml');
396       });
397
398       it('should submit smb', () => {
399         component.onSubmit();
400         expect(cephServiceService.create).toHaveBeenCalledWith({
401           service_type: 'smb',
402           placement: {},
403           unmanaged: false,
404           service_id: 'foo',
405           cluster_id: 'cluster_foo',
406           config_uri: 'rados://.smb/foo/scc.toml'
407         });
408       });
409     });
410
411     describe('should test service ingress', () => {
412       beforeEach(() => {
413         formHelper.setValue('service_type', 'ingress');
414         formHelper.setValue('backend_service', 'rgw.foo');
415         formHelper.setValue('virtual_ip', '192.168.20.1/24');
416         formHelper.setValue('ssl', false);
417       });
418
419       it('should submit ingress', () => {
420         component.onSubmit();
421         expect(cephServiceService.create).toHaveBeenCalledWith({
422           service_type: 'ingress',
423           placement: {},
424           unmanaged: false,
425           backend_service: 'rgw.foo',
426           service_id: 'rgw.foo',
427           virtual_ip: '192.168.20.1/24',
428           virtual_interface_networks: null,
429           ssl: false
430         });
431       });
432
433       it('should pre-populate the service id', () => {
434         component.prePopulateId();
435         const prePopulatedID = component.serviceForm.getValue('service_id');
436         expect(prePopulatedID).toBe('rgw.foo');
437       });
438
439       it('should submit valid frontend and monitor port', () => {
440         // min value
441         formHelper.setValue('frontend_port', 1);
442         formHelper.setValue('monitor_port', 1);
443         fixture.detectChanges();
444         formHelper.expectValid('frontend_port');
445         formHelper.expectValid('monitor_port');
446
447         // max value
448         formHelper.setValue('frontend_port', 65535);
449         formHelper.setValue('monitor_port', 65535);
450         fixture.detectChanges();
451         formHelper.expectValid('frontend_port');
452         formHelper.expectValid('monitor_port');
453       });
454
455       it('should submit invalid frontend and monitor port', () => {
456         // min
457         formHelper.setValue('frontend_port', 0);
458         formHelper.setValue('monitor_port', 0);
459         fixture.detectChanges();
460         formHelper.expectError('frontend_port', 'min');
461         formHelper.expectError('monitor_port', 'min');
462
463         // max
464         formHelper.setValue('frontend_port', 65536);
465         formHelper.setValue('monitor_port', 65536);
466         fixture.detectChanges();
467         formHelper.expectError('frontend_port', 'max');
468         formHelper.expectError('monitor_port', 'max');
469
470         // pattern
471         formHelper.setValue('frontend_port', 'abc');
472         formHelper.setValue('monitor_port', 'abc');
473         component.onSubmit();
474         formHelper.expectError('frontend_port', 'pattern');
475         formHelper.expectError('monitor_port', 'pattern');
476       });
477
478       it('should not show private key field with ssl enabled', () => {
479         formHelper.setValue('ssl', true);
480         fixture.detectChanges();
481         const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
482         expect(ssl_key).toBeNull();
483       });
484
485       it('should test .pem file with ssl enabled', () => {
486         const pemCert = `
487 -----BEGIN CERTIFICATE-----
488 iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
489 -----END CERTIFICATE-----
490 -----BEGIN CERTIFICATE-----
491 mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
492 -----END CERTIFICATE-----
493 -----BEGIN RSA PRIVATE KEY-----
494 x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
495 -----END RSA PRIVATE KEY-----`;
496         formHelper.setValue('ssl', true);
497         formHelper.setValue('ssl_cert', pemCert);
498         fixture.detectChanges();
499         formHelper.expectValid('ssl_cert');
500       });
501     });
502
503     describe('should test service snmp-gateway', () => {
504       beforeEach(() => {
505         formHelper.setValue('service_type', 'snmp-gateway');
506         formHelper.setValue('snmp_destination', '192.168.20.1:8443');
507       });
508
509       it('should test snmp-gateway service with V2c', () => {
510         formHelper.setValue('snmp_version', 'V2c');
511         formHelper.setValue('snmp_community', 'public');
512         component.onSubmit();
513         expect(cephServiceService.create).toHaveBeenCalledWith({
514           service_type: 'snmp-gateway',
515           placement: {},
516           unmanaged: false,
517           snmp_version: 'V2c',
518           snmp_destination: '192.168.20.1:8443',
519           credentials: {
520             snmp_community: 'public'
521           }
522         });
523       });
524
525       it('should test snmp-gateway service with V3', () => {
526         formHelper.setValue('snmp_version', 'V3');
527         formHelper.setValue('engine_id', '800C53F00000');
528         formHelper.setValue('auth_protocol', 'SHA');
529         formHelper.setValue('privacy_protocol', 'DES');
530         formHelper.setValue('snmp_v3_auth_username', 'testuser');
531         formHelper.setValue('snmp_v3_auth_password', 'testpass');
532         formHelper.setValue('snmp_v3_priv_password', 'testencrypt');
533         component.onSubmit();
534         expect(cephServiceService.create).toHaveBeenCalledWith({
535           service_type: 'snmp-gateway',
536           placement: {},
537           unmanaged: false,
538           snmp_version: 'V3',
539           snmp_destination: '192.168.20.1:8443',
540           engine_id: '800C53F00000',
541           auth_protocol: 'SHA',
542           privacy_protocol: 'DES',
543           credentials: {
544             snmp_v3_auth_username: 'testuser',
545             snmp_v3_auth_password: 'testpass',
546             snmp_v3_priv_password: 'testencrypt'
547           }
548         });
549       });
550
551       it('should submit invalid snmp destination', () => {
552         formHelper.setValue('snmp_version', 'V2c');
553         formHelper.setValue('snmp_destination', '192.168.20.1');
554         formHelper.setValue('snmp_community', 'public');
555         formHelper.expectError('snmp_destination', 'snmpDestinationPattern');
556       });
557
558       it('should submit invalid snmp engine id', () => {
559         formHelper.setValue('snmp_version', 'V3');
560         formHelper.setValue('snmp_destination', '192.168.20.1');
561         formHelper.setValue('engine_id', 'AABBCCDDE');
562         formHelper.setValue('auth_protocol', 'SHA');
563         formHelper.setValue('privacy_protocol', 'DES');
564         formHelper.setValue('snmp_v3_auth_username', 'testuser');
565         formHelper.setValue('snmp_v3_auth_password', 'testpass');
566
567         formHelper.expectError('engine_id', 'snmpEngineIdPattern');
568       });
569     });
570
571     describe('should test service mds', () => {
572       beforeEach(() => {
573         formHelper.setValue('service_type', 'mds');
574         const paginate_obs = new PaginateObservable<any>(of({}));
575         spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
576       });
577
578       it('should test mds valid service id', () => {
579         formHelper.setValue('service_id', 'svc123');
580         formHelper.expectValid('service_id');
581         formHelper.setValue('service_id', 'svc_id-1');
582         formHelper.expectValid('service_id');
583       });
584
585       it('should test mds invalid service id', () => {
586         formHelper.setValue('service_id', '123');
587         formHelper.expectError('service_id', 'mdsPattern');
588         formHelper.setValue('service_id', '123svc');
589         formHelper.expectError('service_id', 'mdsPattern');
590         formHelper.setValue('service_id', 'svc#1');
591         formHelper.expectError('service_id', 'mdsPattern');
592       });
593     });
594
595     describe('check edit fields', () => {
596       beforeEach(() => {
597         component.editing = true;
598       });
599
600       it('should check whether edit field is correctly loaded', () => {
601         const paginate_obs = new PaginateObservable<any>(of({}));
602         const cephServiceSpy = spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
603         component.ngOnInit();
604         expect(cephServiceSpy).toBeCalledTimes(2);
605         expect(component.action).toBe('Edit');
606         const serviceType = fixture.debugElement.query(By.css('#service_type')).nativeElement;
607         const serviceId = fixture.debugElement.query(By.css('#service_id')).nativeElement;
608         expect(serviceType.disabled).toBeTruthy();
609         expect(serviceId.disabled).toBeTruthy();
610       });
611     });
612   });
613 });