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';
7 import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap';
8 import _ from 'lodash';
9 import { ToastrModule } from 'ngx-toastr';
10 import { of } from 'rxjs';
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';
19 describe('ServiceFormComponent', () => {
20 let component: ServiceFormComponent;
21 let fixture: ComponentFixture<ServiceFormComponent>;
22 let cephServiceService: CephServiceService;
23 let form: CdFormGroup;
24 let formHelper: FormHelper;
27 declarations: [ServiceFormComponent],
28 providers: [NgbActiveModal],
30 HttpClientTestingModule,
35 ToastrModule.forRoot()
40 fixture = TestBed.createComponent(ServiceFormComponent);
41 component = fixture.componentInstance;
43 form = component.serviceForm;
44 formHelper = new FormHelper(form);
45 fixture.detectChanges();
48 it('should create', () => {
49 expect(component).toBeTruthy();
52 describe('should test form', () => {
54 cephServiceService = TestBed.inject(CephServiceService);
55 spyOn(cephServiceService, 'create').and.stub();
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);
64 expect(cephServiceService.create).toHaveBeenCalledWith({
65 service_type: 'crash',
67 hosts: ['mgr0', 'mon0', 'osd0'],
74 it('should test placement (label)', () => {
75 formHelper.setValue('service_type', 'mgr');
76 formHelper.setValue('placement', 'label');
77 formHelper.setValue('label', 'foo');
79 expect(cephServiceService.create).toHaveBeenCalledWith({
88 it('should submit valid count', () => {
89 formHelper.setValue('count', 1);
91 formHelper.expectValid('count');
94 it('should submit invalid count (1)', () => {
95 formHelper.setValue('count', 0);
97 formHelper.expectError('count', 'min');
100 it('should submit invalid count (2)', () => {
101 formHelper.setValue('count', 'abc');
102 component.onSubmit();
103 formHelper.expectError('count', 'pattern');
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({
121 it('should test various services', () => {
123 ['alertmanager', 'crash', 'mds', 'mgr', 'mon', 'node-exporter', 'prometheus', 'rbd-mirror'],
125 formHelper.setValue('service_type', serviceType);
126 component.onSubmit();
127 expect(cephServiceService.create).toHaveBeenCalledWith({
128 service_type: serviceType,
136 describe('should test service grafana', () => {
138 formHelper.setValue('service_type', 'grafana');
141 it('should sumbit grafana', () => {
142 component.onSubmit();
143 expect(cephServiceService.create).toHaveBeenCalledWith({
144 service_type: 'grafana',
147 initial_admin_password: null,
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',
160 initial_admin_password: 'foo',
166 describe('should test service nfs', () => {
168 formHelper.setValue('service_type', 'nfs');
171 it('should submit nfs', () => {
172 component.onSubmit();
173 expect(cephServiceService.create).toHaveBeenCalledWith({
181 describe('should test service rgw', () => {
183 formHelper.setValue('service_type', 'rgw');
184 formHelper.setValue('service_id', 'svc');
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');
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({
203 rgw_realm: 'my-realm',
205 rgw_zonegroup: 'my-zonegroup',
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({
224 rgw_frontend_port: 1234,
225 rgw_frontend_ssl_certificate: '',
230 it('should submit valid rgw port (1)', () => {
231 formHelper.setValue('rgw_frontend_port', 1);
232 component.onSubmit();
233 formHelper.expectValid('rgw_frontend_port');
236 it('should submit valid rgw port (2)', () => {
237 formHelper.setValue('rgw_frontend_port', 65535);
238 component.onSubmit();
239 formHelper.expectValid('rgw_frontend_port');
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');
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');
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');
260 it('should submit rgw w/o port', () => {
261 formHelper.setValue('ssl', false);
262 component.onSubmit();
263 expect(cephServiceService.create).toHaveBeenCalledWith({
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();
282 it('should test .pem file', () => {
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');
300 describe('should test service iscsi', () => {
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);
309 it('should submit iscsi', () => {
310 component.onSubmit();
311 expect(cephServiceService.create).toHaveBeenCalledWith({
312 service_type: 'iscsi',
317 api_password: 'password',
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',
332 api_password: 'password',
336 trusted_ip_list: '172.16.0.5, 192.1.1.10'
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',
349 api_password: 'password',
355 it('should submit valid iscsi port (1)', () => {
356 formHelper.setValue('api_port', 1);
357 component.onSubmit();
358 formHelper.expectValid('api_port');
361 it('should submit valid iscsi port (2)', () => {
362 formHelper.setValue('api_port', 65535);
363 component.onSubmit();
364 formHelper.expectValid('api_port');
367 it('should submit invalid iscsi port (1)', () => {
368 formHelper.setValue('api_port', 0);
369 fixture.detectChanges();
370 formHelper.expectError('api_port', 'min');
373 it('should submit invalid iscsi port (2)', () => {
374 formHelper.setValue('api_port', 65536);
375 fixture.detectChanges();
376 formHelper.expectError('api_port', 'max');
379 it('should submit invalid iscsi port (3)', () => {
380 formHelper.setValue('api_port', 'abc');
381 component.onSubmit();
382 formHelper.expectError('api_port', 'pattern');
385 it('should throw error when there is no pool', () => {
386 formHelper.expectErrorChange('pool', '', 'required');
390 describe('should test service smb', () => {
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');
398 it('should submit smb', () => {
399 component.onSubmit();
400 expect(cephServiceService.create).toHaveBeenCalledWith({
405 cluster_id: 'cluster_foo',
406 config_uri: 'rados://.smb/foo/scc.toml'
411 describe('should test service ingress', () => {
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);
419 it('should submit ingress', () => {
420 component.onSubmit();
421 expect(cephServiceService.create).toHaveBeenCalledWith({
422 service_type: 'ingress',
425 backend_service: 'rgw.foo',
426 service_id: 'rgw.foo',
427 virtual_ip: '192.168.20.1/24',
428 virtual_interface_networks: null,
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');
439 it('should submit valid frontend and monitor port', () => {
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');
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');
455 it('should submit invalid frontend and monitor port', () => {
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');
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');
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');
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();
485 it('should test .pem file with ssl enabled', () => {
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');
503 describe('should test service snmp-gateway', () => {
505 formHelper.setValue('service_type', 'snmp-gateway');
506 formHelper.setValue('snmp_destination', '192.168.20.1:8443');
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',
518 snmp_destination: '192.168.20.1:8443',
520 snmp_community: 'public'
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',
539 snmp_destination: '192.168.20.1:8443',
540 engine_id: '800C53F00000',
541 auth_protocol: 'SHA',
542 privacy_protocol: 'DES',
544 snmp_v3_auth_username: 'testuser',
545 snmp_v3_auth_password: 'testpass',
546 snmp_v3_priv_password: 'testencrypt'
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');
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');
567 formHelper.expectError('engine_id', 'snmpEngineIdPattern');
571 describe('should test service mds', () => {
573 formHelper.setValue('service_type', 'mds');
574 const paginate_obs = new PaginateObservable<any>(of({}));
575 spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
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');
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');
595 describe('check edit fields', () => {
597 component.editing = true;
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();