1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, TestBed } from '@angular/core/testing';
3 import { By } from '@angular/platform-browser';
4 import { RouterTestingModule } from '@angular/router/testing';
6 import { ToastModule } from 'ng2-toastr';
7 import { BsModalRef } from 'ngx-bootstrap/modal';
8 import { of } from 'rxjs';
15 } from '../../../../testing/unit-test-helper';
16 import { ErasureCodeProfileService } from '../../../shared/api/erasure-code-profile.service';
17 import { ErasureCodeProfile } from '../../../shared/models/erasure-code-profile';
18 import { TaskWrapperService } from '../../../shared/services/task-wrapper.service';
19 import { PoolModule } from '../pool.module';
20 import { ErasureCodeProfileFormComponent } from './erasure-code-profile-form.component';
22 describe('ErasureCodeProfileFormComponent', () => {
23 let component: ErasureCodeProfileFormComponent;
24 let ecpService: ErasureCodeProfileService;
25 let fixture: ComponentFixture<ErasureCodeProfileFormComponent>;
26 let formHelper: FormHelper;
27 let fixtureHelper: FixtureHelper;
31 imports: [HttpClientTestingModule, RouterTestingModule, ToastModule.forRoot(), PoolModule],
32 providers: [ErasureCodeProfileService, BsModalRef, i18nProviders]
36 fixture = TestBed.createComponent(ErasureCodeProfileFormComponent);
37 fixtureHelper = new FixtureHelper(fixture);
38 component = fixture.componentInstance;
39 formHelper = new FormHelper(component.form);
40 ecpService = TestBed.get(ErasureCodeProfileService);
42 failure_domains: ['host', 'osd'],
43 plugins: ['isa', 'jerasure', 'shec', 'lrc'],
44 names: ['ecp1', 'ecp2'],
45 devices: ['ssd', 'hdd']
47 spyOn(ecpService, 'getInfo').and.callFake(() => of(data));
48 fixture.detectChanges();
51 it('should create', () => {
52 expect(component).toBeTruthy();
55 it('calls listing to get ecps on ngInit', () => {
56 expect(ecpService.getInfo).toHaveBeenCalled();
57 expect(component.names.length).toBe(2);
60 describe('form validation', () => {
61 it(`isn't valid if name is not set`, () => {
62 expect(component.form.invalid).toBeTruthy();
63 formHelper.setValue('name', 'someProfileName');
64 expect(component.form.valid).toBeTruthy();
67 it('sets name invalid', () => {
68 component.names = ['awesomeProfileName'];
69 formHelper.expectErrorChange('name', 'awesomeProfileName', 'uniqueName');
70 formHelper.expectErrorChange('name', 'some invalid text', 'pattern');
71 formHelper.expectErrorChange('name', null, 'required');
74 it('sets k to min error', () => {
75 formHelper.expectErrorChange('k', 0, 'min');
78 it('sets m to min error', () => {
79 formHelper.expectErrorChange('m', 0, 'min');
82 it(`should show all default form controls`, () => {
83 const showDefaults = (plugin) => {
84 formHelper.setValue('plugin', plugin);
85 fixtureHelper.expectIdElementsVisible(
99 showDefaults('jerasure');
100 showDefaults('shec');
105 describe(`for 'jerasure' plugin (default)`, () => {
106 it(`requires 'm' and 'k'`, () => {
107 formHelper.expectErrorChange('k', null, 'required');
108 formHelper.expectErrorChange('m', null, 'required');
111 it(`should show 'packetSize' and 'technique'`, () => {
112 fixtureHelper.expectIdElementsVisible(['packetSize', 'technique'], true);
115 it(`should not show any other plugin specific form control`, () => {
116 fixtureHelper.expectIdElementsVisible(['c', 'l', 'crushLocality'], false);
120 describe(`for 'isa' plugin`, () => {
122 formHelper.setValue('plugin', 'isa');
125 it(`does not require 'm' and 'k'`, () => {
126 formHelper.setValue('k', null);
127 formHelper.expectValidChange('k', null);
128 formHelper.expectValidChange('m', null);
131 it(`should show 'technique'`, () => {
132 fixtureHelper.expectIdElementsVisible(['technique'], true);
133 expect(fixture.debugElement.query(By.css('#technique'))).toBeTruthy();
136 it(`should not show any other plugin specific form control`, () => {
137 fixtureHelper.expectIdElementsVisible(['c', 'l', 'crushLocality', 'packetSize'], false);
141 describe(`for 'lrc' plugin`, () => {
143 formHelper.setValue('plugin', 'lrc');
146 it(`requires 'm', 'l' and 'k'`, () => {
147 formHelper.expectErrorChange('k', null, 'required');
148 formHelper.expectErrorChange('m', null, 'required');
151 it(`should show 'l' and 'crushLocality'`, () => {
152 fixtureHelper.expectIdElementsVisible(['l', 'crushLocality'], true);
155 it(`should not show any other plugin specific form control`, () => {
156 fixtureHelper.expectIdElementsVisible(['c', 'packetSize', 'technique'], false);
160 describe(`for 'shec' plugin`, () => {
162 formHelper.setValue('plugin', 'shec');
165 it(`does not require 'm' and 'k'`, () => {
166 formHelper.expectValidChange('k', null);
167 formHelper.expectValidChange('m', null);
170 it(`should show 'c'`, () => {
171 fixtureHelper.expectIdElementsVisible(['c'], true);
174 it(`should not show any other plugin specific form control`, () => {
175 fixtureHelper.expectIdElementsVisible(
176 ['l', 'crushLocality', 'packetSize', 'technique'],
183 describe('submission', () => {
184 let ecp: ErasureCodeProfile;
186 const testCreation = () => {
187 fixture.detectChanges();
188 component.onSubmit();
189 expect(ecpService.create).toHaveBeenCalledWith(ecp);
193 ecp = new ErasureCodeProfile();
194 const taskWrapper = TestBed.get(TaskWrapperService);
195 spyOn(taskWrapper, 'wrapTaskAroundCall').and.callThrough();
196 spyOn(ecpService, 'create').and.stub();
199 describe(`'jerasure' usage`, () => {
201 ecp.name = 'jerasureProfile';
204 it('should be able to create a profile with only required fields', () => {
205 formHelper.setMultipleValues(ecp, true);
211 it(`does not create with missing 'k' or invalid form`, () => {
213 formHelper.setMultipleValues(ecp, true);
214 component.onSubmit();
215 expect(ecpService.create).not.toHaveBeenCalled();
218 it('should be able to create a profile with m, k, name, directory and packetSize', () => {
220 ecp.directory = '/different/ecp/path';
221 formHelper.setMultipleValues(ecp, true);
223 formHelper.setValue('packetSize', 8192, true);
224 ecp.packetsize = 8192;
228 it('should not send the profile with unsupported fields', () => {
229 formHelper.setMultipleValues(ecp, true);
232 formHelper.setValue('crushLocality', 'osd', true);
237 describe(`'isa' usage`, () => {
239 ecp.name = 'isaProfile';
243 it('should be able to create a profile with only plugin and name', () => {
244 formHelper.setMultipleValues(ecp, true);
248 it('should send profile with plugin, name, failure domain and technique only', () => {
249 ecp.technique = 'cauchy';
250 formHelper.setMultipleValues(ecp, true);
251 formHelper.setValue('crushFailureDomain', 'osd', true);
252 ecp['crush-failure-domain'] = 'osd';
256 it('should not send the profile with unsupported fields', () => {
257 formHelper.setMultipleValues(ecp, true);
258 formHelper.setValue('packetSize', 'osd', true);
263 describe(`'lrc' usage`, () => {
265 ecp.name = 'lreProfile';
269 it('should be able to create a profile with only required fields', () => {
270 formHelper.setMultipleValues(ecp, true);
277 it('should send profile with all required fields and crush root and locality', () => {
279 formHelper.setMultipleValues(ecp, true);
282 formHelper.setValue('crushLocality', 'osd', true);
283 formHelper.setValue('crushRoot', 'rack', true);
284 ecp['crush-locality'] = 'osd';
285 ecp['crush-root'] = 'rack';
289 it('should not send the profile with unsupported fields', () => {
290 formHelper.setMultipleValues(ecp, true);
294 formHelper.setValue('c', 4, true);
299 describe(`'shec' usage`, () => {
301 ecp.name = 'shecProfile';
305 it('should be able to create a profile with only plugin and name', () => {
306 formHelper.setMultipleValues(ecp, true);
310 it('should send profile with plugin, name, c and crush device class only', () => {
312 formHelper.setMultipleValues(ecp, true);
313 formHelper.setValue('crushDeviceClass', 'ssd', true);
314 ecp['crush-device-class'] = 'ssd';
318 it('should not send the profile with unsupported fields', () => {
319 formHelper.setMultipleValues(ecp, true);
320 formHelper.setValue('l', 8, true);