diff options
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts')
-rwxr-xr-x | src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts | 317 |
1 files changed, 317 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts new file mode 100755 index 000000000..f8b72940b --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/ceph/cluster/osd/osd-recv-speed-modal/osd-recv-speed-modal.component.spec.ts @@ -0,0 +1,317 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ReactiveFormsModule } from '@angular/forms'; +import { RouterTestingModule } from '@angular/router/testing'; + +import { NgbActiveModal } from '@ng-bootstrap/ng-bootstrap'; +import _ from 'lodash'; +import { ToastrModule } from 'ngx-toastr'; +import { of as observableOf } from 'rxjs'; + +import { ConfigurationService } from '~/app/shared/api/configuration.service'; +import { SharedModule } from '~/app/shared/shared.module'; +import { configureTestBed } from '~/testing/unit-test-helper'; +import { OsdRecvSpeedModalComponent } from './osd-recv-speed-modal.component'; + +describe('OsdRecvSpeedModalComponent', () => { + let component: OsdRecvSpeedModalComponent; + let fixture: ComponentFixture<OsdRecvSpeedModalComponent>; + let configurationService: ConfigurationService; + + configureTestBed({ + imports: [ + HttpClientTestingModule, + ReactiveFormsModule, + RouterTestingModule, + SharedModule, + ToastrModule.forRoot() + ], + declarations: [OsdRecvSpeedModalComponent], + providers: [NgbActiveModal] + }); + + let configOptions: any[] = []; + + beforeEach(() => { + fixture = TestBed.createComponent(OsdRecvSpeedModalComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + configurationService = TestBed.inject(ConfigurationService); + configOptions = [ + { + name: 'osd_max_backfills', + desc: '', + type: 'uint', + default: 1 + }, + { + name: 'osd_recovery_max_active', + desc: '', + type: 'uint', + default: 3 + }, + { + name: 'osd_recovery_max_single_start', + desc: '', + type: 'uint', + default: 1 + }, + { + name: 'osd_recovery_sleep', + desc: 'Time in seconds to sleep before next recovery or backfill op', + type: 'float', + default: 0 + } + ]; + spyOn(configurationService, 'filter').and.returnValue(observableOf(configOptions)); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('ngOnInit', () => { + let setPriority: jasmine.Spy; + let setValidators: jasmine.Spy; + + beforeEach(() => { + setPriority = spyOn(component, 'setPriority').and.callThrough(); + setValidators = spyOn(component, 'setValidators').and.callThrough(); + component.ngOnInit(); + }); + + it('should call setValidators', () => { + expect(setValidators).toHaveBeenCalled(); + }); + + it('should get and set priority correctly', () => { + const defaultPriority = _.find(component.priorities, (p) => { + return _.isEqual(p.name, 'default'); + }); + expect(setPriority).toHaveBeenCalledWith(defaultPriority); + }); + + it('should set descriptions correctly', () => { + expect(component.priorityAttrs['osd_max_backfills'].desc).toBe(''); + expect(component.priorityAttrs['osd_recovery_max_active'].desc).toBe(''); + expect(component.priorityAttrs['osd_recovery_max_single_start'].desc).toBe(''); + expect(component.priorityAttrs['osd_recovery_sleep'].desc).toBe( + 'Time in seconds to sleep before next recovery or backfill op' + ); + }); + }); + + describe('setPriority', () => { + it('should prepare the form for a custom priority', () => { + const customPriority = { + name: 'custom', + text: 'Custom', + values: { + osd_max_backfills: 1, + osd_recovery_max_active: 4, + osd_recovery_max_single_start: 1, + osd_recovery_sleep: 1 + } + }; + + component.setPriority(customPriority); + + const customInPriorities = _.find(component.priorities, (p) => { + return p.name === 'custom'; + }); + + expect(customInPriorities).not.toBeNull(); + expect(component.osdRecvSpeedForm.getValue('priority')).toBe('custom'); + expect(component.osdRecvSpeedForm.getValue('osd_max_backfills')).toBe(1); + expect(component.osdRecvSpeedForm.getValue('osd_recovery_max_active')).toBe(4); + expect(component.osdRecvSpeedForm.getValue('osd_recovery_max_single_start')).toBe(1); + expect(component.osdRecvSpeedForm.getValue('osd_recovery_sleep')).toBe(1); + }); + + it('should prepare the form for a none custom priority', () => { + const lowPriority = { + name: 'low', + text: 'Low', + values: { + osd_max_backfills: 1, + osd_recovery_max_active: 1, + osd_recovery_max_single_start: 1, + osd_recovery_sleep: 0.5 + } + }; + + component.setPriority(lowPriority); + + const customInPriorities = _.find(component.priorities, (p) => { + return p.name === 'custom'; + }); + + expect(customInPriorities).toBeUndefined(); + expect(component.osdRecvSpeedForm.getValue('priority')).toBe('low'); + expect(component.osdRecvSpeedForm.getValue('osd_max_backfills')).toBe(1); + expect(component.osdRecvSpeedForm.getValue('osd_recovery_max_active')).toBe(1); + expect(component.osdRecvSpeedForm.getValue('osd_recovery_max_single_start')).toBe(1); + expect(component.osdRecvSpeedForm.getValue('osd_recovery_sleep')).toBe(0.5); + }); + }); + + describe('detectPriority', () => { + const configOptionsLow = { + osd_max_backfills: 1, + osd_recovery_max_active: 1, + osd_recovery_max_single_start: 1, + osd_recovery_sleep: 0.5 + }; + + const configOptionsDefault = { + osd_max_backfills: 1, + osd_recovery_max_active: 3, + osd_recovery_max_single_start: 1, + osd_recovery_sleep: 0 + }; + + const configOptionsHigh = { + osd_max_backfills: 4, + osd_recovery_max_active: 4, + osd_recovery_max_single_start: 4, + osd_recovery_sleep: 0 + }; + + const configOptionsCustom = { + osd_max_backfills: 1, + osd_recovery_max_active: 2, + osd_recovery_max_single_start: 1, + osd_recovery_sleep: 0 + }; + + const configOptionsIncomplete = { + osd_max_backfills: 1, + osd_recovery_max_single_start: 1, + osd_recovery_sleep: 0 + }; + + it('should return priority "low" if the config option values have been set accordingly', () => { + component.detectPriority(configOptionsLow, (priority: Record<string, any>) => { + expect(priority.name).toBe('low'); + }); + expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeFalsy(); + }); + + it('should return priority "default" if the config option values have been set accordingly', () => { + component.detectPriority(configOptionsDefault, (priority: Record<string, any>) => { + expect(priority.name).toBe('default'); + }); + expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeFalsy(); + }); + + it('should return priority "high" if the config option values have been set accordingly', () => { + component.detectPriority(configOptionsHigh, (priority: Record<string, any>) => { + expect(priority.name).toBe('high'); + }); + expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeFalsy(); + }); + + it('should return priority "custom" if the config option values do not match any priority', () => { + component.detectPriority(configOptionsCustom, (priority: Record<string, any>) => { + expect(priority.name).toBe('custom'); + }); + expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeTruthy(); + }); + + it('should return no priority if the config option values are incomplete', () => { + component.detectPriority(configOptionsIncomplete, (priority: Record<string, any>) => { + expect(priority.name).toBeNull(); + }); + expect(component.osdRecvSpeedForm.getValue('customizePriority')).toBeFalsy(); + }); + }); + + describe('getCurrentValues', () => { + it('should return default values if no value has been set by the user', () => { + const currentValues = component.getCurrentValues(configOptions); + configOptions.forEach((configOption) => { + const configOptionValue = currentValues.values[configOption.name]; + expect(configOptionValue).toBe(configOption.default); + }); + }); + + it('should return the values set by the user if they exist', () => { + configOptions.forEach((configOption) => { + configOption['value'] = [{ section: 'osd', value: 7 }]; + }); + + const currentValues = component.getCurrentValues(configOptions); + Object.values(currentValues.values).forEach((configValue) => { + expect(configValue).toBe(7); + }); + }); + + it('should return the default value if one is missing', () => { + for (let i = 1; i < configOptions.length; i++) { + configOptions[i]['value'] = [{ section: 'osd', value: 7 }]; + } + + const currentValues = component.getCurrentValues(configOptions); + Object.entries(currentValues.values).forEach(([configName, configValue]) => { + if (configName === 'osd_max_backfills') { + expect(configValue).toBe(1); + } else { + expect(configValue).toBe(7); + } + }); + }); + + it('should return nothing if neither value nor default value is given', () => { + configOptions[0].default = null; + const currentValues = component.getCurrentValues(configOptions); + expect(currentValues.values).not.toContain('osd_max_backfills'); + }); + }); + + describe('setDescription', () => { + it('should set the description if one is given', () => { + component.setDescription(configOptions); + Object.keys(component.priorityAttrs).forEach((configOptionName) => { + if (configOptionName === 'osd_recovery_sleep') { + expect(component.priorityAttrs[configOptionName].desc).toBe( + 'Time in seconds to sleep before next recovery or backfill op' + ); + } else { + expect(component.priorityAttrs[configOptionName].desc).toBe(''); + } + }); + }); + }); + + describe('setValidators', () => { + it('should set needed validators for config option', () => { + component.setValidators(configOptions); + configOptions.forEach((configOption) => { + const control = component.osdRecvSpeedForm.controls[configOption.name]; + + if (configOption.type === 'float') { + expect(component.priorityAttrs[configOption.name].patternHelpText).toBe( + 'The entered value needs to be a number or decimal.' + ); + } else { + expect(component.priorityAttrs[configOption.name].minValue).toBe(0); + expect(component.priorityAttrs[configOption.name].patternHelpText).toBe( + 'The entered value needs to be an unsigned number.' + ); + + control.setValue(-1); + expect(control.hasError('min')).toBeTruthy(); + } + + control.setValue(null); + expect(control.hasError('required')).toBeTruthy(); + control.setValue('E'); + expect(control.hasError('pattern')).toBeTruthy(); + control.setValue(3); + expect(control.hasError('required')).toBeFalsy(); + expect(control.hasError('min')).toBeFalsy(); + expect(control.hasError('pattern')).toBeFalsy(); + }); + }); + }); +}); |