diff options
Diffstat (limited to 'src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts')
-rw-r--r-- | src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts | 295 |
1 files changed, 295 insertions, 0 deletions
diff --git a/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts new file mode 100644 index 000000000..200a27615 --- /dev/null +++ b/src/pybind/mgr/dashboard/frontend/src/app/shared/components/config-option/config-option.component.spec.ts @@ -0,0 +1,295 @@ +import { HttpClientTestingModule } from '@angular/common/http/testing'; +import { ComponentFixture, TestBed } from '@angular/core/testing'; +import { ReactiveFormsModule } from '@angular/forms'; + +import { NgbPopoverModule } from '@ng-bootstrap/ng-bootstrap'; +import _ from 'lodash'; +import { of as observableOf } from 'rxjs'; + +import { ConfigurationService } from '~/app/shared/api/configuration.service'; +import { CdFormGroup } from '~/app/shared/forms/cd-form-group'; +import { configureTestBed } from '~/testing/unit-test-helper'; +import { HelperComponent } from '../helper/helper.component'; +import { ConfigOptionComponent } from './config-option.component'; + +describe('ConfigOptionComponent', () => { + let component: ConfigOptionComponent; + let fixture: ComponentFixture<ConfigOptionComponent>; + let configurationService: ConfigurationService; + let oNames: Array<string>; + + configureTestBed({ + declarations: [ConfigOptionComponent, HelperComponent], + imports: [NgbPopoverModule, ReactiveFormsModule, HttpClientTestingModule], + providers: [ConfigurationService] + }); + + beforeEach(() => { + fixture = TestBed.createComponent(ConfigOptionComponent); + component = fixture.componentInstance; + fixture.detectChanges(); + configurationService = TestBed.inject(ConfigurationService); + + const configOptions: Record<string, any> = [ + { + name: 'osd_scrub_auto_repair_num_errors', + type: 'uint', + level: 'advanced', + desc: 'Maximum number of detected errors to automatically repair', + long_desc: '', + default: 5, + daemon_default: '', + tags: [], + services: [], + see_also: ['osd_scrub_auto_repair'], + min: '', + max: '', + can_update_at_runtime: true, + flags: [] + }, + { + name: 'osd_debug_deep_scrub_sleep', + type: 'float', + level: 'dev', + desc: + 'Inject an expensive sleep during deep scrub IO to make it easier to induce preemption', + long_desc: '', + default: 0, + daemon_default: '', + tags: [], + services: [], + see_also: [], + min: '', + max: '', + can_update_at_runtime: true, + flags: [] + }, + { + name: 'osd_heartbeat_interval', + type: 'int', + level: 'advanced', + desc: 'Interval (in seconds) between peer pings', + long_desc: '', + default: 6, + daemon_default: '', + tags: [], + services: [], + see_also: [], + min: 1, + max: 86400, + can_update_at_runtime: true, + flags: [], + value: [ + { + section: 'osd', + value: 6 + } + ] + }, + { + name: 'bluestore_compression_algorithm', + type: 'str', + level: 'advanced', + desc: 'Default compression algorithm to use when writing object data', + long_desc: + 'This controls the default compressor to use (if any) if the ' + + 'per-pool property is not set. Note that zstd is *not* recommended for ' + + 'bluestore due to high CPU overhead when compressing small amounts of data.', + default: 'snappy', + daemon_default: '', + tags: [], + services: [], + see_also: [], + enum_values: ['', 'snappy', 'zlib', 'zstd', 'lz4'], + min: '', + max: '', + can_update_at_runtime: true, + flags: ['runtime'] + }, + { + name: 'rbd_discard_on_zeroed_write_same', + type: 'bool', + level: 'advanced', + desc: 'discard data on zeroed write same instead of writing zero', + long_desc: '', + default: true, + daemon_default: '', + tags: [], + services: ['rbd'], + see_also: [], + min: '', + max: '', + can_update_at_runtime: true, + flags: [] + }, + { + name: 'rbd_journal_max_payload_bytes', + type: 'size', + level: 'advanced', + desc: 'maximum journal payload size before splitting', + long_desc: '', + daemon_default: '', + tags: [], + services: ['rbd'], + see_also: [], + min: '', + max: '', + can_update_at_runtime: true, + flags: [], + default: '16384' + }, + { + name: 'cluster_addr', + type: 'addr', + level: 'basic', + desc: 'cluster-facing address to bind to', + long_desc: '', + daemon_default: '', + tags: ['network'], + services: ['osd'], + see_also: [], + min: '', + max: '', + can_update_at_runtime: false, + flags: [], + default: '-' + }, + { + name: 'fsid', + type: 'uuid', + level: 'basic', + desc: 'cluster fsid (uuid)', + long_desc: '', + daemon_default: '', + tags: ['service'], + services: ['common'], + see_also: [], + min: '', + max: '', + can_update_at_runtime: false, + flags: ['no_mon_update'], + default: '00000000-0000-0000-0000-000000000000' + }, + { + name: 'mgr_tick_period', + type: 'secs', + level: 'advanced', + desc: 'Period in seconds of beacon messages to monitor', + long_desc: '', + daemon_default: '', + tags: [], + services: ['mgr'], + see_also: [], + min: '', + max: '', + can_update_at_runtime: true, + flags: [], + default: '2' + } + ]; + + spyOn(configurationService, 'filter').and.returnValue(observableOf(configOptions)); + oNames = _.map(configOptions, 'name'); + component.optionNames = oNames; + component.optionsForm = new CdFormGroup({}); + component.optionsFormGroupName = 'testFormGroupName'; + component.ngOnInit(); + }); + + it('should create', () => { + expect(component).toBeTruthy(); + }); + + describe('optionNameToText', () => { + it('should format config option names correctly', () => { + const configOptionNames = { + osd_scrub_auto_repair_num_errors: 'Scrub Auto Repair Num Errors', + osd_debug_deep_scrub_sleep: 'Debug Deep Scrub Sleep', + osd_heartbeat_interval: 'Heartbeat Interval', + bluestore_compression_algorithm: 'Bluestore Compression Algorithm', + rbd_discard_on_zeroed_write_same: 'Rbd Discard On Zeroed Write Same', + rbd_journal_max_payload_bytes: 'Rbd Journal Max Payload Bytes', + cluster_addr: 'Cluster Addr', + fsid: 'Fsid', + mgr_tick_period: 'Tick Period' + }; + + component.options.forEach((option) => { + expect(option.text).toEqual(configOptionNames[option.name]); + }); + }); + }); + + describe('createForm', () => { + it('should set the optionsFormGroupName correctly', () => { + expect(component.optionsFormGroupName).toEqual('testFormGroupName'); + }); + + it('should create a FormControl for every config option', () => { + component.options.forEach((option) => { + expect(Object.keys(component.optionsFormGroup.controls)).toContain(option.name); + }); + }); + }); + + describe('loadStorageData', () => { + it('should create a list of config options by names', () => { + expect(component.options.length).toEqual(9); + + component.options.forEach((option) => { + expect(oNames).toContain(option.name); + }); + }); + + it('should add all needed attributes to every config option', () => { + component.options.forEach((option) => { + const optionKeys = Object.keys(option); + expect(optionKeys).toContain('text'); + expect(optionKeys).toContain('additionalTypeInfo'); + expect(optionKeys).toContain('value'); + + if (option.type !== 'bool' && option.type !== 'str') { + expect(optionKeys).toContain('patternHelpText'); + } + + if (option.name === 'osd_heartbeat_interval') { + expect(optionKeys).toContain('maxValue'); + expect(optionKeys).toContain('minValue'); + } + }); + }); + + it('should set minValue and maxValue correctly', () => { + component.options.forEach((option) => { + if (option.name === 'osd_heartbeat_interval') { + expect(option.minValue).toEqual(1); + expect(option.maxValue).toEqual(86400); + } + }); + }); + + it('should set the value attribute correctly', () => { + component.options.forEach((option) => { + if (option.name === 'osd_heartbeat_interval') { + const value = option.value; + expect(value).toBeDefined(); + expect(value).toEqual({ section: 'osd', value: 6 }); + } else { + expect(option.value).toBeUndefined(); + } + }); + }); + + it('should set the FormControl value correctly', () => { + component.options.forEach((option) => { + const value = component.optionsFormGroup.getValue(option.name); + if (option.name === 'osd_heartbeat_interval') { + expect(value).toBeDefined(); + expect(value).toEqual(6); + } else { + expect(value).toBeNull(); + } + }); + }); + }); +}); |