Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Feature: Sub tasks show relevant tasks settings & cleanup #1900

Merged
merged 10 commits into from
Feb 5, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -112,12 +112,12 @@
<bl-text-property *ngIf="exitConditionData.default" [label]="'exitConditions.default' | i18n" [value]="exitConditionData.default"></bl-text-property>
</bl-property-group>

<bl-property-group [label]="'multiInstanceSettings.label' | i18n" *ngIf="task.multiInstanceSettings" [collapsed]="true">
<bl-property-group [label]="'multiInstanceSettings.label' | i18n" *ngIf="task.multiInstanceSettings; let multiInstanceSettings" [collapsed]="true">
<div collapsed-preview>
{{task.multiInstanceSettings.numberOfInstances}} subtasks. Running: <i>{{task.multiInstanceSettings.coordinationCommandLine}}</i>
{{multiInstanceSettings.numberOfInstances}} subtasks. Running: <i>{{multiInstanceSettings.coordinationCommandLine}}</i>
</div>
<bl-text-property [label]="'multiInstanceSettings.coordinationCommandLine.label' | i18n" [value]="task.multiInstanceSettings.coordinationCommandLine" [wrap]="true"></bl-text-property>
<bl-text-property [label]="'multiInstanceSettings.numberOfInstances.label' | i18n" [value]="task.multiInstanceSettings.numberOfInstances"></bl-text-property>
<bl-text-property [label]="'multiInstanceSettings.coordinationCommandLine.label' | i18n" [value]="multiInstanceSettings.coordinationCommandLine" [wrap]="true"></bl-text-property>
<bl-text-property [label]="'multiInstanceSettings.numberOfInstances.label' | i18n" [value]="multiInstanceSettings.numberOfInstances"></bl-text-property>
</bl-property-group>
</bl-property-list>
</bl-entity-configuration>
1 change: 0 additions & 1 deletion src/app/components/task/details/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,3 @@ export * from "./task-dependency-browser";
export * from "./task-error-display.component";
export * from "./task-details.module";
export * from "./resource-files";
export * from "./task-sub-tasks-tab.component";
5 changes: 3 additions & 2 deletions src/app/components/task/details/sub-tasks/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from "./sub-task-display-list.component";
export * from "./sub-task-properties.component";
export * from "./sub-tasks-browser.component";
export * from "./properties";
export * from "./list";
1 change: 1 addition & 0 deletions src/app/components/task/details/sub-tasks/list/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./sub-task-list.component";
Original file line number Diff line number Diff line change
@@ -1,31 +1,23 @@
import {
ChangeDetectionStrategy, Component, EventEmitter, Injector, Input, Output, ViewChild,
ChangeDetectionStrategy, Component, EventEmitter, Injector, Input, Output,
} from "@angular/core";
import { ListBaseComponent } from "@batch-flask/ui";
import { LoadingStatus } from "@batch-flask/ui/loading";
import { QuickListComponent, QuickListItemStatus } from "@batch-flask/ui/quick-list";
import { QuickListItemStatus } from "@batch-flask/ui/quick-list";
import { FailureInfoDecorator } from "app/decorators";
import { SubtaskInformation, TaskState } from "app/models";
import { List } from "immutable";

@Component({
selector: "bl-sub-task-display-list",
templateUrl: "sub-task-display-list.html",
selector: "bl-sub-task-list",
templateUrl: "sub-task-list.html",
changeDetection: ChangeDetectionStrategy.OnPush,
})

