]> git.proxmox.com Git - ceph.git/blame - ceph/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts
bump version to 18.2.2-pve1
[ceph.git] / ceph / src / pybind / mgr / dashboard / frontend / src / app / ceph / cluster / services / service-form / service-form.component.spec.ts
CommitLineData
adb31ebb
TL
1import { HttpClientTestingModule } from '@angular/common/http/testing';
2import { ComponentFixture, TestBed } from '@angular/core/testing';
3import { ReactiveFormsModule } from '@angular/forms';
522d829b 4import { By } from '@angular/platform-browser';
adb31ebb
TL
5import { RouterTestingModule } from '@angular/router/testing';
6
a4b75251 7import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
f67539c2 8import _ from 'lodash';
adb31ebb 9import { ToastrModule } from 'ngx-toastr';
39ae355f 10import { of } from 'rxjs';
adb31ebb 11
f67539c2 12import { CephServiceService } from '~/app/shared/api/ceph-service.service';
39ae355f 13import { PaginateObservable } from '~/app/shared/api/paginate.model';
f67539c2
TL
14import { CdFormGroup } from '~/app/shared/forms/cd-form-group';
15import { SharedModule } from '~/app/shared/shared.module';
16import { configureTestBed, FormHelper } from '~/testing/unit-test-helper';
adb31ebb
TL
17import { ServiceFormComponent } from './service-form.component';
18
19describe('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],
a4b75251 28 providers: [NgbActiveModal],
adb31ebb
TL
29 imports: [
30 HttpClientTestingModule,
f67539c2 31 NgbTypeaheadModule,
adb31ebb
TL
32 ReactiveFormsModule,
33 RouterTestingModule,
34 SharedModule,
35 ToastrModule.forRoot()
f67539c2 36 ]
adb31ebb
TL
37 });
38
39 beforeEach(() => {
40 fixture = TestBed.createComponent(ServiceFormComponent);
41 component = fixture.componentInstance;
a4b75251 42 component.ngOnInit();
adb31ebb
TL
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(() => {
f67539c2 54 cephServiceService = TestBed.inject(CephServiceService);
adb31ebb
TL
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', () => {
522d829b
TL
107 formHelper.setValue('service_type', 'mgr');
108 formHelper.setValue('service_id', 'svc');
adb31ebb
TL
109 formHelper.setValue('placement', 'label');
110 formHelper.setValue('label', 'bar');
adb31ebb
TL
111 formHelper.setValue('unmanaged', true);
112 component.onSubmit();
113 expect(cephServiceService.create).toHaveBeenCalledWith({
522d829b
TL
114 service_type: 'mgr',
115 service_id: 'svc',
adb31ebb
TL
116 placement: {},
117 unmanaged: true
118 });
119 });
120
121 it('should test various services', () => {
122 _.forEach(
1e59de90 123 ['alertmanager', 'crash', 'mds', 'mgr', 'mon', 'node-exporter', 'prometheus', 'rbd-mirror'],
adb31ebb
TL
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 });
1e59de90
TL
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 });
adb31ebb
TL
165
166 describe('should test service nfs', () => {
167 beforeEach(() => {
168 formHelper.setValue('service_type', 'nfs');
adb31ebb
TL
169 });
170
a4b75251 171 it('should submit nfs', () => {
adb31ebb
TL
172 component.onSubmit();
173 expect(cephServiceService.create).toHaveBeenCalledWith({
174 service_type: 'nfs',
175 placement: {},
a4b75251 176 unmanaged: false
adb31ebb
TL
177 });
178 });
179 });
180
181 describe('should test service rgw', () => {
182 beforeEach(() => {
183 formHelper.setValue('service_type', 'rgw');
522d829b 184 formHelper.setValue('service_id', 'svc');
adb31ebb
TL
185 });
186
187 it('should test rgw valid service id', () => {
522d829b 188 formHelper.setValue('service_id', 'svc.realm.zone');
adb31ebb 189 formHelper.expectValid('service_id');
522d829b 190 formHelper.setValue('service_id', 'svc');
adb31ebb
TL
191 formHelper.expectValid('service_id');
192 });
193
aee94f69
TL
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');
522d829b
TL
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',
aee94f69 205 rgw_zonegroup: 'my-zonegroup',
522d829b
TL
206 placement: {},
207 unmanaged: false,
208 ssl: false
209 });
210 });
211
212 it('should submit rgw with port and ssl enabled', () => {
adb31ebb
TL
213 formHelper.setValue('rgw_frontend_port', 1234);
214 formHelper.setValue('ssl', true);
215 component.onSubmit();
216 expect(cephServiceService.create).toHaveBeenCalledWith({
217 service_type: 'rgw',
522d829b 218 service_id: 'svc',
aee94f69
TL
219 rgw_realm: null,
220 rgw_zone: null,
221 rgw_zonegroup: null,
adb31ebb
TL
222 placement: {},
223 unmanaged: false,
224 rgw_frontend_port: 1234,
225 rgw_frontend_ssl_certificate: '',
adb31ebb
TL
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);
20effc67 244 fixture.detectChanges();
adb31ebb
TL
245 formHelper.expectError('rgw_frontend_port', 'min');
246 });
247
248 it('should submit invalid rgw port (2)', () => {
249 formHelper.setValue('rgw_frontend_port', 65536);
20effc67 250 fixture.detectChanges();
adb31ebb
TL
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',
522d829b 265 service_id: 'svc',
aee94f69
TL
266 rgw_realm: null,
267 rgw_zone: null,
268 rgw_zonegroup: null,
adb31ebb
TL
269 placement: {},
270 unmanaged: false,
271 ssl: false
272 });
273 });
522d829b
TL
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-----
285iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
286-----END CERTIFICATE-----
287-----BEGIN CERTIFICATE-----
288mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
289-----END CERTIFICATE-----
290-----BEGIN RSA PRIVATE KEY-----
291x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
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 });
adb31ebb
TL
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);
f67539c2 324 formHelper.setValue('trusted_ip_list', ' 172.16.0.5, 192.1.1.10 ');
adb31ebb
TL
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: '',
f67539c2 336 trusted_ip_list: '172.16.0.5, 192.1.1.10'
adb31ebb
TL
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);
20effc67 369 fixture.detectChanges();
adb31ebb
TL
370 formHelper.expectError('api_port', 'min');
371 });
372
373 it('should submit invalid iscsi port (2)', () => {
374 formHelper.setValue('api_port', 65536);
20effc67 375 fixture.detectChanges();
adb31ebb
TL
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 });
20effc67
TL
384
385 it('should throw error when there is no pool', () => {
386 formHelper.expectErrorChange('pool', '', 'required');
387 });
adb31ebb 388 });
b3b6e05e
TL
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);
20effc67 422 fixture.detectChanges();
b3b6e05e
TL
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);
20effc67 429 fixture.detectChanges();
b3b6e05e
TL
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);
20effc67 438 fixture.detectChanges();
b3b6e05e
TL
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);
20effc67 445 fixture.detectChanges();
b3b6e05e
TL
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 });
33c7a0ef
TL
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-----
467iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
468-----END CERTIFICATE-----
469-----BEGIN CERTIFICATE-----
470mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
471-----END CERTIFICATE-----
472-----BEGIN RSA PRIVATE KEY-----
473x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
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 });
b3b6e05e 480 });
a4b75251 481
20effc67
TL
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
39ae355f
TL
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
a4b75251
TL
574 describe('check edit fields', () => {
575 beforeEach(() => {
576 component.editing = true;
577 });
578
579 it('should check whether edit field is correctly loaded', () => {
39ae355f
TL
580 const paginate_obs = new PaginateObservable<any>(of({}));
581 const cephServiceSpy = spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
a4b75251
TL
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 });
adb31ebb
TL
591 });
592});