import { PopoverModule } from 'ngx-bootstrap';
+import { ExecutingTask } from '../../../shared/models/executing-task';
+import { FinishedTask } from '../../../shared/models/finished-task';
import { SharedModule } from '../../../shared/shared.module';
import { configureTestBed } from '../../../shared/unit-test-helper';
import { TaskManagerComponent } from './task-manager.component';
describe('TaskManagerComponent', () => {
let component: TaskManagerComponent;
let fixture: ComponentFixture<TaskManagerComponent>;
+ const tasks = {
+ executing: [],
+ finished: []
+ };
configureTestBed({
imports: [SharedModule, PopoverModule.forRoot(), HttpClientTestingModule],
fixture = TestBed.createComponent(TaskManagerComponent);
component = fixture.componentInstance;
fixture.detectChanges();
+ tasks.executing = [
+ new ExecutingTask('rbd/delete', {
+ pool_name: 'somePool',
+ image_name: 'someImage'
+ })
+ ];
+ tasks.finished = [
+ new FinishedTask('rbd/copy', {
+ dest_pool_name: 'somePool',
+ dest_image_name: 'someImage'
+ }),
+ new FinishedTask('rbd/clone', {
+ child_pool_name: 'somePool',
+ child_image_name: 'someImage'
+ })
+ ];
+ tasks.finished[1].success = false;
+ tasks.finished[1].exception = { code: 17 };
});
it('should create', () => {
expect(component).toBeTruthy();
});
+
+ it('should get executing message for task', () => {
+ component._handleTasks(tasks.executing, []);
+ expect(component.executingTasks.length).toBe(1);
+ expect(component.executingTasks[0].description).toBe('Deleting RBD \'somePool/someImage\'');
+ });
+
+ it('should get finished message for task', () => {
+ component._handleTasks([], tasks.finished);
+ expect(component.finishedTasks.length).toBe(2);
+ expect(component.finishedTasks[0].description).toBe('Copy RBD \'somePool/someImage\'');
+ expect(component.finishedTasks[0].errorMessage).toBe(undefined);
+ expect(component.finishedTasks[1].description).toBe('Clone RBD \'somePool/someImage\'');
+ expect(component.finishedTasks[1].errorMessage).toBe(
+ 'Name \'somePool/someImage\' is already in use.'
+ );
+ });
+
+ it('should get an empty hour glass with only finished tasks', () => {
+ component._setIcon(0);
+ expect(component.icon).toBe('fa-hourglass-o');
+ });
+
+ it('should get a nearly empty hour glass with executing tasks', () => {
+ component._setIcon(10);
+ expect(component.icon).toBe('fa-hourglass-start');
+ });
});
styleUrls: ['./task-manager.component.scss']
})
export class TaskManagerComponent implements OnInit {
-
- executingTasks: Array<ExecutingTask> = [];
- finishedTasks: Array<FinishedTask> = [];
+ executingTasks: ExecutingTask[] = [];
+ finishedTasks: FinishedTask[] = [];
icon = 'fa-hourglass-o';
- constructor(private summaryService: SummaryService,
- private taskManagerMessageService: TaskManagerMessageService) {
- }
+ constructor(
+ private summaryService: SummaryService,
+ private taskMessageManager: TaskManagerMessageService
+ ) {}
ngOnInit() {
- const icons = ['fa-hourglass-o', 'fa-hourglass-start', 'fa-hourglass-half', 'fa-hourglass-end'];
- let iconIndex = 0;
this.summaryService.summaryData$.subscribe((data: any) => {
- this.executingTasks = data.executing_tasks;
- this.finishedTasks = data.finished_tasks;
- for (const excutingTask of this.executingTasks) {
- excutingTask.description = this.taskManagerMessageService.getDescription(excutingTask);
- }
- for (const finishedTask of this.finishedTasks) {
- finishedTask.description = this.taskManagerMessageService.getDescription(finishedTask);
- if (finishedTask.success === false) {
- finishedTask.errorMessage = this.taskManagerMessageService.getErrorMessage(finishedTask);
- }
- }
- if (this.executingTasks.length > 0) {
- iconIndex = (iconIndex + 1) % icons.length;
- } else {
- iconIndex = 0;
- }
- this.icon = icons[iconIndex];
+ this._handleTasks(data.executing_tasks, data.finished_tasks);
+ this._setIcon(data.executing_tasks.length);
});
}
+ _handleTasks(executingTasks: ExecutingTask[], finishedTasks: FinishedTask[]) {
+ for (const excutingTask of executingTasks) {
+ excutingTask.description = this.taskMessageManager.getRunningMessage(excutingTask);
+ }
+ for (const finishedTask of finishedTasks) {
+ finishedTask.description = this.taskMessageManager.getDescription(finishedTask);
+ if (finishedTask.success === false) {
+ finishedTask.errorMessage = this.taskMessageManager.getErrorMessage(finishedTask);
+ }
+ }
+ this.executingTasks = executingTasks;
+ this.finishedTasks = finishedTasks;
+ }
+
+ _setIcon(executingTasks: number) {
+ const iconSuffix = ['o', 'start', 'half', 'end']; // TODO: Use all suffixes
+ const iconIndex = executingTasks > 0 ? 1 : 0;
+ this.icon = 'fa-hourglass-' + iconSuffix[iconIndex];
+ }
}
expect(message).toBe('Unknown Task');
});
+ it('should get default running message', () => {
+ finishedTask.metadata = {};
+ let message = service.getRunningMessage(finishedTask);
+ expect(message).toBe('Executing unknown task');
+ finishedTask.metadata = { component: 'rbd' };
+ message = service.getRunningMessage(finishedTask);
+ expect(message).toBe('Executing RBD');
+ });
+
+ it('should get custom running message', () => {
+ finishedTask.name = 'rbd/create';
+ finishedTask.metadata = {
+ pool_name: 'somePool',
+ image_name: 'someImage'
+ };
+ const message = service.getRunningMessage(finishedTask);
+ expect(message).toBe('Creating RBD \'somePool/someImage\'');
+ });
+
it('should getErrorMessage', () => {
finishedTask.exception = _.assign(new TaskException(), {
code: 1
expect(value.descr({})).toBeTruthy();
expect(value.success({})).toBeTruthy();
expect(value.error({})).toBeTruthy();
+ expect(value.running({})).toBeTruthy();
});
});
});
class TaskManagerMessage {
descr: (metadata) => string;
+ running: (metadata) => string;
success: (metadata) => string;
error: (metadata) => object;
constructor(
descr: (metadata) => string,
+ running: (metadata) => string,
success: (metadata) => string,
error: (metadata) => object
) {
this.descr = descr;
+ this.running = running;
this.success = success;
this.error = error;
}
messages = {
'rbd/create': new TaskManagerMessage(
(metadata) => `Create RBD '${metadata.pool_name}/${metadata.image_name}'`,
- (metadata) => `RBD '${metadata.pool_name}/${metadata.image_name}'
- has been created successfully`,
+ (metadata) => `Creating RBD '${metadata.pool_name}/${metadata.image_name}'`,
+ (metadata) =>
+ `RBD '${metadata.pool_name}/${metadata.image_name}' has been created successfully`,
(metadata) => {
return {
- '17': `Name '${metadata.pool_name}/${metadata.image_name}' is already
- in use.`
+ '17': `Name '${metadata.pool_name}/${metadata.image_name}' is already in use.`
};
}
),
'rbd/edit': new TaskManagerMessage(
(metadata) => `Update RBD '${metadata.pool_name}/${metadata.image_name}'`,
- (metadata) => `RBD '${metadata.pool_name}/${metadata.image_name}'
- has been updated successfully`,
+ (metadata) => `Updating RBD '${metadata.pool_name}/${metadata.image_name}'`,
+ (metadata) =>
+ `RBD '${metadata.pool_name}/${metadata.image_name}' has been updated successfully`,
(metadata) => {
return {
- '17': `Name '${metadata.pool_name}/${metadata.name}' is already
- in use.`
+ '17': `Name '${metadata.pool_name}/${metadata.name}' is already in use.`
};
}
),
'rbd/delete': new TaskManagerMessage(
(metadata) => `Delete RBD '${metadata.pool_name}/${metadata.image_name}'`,
- (metadata) => `RBD '${metadata.pool_name}/${metadata.image_name}'
- has been deleted successfully`,
+ (metadata) => `Deleting RBD '${metadata.pool_name}/${metadata.image_name}'`,
+ (metadata) =>
+ `RBD '${metadata.pool_name}/${metadata.image_name}' has been deleted successfully`,
(metadata) => {
return {
'39': `RBD image contains snapshots.`
),
'rbd/clone': new TaskManagerMessage(
(metadata) => `Clone RBD '${metadata.child_pool_name}/${metadata.child_image_name}'`,
- (metadata) => `RBD '${metadata.child_pool_name}/${metadata.child_image_name}'
- has been cloned successfully`,
+ (metadata) => `Cloning RBD '${metadata.child_pool_name}/${metadata.child_image_name}'`,
+ (metadata) =>
+ `RBD '${metadata.child_pool_name}/${
+ metadata.child_image_name
+ }' has been cloned successfully`,
(metadata) => {
return {
- '17': `Name '${metadata.child_pool_name}/${metadata.child_image_name}' is already
- in use.`,
+ '17': `Name '${metadata.child_pool_name}/${
+ metadata.child_image_name
+ }' is already in use.`,
'22': `Snapshot must be protected.`
};
}
),
'rbd/copy': new TaskManagerMessage(
(metadata) => `Copy RBD '${metadata.dest_pool_name}/${metadata.dest_image_name}'`,
- (metadata) => `RBD '${metadata.dest_pool_name}/${metadata.dest_image_name}'
- has been copied successfully`,
+ (metadata) => `Copying RBD '${metadata.dest_pool_name}/${metadata.dest_image_name}'`,
+ (metadata) =>
+ `RBD '${metadata.dest_pool_name}/${metadata.dest_image_name}' has been copied successfully`,
(metadata) => {
return {
- '17': `Name '${metadata.dest_pool_name}/${metadata.dest_image_name}' is already
- in use.`
+ '17': `Name '${metadata.dest_pool_name}/${metadata.dest_image_name}' is already in use.`
};
}
),
'rbd/flatten': new TaskManagerMessage(
(metadata) => `Flatten RBD '${metadata.pool_name}/${metadata.image_name}'`,
- (metadata) => `RBD '${metadata.pool_name}/${metadata.image_name}'
- has been flattened successfully`,
+ (metadata) => `Flattening RBD '${metadata.pool_name}/${metadata.image_name}'`,
+ (metadata) =>
+ `RBD '${metadata.pool_name}/${metadata.image_name}' has been flattened successfully`,
() => {
return {};
}
(metadata) =>
`Create snapshot ` +
`'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`,
+ (metadata) =>
+ `Creating snapshot ` +
+ `'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`,
(metadata) =>
`Snapshot ` +
`'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}' ` +
(metadata) =>
`Update snapshot ` +
`'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`,
+ (metadata) =>
+ `Updating snapshot ` +
+ `'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`,
(metadata) =>
`Snapshot ` +
`'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}' ` +
(metadata) =>
`Delete snapshot ` +
`'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`,
+ (metadata) =>
+ `Deleting snapshot ` +
+ `'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`,
(metadata) =>
`Snapshot ` +
`'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}' ` +
(metadata) =>
`Rollback snapshot ` +
`'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`,
+ (metadata) =>
+ `Rolling back snapshot ` +
+ `'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}'`,
(metadata) =>
`Snapshot ` +
`'${metadata.pool_name}/${metadata.image_name}@${metadata.snapshot_name}' ` +
(metadata) => {
return Components[metadata.component] || metadata.component || 'Unknown Task';
},
+ (metadata) => {
+ return (
+ 'Executing ' + (Components[metadata.component] || metadata.component || 'unknown task')
+ );
+ },
(metadata) => 'Task executed successfully',
() => {
return {};
const taskManagerMessage = this.messages[task.name] || this.defaultMessage;
return taskManagerMessage.descr(task.metadata);
}
+
+ getRunningMessage(task: Task) {
+ const taskManagerMessage = this.messages[task.name] || this.defaultMessage;
+ return taskManagerMessage.running(task.metadata);
+ }
}
_handleExecutingTasks(task: FinishedTask, tasks?: ExecutingTask[]) {
this.notificationService.show(
NotificationType.info,
- task.name + ' in progress...',
+ this.taskManagerMessageService.getRunningMessage(task),
this.taskManagerMessageService.getDescription(task)
);
const executingTask = new ExecutingTask(task.name, task.metadata);