Skip to content

Commit

Permalink
[ML] Add check that forecast results exist
Browse files Browse the repository at this point in the history
  • Loading branch information
peteharverson committed Feb 10, 2022
1 parent 600f838 commit 7b1fb58
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 6 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,9 @@ export default ({ getService }: FtrProviderContext) => {
const spacesService = getService('spaces');

const forecastJobId = 'fq_single_forecast';
const forecastJobDatafeedId = `datafeed-${forecastJobId}`;
const idSpace1 = 'space1';
const idSpace2 = 'space2';
const jobConfig = ml.commonConfig.getADFqSingleMetricJobConfig(forecastJobId);
const datafeedConfig = ml.commonConfig.getADFqDatafeedConfig(forecastJobId);

async function runForecast(
jobId: string,
Expand All @@ -47,6 +46,9 @@ export default ({ getService }: FtrProviderContext) => {
await spacesService.create({ id: idSpace1, name: 'space_one', disabledFeatures: [] });
await spacesService.create({ id: idSpace2, name: 'space_two', disabledFeatures: [] });

const jobConfig = ml.commonConfig.getADFqSingleMetricJobConfig(forecastJobId);
const datafeedConfig = ml.commonConfig.getADFqDatafeedConfig(forecastJobId);

await ml.api.createAnomalyDetectionJob(jobConfig, idSpace1);
await ml.api.createDatafeed(datafeedConfig, idSpace1);
});
Expand All @@ -73,15 +75,19 @@ export default ({ getService }: FtrProviderContext) => {
});

it('should run forecast for open job with valid job ID', async () => {
await ml.api.startDatafeed(datafeedConfig.datafeed_id, { start: '0', end: `${Date.now()}` });
await ml.api.waitForDatafeedState(datafeedConfig.datafeed_id, DATAFEED_STATE.STOPPED);
await ml.api.waitForJobState(jobConfig.job_id, JOB_STATE.CLOSED);
await ml.api.startDatafeed(forecastJobDatafeedId, { start: '0', end: `${Date.now()}` });
await ml.api.waitForDatafeedState(forecastJobDatafeedId, DATAFEED_STATE.STOPPED);
await ml.api.waitForJobState(forecastJobId, JOB_STATE.CLOSED);
await ml.api.openAnomalyDetectionJob(forecastJobId);
await runForecast(forecastJobId, idSpace1, '1d', USER.ML_POWERUSER, 200);
await ml.testExecution.logTestStep(
`forecast results should exist for job '${forecastJobId}'`
);
await ml.api.assertForecastResultsExist(forecastJobId);
});

it('should not run forecast for open job with invalid duration', async () => {
await runForecast(forecastJobId, idSpace1, 3600000, USER.ML_VIEWER, 403);
await runForecast(forecastJobId, idSpace1, 3600000, USER.ML_POWERUSER, 400);
});

it('should not run forecast for open job with valid job ID as ML Viewer', async () => {
Expand Down
41 changes: 41 additions & 0 deletions x-pack/test/functional/services/ml/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,6 +126,47 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) {
);
},

async hasForecastResults(jobId: string): Promise<boolean> {
const body = await es.search({
index: '.ml-anomalies-*',
body: {
size: 1,
query: {
bool: {
must: [
{
match: {
job_id: jobId,
},
},
{
match: {
result_type: 'model_forecast',
},
},
],
},
},
},
});

return body.hits.hits.length > 0;
},

async assertForecastResultsExist(jobId: string) {
await retry.waitForWithTimeout(
`forecast results for job ${jobId} to exist`,
30 * 1000,
async () => {
if ((await this.hasForecastResults(jobId)) === true) {
return true;
} else {
throw new Error(`expected forecast results for job '${jobId}' to exist`);
}
}
);
},

async createIndex(
indices: string,
mappings?: Record<string, estypes.MappingTypeMapping> | estypes.MappingTypeMapping
Expand Down

0 comments on commit 7b1fb58

Please sign in to comment.