Ensure "Storage capacity" keeps the "Description : Value" approach ("Number of devices: X" and "Raw Capacity: Y" in different lines).Correct issue with "host by services" host count
Fixes: https://tracker.ceph.com/issues/53128
Signed-off-by: Aashish Sharma <aasharma@redhat.com>
createCluster.getStatusTables().should('contain.text', 'Memory');
});
- it('should check Hosts by Services and Host Details tables are present', () => {
+ it('should check Host Details table is present', () => {
// check for there to be two tables
- createCluster.getDataTables().should('have.length', 2);
-
- // check for table header 'Hosts by Services'
- createCluster.getLegends().its(1).should('have.text', 'Hosts by Services');
-
- // check for table header 'Host Details'
- createCluster.getLegends().its(2).should('have.text', 'Host Details');
-
- // verify correct columns on Hosts by Services table
- createCluster.getDataTableHeaders(0).contains('Services');
-
- createCluster.getDataTableHeaders(0).contains('Number of Hosts');
+ createCluster.getDataTables().should('have.length', 1);
// verify correct columns on Host Details table
- createCluster.getDataTableHeaders(1).contains('Hostname');
+ createCluster.getDataTableHeaders(0).contains('Hostname');
- createCluster.getDataTableHeaders(1).contains('Labels');
+ createCluster.getDataTableHeaders(0).contains('Labels');
- createCluster.getDataTableHeaders(1).contains('CPUs');
+ createCluster.getDataTableHeaders(0).contains('CPUs');
- createCluster.getDataTableHeaders(1).contains('Cores');
+ createCluster.getDataTableHeaders(0).contains('Cores');
- createCluster.getDataTableHeaders(1).contains('Total Memory');
+ createCluster.getDataTableHeaders(0).contains('Total Memory');
- createCluster.getDataTableHeaders(1).contains('Raw Capacity');
+ createCluster.getDataTableHeaders(0).contains('Raw Capacity');
- createCluster.getDataTableHeaders(1).contains('HDDs');
+ createCluster.getDataTableHeaders(0).contains('HDDs');
- createCluster.getDataTableHeaders(1).contains('Flash');
+ createCluster.getDataTableHeaders(0).contains('Flash');
- createCluster.getDataTableHeaders(1).contains('NICs');
+ createCluster.getDataTableHeaders(0).contains('NICs');
});
it('should check default host name is present', () => {
<div class="row">
- <div class="col-lg-4">
+ <div class="col-lg-3">
<fieldset>
<legend class="cd-header"
i18n>Cluster Resources</legend>
<td>{{ hostsCount }}</td>
</tr>
<tr>
- <td i18n
- class="bold">Storage Capacity</td>
- <td><span i18n>Number of devices: {{ totalDevices }}. Raw capacity:
- {{ totalCapacity | dimlessBinary }}.</span></td>
+ <td>
+ <dl>
+ <dt>
+ <p i18n>Storage Capacity</p>
+ </dt>
+ <dd>
+ <p i18n>Number of devices</p>
+ </dd>
+ <dd>
+ <p i18n>Raw capacity</p>
+ </dd>
+ </dl>
+ </td>
+ <td class="pt-5"><p>{{ totalDevices }}</p><p>
+ {{ totalCapacity | dimlessBinary }}</p></td>
</tr>
<tr>
<td i18n
</fieldset>
</div>
- <div class="col-lg-8">
- <legend i18n
- class="cd-header">Hosts by Services</legend>
- <cd-table [data]="hostsByService['data']"
- [columns]="hostsByService['columns']"
- [toolHeader]="false">
- </cd-table>
- </div>
+<div class="col-lg-9">
+ <legend i18n
+ class="cd-header">Host Details</legend>
+ <cd-hosts [hiddenColumns]="['services', 'status']"
+ [hideToolHeader]="true"
+ [hideTitle]="true"
+ [hideSubmitBtn]="true"
+ [hasTableDetails]="false"
+ [showGeneralActionsOnly]="true">
+ </cd-hosts>
+</div>
</div>
-
-<legend i18n
- class="cd-header">Host Details</legend>
-<cd-hosts [hiddenColumns]="['services', 'status']"
- [hideToolHeader]="true"
- [hideTitle]="true"
- [hideSubmitBtn]="true"
- [hasTableDetails]="false"
- [showGeneralActionsOnly]="true">
-</cd-hosts>
import _ from 'lodash';
import { ToastrModule } from 'ngx-toastr';
-import { of } from 'rxjs';
import { CephModule } from '~/app/ceph/ceph.module';
import { CoreModule } from '~/app/core/core.module';
-import { CephServiceService } from '~/app/shared/api/ceph-service.service';
import { SharedModule } from '~/app/shared/shared.module';
import { configureTestBed } from '~/testing/unit-test-helper';
import { CreateClusterReviewComponent } from './create-cluster-review.component';
describe('CreateClusterReviewComponent', () => {
let component: CreateClusterReviewComponent;
let fixture: ComponentFixture<CreateClusterReviewComponent>;
- let cephServiceService: CephServiceService;
- let serviceListSpy: jasmine.Spy;
configureTestBed({
imports: [HttpClientTestingModule, SharedModule, ToastrModule.forRoot(), CephModule, CoreModule]
beforeEach(() => {
fixture = TestBed.createComponent(CreateClusterReviewComponent);
component = fixture.componentInstance;
- cephServiceService = TestBed.inject(CephServiceService);
- serviceListSpy = spyOn(cephServiceService, 'list');
});
it('should create', () => {
expect(component).toBeTruthy();
});
-
- it('should verify host metadata calculations', () => {
- const hostnames = ['ceph.test1', 'ceph.test2'];
- const payload = [
- {
- hostname: hostnames[0],
- service_type: ['mgr', 'mon']
- },
- {
- hostname: hostnames[1],
- service_type: ['mgr', 'alertmanager']
- }
- ];
- serviceListSpy.and.callFake(() => of(payload));
- fixture.detectChanges();
- expect(serviceListSpy).toHaveBeenCalled();
-
- expect(component.serviceCount).toBe(2);
- expect(component.uniqueServices.size).toBe(2);
- });
});
import { CephServiceService } from '~/app/shared/api/ceph-service.service';
import { HostService } from '~/app/shared/api/host.service';
import { OsdService } from '~/app/shared/api/osd.service';
-import { CellTemplate } from '~/app/shared/enum/cell-template.enum';
import { CephServiceSpec } from '~/app/shared/models/service.interface';
import { DimlessBinaryPipe } from '~/app/shared/pipes/dimless-binary.pipe';
import { WizardStepsService } from '~/app/shared/services/wizard-steps.service';
})
export class CreateClusterReviewComponent implements OnInit {
hosts: object[] = [];
- hostsByService: object;
hostsCount: number;
- serviceCount: number;
- serviceOccurrences = {};
- hostsCountPerService: object[] = [];
- uniqueServices: Set<string> = new Set();
totalDevices: number;
totalCapacity = 0;
services: Array<CephServiceSpec> = [];
let dbDevices = 0;
let dbDeviceCapacity = 0;
- this.hostsByService = {
- columns: [
- {
- prop: 'service_type',
- name: $localize`Services`,
- flexGrow: 1,
- cellTransformation: CellTemplate.badge,
- customTemplateConfig: {
- class: 'badge-dark'
- }
- },
- {
- name: $localize`Number of Hosts`,
- prop: 'hosts_per_service',
- flexGrow: 1
- }
- ]
- };
-
- this.cephServiceService.list().subscribe((resp: Array<CephServiceSpec>) => {
- this.services = resp;
- this.serviceCount = this.services.length;
-
- _.forEach(this.services, (serviceKey) => {
- this.serviceOccurrences[serviceKey['service_type']] =
- (this.serviceOccurrences[serviceKey['service_type']] || 0) + 1;
- this.uniqueServices.add(serviceKey['service_type']);
- });
-
- this.uniqueServices.forEach((serviceType) => {
- this.hostsCountPerService.push({
- service_type: serviceType,
- hosts_per_service: this.serviceOccurrences[serviceType]
- });
- });
-
- this.hostsByService['data'] = [...this.hostsCountPerService];
- });
-
this.hostService.list('true').subscribe((resp: object[]) => {
this.hosts = resp;
this.hostsCount = this.hosts.length;
<ng-template #orchTmpl>
<span i18n
i18n-ngbTooltip
- ngbTooltip="Data will be available only if Orchestrator is available.">Unavailable</span>
+ ngbTooltip="Data will be available only if Orchestrator is available.">N/A</span>
</ng-template>
<ng-template #flashTmpl>
const spans = fixture.debugElement.nativeElement.querySelectorAll(
'.datatable-body-cell-label span'
);
- expect(spans[7].textContent).toBe('Unavailable');
+ expect(spans[7].textContent).toBe('N/A');
});
it('should test if host facts are unavailable if get_fatcs orch feature is not available', () => {
const spans = fixture.debugElement.nativeElement.querySelectorAll(
'.datatable-body-cell-label span'
);
- expect(spans[7].textContent).toBe('Unavailable');
+ expect(spans[7].textContent).toBe('N/A');
});
it('should show force maintenance modal when it is safe to stop host', () => {