]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
ebecec5cc3854e31fc36f5b1f61df1b509e01159
[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 ingress', () => {
391       beforeEach(() => {
392         formHelper.setValue('service_type', 'ingress');
393         formHelper.setValue('backend_service', 'rgw.foo');
394         formHelper.setValue('virtual_ip', '192.168.20.1/24');
395         formHelper.setValue('ssl', false);
396       });
397
398       it('should submit ingress', () => {
399         component.onSubmit();
400         expect(cephServiceService.create).toHaveBeenCalledWith({
401           service_type: 'ingress',
402           placement: {},
403           unmanaged: false,
404           backend_service: 'rgw.foo',
405           service_id: 'rgw.foo',
406           virtual_ip: '192.168.20.1/24',
407           virtual_interface_networks: null,
408           ssl: false
409         });
410       });
411
412       it('should pre-populate the service id', () => {
413         component.prePopulateId();
414         const prePopulatedID = component.serviceForm.getValue('service_id');
415         expect(prePopulatedID).toBe('rgw.foo');
416       });
417
418       it('should submit valid frontend and monitor port', () => {
419         // min value
420         formHelper.setValue('frontend_port', 1);
421         formHelper.setValue('monitor_port', 1);
422         fixture.detectChanges();
423         formHelper.expectValid('frontend_port');
424         formHelper.expectValid('monitor_port');
425
426         // max value
427         formHelper.setValue('frontend_port', 65535);
428         formHelper.setValue('monitor_port', 65535);
429         fixture.detectChanges();
430         formHelper.expectValid('frontend_port');
431         formHelper.expectValid('monitor_port');
432       });
433
434       it('should submit invalid frontend and monitor port', () => {
435         // min
436         formHelper.setValue('frontend_port', 0);
437         formHelper.setValue('monitor_port', 0);
438         fixture.detectChanges();
439         formHelper.expectError('frontend_port', 'min');
440         formHelper.expectError('monitor_port', 'min');
441
442         // max
443         formHelper.setValue('frontend_port', 65536);
444         formHelper.setValue('monitor_port', 65536);
445         fixture.detectChanges();
446         formHelper.expectError('frontend_port', 'max');
447         formHelper.expectError('monitor_port', 'max');
448
449         // pattern
450         formHelper.setValue('frontend_port', 'abc');
451         formHelper.setValue('monitor_port', 'abc');
452         component.onSubmit();
453         formHelper.expectError('frontend_port', 'pattern');
454         formHelper.expectError('monitor_port', 'pattern');
455       });
456
457       it('should not show private key field with ssl enabled', () => {
458         formHelper.setValue('ssl', true);
459         fixture.detectChanges();
460         const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
461         expect(ssl_key).toBeNull();
462       });
463
464       it('should test .pem file with ssl enabled', () => {
465         const pemCert = `
466 -----BEGIN CERTIFICATE-----
467 iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
468 -----END CERTIFICATE-----
469 -----BEGIN CERTIFICATE-----
470 mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
471 -----END CERTIFICATE-----
472 -----BEGIN RSA PRIVATE KEY-----
473 x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
474 -----END RSA PRIVATE KEY-----`;
475         formHelper.setValue('ssl', true);
476         formHelper.setValue('ssl_cert', pemCert);
477         fixture.detectChanges();
478         formHelper.expectValid('ssl_cert');
479       });
480     });
481
482     describe('should test service snmp-gateway', () => {
483       beforeEach(() => {
484         formHelper.setValue('service_type', 'snmp-gateway');
485         formHelper.setValue('snmp_destination', '192.168.20.1:8443');
486       });
487
488       it('should test snmp-gateway service with V2c', () => {
489         formHelper.setValue('snmp_version', 'V2c');
490         formHelper.setValue('snmp_community', 'public');
491         component.onSubmit();
492         expect(cephServiceService.create).toHaveBeenCalledWith({
493           service_type: 'snmp-gateway',
494           placement: {},
495           unmanaged: false,
496           snmp_version: 'V2c',
497           snmp_destination: '192.168.20.1:8443',
498           credentials: {
499             snmp_community: 'public'
500           }
501         });
502       });
503
504       it('should test snmp-gateway service with V3', () => {
505         formHelper.setValue('snmp_version', 'V3');
506         formHelper.setValue('engine_id', '800C53F00000');
507         formHelper.setValue('auth_protocol', 'SHA');
508         formHelper.setValue('privacy_protocol', 'DES');
509         formHelper.setValue('snmp_v3_auth_username', 'testuser');
510         formHelper.setValue('snmp_v3_auth_password', 'testpass');
511         formHelper.setValue('snmp_v3_priv_password', 'testencrypt');
512         component.onSubmit();
513         expect(cephServiceService.create).toHaveBeenCalledWith({
514           service_type: 'snmp-gateway',
515           placement: {},
516           unmanaged: false,
517           snmp_version: 'V3',
518           snmp_destination: '192.168.20.1:8443',
519           engine_id: '800C53F00000',
520           auth_protocol: 'SHA',
521           privacy_protocol: 'DES',
522           credentials: {
523             snmp_v3_auth_username: 'testuser',
524             snmp_v3_auth_password: 'testpass',
525             snmp_v3_priv_password: 'testencrypt'
526           }
527         });
528       });
529
530       it('should submit invalid snmp destination', () => {
531         formHelper.setValue('snmp_version', 'V2c');
532         formHelper.setValue('snmp_destination', '192.168.20.1');
533         formHelper.setValue('snmp_community', 'public');
534         formHelper.expectError('snmp_destination', 'snmpDestinationPattern');
535       });
536
537       it('should submit invalid snmp engine id', () => {
538         formHelper.setValue('snmp_version', 'V3');
539         formHelper.setValue('snmp_destination', '192.168.20.1');
540         formHelper.setValue('engine_id', 'AABBCCDDE');
541         formHelper.setValue('auth_protocol', 'SHA');
542         formHelper.setValue('privacy_protocol', 'DES');
543         formHelper.setValue('snmp_v3_auth_username', 'testuser');
544         formHelper.setValue('snmp_v3_auth_password', 'testpass');
545
546         formHelper.expectError('engine_id', 'snmpEngineIdPattern');
547       });
548     });
549
550     describe('should test service mds', () => {
551       beforeEach(() => {
552         formHelper.setValue('service_type', 'mds');
553         const paginate_obs = new PaginateObservable<any>(of({}));
554         spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
555       });
556
557       it('should test mds valid service id', () => {
558         formHelper.setValue('service_id', 'svc123');
559         formHelper.expectValid('service_id');
560         formHelper.setValue('service_id', 'svc_id-1');
561         formHelper.expectValid('service_id');
562       });
563
564       it('should test mds invalid service id', () => {
565         formHelper.setValue('service_id', '123');
566         formHelper.expectError('service_id', 'mdsPattern');
567         formHelper.setValue('service_id', '123svc');
568         formHelper.expectError('service_id', 'mdsPattern');
569         formHelper.setValue('service_id', 'svc#1');
570         formHelper.expectError('service_id', 'mdsPattern');
571       });
572     });
573
574     describe('check edit fields', () => {
575       beforeEach(() => {
576         component.editing = true;
577       });
578
579       it('should check whether edit field is correctly loaded', () => {
580         const paginate_obs = new PaginateObservable<any>(of({}));
581         const cephServiceSpy = spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
582         component.ngOnInit();
583         expect(cephServiceSpy).toBeCalledTimes(2);
584         expect(component.action).toBe('Edit');
585         const serviceType = fixture.debugElement.query(By.css('#service_type')).nativeElement;
586         const serviceId = fixture.debugElement.query(By.css('#service_id')).nativeElement;
587         expect(serviceType.disabled).toBeTruthy();
588         expect(serviceId.disabled).toBeTruthy();
589       });
590     });
591   });
592 });