]>
Commit | Line | Data |
---|---|---|
81eedcae TL |
1 | import { HttpClientTestingModule } from '@angular/common/http/testing'; |
2 | import { ComponentFixture, TestBed } from '@angular/core/testing'; | |
3 | import { ReactiveFormsModule } from '@angular/forms'; | |
4 | ||
5 | import * as _ from 'lodash'; | |
6 | import { PopoverModule } from 'ngx-bootstrap/popover'; | |
7 | import { of as observableOf } from 'rxjs'; | |
8 | ||
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'; | |
14 | ||
15 | describe('ConfigOptionComponent', () => { | |
16 | let component: ConfigOptionComponent; | |
17 | let fixture: ComponentFixture<ConfigOptionComponent>; | |
18 | let configurationService: ConfigurationService; | |
19 | let oNames: Array<string>; | |
20 | ||
21 | configureTestBed({ | |
22 | declarations: [ConfigOptionComponent, HelperComponent], | |
23 | imports: [PopoverModule.forRoot(), ReactiveFormsModule, HttpClientTestingModule], | |
24 | providers: [ConfigurationService] | |
25 | }); | |
26 | ||
27 | beforeEach(() => { | |
28 | fixture = TestBed.createComponent(ConfigOptionComponent); | |
29 | component = fixture.componentInstance; | |
30 | fixture.detectChanges(); | |
31 | configurationService = TestBed.get(ConfigurationService); | |
32 | ||
9f95a23c | 33 | const configOptions: Record<string, any> = [ |
81eedcae TL |
34 | { |
35 | name: 'osd_scrub_auto_repair_num_errors', | |
36 | type: 'uint', | |
37 | level: 'advanced', | |
38 | desc: 'Maximum number of detected errors to automatically repair', | |
39 | long_desc: '', | |
40 | default: 5, | |
41 | daemon_default: '', | |
42 | tags: [], | |
43 | services: [], | |
44 | see_also: ['osd_scrub_auto_repair'], | |
45 | min: '', | |
46 | max: '', | |
47 | can_update_at_runtime: true, | |
48 | flags: [] | |
49 | }, | |
50 | { | |
51 | name: 'osd_debug_deep_scrub_sleep', | |
52 | type: 'float', | |
53 | level: 'dev', | |
54 | desc: | |
55 | 'Inject an expensive sleep during deep scrub IO to make it easier to induce preemption', | |
56 | long_desc: '', | |
57 | default: 0, | |
58 | daemon_default: '', | |
59 | tags: [], | |
60 | services: [], | |
61 | see_also: [], | |
62 | min: '', | |
63 | max: '', | |
64 | can_update_at_runtime: true, | |
65 | flags: [] | |
66 | }, | |
67 | { | |
68 | name: 'osd_heartbeat_interval', | |
69 | type: 'int', | |
70 | level: 'advanced', | |
71 | desc: 'Interval (in seconds) between peer pings', | |
72 | long_desc: '', | |
73 | default: 6, | |
74 | daemon_default: '', | |
75 | tags: [], | |
76 | services: [], | |
77 | see_also: [], | |
78 | min: 1, | |
79 | max: 86400, | |
80 | can_update_at_runtime: true, | |
81 | flags: [], | |
82 | value: [ | |
83 | { | |
84 | section: 'osd', | |
85 | value: 6 | |
86 | } | |
87 | ] | |
88 | }, | |
89 | { | |
90 | name: 'bluestore_compression_algorithm', | |
91 | type: 'str', | |
92 | level: 'advanced', | |
93 | desc: 'Default compression algorithm to use when writing object data', | |
94 | long_desc: | |
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.', | |
98 | default: 'snappy', | |
99 | daemon_default: '', | |
100 | tags: [], | |
101 | services: [], | |
102 | see_also: [], | |
103 | enum_values: ['', 'snappy', 'zlib', 'zstd', 'lz4'], | |
104 | min: '', | |
105 | max: '', | |
106 | can_update_at_runtime: true, | |
107 | flags: ['runtime'] | |
108 | }, | |
109 | { | |
110 | name: 'rbd_discard_on_zeroed_write_same', | |
111 | type: 'bool', | |
112 | level: 'advanced', | |
113 | desc: 'discard data on zeroed write same instead of writing zero', | |
114 | long_desc: '', | |
115 | default: true, | |
116 | daemon_default: '', | |
117 | tags: [], | |
118 | services: ['rbd'], | |
119 | see_also: [], | |
120 | min: '', | |
121 | max: '', | |
122 | can_update_at_runtime: true, | |
123 | flags: [] | |
124 | }, | |
125 | { | |
126 | name: 'rbd_journal_max_payload_bytes', | |
127 | type: 'size', | |
128 | level: 'advanced', | |
129 | desc: 'maximum journal payload size before splitting', | |
130 | long_desc: '', | |
131 | daemon_default: '', | |
132 | tags: [], | |
133 | services: ['rbd'], | |
134 | see_also: [], | |
135 | min: '', | |
136 | max: '', | |
137 | can_update_at_runtime: true, | |
138 | flags: [], | |
139 | default: '16384' | |
140 | }, | |
141 | { | |
142 | name: 'cluster_addr', | |
143 | type: 'addr', | |
144 | level: 'basic', | |
145 | desc: 'cluster-facing address to bind to', | |
146 | long_desc: '', | |
147 | daemon_default: '', | |
148 | tags: ['network'], | |
149 | services: ['osd'], | |
150 | see_also: [], | |
151 | min: '', | |
152 | max: '', | |
153 | can_update_at_runtime: false, | |
154 | flags: [], | |
155 | default: '-' | |
156 | }, | |
157 | { | |
158 | name: 'fsid', | |
159 | type: 'uuid', | |
160 | level: 'basic', | |
161 | desc: 'cluster fsid (uuid)', | |
162 | long_desc: '', | |
163 | daemon_default: '', | |
164 | tags: ['service'], | |
165 | services: ['common'], | |
166 | see_also: [], | |
167 | min: '', | |
168 | max: '', | |
169 | can_update_at_runtime: false, | |
170 | flags: ['no_mon_update'], | |
171 | default: '00000000-0000-0000-0000-000000000000' | |
172 | }, | |
173 | { | |
174 | name: 'mgr_tick_period', | |
175 | type: 'secs', | |
176 | level: 'advanced', | |
177 | desc: 'Period in seconds of beacon messages to monitor', | |
178 | long_desc: '', | |
179 | daemon_default: '', | |
180 | tags: [], | |
181 | services: ['mgr'], | |
182 | see_also: [], | |
183 | min: '', | |
184 | max: '', | |
185 | can_update_at_runtime: true, | |
186 | flags: [], | |
187 | default: '2' | |
188 | } | |
189 | ]; | |
190 | ||
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(); | |
197 | }); | |
198 | ||
199 | it('should create', () => { | |
200 | expect(component).toBeTruthy(); | |
201 | }); | |
202 | ||
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', | |
213 | fsid: 'Fsid', | |
214 | mgr_tick_period: 'Tick Period' | |
215 | }; | |
216 | ||
217 | component.options.forEach((option) => { | |
218 | expect(option.text).toEqual(configOptionNames[option.name]); | |
219 | }); | |
220 | }); | |
221 | }); | |
222 | ||
223 | describe('createForm', () => { | |
224 | it('should set the optionsFormGroupName correctly', () => { | |
225 | expect(component.optionsFormGroupName).toEqual('testFormGroupName'); | |
226 | }); | |
227 | ||
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); | |
231 | }); | |
232 | }); | |
233 | }); | |
234 | ||
235 | describe('loadStorageData', () => { | |
236 | it('should create a list of config options by names', () => { | |
237 | expect(component.options.length).toEqual(9); | |
238 | ||
239 | component.options.forEach((option) => { | |
240 | expect(oNames).toContain(option.name); | |
241 | }); | |
242 | }); | |
243 | ||
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'); | |
250 | ||
251 | if (option.type !== 'bool' && option.type !== 'str') { | |
252 | expect(optionKeys).toContain('patternHelpText'); | |
253 | } | |
254 | ||
255 | if (option.name === 'osd_heartbeat_interval') { | |
256 | expect(optionKeys).toContain('maxValue'); | |
257 | expect(optionKeys).toContain('minValue'); | |
258 | } | |
259 | }); | |
260 | }); | |
261 | ||
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); | |
267 | } | |
268 | }); | |
269 | }); | |
270 | ||
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 }); | |
277 | } else { | |
278 | expect(option.value).toBeUndefined(); | |
279 | } | |
280 | }); | |
281 | }); | |
282 | ||
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); | |
289 | } else { | |
290 | expect(value).toBeNull(); | |
291 | } | |
292 | }); | |
293 | }); | |
294 | }); | |
295 | }); |