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

[ML] Data Frame Analytics: Fix steps to be named phases. #65855

Merged
merged 9 commits into from
May 13, 2020
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ import { getAnalysisType, DataFrameAnalyticsId } from '../../../../common';
import { CreateAnalyticsFormProps } from '../../hooks/use_create_analytics_form';
import {
getDataFrameAnalyticsProgress,
getDataFrameAnalyticsProgressPhase,
isDataFrameAnalyticsFailed,
isDataFrameAnalyticsRunning,
isDataFrameAnalyticsStopped,
Expand Down Expand Up @@ -72,22 +73,12 @@ export const getJobTypeBadge = (jobType: string) => (

export const progressColumn = {
name: i18n.translate('xpack.ml.dataframe.analyticsList.progress', {
defaultMessage: 'Progress per Step',
defaultMessage: 'Progress',
}),
sortable: (item: DataFrameAnalyticsListRow) => getDataFrameAnalyticsProgress(item.stats),
truncateText: true,
render(item: DataFrameAnalyticsListRow) {
const totalSteps = item.stats.progress.length;
let step = 0;
let progress = 0;

for (const progressStep of item.stats.progress) {
step++;
progress = progressStep.progress_percent;
if (progressStep.progress_percent < 100) {
break;
}
}
const { currentPhase, progress, totalPhases } = getDataFrameAnalyticsProgressPhase(item.stats);

// For now all analytics jobs are batch jobs.
const isBatchTransform = true;
Expand All @@ -96,25 +87,30 @@ export const progressColumn = {
<EuiFlexGroup alignItems="center" gutterSize="xs">
{isBatchTransform && (
<Fragment>
<EuiFlexItem style={{ width: '40px' }} grow={false}>
<EuiProgress
value={progress}
max={100}
color="primary"
size="m"
data-test-subj="mlAnalyticsTableProgress"
>
{progress}%
</EuiProgress>
</EuiFlexItem>
<EuiFlexItem style={{ width: '35px' }} grow={false}>
<EuiText size="xs">{`${progress}%`}</EuiText>
</EuiFlexItem>
<EuiFlexItem style={{ width: '21px' }} grow={false}>
<EuiFlexItem style={{ width: '60px' }} grow={false}>
<EuiText size="xs">
{step}/{totalSteps}
Phase {currentPhase}/{totalPhases}
</EuiText>
</EuiFlexItem>
<EuiFlexItem style={{ width: '40px' }} grow={false}>
<EuiToolTip
content={i18n.translate('xpack.ml.dataframe.analyticsList.progressOfPhase', {
defaultMessage: 'Progress of phase {currentPhase}: {progress}%',
values: {
currentPhase,
progress,
},
})}
>
<EuiProgress
value={progress}
max={100}
color="primary"
size="m"
data-test-subj="mlAnalyticsTableProgress"
/>
</EuiToolTip>
</EuiFlexItem>
</Fragment>
)}
{!isBatchTransform && (
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
import StatsMock from './__mocks__/analytics_stats.json';

import {
getDataFrameAnalyticsProgress,
getDataFrameAnalyticsProgressPhase,
isCompletedAnalyticsJob,
isDataFrameAnalyticsRunning,
isDataFrameAnalyticsStats,
Expand All @@ -17,13 +19,15 @@ import {
const completedJob = StatsMock.data_frame_analytics[0] as DataFrameAnalyticsStats;
const runningJob = StatsMock.data_frame_analytics[1] as DataFrameAnalyticsStats;

describe('Data Frame Analytics: common utils', () => {
test('isCompletedAnalyticsJob()', () => {
describe('Data Frame Analytics: isCompletedAnalyticsJob()', () => {
test('should report if job is completed', () => {
expect(isCompletedAnalyticsJob(completedJob)).toBe(true);
expect(isCompletedAnalyticsJob(runningJob)).toBe(false);
});
});

test('isDataFrameAnalyticsRunning()', () => {
describe('Data Frame Analytics: isDataFrameAnalyticsRunning()', () => {
test('should report if job is running', () => {
expect(isDataFrameAnalyticsRunning(completedJob.state)).toBe(false);
expect(isDataFrameAnalyticsRunning(runningJob.state)).toBe(true);
runningJob.state = DATA_FRAME_TASK_STATE.STARTED;
Expand All @@ -35,11 +39,35 @@ describe('Data Frame Analytics: common utils', () => {
runningJob.state = DATA_FRAME_TASK_STATE.FAILED;
expect(isDataFrameAnalyticsRunning(runningJob.state)).toBe(false);
});
});

test('isDataFrameAnalyticsStats()', () => {
describe('Data Frame Analytics: isDataFrameAnalyticsStats()', () => {
test('should return if valid analytics stats', () => {
expect(isDataFrameAnalyticsStats(completedJob)).toBe(true);
expect(isDataFrameAnalyticsStats(runningJob)).toBe(true);
expect(isDataFrameAnalyticsStats({})).toBe(false);
expect(isDataFrameAnalyticsStats('no-object')).toBe(false);
});
});

describe('Data Frame Analytics: getDataFrameAnalyticsProgress()', () => {
test('should report overall job progress percentage', () => {
expect(getDataFrameAnalyticsProgress(completedJob)).toBe(100);
expect(getDataFrameAnalyticsProgress(runningJob)).toBe(59);
});
});

describe('Data Frame Analytics: getDataFrameAnalyticsProgressPhase()', () => {
test('should report progress by current phase', () => {
expect(getDataFrameAnalyticsProgressPhase(completedJob)).toStrictEqual({
currentPhase: 4,
progress: 100,
totalPhases: 4,
});
expect(getDataFrameAnalyticsProgressPhase(runningJob)).toStrictEqual({
currentPhase: 3,
progress: 37,
totalPhases: 4,
});
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,22 @@ export function getDataFrameAnalyticsProgress(stats: DataFrameAnalyticsStats) {
return undefined;
}

export function getDataFrameAnalyticsProgressPhase(
stats: DataFrameAnalyticsStats
): { currentPhase: number; progress: number; totalPhases: number } {
let phase = 0;
let progress = 0;

for (const progressPhase of stats.progress) {
phase++;
progress = progressPhase.progress_percent;
if (progressPhase.progress_percent < 100) {
break;
}
}
return { currentPhase: phase, progress, totalPhases: stats.progress.length };
}

export interface DataFrameAnalyticsListRow {
id: DataFrameAnalyticsId;
checkpointing: object;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
Eval,
} from '../../../../common';
import { getTaskStateBadge } from './columns';
import { isCompletedAnalyticsJob } from './common';
import { getDataFrameAnalyticsProgressPhase, isCompletedAnalyticsJob } from './common';
import {
isRegressionAnalysis,
ANALYSIS_CONFIG_TYPE,
Expand Down Expand Up @@ -171,14 +171,7 @@ export const ExpandedRow: FC<Props> = ({ item }) => {
position: 'left',
};

const totalSteps = item.stats.progress.length;
let step = 0;
for (const progressStep of item.stats.progress) {
step++;
if (progressStep.progress_percent < 100) {
break;
}
}
const { currentPhase, totalPhases } = getDataFrameAnalyticsProgressPhase(item.stats);

const progress: SectionConfig = {
title: i18n.translate(
Expand All @@ -188,10 +181,10 @@ export const ExpandedRow: FC<Props> = ({ item }) => {
items: [
{
title: i18n.translate(
'xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.step',
{ defaultMessage: 'Step' }
'xpack.ml.dataframe.analyticsList.expandedRow.tabs.jobSettings.phase',
{ defaultMessage: 'Phase' }
),
description: `${step}/${totalSteps}`,
description: `${currentPhase}/${totalPhases}`,
},
...item.stats.progress.map(s => {
return {
Expand Down