From 2b8561da9fd4c194b2fd3f93ba3b6f10f21eda23 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Fri, 4 Feb 2022 16:45:21 +0000 Subject: [PATCH 1/9] [ML] Adding category definition api tests --- .../ml/results/get_category_definition.ts | 164 ++++++++++++++++++ .../api_integration/apis/ml/results/index.ts | 1 + x-pack/test/functional/services/ml/api.ts | 10 +- 3 files changed, 172 insertions(+), 3 deletions(-) create mode 100644 x-pack/test/api_integration/apis/ml/results/get_category_definition.ts diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts new file mode 100644 index 0000000000000..8658bae07bfa8 --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts @@ -0,0 +1,164 @@ +/* + * 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'; +import { Datafeed } from '../../../../../plugins/ml/common/types/anomaly_detection_jobs'; + +export default ({ getService }: FtrProviderContext) => { + const esArchiver = getService('esArchiver'); + const supertest = getService('supertestWithoutAuth'); + const ml = getService('ml'); + const spacesService = getService('spaces'); + + const jobIdSpace1 = `sample_logs_${Date.now()}`; + const idSpace1 = 'space1'; + const idSpace2 = 'space2'; + + const PARTITION_FIELD_NAME = 'event.dataset'; + const testJobConfig = { + job_id: jobIdSpace1, + groups: ['sample_logs', 'bootstrap', 'categorization'], + description: "count by mlcategory (message) on 'sample logs' dataset with 15m bucket span", + analysis_config: { + bucket_span: '15m', + categorization_field_name: 'message', + per_partition_categorization: { enabled: true, stop_on_warn: true }, + detectors: [ + { + function: 'count', + by_field_name: 'mlcategory', + partition_field_name: PARTITION_FIELD_NAME, + }, + ], + influencers: ['mlcategory'], + }, + analysis_limits: { model_memory_limit: '26MB' }, + data_description: { time_field: '@timestamp', time_format: 'epoch_ms' }, + model_plot_config: { enabled: false, annotations_enabled: true }, + model_snapshot_retention_days: 10, + daily_model_snapshot_retention_after_days: 1, + allow_lazy_open: false, + }; + // @ts-expect-error not full interface + const testDatafeedConfig: Datafeed = { + datafeed_id: `datafeed-${jobIdSpace1}`, + indices: ['ft_module_sample_logs'], + job_id: jobIdSpace1, + query: { bool: { must: [{ match_all: {} }] } }, + }; + + const expectedCategoryDefinition = { + categoryId: '1', + terms: 'GET HTTP/1.1 Mozilla/5.0 X11 Linux x86_64 rv Gecko/20110421 Firefox/6.0a1', + regex: + '.*?GET.+?HTTP/1\\.1.+?Mozilla/5\\.0.+?X11.+?Linux.+?x86_64.+?rv.+?Gecko/20110421.+?Firefox/6\\.0a1.*', + examples: [ + '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', + '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat_1 HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', + '223.87.60.27 - - [2018-07-22T00:39:02.912Z] "GET /elasticsearch/elasticsearch-6.3.2.deb HTTP/1.1" 200 6219 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', + '223.87.60.27 - - [2018-07-22T00:39:02.912Z] "GET /elasticsearch/elasticsearch-6.3.2.deb_1 HTTP/1.1" 200 6219 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', + ], + }; + + async function getCategoryDefinition( + jobId: string, + categoryId: string, + user: USER, + expectedStatusCode: number, + space?: string + ) { + const { body } = await supertest + .post(`${space ? `/s/${space}` : ''}/api/ml/results/category_definition`) + .auth(user, ml.securityCommon.getPasswordForUser(user)) + .set(COMMON_REQUEST_HEADERS) + .send({ jobId, categoryId }) + .expect(expectedStatusCode); + + return body; + } + + describe('get category_definition', function () { + before(async () => { + await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/module_sample_logs'); + await ml.testResources.setKibanaTimeZoneToUTC(); + await spacesService.create({ id: idSpace1, name: 'space_one', disabledFeatures: [] }); + await spacesService.create({ id: idSpace2, name: 'space_two', disabledFeatures: [] }); + + await ml.api.createAndRunAnomalyDetectionLookbackJob( + // @ts-expect-error not full interface + testJobConfig, + testDatafeedConfig, + idSpace1 + ); + }); + + after(async () => { + await spacesService.delete(idSpace1); + await spacesService.delete(idSpace2); + await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); + await ml.api.cleanMlIndices(); + }); + + it('should produce the correct category for the job', async () => { + const resp = await getCategoryDefinition( + jobIdSpace1, + expectedCategoryDefinition.categoryId, + USER.ML_POWERUSER, + 200, + idSpace1 + ); + + expect(resp).to.eql( + expectedCategoryDefinition, + `response should be ${JSON.stringify(expectedCategoryDefinition)} (got ${JSON.stringify( + resp + )})` + ); + }); + + it('should produce the correct category for the job', async () => { + const resp = await getCategoryDefinition(jobIdSpace1, '2', USER.ML_POWERUSER, 200, idSpace1); + + expect(resp).to.not.eql( + expectedCategoryDefinition, + `response should not be ${JSON.stringify(expectedCategoryDefinition)} (got ${JSON.stringify( + resp + )})` + ); + }); + + it('should not produce the correct category for the job in the wrong space', async () => { + await getCategoryDefinition( + jobIdSpace1, + expectedCategoryDefinition.categoryId, + USER.ML_POWERUSER, + 404, + idSpace2 + ); + }); + + it('should produce the correct category for ml view user', async () => { + const resp = await getCategoryDefinition( + jobIdSpace1, + expectedCategoryDefinition.categoryId, + USER.ML_VIEWER, + 200, + idSpace1 + ); + + expect(resp).to.eql( + expectedCategoryDefinition, + `response should be ${JSON.stringify(expectedCategoryDefinition)} (got ${JSON.stringify( + resp + )})` + ); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/results/index.ts b/x-pack/test/api_integration/apis/ml/results/index.ts index 83338dcab57cd..9c890e23af353 100644 --- a/x-pack/test/api_integration/apis/ml/results/index.ts +++ b/x-pack/test/api_integration/apis/ml/results/index.ts @@ -12,5 +12,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./get_anomalies_table_data')); loadTestFile(require.resolve('./get_categorizer_stats')); loadTestFile(require.resolve('./get_stopped_partitions')); + loadTestFile(require.resolve('./get_category_definition')); }); } diff --git a/x-pack/test/functional/services/ml/api.ts b/x-pack/test/functional/services/ml/api.ts index ebe7f7e84d158..58f0b6d678cc2 100644 --- a/x-pack/test/functional/services/ml/api.ts +++ b/x-pack/test/functional/services/ml/api.ts @@ -681,9 +681,13 @@ export function MachineLearningAPIProvider({ getService }: FtrProviderContext) { log.debug('> Datafeed stopped.'); }, - async createAndRunAnomalyDetectionLookbackJob(jobConfig: Job, datafeedConfig: Datafeed) { - await this.createAnomalyDetectionJob(jobConfig); - await this.createDatafeed(datafeedConfig); + async createAndRunAnomalyDetectionLookbackJob( + jobConfig: Job, + datafeedConfig: Datafeed, + space?: string + ) { + await this.createAnomalyDetectionJob(jobConfig, space); + await this.createDatafeed(datafeedConfig, space); await this.openAnomalyDetectionJob(jobConfig.job_id); await this.startDatafeed(datafeedConfig.datafeed_id, { start: '0', end: `${Date.now()}` }); await this.waitForDatafeedState(datafeedConfig.datafeed_id, DATAFEED_STATE.STOPPED); From 4ecb094290173d01ce0cecbbf55417c5b1285c11 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Fri, 4 Feb 2022 16:56:09 +0000 Subject: [PATCH 2/9] adding test --- .../apis/ml/results/get_category_definition.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts index 8658bae07bfa8..0886cc2a01df3 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts @@ -144,7 +144,7 @@ export default ({ getService }: FtrProviderContext) => { ); }); - it('should produce the correct category for ml view user', async () => { + it('should produce the correct category for ml viewer user', async () => { const resp = await getCategoryDefinition( jobIdSpace1, expectedCategoryDefinition.categoryId, @@ -160,5 +160,15 @@ export default ({ getService }: FtrProviderContext) => { )})` ); }); + + it('should not produce the correct category for ml unauthorized user', async () => { + await getCategoryDefinition( + jobIdSpace1, + expectedCategoryDefinition.categoryId, + USER.ML_UNAUTHORIZED, + 403, + idSpace1 + ); + }); }); }; From 145a8c65eea48b8f2061ec3d3eb4d7c50d90feea Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Mon, 7 Feb 2022 13:59:45 +0000 Subject: [PATCH 3/9] adding category examples tests --- .../ml/results/get_category_definition.ts | 2 +- .../apis/ml/results/get_category_examples.ts | 204 ++++++++++++++++++ .../api_integration/apis/ml/results/index.ts | 1 + 3 files changed, 206 insertions(+), 1 deletion(-) create mode 100644 x-pack/test/api_integration/apis/ml/results/get_category_examples.ts diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts index 0886cc2a01df3..6bcc581549251 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts @@ -123,7 +123,7 @@ export default ({ getService }: FtrProviderContext) => { ); }); - it('should produce the correct category for the job', async () => { + it('should not produce the correct category for the job', async () => { const resp = await getCategoryDefinition(jobIdSpace1, '2', USER.ML_POWERUSER, 200, idSpace1); expect(resp).to.not.eql( diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts b/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts new file mode 100644 index 0000000000000..10505c244deb8 --- /dev/null +++ b/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts @@ -0,0 +1,204 @@ +/* + * 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'; +import { Datafeed } from '../../../../../plugins/ml/common/types/anomaly_detection_jobs'; + +export default ({ getService }: FtrProviderContext) => { + const esArchiver = getService('esArchiver'); + const supertest = getService('supertestWithoutAuth'); + const ml = getService('ml'); + const spacesService = getService('spaces'); + + const jobIdSpace1 = `sample_logs_${Date.now()}`; + const idSpace1 = 'space1'; + const idSpace2 = 'space2'; + + const PARTITION_FIELD_NAME = 'event.dataset'; + const testJobConfig = { + job_id: jobIdSpace1, + groups: ['sample_logs', 'bootstrap', 'categorization'], + description: "count by mlcategory (message) on 'sample logs' dataset with 15m bucket span", + analysis_config: { + bucket_span: '15m', + categorization_field_name: 'message', + per_partition_categorization: { enabled: true, stop_on_warn: true }, + detectors: [ + { + function: 'count', + by_field_name: 'mlcategory', + partition_field_name: PARTITION_FIELD_NAME, + }, + ], + influencers: ['mlcategory'], + }, + analysis_limits: { model_memory_limit: '26MB' }, + data_description: { time_field: '@timestamp', time_format: 'epoch_ms' }, + model_plot_config: { enabled: false, annotations_enabled: true }, + model_snapshot_retention_days: 10, + daily_model_snapshot_retention_after_days: 1, + allow_lazy_open: false, + }; + // @ts-expect-error not full interface + const testDatafeedConfig: Datafeed = { + datafeed_id: `datafeed-${jobIdSpace1}`, + indices: ['ft_module_sample_logs'], + job_id: jobIdSpace1, + query: { bool: { must: [{ match_all: {} }] } }, + }; + + const expectedCategoryExamples1 = { + '1': [ + '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', + ], + }; + const expectedCategoryExamples3 = { + '1': [ + '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', + '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat_1 HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', + '223.87.60.27 - - [2018-07-22T00:39:02.912Z] "GET /elasticsearch/elasticsearch-6.3.2.deb HTTP/1.1" 200 6219 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', + ], + }; + + async function getCategoryExamples( + jobId: string, + categoryIds: string[], + maxExamples: number, + user: USER, + expectedStatusCode: number, + space?: string + ) { + const { body } = await supertest + .post(`${space ? `/s/${space}` : ''}/api/ml/results/category_examples`) + .auth(user, ml.securityCommon.getPasswordForUser(user)) + .set(COMMON_REQUEST_HEADERS) + .send({ jobId, categoryIds, maxExamples }) + .expect(expectedStatusCode); + + return body; + } + + describe('get category_examples', function () { + before(async () => { + await esArchiver.loadIfNeeded('x-pack/test/functional/es_archives/ml/module_sample_logs'); + await ml.testResources.setKibanaTimeZoneToUTC(); + await spacesService.create({ id: idSpace1, name: 'space_one', disabledFeatures: [] }); + await spacesService.create({ id: idSpace2, name: 'space_two', disabledFeatures: [] }); + + await ml.api.createAndRunAnomalyDetectionLookbackJob( + // @ts-expect-error not full interface + testJobConfig, + testDatafeedConfig, + idSpace1 + ); + }); + + after(async () => { + await spacesService.delete(idSpace1); + await spacesService.delete(idSpace2); + await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); + await ml.api.cleanMlIndices(); + }); + + it('should produce the correct 1 example for the job', async () => { + const resp = await getCategoryExamples( + jobIdSpace1, + Object.keys(expectedCategoryExamples1), + 1, + USER.ML_POWERUSER, + 200, + idSpace1 + ); + + expect(resp).to.eql( + expectedCategoryExamples1, + `response should be ${JSON.stringify(expectedCategoryExamples1)} (got ${JSON.stringify( + resp + )})` + ); + }); + + it('should produce the correct 3 examples for the job', async () => { + const resp = await getCategoryExamples( + jobIdSpace1, + Object.keys(expectedCategoryExamples3), + 3, + USER.ML_POWERUSER, + 200, + idSpace1 + ); + + expect(resp).to.eql( + expectedCategoryExamples3, + `response should be ${JSON.stringify(expectedCategoryExamples3)} (got ${JSON.stringify( + resp + )})` + ); + }); + + it('should not produce the correct example for the job', async () => { + const resp = await getCategoryExamples( + jobIdSpace1, + ['2'], + 3, + USER.ML_POWERUSER, + 200, + idSpace1 + ); + + expect(resp).to.not.eql( + expectedCategoryExamples3, + `response should not be ${JSON.stringify(expectedCategoryExamples3)} (got ${JSON.stringify( + resp + )})` + ); + }); + + it('should not produce the correct examples for the job in the wrong space', async () => { + await getCategoryExamples( + jobIdSpace1, + Object.keys(expectedCategoryExamples1), + 3, + USER.ML_POWERUSER, + 404, + idSpace2 + ); + }); + + it('should produce the correct example for the job for the ml viewer user', async () => { + const resp = await getCategoryExamples( + jobIdSpace1, + Object.keys(expectedCategoryExamples3), + 3, + USER.ML_VIEWER, + 200, + idSpace1 + ); + + expect(resp).to.eql( + expectedCategoryExamples3, + `response should be ${JSON.stringify(expectedCategoryExamples3)} (got ${JSON.stringify( + resp + )})` + ); + }); + + it('should not produce the correct example for the job for the ml unauthorized user', async () => { + await getCategoryExamples( + jobIdSpace1, + Object.keys(expectedCategoryExamples3), + 3, + USER.ML_UNAUTHORIZED, + 403, + idSpace1 + ); + }); + }); +}; diff --git a/x-pack/test/api_integration/apis/ml/results/index.ts b/x-pack/test/api_integration/apis/ml/results/index.ts index 9c890e23af353..575435fa3a720 100644 --- a/x-pack/test/api_integration/apis/ml/results/index.ts +++ b/x-pack/test/api_integration/apis/ml/results/index.ts @@ -13,5 +13,6 @@ export default function ({ loadTestFile }: FtrProviderContext) { loadTestFile(require.resolve('./get_categorizer_stats')); loadTestFile(require.resolve('./get_stopped_partitions')); loadTestFile(require.resolve('./get_category_definition')); + loadTestFile(require.resolve('./get_category_examples')); }); } From 5bece64acc7920fec016ae9804f23d2d4f730f8e Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Mon, 7 Feb 2022 18:01:25 +0000 Subject: [PATCH 4/9] updating test checks --- .../ml/results/get_category_definition.ts | 40 ++++++++++++------- .../apis/ml/results/get_category_examples.ts | 34 +++++++--------- 2 files changed, 39 insertions(+), 35 deletions(-) diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts index 6bcc581549251..78e3853abad85 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts @@ -115,22 +115,26 @@ export default ({ getService }: FtrProviderContext) => { idSpace1 ); - expect(resp).to.eql( - expectedCategoryDefinition, - `response should be ${JSON.stringify(expectedCategoryDefinition)} (got ${JSON.stringify( - resp - )})` + expect(resp.categoryId).to.eql( + expectedCategoryDefinition.categoryId, + `categoryId should be ${expectedCategoryDefinition.categoryId} (got ${resp.categoryId})` + ); + expect(resp.examples.length).to.eql( + expectedCategoryDefinition.examples.length, + `examples list length should be ${expectedCategoryDefinition.examples.length} (got ${resp.examples.length})` + ); + expect(resp.terms.length).to.be.greaterThan( + 0, + `terms string length should be greater than 0 (got ${resp.terms.length})` ); }); it('should not produce the correct category for the job', async () => { const resp = await getCategoryDefinition(jobIdSpace1, '2', USER.ML_POWERUSER, 200, idSpace1); - expect(resp).to.not.eql( - expectedCategoryDefinition, - `response should not be ${JSON.stringify(expectedCategoryDefinition)} (got ${JSON.stringify( - resp - )})` + expect(resp.categoryId).to.not.eql( + expectedCategoryDefinition.categoryId, + `categoryId should not be ${expectedCategoryDefinition.categoryId} (got ${resp.categoryId})` ); }); @@ -153,11 +157,17 @@ export default ({ getService }: FtrProviderContext) => { idSpace1 ); - expect(resp).to.eql( - expectedCategoryDefinition, - `response should be ${JSON.stringify(expectedCategoryDefinition)} (got ${JSON.stringify( - resp - )})` + expect(resp.categoryId).to.eql( + expectedCategoryDefinition.categoryId, + `categoryId should be ${expectedCategoryDefinition.categoryId} (got ${resp.categoryId})` + ); + expect(resp.examples.length).to.eql( + expectedCategoryDefinition.examples.length, + `examples list length should be ${expectedCategoryDefinition.examples.length} (got ${resp.examples.length})` + ); + expect(resp.terms.length).to.be.greaterThan( + 0, + `terms string length should be greater than 0 (got ${resp.terms.length})` ); }); diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts b/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts index 10505c244deb8..271c26d35dce6 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts @@ -117,11 +117,9 @@ export default ({ getService }: FtrProviderContext) => { idSpace1 ); - expect(resp).to.eql( - expectedCategoryExamples1, - `response should be ${JSON.stringify(expectedCategoryExamples1)} (got ${JSON.stringify( - resp - )})` + expect(resp['1'].length).to.eql( + expectedCategoryExamples1['1'].length, + `response examples length should be ${expectedCategoryExamples1['1'].length} (got ${resp['1'].length})` ); }); @@ -135,11 +133,9 @@ export default ({ getService }: FtrProviderContext) => { idSpace1 ); - expect(resp).to.eql( - expectedCategoryExamples3, - `response should be ${JSON.stringify(expectedCategoryExamples3)} (got ${JSON.stringify( - resp - )})` + expect(resp['1'].length).to.eql( + expectedCategoryExamples3['1'].length, + `response examples length should be ${expectedCategoryExamples3['1'].length} (got ${resp['1'].length})` ); }); @@ -153,11 +149,11 @@ export default ({ getService }: FtrProviderContext) => { idSpace1 ); - expect(resp).to.not.eql( - expectedCategoryExamples3, - `response should not be ${JSON.stringify(expectedCategoryExamples3)} (got ${JSON.stringify( - resp - )})` + expect(Object.keys(resp)).to.not.eql( + Object.keys(expectedCategoryExamples3), + `response examples keys should be ${Object.keys( + expectedCategoryExamples3 + )} (got ${Object.keys(resp)})` ); }); @@ -182,11 +178,9 @@ export default ({ getService }: FtrProviderContext) => { idSpace1 ); - expect(resp).to.eql( - expectedCategoryExamples3, - `response should be ${JSON.stringify(expectedCategoryExamples3)} (got ${JSON.stringify( - resp - )})` + expect(resp['1'].length).to.eql( + expectedCategoryExamples3['1'].length, + `response examples length should be ${expectedCategoryExamples3['1'].length} (got ${resp['1'].length})` ); }); From 7634363c0ce8420f1ce649f17012731ecce30cae Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 8 Feb 2022 11:49:46 +0000 Subject: [PATCH 5/9] changes based on review --- .../ml/results/get_category_definition.ts | 38 +++++---- .../apis/ml/results/get_category_examples.ts | 82 +++++++------------ 2 files changed, 53 insertions(+), 67 deletions(-) diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts index 78e3853abad85..9e78b02f0d1a6 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts @@ -56,15 +56,7 @@ export default ({ getService }: FtrProviderContext) => { const expectedCategoryDefinition = { categoryId: '1', - terms: 'GET HTTP/1.1 Mozilla/5.0 X11 Linux x86_64 rv Gecko/20110421 Firefox/6.0a1', - regex: - '.*?GET.+?HTTP/1\\.1.+?Mozilla/5\\.0.+?X11.+?Linux.+?x86_64.+?rv.+?Gecko/20110421.+?Firefox/6\\.0a1.*', - examples: [ - '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', - '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat_1 HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', - '223.87.60.27 - - [2018-07-22T00:39:02.912Z] "GET /elasticsearch/elasticsearch-6.3.2.deb HTTP/1.1" 200 6219 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', - '223.87.60.27 - - [2018-07-22T00:39:02.912Z] "GET /elasticsearch/elasticsearch-6.3.2.deb_1 HTTP/1.1" 200 6219 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', - ], + examplesLength: 4, }; async function getCategoryDefinition( @@ -102,7 +94,6 @@ export default ({ getService }: FtrProviderContext) => { after(async () => { await spacesService.delete(idSpace1); await spacesService.delete(idSpace2); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); await ml.api.cleanMlIndices(); }); @@ -120,17 +111,28 @@ export default ({ getService }: FtrProviderContext) => { `categoryId should be ${expectedCategoryDefinition.categoryId} (got ${resp.categoryId})` ); expect(resp.examples.length).to.eql( - expectedCategoryDefinition.examples.length, - `examples list length should be ${expectedCategoryDefinition.examples.length} (got ${resp.examples.length})` + expectedCategoryDefinition.examplesLength, + `examples list length should be ${expectedCategoryDefinition.examplesLength} (got ${resp.examples.length})` ); expect(resp.terms.length).to.be.greaterThan( 0, `terms string length should be greater than 0 (got ${resp.terms.length})` ); + expect(resp.regex.length).to.be.greaterThan( + 0, + `regex string length should be greater than 0 (got ${resp.terms.length})` + ); }); - it('should not produce the correct category for the job', async () => { - const resp = await getCategoryDefinition(jobIdSpace1, '2', USER.ML_POWERUSER, 200, idSpace1); + it('should produce the correct category for the job', async () => { + const categoryId = '2'; + const resp = await getCategoryDefinition( + jobIdSpace1, + categoryId, + USER.ML_POWERUSER, + 200, + idSpace1 + ); expect(resp.categoryId).to.not.eql( expectedCategoryDefinition.categoryId, @@ -162,13 +164,17 @@ export default ({ getService }: FtrProviderContext) => { `categoryId should be ${expectedCategoryDefinition.categoryId} (got ${resp.categoryId})` ); expect(resp.examples.length).to.eql( - expectedCategoryDefinition.examples.length, - `examples list length should be ${expectedCategoryDefinition.examples.length} (got ${resp.examples.length})` + expectedCategoryDefinition.examplesLength, + `examples list length should be ${expectedCategoryDefinition.examplesLength} (got ${resp.examples.length})` ); expect(resp.terms.length).to.be.greaterThan( 0, `terms string length should be greater than 0 (got ${resp.terms.length})` ); + expect(resp.regex.length).to.be.greaterThan( + 0, + `regex string length should be greater than 0 (got ${resp.terms.length})` + ); }); it('should not produce the correct category for ml unauthorized user', async () => { diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts b/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts index 271c26d35dce6..f5525599f5d86 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts @@ -54,22 +54,14 @@ export default ({ getService }: FtrProviderContext) => { query: { bool: { must: [{ match_all: {} }] } }, }; - const expectedCategoryExamples1 = { - '1': [ - '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', - ], - }; - const expectedCategoryExamples3 = { - '1': [ - '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', - '130.246.123.197 - - [2018-07-22T03:26:21.326Z] "GET /beats/metricbeat_1 HTTP/1.1" 200 6850 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', - '223.87.60.27 - - [2018-07-22T00:39:02.912Z] "GET /elasticsearch/elasticsearch-6.3.2.deb HTTP/1.1" 200 6219 "-" "Mozilla/5.0 (X11; Linux x86_64; rv:6.0a1) Gecko/20110421 Firefox/6.0a1"', - ], + const expectedCategoryExamples = { + categoryId: '1', + examplesLength: 3, }; async function getCategoryExamples( jobId: string, - categoryIds: string[], + categoryId: string[], maxExamples: number, user: USER, expectedStatusCode: number, @@ -79,7 +71,7 @@ export default ({ getService }: FtrProviderContext) => { .post(`${space ? `/s/${space}` : ''}/api/ml/results/category_examples`) .auth(user, ml.securityCommon.getPasswordForUser(user)) .set(COMMON_REQUEST_HEADERS) - .send({ jobId, categoryIds, maxExamples }) + .send({ jobId, categoryId, maxExamples }) .expect(expectedStatusCode); return body; @@ -103,65 +95,51 @@ export default ({ getService }: FtrProviderContext) => { after(async () => { await spacesService.delete(idSpace1); await spacesService.delete(idSpace2); - await ml.testResources.deleteIndexPatternByTitle('ft_module_sample_logs'); await ml.api.cleanMlIndices(); }); it('should produce the correct 1 example for the job', async () => { + const maxExamples = 1; const resp = await getCategoryExamples( jobIdSpace1, - Object.keys(expectedCategoryExamples1), - 1, + [expectedCategoryExamples.categoryId], + maxExamples, USER.ML_POWERUSER, 200, idSpace1 ); - expect(resp['1'].length).to.eql( - expectedCategoryExamples1['1'].length, - `response examples length should be ${expectedCategoryExamples1['1'].length} (got ${resp['1'].length})` + expect(resp[expectedCategoryExamples.categoryId].length).to.eql( + maxExamples, + `response examples length should be ${maxExamples} (got ${ + resp[expectedCategoryExamples.categoryId].length + })` ); }); it('should produce the correct 3 examples for the job', async () => { const resp = await getCategoryExamples( jobIdSpace1, - Object.keys(expectedCategoryExamples3), - 3, - USER.ML_POWERUSER, - 200, - idSpace1 - ); - - expect(resp['1'].length).to.eql( - expectedCategoryExamples3['1'].length, - `response examples length should be ${expectedCategoryExamples3['1'].length} (got ${resp['1'].length})` - ); - }); - - it('should not produce the correct example for the job', async () => { - const resp = await getCategoryExamples( - jobIdSpace1, - ['2'], - 3, + [expectedCategoryExamples.categoryId], + expectedCategoryExamples.examplesLength, USER.ML_POWERUSER, 200, idSpace1 ); - expect(Object.keys(resp)).to.not.eql( - Object.keys(expectedCategoryExamples3), - `response examples keys should be ${Object.keys( - expectedCategoryExamples3 - )} (got ${Object.keys(resp)})` + expect(resp[expectedCategoryExamples.categoryId].length).to.eql( + expectedCategoryExamples.examplesLength, + `response examples length should be ${expectedCategoryExamples.examplesLength} (got ${ + resp[expectedCategoryExamples.categoryId].length + })` ); }); it('should not produce the correct examples for the job in the wrong space', async () => { await getCategoryExamples( jobIdSpace1, - Object.keys(expectedCategoryExamples1), - 3, + [expectedCategoryExamples.categoryId], + expectedCategoryExamples.examplesLength, USER.ML_POWERUSER, 404, idSpace2 @@ -171,24 +149,26 @@ export default ({ getService }: FtrProviderContext) => { it('should produce the correct example for the job for the ml viewer user', async () => { const resp = await getCategoryExamples( jobIdSpace1, - Object.keys(expectedCategoryExamples3), - 3, + [expectedCategoryExamples.categoryId], + expectedCategoryExamples.examplesLength, USER.ML_VIEWER, 200, idSpace1 ); - expect(resp['1'].length).to.eql( - expectedCategoryExamples3['1'].length, - `response examples length should be ${expectedCategoryExamples3['1'].length} (got ${resp['1'].length})` + expect(resp[expectedCategoryExamples.categoryId].length).to.eql( + expectedCategoryExamples.examplesLength, + `response examples length should be ${expectedCategoryExamples.examplesLength} (got ${ + resp[expectedCategoryExamples.categoryId].length + })` ); }); it('should not produce the correct example for the job for the ml unauthorized user', async () => { await getCategoryExamples( jobIdSpace1, - Object.keys(expectedCategoryExamples3), - 3, + [expectedCategoryExamples.categoryId], + expectedCategoryExamples.examplesLength, USER.ML_UNAUTHORIZED, 403, idSpace1 From 11793fcdf9fee1d89c8c5269af39cb987d51450d Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 8 Feb 2022 11:51:24 +0000 Subject: [PATCH 6/9] removing test --- .../apis/ml/results/get_category_definition.ts | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts index 9e78b02f0d1a6..17925d4c9077e 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts @@ -140,16 +140,6 @@ export default ({ getService }: FtrProviderContext) => { ); }); - it('should not produce the correct category for the job in the wrong space', async () => { - await getCategoryDefinition( - jobIdSpace1, - expectedCategoryDefinition.categoryId, - USER.ML_POWERUSER, - 404, - idSpace2 - ); - }); - it('should produce the correct category for ml viewer user', async () => { const resp = await getCategoryDefinition( jobIdSpace1, From b8884810b6b10569fe6fe4030ea6326640c7f951 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 8 Feb 2022 15:26:14 +0000 Subject: [PATCH 7/9] correcting mistake where wrong test was removed --- .../apis/ml/results/get_category_definition.ts | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts index 17925d4c9077e..583ab50722c53 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts @@ -124,19 +124,13 @@ export default ({ getService }: FtrProviderContext) => { ); }); - it('should produce the correct category for the job', async () => { - const categoryId = '2'; - const resp = await getCategoryDefinition( + it('should not produce the correct category for the job in the wrong space', async () => { + await getCategoryDefinition( jobIdSpace1, - categoryId, - USER.ML_POWERUSER, - 200, - idSpace1 - ); - - expect(resp.categoryId).to.not.eql( expectedCategoryDefinition.categoryId, - `categoryId should not be ${expectedCategoryDefinition.categoryId} (got ${resp.categoryId})` + USER.ML_POWERUSER, + 404, + idSpace2 ); }); From 6e36da4872ad922c3ec354e89dc768ea9f0e9a60 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Tue, 8 Feb 2022 15:29:04 +0000 Subject: [PATCH 8/9] correctling text text --- .../apis/ml/results/get_category_definition.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts index 583ab50722c53..36f0f3946ac66 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_definition.ts @@ -120,7 +120,7 @@ export default ({ getService }: FtrProviderContext) => { ); expect(resp.regex.length).to.be.greaterThan( 0, - `regex string length should be greater than 0 (got ${resp.terms.length})` + `regex string length should be greater than 0 (got ${resp.regex.length})` ); }); @@ -157,7 +157,7 @@ export default ({ getService }: FtrProviderContext) => { ); expect(resp.regex.length).to.be.greaterThan( 0, - `regex string length should be greater than 0 (got ${resp.terms.length})` + `regex string length should be greater than 0 (got ${resp.regex.length})` ); }); From 0ab865b2712a552ebba25612364a7e9b4d43ea44 Mon Sep 17 00:00:00 2001 From: James Gowdy Date: Wed, 9 Feb 2022 08:21:24 +0000 Subject: [PATCH 9/9] fixing test --- .../api_integration/apis/ml/results/get_category_examples.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts b/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts index f5525599f5d86..79586daaa4aac 100644 --- a/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts +++ b/x-pack/test/api_integration/apis/ml/results/get_category_examples.ts @@ -61,7 +61,7 @@ export default ({ getService }: FtrProviderContext) => { async function getCategoryExamples( jobId: string, - categoryId: string[], + categoryIds: string[], maxExamples: number, user: USER, expectedStatusCode: number, @@ -71,7 +71,7 @@ export default ({ getService }: FtrProviderContext) => { .post(`${space ? `/s/${space}` : ''}/api/ml/results/category_examples`) .auth(user, ml.securityCommon.getPasswordForUser(user)) .set(COMMON_REQUEST_HEADERS) - .send({ jobId, categoryId, maxExamples }) + .send({ jobId, categoryIds, maxExamples }) .expect(expectedStatusCode); return body;