export class SubTaskDisplayListComponent extends ListBaseComponent {
@Input() public jobId: string;

@Input() public taskId: string;

export class SubTaskListComponent extends ListBaseComponent {
@Input() public subTasks: List<SubtaskInformation>;

@Input() public status: LoadingStatus;

@ViewChild(QuickListComponent)
public list: QuickListComponent;

@Output() public scrollBottom = new EventEmitter();

constructor(injector: Injector) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from "./sub-task-properties.component";
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
import { Component, DebugElement, NO_ERRORS_SCHEMA } from "@angular/core";
import { ComponentFixture, TestBed } from "@angular/core/testing";
import { By } from "@angular/platform-browser";
import { BoolPropertyComponent, TextPropertyComponent } from "@batch-flask/ui";
import { SubtaskInformation, Task, TaskState } from "app/models";
import { SubTaskPropertiesComponent } from "./sub-task-properties.component";

const task1 = new Task({
commandLine: "echo master",
multiInstanceSettings: {
coordinationCommandLine: "echo coordinating",
numberOfInstances: 7,
commonResourceFiles: [] as any,
},
});

const subtask1 = new SubtaskInformation({
id: 1,
exitCode: 0,
previousState: TaskState.running,
state: TaskState.completed,
});

const subtaskWithError = new SubtaskInformation({
id: 1,
exitCode: -29,
previousState: TaskState.running,
state: TaskState.completed,
failureInfo: {
code: "FOO",
category: "User",
details: [],
message: "Some error",
},
});

@Component({
template: `<bl-sub-task-properties [task]="task" [parentTask]="parentTask"></bl-sub-task-properties>`,
})
class TestComponent {
public task: SubtaskInformation = subtask1;
public parentTask: Task = task1;
}

describe("SubTaskPropertiesComponent", () => {
let fixture: ComponentFixture<TestComponent>;
let testComponent: TestComponent;
let de: DebugElement;

beforeEach(() => {
TestBed.configureTestingModule({
imports: [],
declarations: [SubTaskPropertiesComponent, TestComponent, TextPropertyComponent, BoolPropertyComponent],
schemas: [NO_ERRORS_SCHEMA],

});
fixture = TestBed.createComponent(TestComponent);
testComponent = fixture.componentInstance;
de = fixture.debugElement.query(By.css("bl-sub-task-properties"));
fixture.detectChanges();
});

function getProperty(label: string): DebugElement {
return de.query(By.css(`[label='${label}']`));
}

it("display ID", () => {
const idEl = getProperty("ID");
expect(idEl).not.toBeFalsy();
expect(idEl.nativeElement.textContent).toContain(1);
});

it("display exit code", () => {
const el = getProperty("Exit code");
expect(el).not.toBeFalsy();
expect(el.nativeElement.textContent).toContain(0);
});

it("display state", () => {
const el = getProperty("State");
expect(el).not.toBeFalsy();
expect(el.nativeElement.textContent).toContain(TaskState.completed);
});

it("display previous state", () => {
const el = getProperty("Previous State");
expect(el).not.toBeFalsy();
expect(el.nativeElement.textContent).toContain(TaskState.running);
});

it("display primary command line", () => {
const el = getProperty("Primary command line");
expect(el).not.toBeFalsy();
expect(el.nativeElement.textContent).toContain("echo master");
});

it("display coordination command line", () => {
const el = getProperty("Coordination command line");
expect(el).not.toBeFalsy();
expect(el.nativeElement.textContent).toContain("echo coordinating");
});

it("display number of sub tasks", () => {
const el = getProperty("Number of instances");
expect(el).not.toBeFalsy();
expect(el.nativeElement.textContent).toContain("7");
});

it("doesn't show the failure info group if there isn't", () => {
const el = de.query(By.css("bl-property-group[label='Failure info']"));
expect(el).toBeFalsy();
});

it("shows the failure info group if there is an error", () => {
testComponent.task = subtaskWithError;
fixture.detectChanges();
const el = de.query(By.css("bl-property-group[label='Failure info']"));
expect(el).toBeFalsy();
});
});
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { ChangeDetectionStrategy, Component, Input } from "@angular/core";
import { SubtaskInformation, Task } from "app/models";

@Component({
selector: "bl-sub-task-properties",
templateUrl: "sub-task-properties.html",
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class SubTaskPropertiesComponent {
@Input() public parentTask: Task;
@Input() public task: SubtaskInformation;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
<bl-property-list>
<bl-property-group label="General" class="normal">
<bl-text-property label="ID" [value]="task.id"></bl-text-property>
<bl-date-property label="Start time" [value]="task.startTime"></bl-date-property>
<bl-date-property label="End time" [value]="task.endTime"></bl-date-property>
<bl-text-property label="Exit code" [value]="task.exitCode"></bl-text-property>
<bl-text-property label="State" [value]="task.state"></bl-text-property>
<bl-date-property label="State transition time" [value]="task.stateTransitionTime"></bl-date-property>
<bl-text-property label="Previous State" [value]="task.previousState"></bl-text-property>
<bl-date-property label="Previous state transition time" [value]="task.previousStateTransitionTime"></bl-date-property>
</bl-property-group>

<bl-property-group label="Task common settings" class="normal" *ngIf="parentTask.multiInstanceSettings;let multiInstanceSettings">
<bl-text-property label="Primary command line" [value]="parentTask.commandLine" [wrap]="true"></bl-text-property>
<bl-text-property label="Coordination command line" [value]="multiInstanceSettings.coordinationCommandLine" [wrap]="true"></bl-text-property>
<bl-text-property label="Number of instances" [value]="multiInstanceSettings.numberOfInstances"></bl-text-property>
</bl-property-group>

<bl-property-group label="Compute node" class="normal" *ngIf="task.nodeInfo; let nodeInfo">
<bl-link-property label="Pool ID" [value]="nodeInfo.poolId" [link]="['/pools/', nodeInfo.poolId]"></bl-link-property>
<bl-link-property label="Node ID" [value]="nodeInfo.nodeId" [link]="['/pools/', nodeInfo.poolId, 'nodes', nodeInfo.nodeId]"></bl-link-property>
<bl-text-property label="Node URL" [value]="nodeInfo.nodeUrl"></bl-text-property>
<bl-text-property label="Affinity ID" [value]="nodeInfo.affinityId"></bl-text-property>
<bl-text-property label="Task root directory" [value]="nodeInfo.taskRootDirectory"></bl-text-property>
<bl-text-property label="Task root directory URL" [value]="nodeInfo.taskRootDirectoryUrl"></bl-text-property>
</bl-property-group>

<bl-property-group label="Scheduling Error" class="normal" *ngIf="task.failureInfo; let failureInfo">
<bl-text-property label="Category" [value]="failureInfo.category"></bl-text-property>
<bl-text-property label="Code" [value]="failureInfo.code"></bl-text-property>
<bl-text-property label="Message" [value]="failureInfo.message"></bl-text-property>
<bl-text-property label="Detals" [value]="failureInfo.details"></bl-text-property>
</bl-property-group>
</bl-property-list>

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,70 +1,52 @@
import {
ChangeDetectionStrategy, Component, Injector, Input, OnChanges, OnDestroy, ViewChild,
ChangeDetectionStrategy, ChangeDetectorRef, Component, Input, OnChanges, OnDestroy, SimpleChanges,
} from "@angular/core";
import { ListView, autobind } from "@batch-flask/core";
import { ListBaseComponent } from "@batch-flask/ui";
import { SubtaskInformation } from "app/models";
import { SubtaskInformation, Task } from "app/models";
import { SubtaskListParams, TaskService } from "app/services";
import { List } from "immutable";
import { Observable } from "rxjs";
import { SubTaskDisplayListComponent } from "./sub-tasks";

import { ComponentUtils } from "app/utils";
import "./sub-tasks-browser.scss";

@Component({
selector: "bl-task-sub-tasks-tab",
templateUrl: "task-sub-tasks-tab.html",
selector: "bl-sub-tasks-browser",
templateUrl: "sub-tasks-browser.html",
changeDetection: ChangeDetectionStrategy.OnPush,
})
export class TaskSubTasksTabComponent extends ListBaseComponent implements OnChanges, OnDestroy {
@Input() public set jobId(value: string) {
this._jobId = (value && value.trim());
}
public get jobId() { return this._jobId; }

@Input() public set taskId(value: string) {
this._taskId = (value && value.trim());
}
public get taskId() { return this._jobId; }

@ViewChild(SubTaskDisplayListComponent)
public list: any;
export class TaskSubTasksBrowserComponent implements OnChanges, OnDestroy {
@Input() public jobId: string;
@Input() public task: Task;

public data: ListView<SubtaskInformation, SubtaskListParams>;

public selectedTask: SubtaskInformation;
public selectedTaskId: number;
public subTasks: List<SubtaskInformation>;

private _jobId: string;
private _taskId: string;

constructor(private taskService: TaskService, injector: Injector) {
super(injector);

constructor(private taskService: TaskService, private changeDetector: ChangeDetectorRef) {
this.data = this.taskService.listSubTasksView({});
this.data.items.subscribe((subTasks) => {
this.subTasks = subTasks;
this._updateSelectedTask();
this.changeDetector.markForCheck();
});

this.data.status.subscribe((status) => {
this.status = status;
});
}

public ngOnChanges(changes) {
if (changes.jobId || changes.taskId) {
public ngOnChanges(changes: SimpleChanges) {
if (changes.jobId || ComponentUtils.recordChangedId(changes.task)) {
this.refresh();
}
}

public ngOnDestroy() {
super.ngOnDestroy();
this.data.dispose();
}

@autobind()
public refresh(): Observable<any> {
this.data.params = { jobId: this._jobId, taskId: this._taskId };
this.data.params = { jobId: this.jobId, taskId: this.task.id };
this.selectedTask = null;
this.selectedTaskId = null;
this.changeDetector.markForCheck();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
<bl-sub-task-list
[class.item-selected]="selectedTask"
[subTasks]="subTasks"
[status]="data.status | async"
[activeItem]="selectedTaskId"
(activeItemChange)="selectedTaskChanged($event)"
(scrollBottom)="onScrollToBottom()">
</bl-sub-task-list>
<bl-sub-task-properties [task]="selectedTask" [parentTask]="task" *ngIf="selectedTask"></bl-sub-task-properties>
Loading