]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
cbecc908e87d4cc22e9234119398282a307f5887
[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, Mocks } from '~/testing/unit-test-helper';
17 import { ServiceFormComponent } from './service-form.component';
18 import { PoolService } from '~/app/shared/api/pool.service';
19
20 // for 'nvmeof' service
21 const mockPools = [
22   Mocks.getPool('pool-1', 1, ['cephfs']),
23   Mocks.getPool('rbd', 2),
24   Mocks.getPool('pool-2', 3)
25 ];
26 class MockPoolService {
27   getList() {
28     return of(mockPools);
29   }
30 }
31
32 describe('ServiceFormComponent', () => {
33   let component: ServiceFormComponent;
34   let fixture: ComponentFixture<ServiceFormComponent>;
35   let cephServiceService: CephServiceService;
36   let form: CdFormGroup;
37   let formHelper: FormHelper;
38
39   configureTestBed({
40     declarations: [ServiceFormComponent],
41     providers: [NgbActiveModal, { provide: PoolService, useClass: MockPoolService }],
42     imports: [
43       HttpClientTestingModule,
44       NgbTypeaheadModule,
45       ReactiveFormsModule,
46       RouterTestingModule,
47       SharedModule,
48       ToastrModule.forRoot()
49     ]
50   });
51
52   beforeEach(() => {
53     fixture = TestBed.createComponent(ServiceFormComponent);
54     component = fixture.componentInstance;
55     component.ngOnInit();
56     form = component.serviceForm;
57     formHelper = new FormHelper(form);
58     fixture.detectChanges();
59   });
60
61   it('should create', () => {
62     expect(component).toBeTruthy();
63   });
64
65   describe('should test form', () => {
66     beforeEach(() => {
67       cephServiceService = TestBed.inject(CephServiceService);
68       spyOn(cephServiceService, 'create').and.stub();
69     });
70
71     it('should test placement (host)', () => {
72       formHelper.setValue('service_type', 'crash');
73       formHelper.setValue('placement', 'hosts');
74       formHelper.setValue('hosts', ['mgr0', 'mon0', 'osd0']);
75       formHelper.setValue('count', 2);
76       component.onSubmit();
77       expect(cephServiceService.create).toHaveBeenCalledWith({
78         service_type: 'crash',
79         placement: {
80           hosts: ['mgr0', 'mon0', 'osd0'],
81           count: 2
82         },
83         unmanaged: false
84       });
85     });
86
87     it('should test placement (label)', () => {
88       formHelper.setValue('service_type', 'mgr');
89       formHelper.setValue('placement', 'label');
90       formHelper.setValue('label', 'foo');
91       component.onSubmit();
92       expect(cephServiceService.create).toHaveBeenCalledWith({
93         service_type: 'mgr',
94         placement: {
95           label: 'foo'
96         },
97         unmanaged: false
98       });
99     });
100
101     it('should submit valid count', () => {
102       formHelper.setValue('count', 1);
103       component.onSubmit();
104       formHelper.expectValid('count');
105     });
106
107     it('should submit invalid count (1)', () => {
108       formHelper.setValue('count', 0);
109       component.onSubmit();
110       formHelper.expectError('count', 'min');
111     });
112
113     it('should submit invalid count (2)', () => {
114       formHelper.setValue('count', 'abc');
115       component.onSubmit();
116       formHelper.expectError('count', 'pattern');
117     });
118
119     it('should test unmanaged', () => {
120       formHelper.setValue('service_type', 'mgr');
121       formHelper.setValue('service_id', 'svc');
122       formHelper.setValue('placement', 'label');
123       formHelper.setValue('label', 'bar');
124       formHelper.setValue('unmanaged', true);
125       component.onSubmit();
126       expect(cephServiceService.create).toHaveBeenCalledWith({
127         service_type: 'mgr',
128         service_id: 'svc',
129         placement: {},
130         unmanaged: true
131       });
132     });
133
134     it('should test various services', () => {
135       _.forEach(
136         ['alertmanager', 'crash', 'mds', 'mgr', 'mon', 'node-exporter', 'prometheus', 'rbd-mirror'],
137         (serviceType) => {
138           formHelper.setValue('service_type', serviceType);
139           component.onSubmit();
140           expect(cephServiceService.create).toHaveBeenCalledWith({
141             service_type: serviceType,
142             placement: {},
143             unmanaged: false
144           });
145         }
146       );
147     });
148
149     describe('should test service grafana', () => {
150       beforeEach(() => {
151         formHelper.setValue('service_type', 'grafana');
152       });
153
154       it('should sumbit grafana', () => {
155         component.onSubmit();
156         expect(cephServiceService.create).toHaveBeenCalledWith({
157           service_type: 'grafana',
158           placement: {},
159           unmanaged: false,
160           initial_admin_password: null,
161           port: null
162         });
163       });
164
165       it('should sumbit grafana with custom port and initial password', () => {
166         formHelper.setValue('grafana_port', 1234);
167         formHelper.setValue('grafana_admin_password', 'foo');
168         component.onSubmit();
169         expect(cephServiceService.create).toHaveBeenCalledWith({
170           service_type: 'grafana',
171           placement: {},
172           unmanaged: false,
173           initial_admin_password: 'foo',
174           port: 1234
175         });
176       });
177     });
178
179     describe('should test service nfs', () => {
180       beforeEach(() => {
181         formHelper.setValue('service_type', 'nfs');
182       });
183
184       it('should submit nfs', () => {
185         component.onSubmit();
186         expect(cephServiceService.create).toHaveBeenCalledWith({
187           service_type: 'nfs',
188           placement: {},
189           unmanaged: false
190         });
191       });
192     });
193
194     describe('should test service rgw', () => {
195       beforeEach(() => {
196         formHelper.setValue('service_type', 'rgw');
197         formHelper.setValue('service_id', 'svc');
198       });
199
200       it('should test rgw valid service id', () => {
201         formHelper.setValue('service_id', 'svc.realm.zone');
202         formHelper.expectValid('service_id');
203         formHelper.setValue('service_id', 'svc');
204         formHelper.expectValid('service_id');
205       });
206
207       it('should submit rgw with realm, zonegroup and zone', () => {
208         formHelper.setValue('service_id', 'svc');
209         formHelper.setValue('realm_name', 'my-realm');
210         formHelper.setValue('zone_name', 'my-zone');
211         formHelper.setValue('zonegroup_name', 'my-zonegroup');
212         component.onSubmit();
213         expect(cephServiceService.create).toHaveBeenCalledWith({
214           service_type: 'rgw',
215           service_id: 'svc',
216           rgw_realm: 'my-realm',
217           rgw_zone: 'my-zone',
218           rgw_zonegroup: 'my-zonegroup',
219           placement: {},
220           unmanaged: false,
221           ssl: false
222         });
223       });
224
225       it('should submit rgw with port and ssl enabled', () => {
226         formHelper.setValue('rgw_frontend_port', 1234);
227         formHelper.setValue('ssl', true);
228         component.onSubmit();
229         expect(cephServiceService.create).toHaveBeenCalledWith({
230           service_type: 'rgw',
231           service_id: 'svc',
232           rgw_realm: null,
233           rgw_zone: null,
234           rgw_zonegroup: null,
235           placement: {},
236           unmanaged: false,
237           rgw_frontend_port: 1234,
238           rgw_frontend_ssl_certificate: '',
239           ssl: true
240         });
241       });
242
243       it('should submit valid rgw port (1)', () => {
244         formHelper.setValue('rgw_frontend_port', 1);
245         component.onSubmit();
246         formHelper.expectValid('rgw_frontend_port');
247       });
248
249       it('should submit valid rgw port (2)', () => {
250         formHelper.setValue('rgw_frontend_port', 65535);
251         component.onSubmit();
252         formHelper.expectValid('rgw_frontend_port');
253       });
254
255       it('should submit invalid rgw port (1)', () => {
256         formHelper.setValue('rgw_frontend_port', 0);
257         fixture.detectChanges();
258         formHelper.expectError('rgw_frontend_port', 'min');
259       });
260
261       it('should submit invalid rgw port (2)', () => {
262         formHelper.setValue('rgw_frontend_port', 65536);
263         fixture.detectChanges();
264         formHelper.expectError('rgw_frontend_port', 'max');
265       });
266
267       it('should submit invalid rgw port (3)', () => {
268         formHelper.setValue('rgw_frontend_port', 'abc');
269         component.onSubmit();
270         formHelper.expectError('rgw_frontend_port', 'pattern');
271       });
272
273       it('should submit rgw w/o port', () => {
274         formHelper.setValue('ssl', false);
275         component.onSubmit();
276         expect(cephServiceService.create).toHaveBeenCalledWith({
277           service_type: 'rgw',
278           service_id: 'svc',
279           rgw_realm: null,
280           rgw_zone: null,
281           rgw_zonegroup: null,
282           placement: {},
283           unmanaged: false,
284           ssl: false
285         });
286       });
287
288       it('should not show private key field', () => {
289         formHelper.setValue('ssl', true);
290         fixture.detectChanges();
291         const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
292         expect(ssl_key).toBeNull();
293       });
294
295       it('should test .pem file', () => {
296         const pemCert = `
297 -----BEGIN CERTIFICATE-----
298 iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
299 -----END CERTIFICATE-----
300 -----BEGIN CERTIFICATE-----
301 mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
302 -----END CERTIFICATE-----
303 -----BEGIN RSA PRIVATE KEY-----
304 x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
305 -----END RSA PRIVATE KEY-----`;
306         formHelper.setValue('ssl', true);
307         formHelper.setValue('ssl_cert', pemCert);
308         fixture.detectChanges();
309         formHelper.expectValid('ssl_cert');
310       });
311     });
312
313     describe('should test service iscsi', () => {
314       beforeEach(() => {
315         formHelper.setValue('service_type', 'iscsi');
316         formHelper.setValue('pool', 'xyz');
317         formHelper.setValue('api_user', 'user');
318         formHelper.setValue('api_password', 'password');
319         formHelper.setValue('ssl', false);
320       });
321
322       it('should submit iscsi', () => {
323         component.onSubmit();
324         expect(cephServiceService.create).toHaveBeenCalledWith({
325           service_type: 'iscsi',
326           placement: {},
327           unmanaged: false,
328           pool: 'xyz',
329           api_user: 'user',
330           api_password: 'password',
331           api_secure: false
332         });
333       });
334
335       it('should submit iscsi with trusted ips', () => {
336         formHelper.setValue('ssl', true);
337         formHelper.setValue('trusted_ip_list', ' 172.16.0.5, 192.1.1.10  ');
338         component.onSubmit();
339         expect(cephServiceService.create).toHaveBeenCalledWith({
340           service_type: 'iscsi',
341           placement: {},
342           unmanaged: false,
343           pool: 'xyz',
344           api_user: 'user',
345           api_password: 'password',
346           api_secure: true,
347           ssl_cert: '',
348           ssl_key: '',
349           trusted_ip_list: '172.16.0.5, 192.1.1.10'
350         });
351       });
352
353       it('should submit iscsi with port', () => {
354         formHelper.setValue('api_port', 456);
355         component.onSubmit();
356         expect(cephServiceService.create).toHaveBeenCalledWith({
357           service_type: 'iscsi',
358           placement: {},
359           unmanaged: false,
360           pool: 'xyz',
361           api_user: 'user',
362           api_password: 'password',
363           api_secure: false,
364           api_port: 456
365         });
366       });
367
368       it('should submit valid iscsi port (1)', () => {
369         formHelper.setValue('api_port', 1);
370         component.onSubmit();
371         formHelper.expectValid('api_port');
372       });
373
374       it('should submit valid iscsi port (2)', () => {
375         formHelper.setValue('api_port', 65535);
376         component.onSubmit();
377         formHelper.expectValid('api_port');
378       });
379
380       it('should submit invalid iscsi port (1)', () => {
381         formHelper.setValue('api_port', 0);
382         fixture.detectChanges();
383         formHelper.expectError('api_port', 'min');
384       });
385
386       it('should submit invalid iscsi port (2)', () => {
387         formHelper.setValue('api_port', 65536);
388         fixture.detectChanges();
389         formHelper.expectError('api_port', 'max');
390       });
391
392       it('should submit invalid iscsi port (3)', () => {
393         formHelper.setValue('api_port', 'abc');
394         component.onSubmit();
395         formHelper.expectError('api_port', 'pattern');
396       });
397
398       it('should throw error when there is no pool', () => {
399         formHelper.expectErrorChange('pool', '', 'required');
400       });
401     });
402
403     describe('should test service nvmeof', () => {
404       beforeEach(() => {
405         component.serviceType = 'nvmeof';
406         formHelper.setValue('service_type', 'nvmeof');
407         component.ngOnInit();
408         fixture.detectChanges();
409       });
410
411       it('should set rbd pools correctly onInit', () => {
412         expect(component.pools.length).toBe(3);
413         expect(component.rbdPools.length).toBe(2);
414       });
415
416       it('should set default values correctly onInit', () => {
417         expect(form.get('service_type').value).toBe('nvmeof');
418         expect(form.get('group').value).toBe('default');
419         expect(form.get('pool').value).toBe('rbd');
420         expect(form.get('service_id').value).toBe('rbd.default');
421       });
422
423       it('should reflect correct values on group change', () => {
424         // Initially the group value should be 'default'
425         expect(component.serviceForm.get('group')?.value).toBe('default');
426         const groupInput = fixture.debugElement.query(By.css('#group')).nativeElement;
427         // Simulate input value change
428         groupInput.value = 'foo';
429         // Trigger the input event
430         groupInput.dispatchEvent(new Event('input'));
431         // Trigger the change event
432         groupInput.dispatchEvent(new Event('change'));
433         fixture.detectChanges();
434         // Verify values after change
435         expect(form.get('group').value).toBe('foo');
436         expect(form.get('service_id').value).toBe('rbd.foo');
437       });
438
439       it('should reflect correct values on pool change', () => {
440         // Initially the pool value should be 'rbd'
441         expect(component.serviceForm.get('pool')?.value).toBe('rbd');
442         const poolInput = fixture.debugElement.query(By.css('#pool')).nativeElement;
443         // Simulate input value change
444         poolInput.value = 'pool-2';
445         // Trigger the input event
446         poolInput.dispatchEvent(new Event('input'));
447         // Trigger the change event
448         poolInput.dispatchEvent(new Event('change'));
449         fixture.detectChanges();
450         // Verify values after change
451         expect(form.get('pool').value).toBe('pool-2');
452         expect(form.get('service_id').value).toBe('pool-2.default');
453       });
454
455       it('should throw error when there is no service id', () => {
456         formHelper.expectErrorChange('service_id', '', 'required');
457       });
458
459       it('should throw error when there is no pool', () => {
460         formHelper.expectErrorChange('pool', '', 'required');
461       });
462
463       it('should throw error when there is no group', () => {
464         formHelper.expectErrorChange('group', '', 'required');
465       });
466
467       it('should hide the count element when service_type is "nvmeof"', () => {
468         const countEl = fixture.debugElement.query(By.css('#count'));
469         expect(countEl).toBeNull();
470       });
471
472       it('should not show certs and keys field with mTLS disabled', () => {
473         formHelper.setValue('ssl', true);
474         fixture.detectChanges();
475         const root_ca_cert = fixture.debugElement.query(By.css('#root_ca_cert'));
476         const client_cert = fixture.debugElement.query(By.css('#client_cert'));
477         const client_key = fixture.debugElement.query(By.css('#client_key'));
478         const server_cert = fixture.debugElement.query(By.css('#server_cert'));
479         const server_key = fixture.debugElement.query(By.css('#server_key'));
480         expect(root_ca_cert).toBeNull();
481         expect(client_cert).toBeNull();
482         expect(client_key).toBeNull();
483         expect(server_cert).toBeNull();
484         expect(server_key).toBeNull();
485       });
486
487       it('should submit nvmeof without mTLS', () => {
488         component.onSubmit();
489         expect(cephServiceService.create).toHaveBeenCalledWith({
490           service_type: 'nvmeof',
491           service_id: 'rbd.default',
492           placement: {},
493           unmanaged: false,
494           pool: 'rbd',
495           group: 'default',
496           enable_auth: false
497         });
498       });
499
500       it('should submit nvmeof with mTLS', () => {
501         formHelper.setValue('enable_mtls', true);
502         formHelper.setValue('root_ca_cert', 'root_ca_cert');
503         formHelper.setValue('client_cert', 'client_cert');
504         formHelper.setValue('client_key', 'client_key');
505         formHelper.setValue('server_cert', 'server_cert');
506         formHelper.setValue('server_key', 'server_key');
507         component.onSubmit();
508         expect(cephServiceService.create).toHaveBeenCalledWith({
509           service_type: 'nvmeof',
510           service_id: 'rbd.default',
511           placement: {},
512           unmanaged: false,
513           pool: 'rbd',
514           group: 'default',
515           enable_auth: true,
516           root_ca_cert: 'root_ca_cert',
517           client_cert: 'client_cert',
518           client_key: 'client_key',
519           server_cert: 'server_cert',
520           server_key: 'server_key'
521         });
522       });
523     });
524
525     describe('should test service smb', () => {
526       beforeEach(() => {
527         formHelper.setValue('service_type', 'smb');
528         formHelper.setValue('service_id', 'foo');
529         formHelper.setValue('cluster_id', 'cluster_foo');
530         formHelper.setValue('config_uri', 'rados://.smb/foo/scc.toml');
531       });
532
533       it('should submit smb', () => {
534         component.onSubmit();
535         expect(cephServiceService.create).toHaveBeenCalledWith({
536           service_type: 'smb',
537           placement: {},
538           unmanaged: false,
539           service_id: 'foo',
540           cluster_id: 'cluster_foo',
541           config_uri: 'rados://.smb/foo/scc.toml'
542         });
543       });
544     });
545
546     describe('should test service ingress', () => {
547       beforeEach(() => {
548         formHelper.setValue('service_type', 'ingress');
549         formHelper.setValue('backend_service', 'rgw.foo');
550         formHelper.setValue('virtual_ip', '192.168.20.1/24');
551         formHelper.setValue('ssl', false);
552       });
553
554       it('should submit ingress', () => {
555         component.onSubmit();
556         expect(cephServiceService.create).toHaveBeenCalledWith({
557           service_type: 'ingress',
558           placement: {},
559           unmanaged: false,
560           backend_service: 'rgw.foo',
561           service_id: 'rgw.foo',
562           virtual_ip: '192.168.20.1/24',
563           virtual_interface_networks: null,
564           ssl: false
565         });
566       });
567
568       it('should pre-populate the service id', () => {
569         component.prePopulateId();
570         const prePopulatedID = component.serviceForm.getValue('service_id');
571         expect(prePopulatedID).toBe('rgw.foo');
572       });
573
574       it('should submit valid frontend and monitor port', () => {
575         // min value
576         formHelper.setValue('frontend_port', 1);
577         formHelper.setValue('monitor_port', 1);
578         fixture.detectChanges();
579         formHelper.expectValid('frontend_port');
580         formHelper.expectValid('monitor_port');
581
582         // max value
583         formHelper.setValue('frontend_port', 65535);
584         formHelper.setValue('monitor_port', 65535);
585         fixture.detectChanges();
586         formHelper.expectValid('frontend_port');
587         formHelper.expectValid('monitor_port');
588       });
589
590       it('should submit invalid frontend and monitor port', () => {
591         // min
592         formHelper.setValue('frontend_port', 0);
593         formHelper.setValue('monitor_port', 0);
594         fixture.detectChanges();
595         formHelper.expectError('frontend_port', 'min');
596         formHelper.expectError('monitor_port', 'min');
597
598         // max
599         formHelper.setValue('frontend_port', 65536);
600         formHelper.setValue('monitor_port', 65536);
601         fixture.detectChanges();
602         formHelper.expectError('frontend_port', 'max');
603         formHelper.expectError('monitor_port', 'max');
604
605         // pattern
606         formHelper.setValue('frontend_port', 'abc');
607         formHelper.setValue('monitor_port', 'abc');
608         component.onSubmit();
609         formHelper.expectError('frontend_port', 'pattern');
610         formHelper.expectError('monitor_port', 'pattern');
611       });
612
613       it('should not show private key field with ssl enabled', () => {
614         formHelper.setValue('ssl', true);
615         fixture.detectChanges();
616         const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
617         expect(ssl_key).toBeNull();
618       });
619
620       it('should test .pem file with ssl enabled', () => {
621         const pemCert = `
622 -----BEGIN CERTIFICATE-----
623 iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
624 -----END CERTIFICATE-----
625 -----BEGIN CERTIFICATE-----
626 mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
627 -----END CERTIFICATE-----
628 -----BEGIN RSA PRIVATE KEY-----
629 x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
630 -----END RSA PRIVATE KEY-----`;
631         formHelper.setValue('ssl', true);
632         formHelper.setValue('ssl_cert', pemCert);
633         fixture.detectChanges();
634         formHelper.expectValid('ssl_cert');
635       });
636     });
637
638     describe('should test service snmp-gateway', () => {
639       beforeEach(() => {
640         formHelper.setValue('service_type', 'snmp-gateway');
641         formHelper.setValue('snmp_destination', '192.168.20.1:8443');
642       });
643
644       it('should test snmp-gateway service with V2c', () => {
645         formHelper.setValue('snmp_version', 'V2c');
646         formHelper.setValue('snmp_community', 'public');
647         component.onSubmit();
648         expect(cephServiceService.create).toHaveBeenCalledWith({
649           service_type: 'snmp-gateway',
650           placement: {},
651           unmanaged: false,
652           snmp_version: 'V2c',
653           snmp_destination: '192.168.20.1:8443',
654           credentials: {
655             snmp_community: 'public'
656           }
657         });
658       });
659
660       it('should test snmp-gateway service with V3', () => {
661         formHelper.setValue('snmp_version', 'V3');
662         formHelper.setValue('engine_id', '800C53F00000');
663         formHelper.setValue('auth_protocol', 'SHA');
664         formHelper.setValue('privacy_protocol', 'DES');
665         formHelper.setValue('snmp_v3_auth_username', 'testuser');
666         formHelper.setValue('snmp_v3_auth_password', 'testpass');
667         formHelper.setValue('snmp_v3_priv_password', 'testencrypt');
668         component.onSubmit();
669         expect(cephServiceService.create).toHaveBeenCalledWith({
670           service_type: 'snmp-gateway',
671           placement: {},
672           unmanaged: false,
673           snmp_version: 'V3',
674           snmp_destination: '192.168.20.1:8443',
675           engine_id: '800C53F00000',
676           auth_protocol: 'SHA',
677           privacy_protocol: 'DES',
678           credentials: {
679             snmp_v3_auth_username: 'testuser',
680             snmp_v3_auth_password: 'testpass',
681             snmp_v3_priv_password: 'testencrypt'
682           }
683         });
684       });
685
686       it('should submit invalid snmp destination', () => {
687         formHelper.setValue('snmp_version', 'V2c');
688         formHelper.setValue('snmp_destination', '192.168.20.1');
689         formHelper.setValue('snmp_community', 'public');
690         formHelper.expectError('snmp_destination', 'snmpDestinationPattern');
691       });
692
693       it('should submit invalid snmp engine id', () => {
694         formHelper.setValue('snmp_version', 'V3');
695         formHelper.setValue('snmp_destination', '192.168.20.1');
696         formHelper.setValue('engine_id', 'AABBCCDDE');
697         formHelper.setValue('auth_protocol', 'SHA');
698         formHelper.setValue('privacy_protocol', 'DES');
699         formHelper.setValue('snmp_v3_auth_username', 'testuser');
700         formHelper.setValue('snmp_v3_auth_password', 'testpass');
701
702         formHelper.expectError('engine_id', 'snmpEngineIdPattern');
703       });
704     });
705
706     describe('should test service mds', () => {
707       beforeEach(() => {
708         formHelper.setValue('service_type', 'mds');
709         const paginate_obs = new PaginateObservable<any>(of({}));
710         spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
711       });
712
713       it('should test mds valid service id', () => {
714         formHelper.setValue('service_id', 'svc123');
715         formHelper.expectValid('service_id');
716         formHelper.setValue('service_id', 'svc_id-1');
717         formHelper.expectValid('service_id');
718       });
719
720       it('should test mds invalid service id', () => {
721         formHelper.setValue('service_id', '123');
722         formHelper.expectError('service_id', 'mdsPattern');
723         formHelper.setValue('service_id', '123svc');
724         formHelper.expectError('service_id', 'mdsPattern');
725         formHelper.setValue('service_id', 'svc#1');
726         formHelper.expectError('service_id', 'mdsPattern');
727       });
728     });
729
730     describe('check edit fields', () => {
731       beforeEach(() => {
732         component.editing = true;
733       });
734
735       it('should check whether edit field is correctly loaded', () => {
736         const paginate_obs = new PaginateObservable<any>(of({}));
737         const cephServiceSpy = spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
738         component.ngOnInit();
739         expect(cephServiceSpy).toBeCalledTimes(2);
740         expect(component.action).toBe('Edit');
741         const serviceType = fixture.debugElement.query(By.css('#service_type')).nativeElement;
742         const serviceId = fixture.debugElement.query(By.css('#service_id')).nativeElement;
743         expect(serviceType.disabled).toBeTruthy();
744         expect(serviceId.disabled).toBeTruthy();
745       });
746
747       it('should not edit pools for nvmeof service', () => {
748         component.serviceType = 'nvmeof';
749         formHelper.setValue('service_type', 'nvmeof');
750         component.ngOnInit();
751         fixture.detectChanges();
752         const poolId = fixture.debugElement.query(By.css('#pool')).nativeElement;
753         expect(poolId.disabled).toBeTruthy();
754       });
755
756       it('should not edit groups for nvmeof service', () => {
757         component.serviceType = 'nvmeof';
758         formHelper.setValue('service_type', 'nvmeof');
759         component.ngOnInit();
760         fixture.detectChanges();
761         const groupId = fixture.debugElement.query(By.css('#group')).nativeElement;
762         expect(groupId.disabled).toBeTruthy();
763       });
764
765       it('should update nvmeof service to disable mTLS', () => {
766         spyOn(cephServiceService, 'update').and.stub();
767         component.serviceType = 'nvmeof';
768         formHelper.setValue('service_type', 'nvmeof');
769         formHelper.setValue('pool', 'rbd');
770         formHelper.setValue('group', 'default');
771         // mTLS disabled
772         formHelper.setValue('enable_auth', false);
773         component.onSubmit();
774         expect(cephServiceService.update).toHaveBeenCalledWith({
775           service_type: 'nvmeof',
776           placement: {},
777           unmanaged: false,
778           pool: 'rbd',
779           group: 'default',
780           enable_auth: false
781         });
782       });
783     });
784   });
785 });