import { HttpClientTestingModule } from '@angular/common/http/testing';
-import { DebugElement, Type } from '@angular/core';
-import { ComponentFixture, TestBed } from '@angular/core/testing';
+import { DebugElement } from '@angular/core';
+import { ComponentFixture, fakeAsync, TestBed, tick } from '@angular/core/testing';
import { TreeModule } from '@circlon/angular-tree-component';
import { of } from 'rxjs';
-import { HealthService } from '~/app/shared/api/health.service';
+import { CrushRuleService } from '~/app/shared/api/crush-rule.service';
import { SharedModule } from '~/app/shared/shared.module';
import { configureTestBed } from '~/testing/unit-test-helper';
import { CrushmapComponent } from './crushmap.component';
let component: CrushmapComponent;
let fixture: ComponentFixture<CrushmapComponent>;
let debugElement: DebugElement;
+ let crushRuleService: CrushRuleService;
+ let crushRuleServiceInfoSpy: jasmine.Spy;
configureTestBed({
imports: [HttpClientTestingModule, TreeModule, SharedModule],
- declarations: [CrushmapComponent],
- providers: [HealthService]
+ declarations: [CrushmapComponent]
});
beforeEach(() => {
fixture = TestBed.createComponent(CrushmapComponent);
component = fixture.componentInstance;
debugElement = fixture.debugElement;
+ crushRuleService = TestBed.inject(CrushRuleService);
+ crushRuleServiceInfoSpy = spyOn(crushRuleService, 'getInfo');
});
it('should create', () => {
});
it('should display right title', () => {
- fixture.detectChanges();
const span = debugElement.nativeElement.querySelector('.card-header');
expect(span.textContent).toBe('CRUSH map viewer');
});
- describe('test tree', () => {
- let healthService: HealthService;
- const prepareGetHealth = (nodes: object[]) => {
- spyOn(healthService, 'getFullHealth').and.returnValue(
- of({ osd_map: { tree: { nodes: nodes } } })
- );
- fixture.detectChanges();
- };
-
- beforeEach(() => {
- healthService = debugElement.injector.get(HealthService as Type<HealthService>);
- });
-
- it('should display "No nodes!" if ceph tree nodes is empty array', () => {
- prepareGetHealth([]);
- expect(healthService.getFullHealth).toHaveBeenCalled();
- expect(component.nodes[0].name).toEqual('No nodes!');
- });
+ it('should display "No nodes!" if ceph tree nodes is empty array', fakeAsync(() => {
+ crushRuleServiceInfoSpy.and.returnValue(of({ nodes: [] }));
+ fixture.detectChanges();
+ tick(5000);
+ expect(crushRuleService.getInfo).toHaveBeenCalled();
+ expect(component.nodes[0].name).toEqual('No nodes!');
+ component.ngOnDestroy();
+ }));
- describe('nodes not empty', () => {
- beforeEach(() => {
- prepareGetHealth([
+ it('should have two root nodes', fakeAsync(() => {
+ crushRuleServiceInfoSpy.and.returnValue(
+ of({
+ nodes: [
{ children: [-2], type: 'root', name: 'default', id: -1 },
{ children: [1, 0, 2], type: 'host', name: 'my-host', id: -2 },
{ status: 'up', type: 'osd', name: 'osd.0', id: 0 },
{ children: [-4], type: 'root', name: 'default-2', id: -3 },
{ children: [4], type: 'host', name: 'my-host-2', id: -4 },
{ status: 'up', type: 'osd', name: 'osd.0-2', id: 4 }
- ]);
- });
-
- it('should have two root nodes', () => {
- expect(component.nodes).toEqual([
+ ]
+ })
+ );
+ fixture.detectChanges();
+ tick(10000);
+ expect(crushRuleService.getInfo).toHaveBeenCalled();
+ expect(component.nodes).toEqual([
+ {
+ cdId: -3,
+ children: [
{
- cdId: -3,
children: [
{
- children: [
- {
- id: component.nodes[0].children[0].children[0].id,
- cdId: 4,
- status: 'up',
- type: 'osd',
- name: 'osd.0-2 (osd)'
- }
- ],
- id: component.nodes[0].children[0].id,
- cdId: -4,
- status: undefined,
- type: 'host',
- name: 'my-host-2 (host)'
+ id: component.nodes[0].children[0].children[0].id,
+ cdId: 4,
+ status: 'up',
+ type: 'osd',
+ name: 'osd.0-2 (osd)'
}
],
- id: component.nodes[0].id,
+ id: component.nodes[0].children[0].id,
+ cdId: -4,
status: undefined,
- type: 'root',
- name: 'default-2 (root)'
- },
+ type: 'host',
+ name: 'my-host-2 (host)'
+ }
+ ],
+ id: component.nodes[0].id,
+ status: undefined,
+ type: 'root',
+ name: 'default-2 (root)'
+ },
+ {
+ children: [
{
children: [
{
- children: [
- {
- id: component.nodes[1].children[0].children[0].id,
- cdId: 0,
- status: 'up',
- type: 'osd',
- name: 'osd.0 (osd)'
- },
- {
- id: component.nodes[1].children[0].children[1].id,
- cdId: 1,
- status: 'down',
- type: 'osd',
- name: 'osd.1 (osd)'
- },
- {
- id: component.nodes[1].children[0].children[2].id,
- cdId: 2,
- status: 'up',
- type: 'osd',
- name: 'osd.2 (osd)'
- }
- ],
- id: component.nodes[1].children[0].id,
- cdId: -2,
- status: undefined,
- type: 'host',
- name: 'my-host (host)'
+ id: component.nodes[1].children[0].children[0].id,
+ cdId: 0,
+ status: 'up',
+ type: 'osd',
+ name: 'osd.0 (osd)'
+ },
+ {
+ id: component.nodes[1].children[0].children[1].id,
+ cdId: 1,
+ status: 'down',
+ type: 'osd',
+ name: 'osd.1 (osd)'
+ },
+ {
+ id: component.nodes[1].children[0].children[2].id,
+ cdId: 2,
+ status: 'up',
+ type: 'osd',
+ name: 'osd.2 (osd)'
}
],
- id: component.nodes[1].id,
- cdId: -1,
+ id: component.nodes[1].children[0].id,
+ cdId: -2,
status: undefined,
- type: 'root',
- name: 'default (root)'
+ type: 'host',
+ name: 'my-host (host)'
}
- ]);
- });
- });
- });
+ ],
+ id: component.nodes[1].id,
+ cdId: -1,
+ status: undefined,
+ type: 'root',
+ name: 'default (root)'
+ }
+ ]);
+ component.ngOnDestroy();
+ }));
});
TreeNode,
TREE_ACTIONS
} from '@circlon/angular-tree-component';
-import { Subscription } from 'rxjs';
+import { Observable, Subscription } from 'rxjs';
-import { HealthService } from '~/app/shared/api/health.service';
+import { CrushRuleService } from '~/app/shared/api/crush-rule.service';
import { Icons } from '~/app/shared/enum/icons.enum';
import { TimerService } from '~/app/shared/services/timer.service';
templateUrl: './crushmap.component.html',
styleUrls: ['./crushmap.component.scss']
})
-export class CrushmapComponent implements OnInit, OnDestroy {
+export class CrushmapComponent implements OnDestroy, OnInit {
private sub = new Subscription();
@ViewChild('tree') tree: TreeComponent;
metadata: any;
metadataTitle: string;
metadataKeyMap: { [key: number]: any } = {};
+ data$: Observable<object>;
- constructor(private healthService: HealthService, private timerService: TimerService) {}
+ constructor(private crushRuleService: CrushRuleService, private timerService: TimerService) {}
ngOnInit() {
- this.healthService.getFullHealth().subscribe((data: any) => {
- this.loadingIndicator = false;
- this.nodes = this.abstractTreeData(data);
- });
this.sub = this.timerService
- .get(() => this.healthService.getFullHealth(), 5000)
+ .get(() => this.crushRuleService.getInfo(), 5000)
.subscribe((data: any) => {
+ this.loadingIndicator = false;
this.nodes = this.abstractTreeData(data);
});
}
}
private abstractTreeData(data: any): any[] {
- const nodes = data.osd_map.tree.nodes || [];
+ const nodes = data.nodes || [];
const treeNodeMap: { [key: number]: any } = {};
if (0 === nodes.length) {