[ML] Transform functional tests - bootstrap transform job for clone test (#57992)
This PR adds transform bootstrapping to the functional test transform.api service and demonstrates the usage in a new cloning test file, which will be completed as part of the transform cloning PR.
This commit is contained in:
parent
b07aa09606
commit
16eb81628f
3 changed files with 157 additions and 0 deletions
65
x-pack/test/functional/apps/transform/cloning.ts
Normal file
65
x-pack/test/functional/apps/transform/cloning.ts
Normal file
|
@ -0,0 +1,65 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
import { TransformPivotConfig } from '../../../../legacy/plugins/transform/public/app/common';
|
||||
|
||||
function getTransformConfig(): TransformPivotConfig {
|
||||
const date = Date.now();
|
||||
return {
|
||||
id: `ec_2_${date}`,
|
||||
source: { index: ['ecommerce'] },
|
||||
pivot: {
|
||||
group_by: { category: { terms: { field: 'category.keyword' } } },
|
||||
aggregations: { 'products.base_price.avg': { avg: { field: 'products.base_price' } } },
|
||||
},
|
||||
description:
|
||||
'ecommerce batch transform with avg(products.base_price) grouped by terms(category.keyword)',
|
||||
dest: { index: `user-ec_2_${date}` },
|
||||
};
|
||||
}
|
||||
|
||||
export default function({ getService }: FtrProviderContext) {
|
||||
const esArchiver = getService('esArchiver');
|
||||
const transform = getService('transform');
|
||||
|
||||
describe('cloning', function() {
|
||||
this.tags(['smoke']);
|
||||
const transformConfig = getTransformConfig();
|
||||
|
||||
before(async () => {
|
||||
await esArchiver.load('ml/ecommerce');
|
||||
await transform.api.createAndRunTransform(transformConfig);
|
||||
await transform.securityUI.loginAsTransformPowerUser();
|
||||
});
|
||||
|
||||
after(async () => {
|
||||
await esArchiver.unload('ml/ecommerce');
|
||||
await transform.api.deleteIndices(transformConfig.dest.index);
|
||||
await transform.api.cleanTransformIndices();
|
||||
});
|
||||
|
||||
const testDataList = [
|
||||
{
|
||||
suiteTitle: 'batch transform with terms group and avg agg',
|
||||
expected: {},
|
||||
},
|
||||
];
|
||||
|
||||
for (const testData of testDataList) {
|
||||
describe(`${testData.suiteTitle}`, function() {
|
||||
after(async () => {
|
||||
// await transform.api.deleteIndices(<CLONE_DEST_INDEX>);
|
||||
});
|
||||
|
||||
it('loads the home page', async () => {
|
||||
await transform.navigation.navigateTo();
|
||||
await transform.management.assertTransformListPageExists();
|
||||
});
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
|
@ -23,5 +23,6 @@ export default function({ getService, loadTestFile }: FtrProviderContext) {
|
|||
|
||||
loadTestFile(require.resolve('./creation_index_pattern'));
|
||||
loadTestFile(require.resolve('./creation_saved_search'));
|
||||
loadTestFile(require.resolve('./cloning'));
|
||||
});
|
||||
}
|
||||
|
|
|
@ -7,10 +7,17 @@ import expect from '@kbn/expect';
|
|||
|
||||
import { FtrProviderContext } from '../../ftr_provider_context';
|
||||
|
||||
import {
|
||||
TRANSFORM_STATE,
|
||||
TransformPivotConfig,
|
||||
TransformStats,
|
||||
} from '../../../../legacy/plugins/transform/public/app/common';
|
||||
|
||||
export function TransformAPIProvider({ getService }: FtrProviderContext) {
|
||||
const es = getService('legacyEs');
|
||||
const log = getService('log');
|
||||
const retry = getService('retry');
|
||||
const esSupertest = getService('esSupertest');
|
||||
|
||||
return {
|
||||
async deleteIndices(indices: string) {
|
||||
|
@ -39,5 +46,89 @@ export function TransformAPIProvider({ getService }: FtrProviderContext) {
|
|||
async cleanTransformIndices() {
|
||||
await this.deleteIndices('.transform-*');
|
||||
},
|
||||
|
||||
async getTransformStats(transformId: string): Promise<TransformStats> {
|
||||
log.debug(`Fetching transform stats for transform ${transformId}`);
|
||||
const statsResponse = await esSupertest
|
||||
.get(`/_transform/${transformId}/_stats`)
|
||||
.expect(200)
|
||||
.then((res: any) => res.body);
|
||||
|
||||
expect(statsResponse.transforms).to.have.length(1);
|
||||
return statsResponse.transforms[0];
|
||||
},
|
||||
|
||||
async getTransformState(transformId: string): Promise<TRANSFORM_STATE> {
|
||||
const stats = await this.getTransformStats(transformId);
|
||||
const state: TRANSFORM_STATE = stats.state;
|
||||
|
||||
return state;
|
||||
},
|
||||
|
||||
async waitForTransformState(transformId: string, expectedState: TRANSFORM_STATE) {
|
||||
await retry.waitForWithTimeout(
|
||||
`transform state to be ${expectedState}`,
|
||||
2 * 60 * 1000,
|
||||
async () => {
|
||||
const state = await this.getTransformState(transformId);
|
||||
if (state === expectedState) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(`expected transform state to be ${expectedState} but got ${state}`);
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
async waitForBatchTransformToComplete(transformId: string) {
|
||||
await retry.waitForWithTimeout(`batch transform to complete`, 2 * 60 * 1000, async () => {
|
||||
const stats = await this.getTransformStats(transformId);
|
||||
if (stats.state === TRANSFORM_STATE.STOPPED && stats.checkpointing.last.checkpoint === 1) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(
|
||||
`expected batch transform to be stopped with last checkpoint = 1 (got status: '${stats.state}', checkpoint: '${stats.checkpointing.last.checkpoint}')`
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async getTransform(transformId: string) {
|
||||
return await esSupertest.get(`/_transform/${transformId}`).expect(200);
|
||||
},
|
||||
|
||||
async createTransform(transformConfig: TransformPivotConfig) {
|
||||
const transformId = transformConfig.id;
|
||||
log.debug(`Creating transform with id '${transformId}'...`);
|
||||
await esSupertest
|
||||
.put(`/_transform/${transformId}`)
|
||||
.send(transformConfig)
|
||||
.expect(200);
|
||||
|
||||
await retry.waitForWithTimeout(`'${transformId}' to be created`, 5 * 1000, async () => {
|
||||
if (await this.getTransform(transformId)) {
|
||||
return true;
|
||||
} else {
|
||||
throw new Error(`expected transform '${transformId}' to be created`);
|
||||
}
|
||||
});
|
||||
},
|
||||
|
||||
async startTransform(transformId: string) {
|
||||
log.debug(`Starting transform '${transformId}' ...`);
|
||||
await esSupertest.post(`/_transform/${transformId}/_start`).expect(200);
|
||||
},
|
||||
|
||||
async createAndRunTransform(transformConfig: TransformPivotConfig) {
|
||||
await this.createTransform(transformConfig);
|
||||
await this.startTransform(transformConfig.id);
|
||||
if (transformConfig.sync === undefined) {
|
||||
// batch mode
|
||||
await this.waitForBatchTransformToComplete(transformConfig.id);
|
||||
} else {
|
||||
// continuous mode
|
||||
await this.waitForTransformState(transformConfig.id, TRANSFORM_STATE.STARTED);
|
||||
}
|
||||
},
|
||||
};
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue