from . import ApiController, RESTController, UpdatePermission
from .. import mgr, logger
from ..security import Scope
-from ..services.ceph_service import CephService
+from ..services.ceph_service import CephService, SendCommandError
from ..services.exception import handle_send_command_error
from ..tools import str_to_bool
@handle_send_command_error('osd')
def get(self, svc_id):
- histogram = CephService.send_command('osd', srv_spec=svc_id, prefix='perf histogram dump')
+ """
+ Returns collected data about an OSD.
+
+ :return: Returns the requested data. The `histogram` key man contain a
+ string with an error that occurred when the OSD is down.
+ """
+ try:
+ histogram = CephService.send_command('osd', srv_spec=svc_id,
+ prefix='perf histogram dump')
+ except SendCommandError as e:
+ if 'osd down' in e.message:
+ histogram = e.message
+ else:
+ raise
+
return {
'osd_map': self.get_osd_map()[svc_id],
'osd_metadata': mgr.get_metadata('osd', svc_id),
import { HttpClientModule } from '@angular/common/http';
+import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { of } from 'rxjs';
+
import { TabsModule } from 'ngx-bootstrap';
import { configureTestBed } from '../../../../../testing/unit-test-helper';
+import { OsdService } from '../../../../shared/api/osd.service';
import { DataTableModule } from '../../../../shared/datatable/datatable.module';
import { CdTableSelection } from '../../../../shared/models/cd-table-selection';
import { SharedModule } from '../../../../shared/shared.module';
describe('OsdDetailsComponent', () => {
let component: OsdDetailsComponent;
let fixture: ComponentFixture<OsdDetailsComponent>;
+ let debugElement: DebugElement;
+ let osdService: OsdService;
+ let getDetailsSpy;
configureTestBed({
imports: [
DataTableModule,
SharedModule
],
- declarations: [OsdDetailsComponent, OsdPerformanceHistogramComponent]
+ declarations: [OsdDetailsComponent, OsdPerformanceHistogramComponent],
+ providers: [OsdService]
});
beforeEach(() => {
component = fixture.componentInstance;
component.selection = new CdTableSelection();
+ debugElement = fixture.debugElement;
+ osdService = debugElement.injector.get(OsdService);
+
+ getDetailsSpy = spyOn(osdService, 'getDetails');
fixture.detectChanges();
});
it('should create', () => {
expect(component).toBeTruthy();
});
+
+ it('should fail creating a histogram', () => {
+ const detailDataWithoutHistogram = {
+ osd_map: {},
+ osd_metadata: {},
+ histogram: 'osd down'
+ };
+ getDetailsSpy.and.returnValue(of(detailDataWithoutHistogram));
+ component.osd = { tree: { id: 0 } };
+ component.refresh();
+ expect(getDetailsSpy).toHaveBeenCalled();
+ expect(component.osd.histogram_failed).toBe('osd down');
+ });
+
+ it('should succeed creating a histogram', () => {
+ const detailDataWithHistogram = {
+ osd_map: {},
+ osd_metdata: {},
+ histogram: {}
+ };
+ getDetailsSpy.and.returnValue(of(detailDataWithHistogram));
+ component.osd = { tree: { id: 0 } };
+ component.refresh();
+ expect(getDetailsSpy).toHaveBeenCalled();
+ expect(component.osd.histogram_failed).toBe('');
+ });
});
</cd-osd-details>
</cd-table>
-<ng-template #statusColor
- let-value="value">
+<ng-template #statusColor let-value="value">
<span *ngFor="let state of value; last as last">
- <span [class.text-success]="'up' === state || 'in' === state"
- [class.text-warning]="'down' === state || 'out' === state">
- {{ state }}</span>
- <span *ngIf="!last">, </span>
+ <span class="label"
+ [ngClass]="{'label-success': ['in', 'up'].includes(state), 'label-danger': ['down', 'out'].includes(state)}">{{ state }}</span>
+ <span *ngIf="!last"> </span>
</span>
</ng-template>