1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, TestBed } from '@angular/core/testing';
3 import { ReactiveFormsModule } from '@angular/forms';
5 import * as _ from 'lodash';
6 import { PopoverModule } from 'ngx-bootstrap/popover';
7 import { of as observableOf } from 'rxjs';
9 import { configureTestBed } from '../../../../testing/unit-test-helper';
10 import { ConfigurationService } from '../../api/configuration.service';
11 import { CdFormGroup } from '../../forms/cd-form-group';
12 import { HelperComponent } from '../helper/helper.component';
13 import { ConfigOptionComponent } from './config-option.component';
15 describe('ConfigOptionComponent', () => {
16 let component: ConfigOptionComponent;
17 let fixture: ComponentFixture<ConfigOptionComponent>;
18 let configurationService: ConfigurationService;
19 let oNames: Array<string>;
22 declarations: [ConfigOptionComponent, HelperComponent],
23 imports: [PopoverModule.forRoot(), ReactiveFormsModule, HttpClientTestingModule],
24 providers: [ConfigurationService]
28 fixture = TestBed.createComponent(ConfigOptionComponent);
29 component = fixture.componentInstance;
30 fixture.detectChanges();
31 configurationService = TestBed.get(ConfigurationService);
33 const configOptions: Record<string, any> = [
35 name: 'osd_scrub_auto_repair_num_errors',
38 desc: 'Maximum number of detected errors to automatically repair',
44 see_also: ['osd_scrub_auto_repair'],
47 can_update_at_runtime: true,
51 name: 'osd_debug_deep_scrub_sleep',
55 'Inject an expensive sleep during deep scrub IO to make it easier to induce preemption',
64 can_update_at_runtime: true,
68 name: 'osd_heartbeat_interval',
71 desc: 'Interval (in seconds) between peer pings',
80 can_update_at_runtime: true,
90 name: 'bluestore_compression_algorithm',
93 desc: 'Default compression algorithm to use when writing object data',
95 'This controls the default compressor to use (if any) if the ' +
96 'per-pool property is not set. Note that zstd is *not* recommended for ' +
97 'bluestore due to high CPU overhead when compressing small amounts of data.',
103 enum_values: ['', 'snappy', 'zlib', 'zstd', 'lz4'],
106 can_update_at_runtime: true,
110 name: 'rbd_discard_on_zeroed_write_same',
113 desc: 'discard data on zeroed write same instead of writing zero',
122 can_update_at_runtime: true,
126 name: 'rbd_journal_max_payload_bytes',
129 desc: 'maximum journal payload size before splitting',
137 can_update_at_runtime: true,
142 name: 'cluster_addr',
145 desc: 'cluster-facing address to bind to',
153 can_update_at_runtime: false,
161 desc: 'cluster fsid (uuid)',
165 services: ['common'],
169 can_update_at_runtime: false,
170 flags: ['no_mon_update'],
171 default: '00000000-0000-0000-0000-000000000000'
174 name: 'mgr_tick_period',
177 desc: 'Period in seconds of beacon messages to monitor',
185 can_update_at_runtime: true,
191 spyOn(configurationService, 'filter').and.returnValue(observableOf(configOptions));
192 oNames = _.map(configOptions, 'name');
193 component.optionNames = oNames;
194 component.optionsForm = new CdFormGroup({});
195 component.optionsFormGroupName = 'testFormGroupName';
196 component.ngOnInit();
199 it('should create', () => {
200 expect(component).toBeTruthy();
203 describe('optionNameToText', () => {
204 it('should format config option names correctly', () => {
205 const configOptionNames = {
206 osd_scrub_auto_repair_num_errors: 'Scrub Auto Repair Num Errors',
207 osd_debug_deep_scrub_sleep: 'Debug Deep Scrub Sleep',
208 osd_heartbeat_interval: 'Heartbeat Interval',
209 bluestore_compression_algorithm: 'Bluestore Compression Algorithm',
210 rbd_discard_on_zeroed_write_same: 'Rbd Discard On Zeroed Write Same',
211 rbd_journal_max_payload_bytes: 'Rbd Journal Max Payload Bytes',
212 cluster_addr: 'Cluster Addr',
214 mgr_tick_period: 'Tick Period'
217 component.options.forEach((option) => {
218 expect(option.text).toEqual(configOptionNames[option.name]);
223 describe('createForm', () => {
224 it('should set the optionsFormGroupName correctly', () => {
225 expect(component.optionsFormGroupName).toEqual('testFormGroupName');
228 it('should create a FormControl for every config option', () => {
229 component.options.forEach((option) => {
230 expect(Object.keys(component.optionsFormGroup.controls)).toContain(option.name);
235 describe('loadStorageData', () => {
236 it('should create a list of config options by names', () => {
237 expect(component.options.length).toEqual(9);
239 component.options.forEach((option) => {
240 expect(oNames).toContain(option.name);
244 it('should add all needed attributes to every config option', () => {
245 component.options.forEach((option) => {
246 const optionKeys = Object.keys(option);
247 expect(optionKeys).toContain('text');
248 expect(optionKeys).toContain('additionalTypeInfo');
249 expect(optionKeys).toContain('value');
251 if (option.type !== 'bool' && option.type !== 'str') {
252 expect(optionKeys).toContain('patternHelpText');
255 if (option.name === 'osd_heartbeat_interval') {
256 expect(optionKeys).toContain('maxValue');
257 expect(optionKeys).toContain('minValue');
262 it('should set minValue and maxValue correctly', () => {
263 component.options.forEach((option) => {
264 if (option.name === 'osd_heartbeat_interval') {
265 expect(option.minValue).toEqual(1);
266 expect(option.maxValue).toEqual(86400);
271 it('should set the value attribute correctly', () => {
272 component.options.forEach((option) => {
273 if (option.name === 'osd_heartbeat_interval') {
274 const value = option.value;
275 expect(value).toBeDefined();
276 expect(value).toEqual({ section: 'osd', value: 6 });
278 expect(option.value).toBeUndefined();
283 it('should set the FormControl value correctly', () => {
284 component.options.forEach((option) => {
285 const value = component.optionsFormGroup.getValue(option.name);
286 if (option.name === 'osd_heartbeat_interval') {
287 expect(value).toBeDefined();
288 expect(value).toEqual(6);
290 expect(value).toBeNull();