]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/blob
31739a7c2988f26875bfd381d3ed99b787dfc730
[ceph-ci.git] /
1 import { HttpClientTestingModule } from '@angular/common/http/testing';
2 import { ComponentFixture, TestBed } from '@angular/core/testing';
3
4 import _ from 'lodash';
5 import { NgxPipeFunctionModule } from 'ngx-pipe-function';
6 import { ToastrModule } from 'ngx-toastr';
7 import { of } from 'rxjs';
8
9 import { CephModule } from '~/app/ceph/ceph.module';
10 import { CoreModule } from '~/app/core/core.module';
11 import { CephServiceService } from '~/app/shared/api/ceph-service.service';
12 import { HostService } from '~/app/shared/api/host.service';
13 import { CdTableFetchDataContext } from '~/app/shared/models/cd-table-fetch-data-context';
14 import { SharedModule } from '~/app/shared/shared.module';
15 import { configureTestBed } from '~/testing/unit-test-helper';
16 import { ServiceDaemonListComponent } from './service-daemon-list.component';
17
18 describe('ServiceDaemonListComponent', () => {
19   let component: ServiceDaemonListComponent;
20   let fixture: ComponentFixture<ServiceDaemonListComponent>;
21
22   const daemons = [
23     {
24       hostname: 'osd0',
25       container_id: '003c10beafc8c27b635bcdfed1ed832e4c1005be89bb1bb05ad4cc6c2b98e41b',
26       container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
27       container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
28       daemon_id: '3',
29       daemon_type: 'osd',
30       daemon_name: 'osd.3',
31       version: '15.1.0-1174-g16a11f7',
32       memory_usage: '17.7',
33       cpu_percentage: '3.54%',
34       status: 1,
35       status_desc: 'running',
36       last_refresh: '2020-02-25T04:33:26.465699',
37       events: [
38         { created: '2020-02-24T04:33:26.465699' },
39         { created: '2020-02-25T04:33:26.465699' },
40         { created: '2020-02-26T04:33:26.465699' }
41       ]
42     },
43     {
44       hostname: 'osd0',
45       container_id: 'baeec41a01374b3ed41016d542d19aef4a70d69c27274f271e26381a0cc58e7a',
46       container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
47       container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
48       daemon_id: '4',
49       daemon_type: 'osd',
50       daemon_name: 'osd.4',
51       version: '15.1.0-1174-g16a11f7',
52       memory_usage: '17.7',
53       cpu_percentage: '3.54%',
54       status: 1,
55       status_desc: 'running',
56       last_refresh: '2020-02-25T04:33:26.465822',
57       events: []
58     },
59     {
60       hostname: 'osd0',
61       container_id: '8483de277e365bea4365cee9e1f26606be85c471e4da5d51f57e4b85a42c616e',
62       container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
63       container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
64       daemon_id: '5',
65       daemon_type: 'osd',
66       daemon_name: 'osd.5',
67       version: '15.1.0-1174-g16a11f7',
68       memory_usage: '17.7',
69       cpu_percentage: '3.54%',
70       status: 1,
71       status_desc: 'running',
72       last_refresh: '2020-02-25T04:33:26.465886',
73       events: []
74     },
75     {
76       hostname: 'mon0',
77       container_id: '6ca0574f47e300a6979eaf4e7c283a8c4325c2235ae60358482fc4cd58844a21',
78       container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
79       container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
80       daemon_id: 'a',
81       daemon_name: 'mon.a',
82       daemon_type: 'mon',
83       version: '15.1.0-1174-g16a11f7',
84       memory_usage: '17.7',
85       cpu_percentage: '3.54%',
86       status: 1,
87       status_desc: 'running',
88       last_refresh: '2020-02-25T04:33:26.465886',
89       events: []
90     }
91   ];
92
93   const services = [
94     {
95       service_type: 'osd',
96       service_name: 'osd',
97       status: {
98         container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
99         container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
100         size: 3,
101         running: 3,
102         last_refresh: '2020-02-25T04:33:26.465699'
103       },
104       events: '2021-03-22T07:34:48.582163Z service:osd [INFO] "service was created"'
105     },
106     {
107       service_type: 'crash',
108       service_name: 'crash',
109       status: {
110         container_image_id: 'e70344c77bcbf3ee389b9bf5128f635cf95f3d59e005c5d8e67fc19bcc74ed23',
111         container_image_name: 'docker.io/ceph/daemon-base:latest-master-devel',
112         size: 1,
113         running: 1,
114         last_refresh: '2020-02-25T04:33:26.465766'
115       },
116       events: '2021-03-22T07:34:48.582163Z service:osd [INFO] "service was created"'
117     }
118   ];
119
120   const getDaemonsByHostname = (hostname?: string) => {
121     return hostname ? _.filter(daemons, { hostname: hostname }) : daemons;
122   };
123
124   const getDaemonsByServiceName = (serviceName?: string) => {
125     return serviceName ? _.filter(daemons, { daemon_type: serviceName }) : daemons;
126   };
127
128   configureTestBed({
129     imports: [
130       HttpClientTestingModule,
131       CephModule,
132       CoreModule,
133       NgxPipeFunctionModule,
134       SharedModule,
135       ToastrModule.forRoot()
136     ]
137   });
138
139   beforeEach(() => {
140     fixture = TestBed.createComponent(ServiceDaemonListComponent);
141     component = fixture.componentInstance;
142     const hostService = TestBed.inject(HostService);
143     const cephServiceService = TestBed.inject(CephServiceService);
144     spyOn(hostService, 'getDaemons').and.callFake(() =>
145       of(getDaemonsByHostname(component.hostname))
146     );
147     spyOn(cephServiceService, 'getDaemons').and.callFake(() =>
148       of(getDaemonsByServiceName(component.serviceName))
149     );
150     spyOn(cephServiceService, 'list').and.returnValue(of(services));
151     fixture.detectChanges();
152   });
153
154   it('should create', () => {
155     expect(component).toBeTruthy();
156   });
157
158   it('should list daemons by host', () => {
159     component.hostname = 'mon0';
160     component.getDaemons(new CdTableFetchDataContext(() => undefined));
161     expect(component.daemons.length).toBe(1);
162   });
163
164   it('should list daemons by service', () => {
165     component.serviceName = 'osd';
166     component.getDaemons(new CdTableFetchDataContext(() => undefined));
167     expect(component.daemons.length).toBe(3);
168   });
169
170   it('should list services', () => {
171     component.getServices(new CdTableFetchDataContext(() => undefined));
172     expect(component.services.length).toBe(2);
173   });
174
175   it('should not display doc panel if orchestrator is available', () => {
176     expect(component.showDocPanel).toBeFalsy();
177   });
178
179   it('should call daemon action', () => {
180     const daemon = daemons[0];
181     component.selection.selected = [daemon];
182     component['daemonService'].action = jest.fn(() => of());
183     for (const action of ['start', 'stop', 'restart', 'redeploy']) {
184       component.daemonAction(action);
185       expect(component['daemonService'].action).toHaveBeenCalledWith(daemon.daemon_name, action);
186     }
187   });
188
189   it('should disable daemon actions', () => {
190     const daemon = {
191       daemon_type: 'osd',
192       status_desc: 'running'
193     };
194
195     const states = {
196       start: true,
197       stop: false,
198       restart: false,
199       redeploy: false
200     };
201     const expectBool = (toExpect: boolean, arg: boolean) => {
202       if (toExpect === true) {
203         expect(arg).toBeTruthy();
204       } else {
205         expect(arg).toBeFalsy();
206       }
207     };
208
209     component.selection.selected = [daemon];
210     for (const action of ['start', 'stop', 'restart', 'redeploy']) {
211       expectBool(states[action], component.actionDisabled(action));
212     }
213
214     daemon.status_desc = 'stopped';
215     states.start = false;
216     states.stop = true;
217     component.selection.selected = [daemon];
218     for (const action of ['start', 'stop', 'restart', 'redeploy']) {
219       expectBool(states[action], component.actionDisabled(action));
220     }
221   });
222
223   it('should disable daemon actions in mgr and mon daemon', () => {
224     const daemon = {
225       daemon_type: 'mgr',
226       status_desc: 'running'
227     };
228     for (const action of ['start', 'stop', 'restart', 'redeploy']) {
229       expect(component.actionDisabled(action)).toBeTruthy();
230     }
231     daemon.daemon_type = 'mon';
232     for (const action of ['start', 'stop', 'restart', 'redeploy']) {
233       expect(component.actionDisabled(action)).toBeTruthy();
234     }
235   });
236
237   it('should disable daemon actions if no selection', () => {
238     component.selection.selected = [];
239     for (const action of ['start', 'stop', 'restart', 'redeploy']) {
240       expect(component.actionDisabled(action)).toBeTruthy();
241     }
242   });
243
244   it('should sort daemons events', () => {
245     component.sortDaemonEvents();
246     const daemon = daemons[0];
247     for (let i = 1; i < daemon.events.length; i++) {
248       const t1 = new Date(daemon.events[i - 1].created).getTime();
249       const t2 = new Date(daemon.events[i].created).getTime();
250       expect(t1 >= t2).toBeTruthy();
251     }
252   });
253 });