This commit is intended for code cleanup of Histogram component.
Fixes: https://tracker.ceph.com/issues/26954
Signed-off-by: Aashish Sharma <aasharma@redhat.com>
def test_details(self):
data = self._get('/api/osd/0')
self.assertStatus(200)
- self.assert_in_and_not_none(data, ['osd_metadata', 'histogram'])
- self.assert_in_and_not_none(data['histogram'], ['osd'])
- self.assert_in_and_not_none(data['histogram']['osd'], ['op_w_latency_in_bytes_histogram',
- 'op_r_latency_out_bytes_histogram'])
+ self.assert_in_and_not_none(data, ['osd_metadata'])
def test_scrub(self):
self._post('/api/osd/0/scrub?deep=False')
"""
Returns collected data about an OSD.
- :return: Returns the requested data. The `histogram` key may contain a
- string with an error that occurred if the OSD is down.
+ :return: Returns the requested data.
"""
- try:
- histogram = CephService.send_command(
- 'osd', srv_spec=svc_id, prefix='perf histogram dump')
- except SendCommandError as e: # pragma: no cover - the handling is too obvious
- if 'osd down' in str(e): # pragma: no cover - no complexity there
- histogram = str(e)
- else: # pragma: no cover - no complexity there
- raise
-
return {
'osd_map': self.get_osd_map(svc_id),
'osd_metadata': mgr.get_metadata('osd', svc_id),
- 'histogram': histogram,
}
def set(self, svc_id, device_class): # pragma: no cover
'Metadata',
'Device health',
'Performance counter',
- 'Histogram',
'Performance Details'
]);
});
import { OsdFlagsModalComponent } from './osd/osd-flags-modal/osd-flags-modal.component';
import { OsdFormComponent } from './osd/osd-form/osd-form.component';
import { OsdListComponent } from './osd/osd-list/osd-list.component';
-import { OsdPerformanceHistogramComponent } from './osd/osd-performance-histogram/osd-performance-histogram.component';
import { OsdPgScrubModalComponent } from './osd/osd-pg-scrub-modal/osd-pg-scrub-modal.component';
import { OsdRecvSpeedModalComponent } from './osd/osd-recv-speed-modal/osd-recv-speed-modal.component';
import { OsdReweightModalComponent } from './osd/osd-reweight-modal/osd-reweight-modal.component';
ConfigurationComponent,
OsdListComponent,
OsdDetailsComponent,
- OsdPerformanceHistogramComponent,
OsdScrubModalComponent,
OsdFlagsModalComponent,
HostDetailsComponent,
</cd-table-performance-counter>
</ng-template>
</li>
- <li ngbNavItem="histogram">
- <a ngbNavLink
- i18n>Histogram</a>
- <ng-template ngbNavContent>
- <cd-alert-panel *ngIf="osd?.histogram_failed"
- type="warning"
- i18n>Histogram not available: {{ osd?.histogram_failed }}</cd-alert-panel>
-
- <div class="row"
- *ngIf="osd?.details?.histogram">
- <div class="col-md-6">
- <h4 i18n>Writes</h4>
- <cd-osd-performance-histogram [histogram]="osd?.details?.histogram?.osd?.op_w_latency_in_bytes_histogram">
- </cd-osd-performance-histogram>
- </div>
- <div class="col-md-6">
- <h4 i18n>Reads</h4>
- <cd-osd-performance-histogram [histogram]="osd?.details?.histogram?.osd?.op_r_latency_out_bytes_histogram">
- </cd-osd-performance-histogram>
- </div>
- </div>
- </ng-template>
- </li>
<li ngbNavItem="performance-details"
*ngIf="grafanaPermission.read">
<a ngbNavLink
import { HttpClientTestingModule } from '@angular/common/http/testing';
-import { DebugElement } from '@angular/core';
import { ComponentFixture, TestBed } from '@angular/core/testing';
import { NgbNavModule } from '@ng-bootstrap/ng-bootstrap';
-import { of } from 'rxjs';
import { configureTestBed } from '../../../../../testing/unit-test-helper';
-import { OsdService } from '../../../../shared/api/osd.service';
import { SharedModule } from '../../../../shared/shared.module';
import { TablePerformanceCounterComponent } from '../../../performance-counter/table-performance-counter/table-performance-counter.component';
import { DeviceListComponent } from '../../../shared/device-list/device-list.component';
import { SmartListComponent } from '../../../shared/smart-list/smart-list.component';
-import { OsdPerformanceHistogramComponent } from '../osd-performance-histogram/osd-performance-histogram.component';
import { OsdDetailsComponent } from './osd-details.component';
describe('OsdDetailsComponent', () => {
let component: OsdDetailsComponent;
let fixture: ComponentFixture<OsdDetailsComponent>;
- let debugElement: DebugElement;
- let osdService: OsdService;
- let getDetailsSpy: jasmine.Spy;
configureTestBed({
imports: [HttpClientTestingModule, NgbNavModule, SharedModule],
OsdDetailsComponent,
DeviceListComponent,
SmartListComponent,
- TablePerformanceCounterComponent,
- OsdPerformanceHistogramComponent
+ TablePerformanceCounterComponent
]
});
beforeEach(() => {
fixture = TestBed.createComponent(OsdDetailsComponent);
component = fixture.componentInstance;
-
component.selection = undefined;
- 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_metadata: {},
- histogram: {}
- };
- getDetailsSpy.and.returnValue(of(detailDataWithHistogram));
- component.osd = { tree: { id: 0 } };
- component.refresh();
- expect(getDetailsSpy).toHaveBeenCalled();
- expect(component.osd.histogram_failed).toBe('');
- });
});
osd: {
id?: number;
details?: any;
- histogram_failed?: string;
tree?: any;
};
grafanaPermission: Permission;
refresh() {
this.osdService.getDetails(this.osd.id).subscribe((data) => {
this.osd.details = data;
- this.osd.histogram_failed = '';
- if (!_.isObject(data.histogram)) {
- this.osd.histogram_failed = data.histogram;
- this.osd.details.histogram = undefined;
- }
});
}
}
+++ /dev/null
-<table>
- <tr *ngFor="let row of valuesStyle">
- <td *ngFor="let col of row"
- [ngStyle]="col">
- </td>
- </tr>
-</table>
+++ /dev/null
-table {
- tr {
- height: 10px;
- }
-
- td {
- height: 10px;
- width: 10px;
- }
-}
+++ /dev/null
-import { ComponentFixture, TestBed } from '@angular/core/testing';
-
-import { configureTestBed } from '../../../../../testing/unit-test-helper';
-import { OsdPerformanceHistogramComponent } from './osd-performance-histogram.component';
-
-describe('OsdPerformanceHistogramComponent', () => {
- let component: OsdPerformanceHistogramComponent;
- let fixture: ComponentFixture<OsdPerformanceHistogramComponent>;
-
- configureTestBed({
- declarations: [OsdPerformanceHistogramComponent]
- });
-
- beforeEach(() => {
- fixture = TestBed.createComponent(OsdPerformanceHistogramComponent);
- component = fixture.componentInstance;
- fixture.detectChanges();
- });
-
- it('should create', () => {
- expect(component).toBeTruthy();
- });
-});
+++ /dev/null
-import { Component, Input, OnChanges } from '@angular/core';
-
-import _ from 'lodash';
-
-@Component({
- selector: 'cd-osd-performance-histogram',
- templateUrl: './osd-performance-histogram.component.html',
- styleUrls: ['./osd-performance-histogram.component.scss']
-})
-export class OsdPerformanceHistogramComponent implements OnChanges {
- @Input()
- histogram: any;
- valuesStyle: any;
- last = {};
-
- ngOnChanges() {
- this.render();
- }
-
- hexdigits(v: number): string {
- const i = Math.floor(v * 255).toString(16);
- return i.length === 1 ? '0' + i : i;
- }
-
- hexcolor(r: number, g: number, b: number) {
- return '#' + this.hexdigits(r) + this.hexdigits(g) + this.hexdigits(b);
- }
-
- render() {
- if (!this.histogram) {
- return;
- }
- let max = 0;
-
- _.each(this.histogram.values, (row, i) => {
- _.each(row, (col, j) => {
- let val;
- if (this.last && this.last[i] && this.last[i][j]) {
- val = col - this.last[i][j];
- } else {
- val = col;
- }
- max = Math.max(max, val);
- });
- });
-
- this.valuesStyle = this.histogram.values.map((row: any, i: number) => {
- return row.map((col: any, j: number) => {
- const val = this.last && this.last[i] && this.last[i][j] ? col - this.last[i][j] : col;
- const g = max ? val / max : 0;
- const r = 1 - g;
- return { backgroundColor: this.hexcolor(r, g, 0) };
- });
- });
-
- this.last = this.histogram.values;
- }
-}
interface OsdData {
osd_map: { [key: string]: any };
osd_metadata: { [key: string]: any };
- histogram: { [key: string]: object };
smart: { [device_identifier: string]: any };
}
return this.http.get<OsdData>(`${this.path}/${id}`);