diff options
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts')
-rw-r--r-- | src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts | 550 |
1 files changed, 550 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts new file mode 100644 index 000000000..082fe9162 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/services/service-form/service-form.component.spec.ts @@ -0,0 +1,550 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ReactiveFormsModule } from '@angular/forms'; +import { By } from '@angular/platform-browser'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { NgbActiveModal, NgbTypeaheadModule } from '@ng-bootstrap/ng-bootstrap'; +import _ from 'lodash'; +import { ToastrModule } from 'ngx-toastr'; + +import { CephServiceService } from '~/app/shared/api/ceph-service.service'; +import { CdFormGroup } from '~/app/shared/forms/cd-form-group'; +import { SharedModule } from '~/app/shared/shared.module'; +import { configureTestBed, FormHelper } from '~/testing/unit-test-helper'; +import { ServiceFormComponent } from './service-form.component'; + +describe('ServiceFormComponent', () => { + let component: ServiceFormComponent; + let fixture: ComponentFixture<ServiceFormComponent>; + let cephServiceService: CephServiceService; + let form: CdFormGroup; + let formHelper: FormHelper; + + configureTestBed({ + declarations: [ServiceFormComponent], + providers: [NgbActiveModal], + imports: [ + HttpClientTestingModule, + NgbTypeaheadModule, + ReactiveFormsModule, + RouterTestingModule, + SharedModule, + ToastrModule.forRoot() + ] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ServiceFormComponent); + component = fixture.componentInstance; + component.ngOnInit(); + form = component.serviceForm; + formHelper = new FormHelper(form); + fixture.detectChanges(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('should test form', () => { + beforeEach(() => { + cephServiceService = TestBed.inject(CephServiceService); + spyOn(cephServiceService, 'create').and.stub(); + }); + + it('should test placement (host)', () => { + formHelper.setValue('service_type', 'crash'); + formHelper.setValue('placement', 'hosts'); + formHelper.setValue('hosts', ['mgr0', 'mon0', 'osd0']); + formHelper.setValue('count', 2); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'crash', + placement: { + hosts: ['mgr0', 'mon0', 'osd0'], + count: 2 + }, + unmanaged: false + }); + }); + + it('should test placement (label)', () => { + formHelper.setValue('service_type', 'mgr'); + formHelper.setValue('placement', 'label'); + formHelper.setValue('label', 'foo'); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'mgr', + placement: { + label: 'foo' + }, + unmanaged: false + }); + }); + + it('should submit valid count', () => { + formHelper.setValue('count', 1); + component.onSubmit(); + formHelper.expectValid('count'); + }); + + it('should submit invalid count (1)', () => { + formHelper.setValue('count', 0); + component.onSubmit(); + formHelper.expectError('count', 'min'); + }); + + it('should submit invalid count (2)', () => { + formHelper.setValue('count', 'abc'); + component.onSubmit(); + formHelper.expectError('count', 'pattern'); + }); + + it('should test unmanaged', () => { + formHelper.setValue('service_type', 'mgr'); + formHelper.setValue('service_id', 'svc'); + formHelper.setValue('placement', 'label'); + formHelper.setValue('label', 'bar'); + formHelper.setValue('unmanaged', true); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'mgr', + service_id: 'svc', + placement: {}, + unmanaged: true + }); + }); + + it('should test various services', () => { + _.forEach( + [ + 'alertmanager', + 'crash', + 'grafana', + 'mds', + 'mgr', + 'mon', + 'node-exporter', + 'prometheus', + 'rbd-mirror' + ], + (serviceType) => { + formHelper.setValue('service_type', serviceType); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: serviceType, + placement: {}, + unmanaged: false + }); + } + ); + }); + + describe('should test service nfs', () => { + beforeEach(() => { + formHelper.setValue('service_type', 'nfs'); + }); + + it('should submit nfs', () => { + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'nfs', + placement: {}, + unmanaged: false + }); + }); + }); + + describe('should test service rgw', () => { + beforeEach(() => { + formHelper.setValue('service_type', 'rgw'); + formHelper.setValue('service_id', 'svc'); + }); + + it('should test rgw valid service id', () => { + formHelper.setValue('service_id', 'svc.realm.zone'); + formHelper.expectValid('service_id'); + formHelper.setValue('service_id', 'svc'); + formHelper.expectValid('service_id'); + }); + + it('should test rgw invalid service id', () => { + formHelper.setValue('service_id', '.'); + formHelper.expectError('service_id', 'rgwPattern'); + formHelper.setValue('service_id', 'svc.'); + formHelper.expectError('service_id', 'rgwPattern'); + formHelper.setValue('service_id', 'svc.realm'); + formHelper.expectError('service_id', 'rgwPattern'); + formHelper.setValue('service_id', 'svc.realm.'); + formHelper.expectError('service_id', 'rgwPattern'); + formHelper.setValue('service_id', '.svc.realm'); + formHelper.expectError('service_id', 'rgwPattern'); + formHelper.setValue('service_id', 'svc.realm.zone.'); + formHelper.expectError('service_id', 'rgwPattern'); + }); + + it('should submit rgw with realm and zone', () => { + formHelper.setValue('service_id', 'svc.my-realm.my-zone'); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'rgw', + service_id: 'svc', + rgw_realm: 'my-realm', + rgw_zone: 'my-zone', + placement: {}, + unmanaged: false, + ssl: false + }); + }); + + it('should submit rgw with port and ssl enabled', () => { + formHelper.setValue('rgw_frontend_port', 1234); + formHelper.setValue('ssl', true); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'rgw', + service_id: 'svc', + placement: {}, + unmanaged: false, + rgw_frontend_port: 1234, + rgw_frontend_ssl_certificate: '', + ssl: true + }); + }); + + it('should submit valid rgw port (1)', () => { + formHelper.setValue('rgw_frontend_port', 1); + component.onSubmit(); + formHelper.expectValid('rgw_frontend_port'); + }); + + it('should submit valid rgw port (2)', () => { + formHelper.setValue('rgw_frontend_port', 65535); + component.onSubmit(); + formHelper.expectValid('rgw_frontend_port'); + }); + + it('should submit invalid rgw port (1)', () => { + formHelper.setValue('rgw_frontend_port', 0); + fixture.detectChanges(); + formHelper.expectError('rgw_frontend_port', 'min'); + }); + + it('should submit invalid rgw port (2)', () => { + formHelper.setValue('rgw_frontend_port', 65536); + fixture.detectChanges(); + formHelper.expectError('rgw_frontend_port', 'max'); + }); + + it('should submit invalid rgw port (3)', () => { + formHelper.setValue('rgw_frontend_port', 'abc'); + component.onSubmit(); + formHelper.expectError('rgw_frontend_port', 'pattern'); + }); + + it('should submit rgw w/o port', () => { + formHelper.setValue('ssl', false); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'rgw', + service_id: 'svc', + placement: {}, + unmanaged: false, + ssl: false + }); + }); + + it('should not show private key field', () => { + formHelper.setValue('ssl', true); + fixture.detectChanges(); + const ssl_key = fixture.debugElement.query(By.css('#ssl_key')); + expect(ssl_key).toBeNull(); + }); + + it('should test .pem file', () => { + const pemCert = ` +-----BEGIN CERTIFICATE----- +iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA== +-----END RSA PRIVATE KEY-----`; + formHelper.setValue('ssl', true); + formHelper.setValue('ssl_cert', pemCert); + fixture.detectChanges(); + formHelper.expectValid('ssl_cert'); + }); + }); + + describe('should test service iscsi', () => { + beforeEach(() => { + formHelper.setValue('service_type', 'iscsi'); + formHelper.setValue('pool', 'xyz'); + formHelper.setValue('api_user', 'user'); + formHelper.setValue('api_password', 'password'); + formHelper.setValue('ssl', false); + }); + + it('should submit iscsi', () => { + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'iscsi', + placement: {}, + unmanaged: false, + pool: 'xyz', + api_user: 'user', + api_password: 'password', + api_secure: false + }); + }); + + it('should submit iscsi with trusted ips', () => { + formHelper.setValue('ssl', true); + formHelper.setValue('trusted_ip_list', ' 172.16.0.5, 192.1.1.10 '); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'iscsi', + placement: {}, + unmanaged: false, + pool: 'xyz', + api_user: 'user', + api_password: 'password', + api_secure: true, + ssl_cert: '', + ssl_key: '', + trusted_ip_list: '172.16.0.5, 192.1.1.10' + }); + }); + + it('should submit iscsi with port', () => { + formHelper.setValue('api_port', 456); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'iscsi', + placement: {}, + unmanaged: false, + pool: 'xyz', + api_user: 'user', + api_password: 'password', + api_secure: false, + api_port: 456 + }); + }); + + it('should submit valid iscsi port (1)', () => { + formHelper.setValue('api_port', 1); + component.onSubmit(); + formHelper.expectValid('api_port'); + }); + + it('should submit valid iscsi port (2)', () => { + formHelper.setValue('api_port', 65535); + component.onSubmit(); + formHelper.expectValid('api_port'); + }); + + it('should submit invalid iscsi port (1)', () => { + formHelper.setValue('api_port', 0); + fixture.detectChanges(); + formHelper.expectError('api_port', 'min'); + }); + + it('should submit invalid iscsi port (2)', () => { + formHelper.setValue('api_port', 65536); + fixture.detectChanges(); + formHelper.expectError('api_port', 'max'); + }); + + it('should submit invalid iscsi port (3)', () => { + formHelper.setValue('api_port', 'abc'); + component.onSubmit(); + formHelper.expectError('api_port', 'pattern'); + }); + + it('should throw error when there is no pool', () => { + formHelper.expectErrorChange('pool', '', 'required'); + }); + }); + + describe('should test service ingress', () => { + beforeEach(() => { + formHelper.setValue('service_type', 'ingress'); + formHelper.setValue('backend_service', 'rgw.foo'); + formHelper.setValue('virtual_ip', '192.168.20.1/24'); + formHelper.setValue('ssl', false); + }); + + it('should submit ingress', () => { + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'ingress', + placement: {}, + unmanaged: false, + backend_service: 'rgw.foo', + service_id: 'rgw.foo', + virtual_ip: '192.168.20.1/24', + virtual_interface_networks: null, + ssl: false + }); + }); + + it('should pre-populate the service id', () => { + component.prePopulateId(); + const prePopulatedID = component.serviceForm.getValue('service_id'); + expect(prePopulatedID).toBe('rgw.foo'); + }); + + it('should submit valid frontend and monitor port', () => { + // min value + formHelper.setValue('frontend_port', 1); + formHelper.setValue('monitor_port', 1); + fixture.detectChanges(); + formHelper.expectValid('frontend_port'); + formHelper.expectValid('monitor_port'); + + // max value + formHelper.setValue('frontend_port', 65535); + formHelper.setValue('monitor_port', 65535); + fixture.detectChanges(); + formHelper.expectValid('frontend_port'); + formHelper.expectValid('monitor_port'); + }); + + it('should submit invalid frontend and monitor port', () => { + // min + formHelper.setValue('frontend_port', 0); + formHelper.setValue('monitor_port', 0); + fixture.detectChanges(); + formHelper.expectError('frontend_port', 'min'); + formHelper.expectError('monitor_port', 'min'); + + // max + formHelper.setValue('frontend_port', 65536); + formHelper.setValue('monitor_port', 65536); + fixture.detectChanges(); + formHelper.expectError('frontend_port', 'max'); + formHelper.expectError('monitor_port', 'max'); + + // pattern + formHelper.setValue('frontend_port', 'abc'); + formHelper.setValue('monitor_port', 'abc'); + component.onSubmit(); + formHelper.expectError('frontend_port', 'pattern'); + formHelper.expectError('monitor_port', 'pattern'); + }); + + it('should not show private key field with ssl enabled', () => { + formHelper.setValue('ssl', true); + fixture.detectChanges(); + const ssl_key = fixture.debugElement.query(By.css('#ssl_key')); + expect(ssl_key).toBeNull(); + }); + + it('should test .pem file with ssl enabled', () => { + const pemCert = ` +-----BEGIN CERTIFICATE----- +iJ5IbgzlKPssdYwuAEI3yPZxX/g5vKBrgcyD3LttLL/DlElq/1xCnwVrv7WROSNu +-----END CERTIFICATE----- +-----BEGIN CERTIFICATE----- +mn/S7BNBEC7AGe5ajmN+8hBTGdACUXe8rwMNrtTy/MwBZ0VpJsAAjJh+aptZh5yB +-----END CERTIFICATE----- +-----BEGIN RSA PRIVATE KEY----- +x4Ea7kGVgx9kWh5XjWz9wjZvY49UKIT5ppIAWPMbLl3UpfckiuNhTA== +-----END RSA PRIVATE KEY-----`; + formHelper.setValue('ssl', true); + formHelper.setValue('ssl_cert', pemCert); + fixture.detectChanges(); + formHelper.expectValid('ssl_cert'); + }); + }); + + describe('should test service snmp-gateway', () => { + beforeEach(() => { + formHelper.setValue('service_type', 'snmp-gateway'); + formHelper.setValue('snmp_destination', '192.168.20.1:8443'); + }); + + it('should test snmp-gateway service with V2c', () => { + formHelper.setValue('snmp_version', 'V2c'); + formHelper.setValue('snmp_community', 'public'); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'snmp-gateway', + placement: {}, + unmanaged: false, + snmp_version: 'V2c', + snmp_destination: '192.168.20.1:8443', + credentials: { + snmp_community: 'public' + } + }); + }); + + it('should test snmp-gateway service with V3', () => { + formHelper.setValue('snmp_version', 'V3'); + formHelper.setValue('engine_id', '800C53F00000'); + formHelper.setValue('auth_protocol', 'SHA'); + formHelper.setValue('privacy_protocol', 'DES'); + formHelper.setValue('snmp_v3_auth_username', 'testuser'); + formHelper.setValue('snmp_v3_auth_password', 'testpass'); + formHelper.setValue('snmp_v3_priv_password', 'testencrypt'); + component.onSubmit(); + expect(cephServiceService.create).toHaveBeenCalledWith({ + service_type: 'snmp-gateway', + placement: {}, + unmanaged: false, + snmp_version: 'V3', + snmp_destination: '192.168.20.1:8443', + engine_id: '800C53F00000', + auth_protocol: 'SHA', + privacy_protocol: 'DES', + credentials: { + snmp_v3_auth_username: 'testuser', + snmp_v3_auth_password: 'testpass', + snmp_v3_priv_password: 'testencrypt' + } + }); + }); + + it('should submit invalid snmp destination', () => { + formHelper.setValue('snmp_version', 'V2c'); + formHelper.setValue('snmp_destination', '192.168.20.1'); + formHelper.setValue('snmp_community', 'public'); + formHelper.expectError('snmp_destination', 'snmpDestinationPattern'); + }); + + it('should submit invalid snmp engine id', () => { + formHelper.setValue('snmp_version', 'V3'); + formHelper.setValue('snmp_destination', '192.168.20.1'); + formHelper.setValue('engine_id', 'AABBCCDDE'); + formHelper.setValue('auth_protocol', 'SHA'); + formHelper.setValue('privacy_protocol', 'DES'); + formHelper.setValue('snmp_v3_auth_username', 'testuser'); + formHelper.setValue('snmp_v3_auth_password', 'testpass'); + + formHelper.expectError('engine_id', 'snmpEngineIdPattern'); + }); + }); + + describe('check edit fields', () => { + beforeEach(() => { + component.editing = true; + }); + + it('should check whether edit field is correctly loaded', () => { + const cephServiceSpy = spyOn(cephServiceService, 'list').and.callThrough(); + component.ngOnInit(); + expect(cephServiceSpy).toBeCalledTimes(2); + expect(component.action).toBe('Edit'); + const serviceType = fixture.debugElement.query(By.css('#service_type')).nativeElement; + const serviceId = fixture.debugElement.query(By.css('#service_id')).nativeElement; + expect(serviceType.disabled).toBeTruthy(); + expect(serviceId.disabled).toBeTruthy(); + }); + }); + }); +}); |