From e32fd9e68a7ed6d592df8f2905fffe058f69d014 Mon Sep 17 00:00:00 2001 From: Robert Oskamp Date: Thu, 7 Jan 2021 08:59:37 +0100 Subject: [PATCH] [ML] API integration tests - stabilize saved objects endpoint tests (#87288) (#87554) This PR stabilizes some saved objects endpoint tests by making sure a different order of objects in a response array is still accepted. --- .../ml/data_visualizer/get_field_stats.ts | 18 +----- .../apis/ml/jobs/jobs_summary.ts | 47 +++++++-------- .../apis/ml/modules/setup_module.ts | 58 +++++++++---------- .../apis/ml/saved_objects/initialize.ts | 15 ++--- .../apis/ml/saved_objects/jobs_spaces.ts | 34 ++++++----- .../apis/ml/saved_objects/status.ts | 10 ++-- 6 files changed, 82 insertions(+), 100 deletions(-) diff --git a/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts b/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts index 5fe0dd5ee5e4f..8465fdc0b1f75 100644 --- a/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts +++ b/x-pack/test/api_integration/apis/ml/data_visualizer/get_field_stats.ts @@ -5,6 +5,7 @@ */ import expect from '@kbn/expect'; +import { sortBy } from 'lodash'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; @@ -174,16 +175,6 @@ export default ({ getService }: FtrProviderContext) => { return body; } - function compareByFieldName(a: { fieldName: string }, b: { fieldName: string }) { - if (a.fieldName < b.fieldName) { - return -1; - } - if (a.fieldName > b.fieldName) { - return 1; - } - return 0; - } - describe('get_field_stats', function () { before(async () => { await esArchiver.loadIfNeeded('ml/farequote'); @@ -221,11 +212,8 @@ export default ({ getService }: FtrProviderContext) => { nonMetricFieldsTestData.expected.responseCode ); - // Sort the fields in the response before validating. - const expectedRspFields = nonMetricFieldsTestData.expected.responseBody.sort( - compareByFieldName - ); - const actualRspFields = body.sort(compareByFieldName); + const expectedRspFields = sortBy(nonMetricFieldsTestData.expected.responseBody, 'fieldName'); + const actualRspFields = sortBy(body, 'fieldName'); expect(actualRspFields).to.eql(expectedRspFields); }); diff --git a/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts b/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts index f85b731355509..4b19893f3d7a5 100644 --- a/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts +++ b/x-pack/test/api_integration/apis/ml/jobs/jobs_summary.ts @@ -5,6 +5,7 @@ */ import expect from '@kbn/expect'; +import { sortBy } from 'lodash'; import { FtrProviderContext } from '../../../ftr_provider_context'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; @@ -181,16 +182,6 @@ export default ({ getService }: FtrProviderContext) => { return body; } - function compareById(a: { id: string }, b: { id: string }) { - if (a.id < b.id) { - return -1; - } - if (a.id > b.id) { - return 1; - } - return 0; - } - function getGroups(jobs: Array<{ groups: string[] }>) { const groupIds: string[] = []; jobs.forEach((job) => { @@ -236,16 +227,18 @@ export default ({ getService }: FtrProviderContext) => { expect(body).to.have.length(expectedResponse.length); // Validate job IDs. - const expectedRspJobIds = expectedResponse - .map((job: { id: string }) => { + const expectedRspJobIds = sortBy( + expectedResponse.map((job: { id: string }) => { return { id: job.id }; - }) - .sort(compareById); - const actualRspJobIds = body - .map((job: { id: string }) => { + }), + 'id' + ); + const actualRspJobIds = sortBy( + body.map((job: { id: string }) => { return { id: job.id }; - }) - .sort(compareById); + }), + 'id' + ); expect(actualRspJobIds).to.eql(expectedRspJobIds); @@ -273,16 +266,18 @@ export default ({ getService }: FtrProviderContext) => { expect(body).to.have.length(expectedResponse.length); // Validate job IDs. - const expectedRspJobIds = expectedResponse - .map((job: { id: string }) => { + const expectedRspJobIds = sortBy( + expectedResponse.map((job: { id: string }) => { return { id: job.id }; - }) - .sort(compareById); - const actualRspJobIds = body - .map((job: { id: string }) => { + }), + 'id' + ); + const actualRspJobIds = sortBy( + body.map((job: { id: string }) => { return { id: job.id }; - }) - .sort(compareById); + }), + 'id' + ); expect(actualRspJobIds).to.eql(expectedRspJobIds); diff --git a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts index d1316a0ededc6..cd5081d56f41b 100644 --- a/x-pack/test/api_integration/apis/ml/modules/setup_module.ts +++ b/x-pack/test/api_integration/apis/ml/modules/setup_module.ts @@ -5,7 +5,7 @@ */ import expect from '@kbn/expect'; -import { isEmpty } from 'lodash'; +import { isEmpty, sortBy } from 'lodash'; import { FtrProviderContext } from '../../../ftr_provider_context'; @@ -701,22 +701,13 @@ export default ({ getService }: FtrProviderContext) => { return body; } - function compareById(a: { id: string }, b: { id: string }) { - if (a.id < b.id) { - return -1; - } - if (a.id > b.id) { - return 1; - } - return 0; - } - function mapIdsToSuccessObjects(ids: string[]) { - const successObjects = ids - .map((id) => { + const successObjects = sortBy( + ids.map((id) => { return { id, success: true }; - }) - .sort(compareById); + }), + 'id' + ); return successObjects; } @@ -765,7 +756,7 @@ export default ({ getService }: FtrProviderContext) => { const expectedJobIds = testData.expected.jobs.map((job) => job.jobId); const expectedRspJobs = mapIdsToSuccessObjects(expectedJobIds); - const actualRspJobs = rspBody.jobs.sort(compareById); + const actualRspJobs = sortBy(rspBody.jobs, 'id'); expect(actualRspJobs).to.eql( expectedRspJobs, @@ -777,17 +768,18 @@ export default ({ getService }: FtrProviderContext) => { // datafeeds expect(rspBody).to.have.property('datafeeds'); - const expectedRspDatafeeds = testData.expected.jobs - .map((job) => { + const expectedRspDatafeeds = sortBy( + testData.expected.jobs.map((job) => { return { id: `datafeed-${job.jobId}`, success: true, started: testData.requestBody.startDatafeed, }; - }) - .sort(compareById); + }), + 'id' + ); - const actualRspDatafeeds = rspBody.datafeeds.sort(compareById); + const actualRspDatafeeds = sortBy(rspBody.datafeeds, 'id'); expect(actualRspDatafeeds).to.eql( expectedRspDatafeeds, @@ -803,9 +795,9 @@ export default ({ getService }: FtrProviderContext) => { let actualDashboards = []; if (isEmpty(rspKibana) === false) { - actualSearches = rspBody.kibana.search.sort(compareById); - actualVisualizations = rspBody.kibana.visualization.sort(compareById); - actualDashboards = rspBody.kibana.dashboard.sort(compareById); + actualSearches = sortBy(rspBody.kibana.search, 'id'); + actualVisualizations = sortBy(rspBody.kibana.visualization, 'id'); + actualDashboards = sortBy(rspBody.kibana.dashboard, 'id'); } const expectedSearches = mapIdsToSuccessObjects(testData.expected.searches); @@ -847,12 +839,13 @@ export default ({ getService }: FtrProviderContext) => { } // compare model memory limits for created jobs - const expectedModelMemoryLimits = testData.expected.jobs - .map((j) => ({ + const expectedModelMemoryLimits = sortBy( + testData.expected.jobs.map((j) => ({ id: j.jobId, modelMemoryLimit: j.modelMemoryLimit, - })) - .sort(compareById); + })), + 'id' + ); const { body: { jobs }, @@ -864,12 +857,13 @@ export default ({ getService }: FtrProviderContext) => { testData.expected.jobs.map((j) => j.jobId).join() ); - const actualModelMemoryLimits = jobs - .map((j) => ({ + const actualModelMemoryLimits = sortBy( + jobs.map((j) => ({ id: j.job_id, modelMemoryLimit: j.analysis_limits!.model_memory_limit, - })) - .sort(compareById); + })), + 'id' + ); expect(actualModelMemoryLimits).to.eql( expectedModelMemoryLimits, diff --git a/x-pack/test/api_integration/apis/ml/saved_objects/initialize.ts b/x-pack/test/api_integration/apis/ml/saved_objects/initialize.ts index 5b836925df37c..d28da5abe24c9 100644 --- a/x-pack/test/api_integration/apis/ml/saved_objects/initialize.ts +++ b/x-pack/test/api_integration/apis/ml/saved_objects/initialize.ts @@ -5,6 +5,8 @@ */ import expect from '@kbn/expect'; +import { sortBy } from 'lodash'; + import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; @@ -52,13 +54,12 @@ export default ({ getService }: FtrProviderContext) => { const body = await runRequest(USER.ML_POWERUSER_ALL_SPACES, 200); - expect(body).to.eql({ - jobs: [ - { id: adJobId, type: 'anomaly-detector' }, - { id: dfaJobId, type: 'data-frame-analytics' }, - ], - success: true, - }); + expect(body).to.have.property('jobs'); + expect(sortBy(body.jobs, 'id')).to.eql([ + { id: adJobId, type: 'anomaly-detector' }, + { id: dfaJobId, type: 'data-frame-analytics' }, + ]); + expect(body).to.have.property('success', true); await ml.api.assertJobSpaces(adJobId, 'anomaly-detector', ['*']); await ml.api.assertJobSpaces(dfaJobId, 'data-frame-analytics', ['*']); }); diff --git a/x-pack/test/api_integration/apis/ml/saved_objects/jobs_spaces.ts b/x-pack/test/api_integration/apis/ml/saved_objects/jobs_spaces.ts index 873a2feb151a0..9f079ea2c8b4c 100644 --- a/x-pack/test/api_integration/apis/ml/saved_objects/jobs_spaces.ts +++ b/x-pack/test/api_integration/apis/ml/saved_objects/jobs_spaces.ts @@ -69,28 +69,30 @@ export default ({ getService }: FtrProviderContext) => { it('should list all jobs for user with access to all spaces', async () => { const body = await runRequest(200, USER.ML_VIEWER_ALL_SPACES); - expect(body).to.eql({ - 'anomaly-detector': { - [adJobIdSpace1]: [idSpace1], - [adJobIdSpace2]: [idSpace2], - }, - 'data-frame-analytics': { - [dfaJobIdSpace1]: [idSpace1], - [dfaJobIdSpace2]: [idSpace2], - }, + expect(body).to.have.property('anomaly-detector'); + expect(body['anomaly-detector']).to.eql({ + [adJobIdSpace1]: [idSpace1], + [adJobIdSpace2]: [idSpace2], + }); + + expect(body).to.have.property('data-frame-analytics'); + expect(body['data-frame-analytics']).to.eql({ + [dfaJobIdSpace1]: [idSpace1], + [dfaJobIdSpace2]: [idSpace2], }); }); it('should only list jobs for the space the user has access to', async () => { const body = await runRequest(200, USER.ML_VIEWER_SPACE1); - expect(body).to.eql({ - 'anomaly-detector': { - [adJobIdSpace1]: [idSpace1], - }, - 'data-frame-analytics': { - [dfaJobIdSpace1]: [idSpace1], - }, + expect(body).to.have.property('anomaly-detector'); + expect(body['anomaly-detector']).to.eql({ + [adJobIdSpace1]: [idSpace1], + }); + + expect(body).to.have.property('data-frame-analytics'); + expect(body['data-frame-analytics']).to.eql({ + [dfaJobIdSpace1]: [idSpace1], }); }); }); diff --git a/x-pack/test/api_integration/apis/ml/saved_objects/status.ts b/x-pack/test/api_integration/apis/ml/saved_objects/status.ts index 80c35d029c1c2..585934e3b420e 100644 --- a/x-pack/test/api_integration/apis/ml/saved_objects/status.ts +++ b/x-pack/test/api_integration/apis/ml/saved_objects/status.ts @@ -5,6 +5,8 @@ */ import expect from '@kbn/expect'; +import { sortBy } from 'lodash'; + import { FtrProviderContext } from '../../../ftr_provider_context'; import { USER } from '../../../../functional/services/ml/security_common'; import { COMMON_REQUEST_HEADERS } from '../../../../functional/services/ml/common_api'; @@ -76,7 +78,7 @@ export default ({ getService }: FtrProviderContext) => { expect(body).to.have.property('jobs'); expect(body.jobs).to.have.property('anomaly-detector'); - expect(body.jobs['anomaly-detector']).to.eql([ + expect(sortBy(body.jobs['anomaly-detector'], 'id')).to.eql([ { checks: { savedObjectExits: true }, datafeedId: null, @@ -90,7 +92,7 @@ export default ({ getService }: FtrProviderContext) => { ]); expect(body.jobs).to.have.property('data-frame-analytics'); - expect(body.jobs['data-frame-analytics']).to.eql([ + expect(sortBy(body.jobs['data-frame-analytics'], 'id')).to.eql([ { checks: { savedObjectExits: true }, datafeedId: null, @@ -107,7 +109,7 @@ export default ({ getService }: FtrProviderContext) => { expect(body).to.have.property('savedObjects'); expect(body.savedObjects).to.have.property('anomaly-detector'); - expect(body.savedObjects['anomaly-detector']).to.eql([ + expect(sortBy(body.savedObjects['anomaly-detector'], 'id')).to.eql([ { checks: { datafeedExists: false, jobExists: true }, datafeedId: null, @@ -125,7 +127,7 @@ export default ({ getService }: FtrProviderContext) => { ]); expect(body.savedObjects).to.have.property('data-frame-analytics'); - expect(body.savedObjects['data-frame-analytics']).to.eql([ + expect(sortBy(body.savedObjects['data-frame-analytics'], 'id')).to.eql([ { checks: { jobExists: true }, jobId: dfaJobIdSpace1,