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

Report all completed steps #73

Merged
merged 1 commit into from
Mar 24, 2021
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
25 changes: 15 additions & 10 deletions src/api/general-services/pipeline-status.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ const getStepsFromExecutionHistory = (history) => {
}
}

allBranchesStarted() {
workingOnBranches() {
return this.branchCount === Object.values(this.branches).length;
}

Expand All @@ -33,7 +33,7 @@ const getStepsFromExecutionHistory = (history) => {
return this;
}

if (event.type === 'End') {
if (event.type === 'MapStateExited') {
return this;
}

Expand All @@ -58,6 +58,10 @@ const getStepsFromExecutionHistory = (history) => {
this.completedTasks.push(this.currentState);
} else if (event.type === 'MapStateStarted') {
this.branchCount = event.mapStateStartedEventDetails.length;
} else if (event.type === 'MapStateExited') {
this.completedTasks = this.completedTasks.concat(this.branches[0].completedTasks);
this.branches = {};
this.branchCount = 0;
}
}
}
Expand All @@ -71,25 +75,26 @@ const getStepsFromExecutionHistory = (history) => {

let shortestCompleted = null;

if (main.allBranchesStarted()) {
if (main.workingOnBranches()) {
const branches = Object.values(main.branches);
for (let ii = 0; ii < branches.length; ii += 1) {
if (!shortestCompleted || branches[ii].completedTasks.length < shortestCompleted.length) {
shortestCompleted = branches[ii].completedTasks;
}
}
}
shortestCompleted = (shortestCompleted || []).concat(main.completedTasks);
return shortestCompleted || [];
};

/*
* Return the `completedSteps` of the state machine (SM) associated to the `experimentId`'s pipeline
* The code assumes that
* - the relevant states for the steps are defined within a Map of the SM
* - the relevant Map is the first Map in the SM
* - a step is only considered completed if it has been completed for all iteration of the Map
* - steps are returned in the completion order, and are unique in the returned array
*/
* Return `completedSteps` of the state machine (SM) associated to the `experimentId`'s pipeline
* The code assumes that
* - the relevant states for the steps are defined within a Map of the SM
* - the relevant Map is the first Map in the SM
* - a step is only considered completed if it has been completed for all iteration of the Map
* - steps are returned in the completion order, and are unique in the returned array
*/
const getPipelineStatus = async (experimentId) => {
const { executionArn } = await (new ExperimentService()).getPipelineHandle(experimentId);
let execution = {};
Expand Down
90 changes: 87 additions & 3 deletions tests/api/general-services/pipeline-status.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -113,12 +113,90 @@ describe('getStepsFromExecutionHistory', () => {
{
// Iteration 1
type: 'TaskStateExited',
id: '24-two-completions-vs-zero',
id: '24-two-completions-vs-one',
previousEventId: 23,
stateExitedEventDetails: {
name: 'CellSizeDistributionFilter',
},
},
{
// Iteration 1
type: 'TaskStateEntered',
id: 25,
previousEventId: '24-two-completions-vs-one',
stateEnteredEventDetails: {
name: 'MitochondrialContentFilter',
},
},
{
// Iteration 1
type: 'TaskSucceeded',
id: 26,
previousEventId: 25,
},
{
// Iteration 1
type: 'TaskStateExited',
id: 27,
previousEventId: 26,
stateExitedEventDetails: {
name: 'MitochondrialContentFilter',
},
},
{
// Iteration 1
type: 'MapIterationSucceeded',
id: 28,
previousEventId: 27,
mapIterationSucceededEventDetails: {
name: 'Filters',
index: 1,
},
},
{
// Iteration 0
type: 'MapIterationSucceeded',
id: 29,
previousEventId: 22,
mapIterationSucceededEventDetails: {
name: 'Filters',
index: 0,
},
},
{
type: 'MapStateSucceeded',
id: 30,
previousEventId: 29,
},
{
type: 'MapStateExited',
id: 31,
previousEventId: 30,
stateExitedEventDetails: {
name: 'Filters',
},
},
{
type: 'TaskStateEntered',
id: 32,
previousEventId: 31,
stateEnteredEventDetails: {
name: 'DataIntegration',
},
},
{
type: 'TaskSucceeded',
id: 33,
previousEventId: 32,
},
{
type: 'TaskStateExited',
id: 34,
previousEventId: 33,
stateExitedEventDetails: {
name: 'DataIntegration',
},
},
];

const singleIterationHistory = [
Expand Down Expand Up @@ -242,16 +320,22 @@ describe('getStepsFromExecutionHistory', () => {
});

it('returns steps completed in all branches', () => {
const events = truncateHistory('24-two-completions-vs-zero');
const events = truncateHistory('24-two-completions-vs-one');
const completedSteps = pipelineStatus.getStepsFromExecutionHistory({ events });
expect(completedSteps).toEqual(['CellSizeDistributionFilter']);
});

it('returns all elements contained in the Map for one-element iterations', () => {
it('returns all steps in a finished single-sample execution', () => {
const history = { events: singleIterationHistory };
const completedSteps = pipelineStatus.getStepsFromExecutionHistory(history);
expect(completedSteps).toEqual(['CellSizeDistributionFilter', 'DataIntegration']);
});

it('returns all steps in a finished multiple-sample execution', () => {
const history = { events: fullHistory };
const completedSteps = pipelineStatus.getStepsFromExecutionHistory(history);
expect(completedSteps).toEqual(['CellSizeDistributionFilter', 'MitochondrialContentFilter', 'DataIntegration']);
});
});

jest.mock('../../../src/api/route-services/experiment', () => jest.fn().mockImplementation(() => ({
Expand Down