forked from elastic/kibana
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
[ML] Add integration tests for
trained_models
API (elastic#104819)
* [ML] api integration tests for get trained models endpoint * [ML] delete ingest pipelines after tests execution * [ML] deleteIngestPipeline method * [ML] test for unauthorized user * [ML] tests for model stats * [ML] delete trained model tests * [ML] fix typo * [ML] fix expect package path * [ML] get model pipelines tests * [ML] test for aliases * [ML] add tests for a 404 response * [ML] fix typo * [ML] fix typo
- Loading branch information
1 parent
a037e19
commit 590883f
Showing
8 changed files
with
371 additions
and
35 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
67 changes: 67 additions & 0 deletions
67
x-pack/test/api_integration/apis/ml/trained_models/delete_model.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import expect from '@kbn/expect'; | ||
import { FtrProviderContext } from '../../../ftr_provider_context'; | ||
import { USER } from '../../../../functional/services/ml/security_common'; | ||
import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; | ||
|
||
export default ({ getService }: FtrProviderContext) => { | ||
const supertest = getService('supertestWithoutAuth'); | ||
const ml = getService('ml'); | ||
|
||
describe('DELETE trained_models', () => { | ||
before(async () => { | ||
await ml.testResources.setKibanaTimeZoneToUTC(); | ||
await ml.api.createdTestTrainedModels('regression', 2); | ||
}); | ||
|
||
after(async () => { | ||
await ml.api.cleanMlIndices(); | ||
}); | ||
|
||
it('deletes trained model by id', async () => { | ||
const { body: deleteResponseBody } = await supertest | ||
.delete(`/api/ml/trained_models/dfa_regression_model_n_0`) | ||
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(200); | ||
|
||
expect(deleteResponseBody).to.eql({ acknowledged: true }); | ||
|
||
// verify that model is actually deleted | ||
await supertest | ||
.get(`/api/ml/trained_models/dfa_regression_model_n_0`) | ||
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(404); | ||
}); | ||
|
||
it('returns 404 if requested trained model does not exist', async () => { | ||
await supertest | ||
.delete(`/api/ml/trained_models/not_existing_model`) | ||
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(404); | ||
}); | ||
|
||
it('does not allow to delete trained model if the user does not have required permissions', async () => { | ||
await supertest | ||
.delete(`/api/ml/trained_models/dfa_regression_model_n_1`) | ||
.auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(403); | ||
|
||
// verify that model has not been deleted | ||
await supertest | ||
.get(`/api/ml/trained_models/dfa_regression_model_n_1`) | ||
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(200); | ||
}); | ||
}); | ||
}; |
51 changes: 51 additions & 0 deletions
51
x-pack/test/api_integration/apis/ml/trained_models/get_model_pipelines.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import expect from '@kbn/expect'; | ||
import { FtrProviderContext } from '../../../ftr_provider_context'; | ||
import { USER } from '../../../../functional/services/ml/security_common'; | ||
import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; | ||
|
||
export default ({ getService }: FtrProviderContext) => { | ||
const supertest = getService('supertestWithoutAuth'); | ||
const ml = getService('ml'); | ||
|
||
describe('GET trained_models/pipelines', () => { | ||
let testModelIds: string[] = []; | ||
|
||
before(async () => { | ||
await ml.testResources.setKibanaTimeZoneToUTC(); | ||
testModelIds = await ml.api.createdTestTrainedModels('regression', 2, true); | ||
}); | ||
|
||
after(async () => { | ||
// delete all created ingest pipelines | ||
await Promise.all(testModelIds.map((modelId) => ml.api.deleteIngestPipeline(modelId))); | ||
await ml.api.cleanMlIndices(); | ||
}); | ||
|
||
it('returns trained model pipelines by id', async () => { | ||
const { body } = await supertest | ||
.get(`/api/ml/trained_models/dfa_regression_model_n_0/pipelines`) | ||
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(200); | ||
|
||
expect(body.length).to.eql(1); | ||
expect(body[0].model_id).to.eql('dfa_regression_model_n_0'); | ||
expect(Object.keys(body[0].pipelines).length).to.eql(1); | ||
}); | ||
|
||
it('returns an error in case user does not have required permission', async () => { | ||
await supertest | ||
.get(`/api/ml/trained_models/dfa_regression_model_n_0/pipelines`) | ||
.auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(403); | ||
}); | ||
}); | ||
}; |
54 changes: 54 additions & 0 deletions
54
x-pack/test/api_integration/apis/ml/trained_models/get_model_stats.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import expect from '@kbn/expect'; | ||
import { FtrProviderContext } from '../../../ftr_provider_context'; | ||
import { USER } from '../../../../functional/services/ml/security_common'; | ||
import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; | ||
|
||
export default ({ getService }: FtrProviderContext) => { | ||
const supertest = getService('supertestWithoutAuth'); | ||
const ml = getService('ml'); | ||
|
||
describe('GET trained_models/_stats', () => { | ||
before(async () => { | ||
await ml.testResources.setKibanaTimeZoneToUTC(); | ||
await ml.api.createdTestTrainedModels('regression', 2); | ||
}); | ||
|
||
after(async () => { | ||
await ml.api.cleanMlIndices(); | ||
}); | ||
|
||
it('returns trained model stats by id', async () => { | ||
const { body } = await supertest | ||
.get(`/api/ml/trained_models/dfa_regression_model_n_0/_stats`) | ||
.auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(200); | ||
|
||
expect(body.count).to.eql(1); | ||
expect(body.trained_model_stats[0].model_id).to.eql('dfa_regression_model_n_0'); | ||
}); | ||
|
||
it('returns 404 if requested trained model does not exist', async () => { | ||
await supertest | ||
.get(`/api/ml/trained_models/not_existing_model/_stats`) | ||
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(404); | ||
}); | ||
|
||
it('returns an error for unauthorized user', async () => { | ||
await supertest | ||
.get(`/api/ml/trained_models/dfa_regression_model_n_0/_stats`) | ||
.auth(USER.ML_UNAUTHORIZED, ml.securityCommon.getPasswordForUser(USER.ML_UNAUTHORIZED)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(403); | ||
}); | ||
}); | ||
}; |
88 changes: 88 additions & 0 deletions
88
x-pack/test/api_integration/apis/ml/trained_models/get_models.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import expect from '@kbn/expect'; | ||
import { FtrProviderContext } from '../../../ftr_provider_context'; | ||
import { USER } from '../../../../functional/services/ml/security_common'; | ||
import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; | ||
|
||
export default ({ getService }: FtrProviderContext) => { | ||
const supertest = getService('supertestWithoutAuth'); | ||
const ml = getService('ml'); | ||
|
||
describe('GET trained_models', () => { | ||
let testModelIds: string[] = []; | ||
|
||
before(async () => { | ||
await ml.testResources.setKibanaTimeZoneToUTC(); | ||
testModelIds = await ml.api.createdTestTrainedModels('regression', 5, true); | ||
await ml.api.createModelAlias('dfa_regression_model_n_0', 'dfa_regression_model_alias'); | ||
await ml.api.createIngestPipeline('dfa_regression_model_alias'); | ||
}); | ||
|
||
after(async () => { | ||
// delete created ingest pipelines | ||
await Promise.all( | ||
['dfa_regression_model_alias', ...testModelIds].map((modelId) => | ||
ml.api.deleteIngestPipeline(modelId) | ||
) | ||
); | ||
await ml.api.cleanMlIndices(); | ||
}); | ||
|
||
it('returns all trained models with associated pipelines including aliases', async () => { | ||
const { body } = await supertest | ||
.get(`/api/ml/trained_models?with_pipelines=true`) | ||
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(200); | ||
// Created models + system model | ||
expect(body.length).to.eql(6); | ||
|
||
const sampleModel = body.find((v: any) => v.model_id === 'dfa_regression_model_n_0'); | ||
expect(Object.keys(sampleModel.pipelines).length).to.eql(2); | ||
}); | ||
|
||
it('returns models without pipeline in case user does not have required permission', async () => { | ||
const { body } = await supertest | ||
.get(`/api/ml/trained_models?with_pipelines=true`) | ||
.auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(200); | ||
// Created models + system model | ||
expect(body.length).to.eql(6); | ||
const sampleModel = body.find((v: any) => v.model_id === 'dfa_regression_model_n_0'); | ||
expect(sampleModel.pipelines).to.eql(undefined); | ||
}); | ||
|
||
it('returns trained model by id', async () => { | ||
const { body } = await supertest | ||
.get(`/api/ml/trained_models/dfa_regression_model_n_1`) | ||
.auth(USER.ML_VIEWER, ml.securityCommon.getPasswordForUser(USER.ML_VIEWER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(200); | ||
expect(body.length).to.eql(1); | ||
expect(body[0].model_id).to.eql('dfa_regression_model_n_1'); | ||
}); | ||
|
||
it('returns 404 if requested trained model does not exist', async () => { | ||
await supertest | ||
.get(`/api/ml/trained_models/not_existing_model`) | ||
.auth(USER.ML_POWERUSER, ml.securityCommon.getPasswordForUser(USER.ML_POWERUSER)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(404); | ||
}); | ||
|
||
it('returns an error for unauthorized user', async () => { | ||
await supertest | ||
.get(`/api/ml/trained_models/dfa_regression_model_n_1`) | ||
.auth(USER.ML_UNAUTHORIZED, ml.securityCommon.getPasswordForUser(USER.ML_UNAUTHORIZED)) | ||
.set(COMMON_REQUEST_HEADERS) | ||
.expect(403); | ||
}); | ||
}); | ||
}; |
17 changes: 17 additions & 0 deletions
17
x-pack/test/api_integration/apis/ml/trained_models/index.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,17 @@ | ||
/* | ||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one | ||
* or more contributor license agreements. Licensed under the Elastic License | ||
* 2.0; you may not use this file except in compliance with the Elastic License | ||
* 2.0. | ||
*/ | ||
|
||
import { FtrProviderContext } from '../../../ftr_provider_context'; | ||
|
||
export default function ({ loadTestFile }: FtrProviderContext) { | ||
describe('trained models', function () { | ||
loadTestFile(require.resolve('./get_models')); | ||
loadTestFile(require.resolve('./get_model_stats')); | ||
loadTestFile(require.resolve('./get_model_pipelines')); | ||
loadTestFile(require.resolve('./delete_model')); | ||
}); | ||
} |
Oops, something went wrong.