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 nvmeof', () => {
392 formHelper.setValue('service_type', 'nvmeof');
393 formHelper.setValue('service_id', 'svc');
394 formHelper.setValue('pool', 'xyz');
395 formHelper.setValue('group', 'abc');
398 it('should submit nvmeof', () => {
399 component.onSubmit();
400 expect(cephServiceService.create).toHaveBeenCalledWith({
401 service_type: 'nvmeof',
410 it('should throw error when there is no service id', () => {
411 formHelper.expectErrorChange('service_id', '', 'required');
414 it('should throw error when there is no pool', () => {
415 formHelper.expectErrorChange('pool', '', 'required');
418 it('should throw error when there is no group', () => {
419 formHelper.expectErrorChange('group', '', 'required');
423 describe('should test service smb', () => {
425 formHelper.setValue('service_type', 'smb');
426 formHelper.setValue('service_id', 'foo');
427 formHelper.setValue('cluster_id', 'cluster_foo');
428 formHelper.setValue('config_uri', 'rados://.smb/foo/scc.toml');
431 it('should submit smb', () => {
432 component.onSubmit();
433 expect(cephServiceService.create).toHaveBeenCalledWith({
438 cluster_id: 'cluster_foo',
439 config_uri: 'rados://.smb/foo/scc.toml'
444 describe('should test service ingress', () => {
446 formHelper.setValue('service_type', 'ingress');
447 formHelper.setValue('backend_service', 'rgw.foo');
448 formHelper.setValue('virtual_ip', '192.168.20.1/24');
449 formHelper.setValue('ssl', false);
452 it('should submit ingress', () => {
453 component.onSubmit();
454 expect(cephServiceService.create).toHaveBeenCalledWith({
455 service_type: 'ingress',
458 backend_service: 'rgw.foo',
459 service_id: 'rgw.foo',
460 virtual_ip: '192.168.20.1/24',
461 virtual_interface_networks: null,
466 it('should pre-populate the service id', () => {
467 component.prePopulateId();
468 const prePopulatedID = component.serviceForm.getValue('service_id');
469 expect(prePopulatedID).toBe('rgw.foo');
472 it('should submit valid frontend and monitor port', () => {
474 formHelper.setValue('frontend_port', 1);
475 formHelper.setValue('monitor_port', 1);
476 fixture.detectChanges();
477 formHelper.expectValid('frontend_port');
478 formHelper.expectValid('monitor_port');
481 formHelper.setValue('frontend_port', 65535);
482 formHelper.setValue('monitor_port', 65535);
483 fixture.detectChanges();
484 formHelper.expectValid('frontend_port');
485 formHelper.expectValid('monitor_port');
488 it('should submit invalid frontend and monitor port', () => {
490 formHelper.setValue('frontend_port', 0);
491 formHelper.setValue('monitor_port', 0);
492 fixture.detectChanges();
493 formHelper.expectError('frontend_port', 'min');
494 formHelper.expectError('monitor_port', 'min');
497 formHelper.setValue('frontend_port', 65536);
498 formHelper.setValue('monitor_port', 65536);
499 fixture.detectChanges();
500 formHelper.expectError('frontend_port', 'max');
501 formHelper.expectError('monitor_port', 'max');
504 formHelper.setValue('frontend_port', 'abc');
505 formHelper.setValue('monitor_port', 'abc');
506 component.onSubmit();
507 formHelper.expectError('frontend_port', 'pattern');
508 formHelper.expectError('monitor_port', 'pattern');
511 it('should not show private key field with ssl enabled', () => {
512 formHelper.setValue('ssl', true);
513 fixture.detectChanges();
514 const ssl_key = fixture.debugElement.query(By.css('#ssl_key'));
515 expect(ssl_key).toBeNull();
518 it('should test .pem file with ssl enabled', () => {
520 -----BEGIN CERTIFICATE-----
521 iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu
522 -----END CERTIFICATE-----
523 -----BEGIN CERTIFICATE-----
524 mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB
525 -----END CERTIFICATE-----
526 -----BEGIN RSA PRIVATE KEY-----
527 x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA==
528 -----END RSA PRIVATE KEY-----`;
529 formHelper.setValue('ssl', true);
530 formHelper.setValue('ssl_cert', pemCert);
531 fixture.detectChanges();
532 formHelper.expectValid('ssl_cert');
536 describe('should test service snmp-gateway', () => {
538 formHelper.setValue('service_type', 'snmp-gateway');
539 formHelper.setValue('snmp_destination', '192.168.20.1:8443');
542 it('should test snmp-gateway service with V2c', () => {
543 formHelper.setValue('snmp_version', 'V2c');
544 formHelper.setValue('snmp_community', 'public');
545 component.onSubmit();
546 expect(cephServiceService.create).toHaveBeenCalledWith({
547 service_type: 'snmp-gateway',
551 snmp_destination: '192.168.20.1:8443',
553 snmp_community: 'public'
558 it('should test snmp-gateway service with V3', () => {
559 formHelper.setValue('snmp_version', 'V3');
560 formHelper.setValue('engine_id', '800C53F00000');
561 formHelper.setValue('auth_protocol', 'SHA');
562 formHelper.setValue('privacy_protocol', 'DES');
563 formHelper.setValue('snmp_v3_auth_username', 'testuser');
564 formHelper.setValue('snmp_v3_auth_password', 'testpass');
565 formHelper.setValue('snmp_v3_priv_password', 'testencrypt');
566 component.onSubmit();
567 expect(cephServiceService.create).toHaveBeenCalledWith({
568 service_type: 'snmp-gateway',
572 snmp_destination: '192.168.20.1:8443',
573 engine_id: '800C53F00000',
574 auth_protocol: 'SHA',
575 privacy_protocol: 'DES',
577 snmp_v3_auth_username: 'testuser',
578 snmp_v3_auth_password: 'testpass',
579 snmp_v3_priv_password: 'testencrypt'
584 it('should submit invalid snmp destination', () => {
585 formHelper.setValue('snmp_version', 'V2c');
586 formHelper.setValue('snmp_destination', '192.168.20.1');
587 formHelper.setValue('snmp_community', 'public');
588 formHelper.expectError('snmp_destination', 'snmpDestinationPattern');
591 it('should submit invalid snmp engine id', () => {
592 formHelper.setValue('snmp_version', 'V3');
593 formHelper.setValue('snmp_destination', '192.168.20.1');
594 formHelper.setValue('engine_id', 'AABBCCDDE');
595 formHelper.setValue('auth_protocol', 'SHA');
596 formHelper.setValue('privacy_protocol', 'DES');
597 formHelper.setValue('snmp_v3_auth_username', 'testuser');
598 formHelper.setValue('snmp_v3_auth_password', 'testpass');
600 formHelper.expectError('engine_id', 'snmpEngineIdPattern');
604 describe('should test service mds', () => {
606 formHelper.setValue('service_type', 'mds');
607 const paginate_obs = new PaginateObservable<any>(of({}));
608 spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
611 it('should test mds valid service id', () => {
612 formHelper.setValue('service_id', 'svc123');
613 formHelper.expectValid('service_id');
614 formHelper.setValue('service_id', 'svc_id-1');
615 formHelper.expectValid('service_id');
618 it('should test mds invalid service id', () => {
619 formHelper.setValue('service_id', '123');
620 formHelper.expectError('service_id', 'mdsPattern');
621 formHelper.setValue('service_id', '123svc');
622 formHelper.expectError('service_id', 'mdsPattern');
623 formHelper.setValue('service_id', 'svc#1');
624 formHelper.expectError('service_id', 'mdsPattern');
628 describe('check edit fields', () => {
630 component.editing = true;
633 it('should check whether edit field is correctly loaded', () => {
634 const paginate_obs = new PaginateObservable<any>(of({}));
635 const cephServiceSpy = spyOn(cephServiceService, 'list').and.returnValue(paginate_obs);
636 component.ngOnInit();
637 expect(cephServiceSpy).toBeCalledTimes(2);
638 expect(component.action).toBe('Edit');
639 const serviceType = fixture.debugElement.query(By.css('#service_type')).nativeElement;
640 const serviceId = fixture.debugElement.query(By.css('#service_id')).nativeElement;
641 expect(serviceType.disabled).toBeTruthy();
642 expect(serviceId.disabled).toBeTruthy();
645 it('should not edit pools for nvmeof service', () => {
646 component.serviceType = 'nvmeof';
647 formHelper.setValue('service_type', 'nvmeof');
648 component.ngOnInit();
649 fixture.detectChanges();
650 const poolId = fixture.debugElement.query(By.css('#pool')).nativeElement;
651 expect(poolId.disabled).toBeTruthy();