From 52d0e38b83bdcd09b11fcb50b6ccfb64e1e2f1e1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Yulia=20=C4=8Cech?= <6585477+yuliacech@users.noreply.github.com> Date: Fri, 24 Nov 2023 12:02:23 +0100 Subject: [PATCH] [Index Management] Add serverless tests for indices routes (#171773) ## Summary This PR adds api integration tests for indices routes that were missing for serverless ("reload" and "delete index"). To avoid copy-pasting the code, this PR also adds an index management service to re-use in serverless tests. Also some refactoring of js code into ts. ### Checklist Delete any items that are not applicable to this PR. - [ ] Any text added follows [EUI's writing guidelines](https://elastic.github.io/eui/#/guidelines/writing), uses sentence case text and includes [i18n support](https://github.com/elastic/kibana/blob/main/packages/kbn-i18n/README.md) - [ ] [Documentation](https://www.elastic.co/guide/en/kibana/master/development-documentation.html) was added for features that require explanation or tutorials - [ ] [Unit or functional tests](https://www.elastic.co/guide/en/kibana/master/development-tests.html) were updated or added to match the most common scenarios - [ ] Any UI touched in this PR is usable by keyboard only (learn more about [keyboard accessibility](https://webaim.org/techniques/keyboard/)) - [ ] Any UI touched in this PR does not create any new axe failures (run axe in browser: [FF](https://addons.mozilla.org/en-US/firefox/addon/axe-devtools/), [Chrome](https://chrome.google.com/webstore/detail/axe-web-accessibility-tes/lhdoppojpmngadmnindnejefpokejbdd?hl=en-US)) - [ ] If a plugin configuration key changed, check if it needs to be allowlisted in the cloud and added to the [docker list](https://github.com/elastic/kibana/blob/main/src/dev/build/tasks/os_packages/docker_generator/resources/base/bin/kibana-docker) - [ ] This renders correctly on smaller devices using a responsive layout. (You can test this [in your browser](https://www.browserstack.com/guide/responsive-testing-on-local-server)) - [ ] This was checked for [cross-browser compatibility](https://www.elastic.co/support/matrix#matrix_browsers) ### Risk Matrix Delete this section if it is not applicable to this PR. Before closing this PR, invite QA, stakeholders, and other developers to identify risks that should be tested prior to the change/feature release. When forming the risk matrix, consider some of the following examples and how they may potentially impact the change: | Risk | Probability | Severity | Mitigation/Notes | |---------------------------|-------------|----------|-------------------------| | Multiple Spaces—unexpected behavior in non-default Kibana Space. | Low | High | Integration tests will verify that all features are still supported in non-default Kibana Space and when user switches between spaces. | | Multiple nodes—Elasticsearch polling might have race conditions when multiple Kibana nodes are polling for the same tasks. | High | Low | Tasks are idempotent, so executing them multiple times will not result in logical error, but will degrade performance. To test for this case we add plenty of unit tests around this logic and document manual testing procedure. | | Code should gracefully handle cases when feature X or plugin Y are disabled. | Medium | High | Unit tests will verify that any feature flag or plugin combination still results in our service operational. | | [See more potential risk examples](https://github.com/elastic/kibana/blob/main/RISK_MATRIX.mdx) | ### For maintainers - [ ] This was checked for breaking API changes and was [labeled appropriately](https://www.elastic.co/guide/en/kibana/master/contributing.html#kibana-release-notes-process) --- .../index_management/indices.helpers.js | 53 --------- .../{indices.js => indices.ts} | 65 +++++------ .../index_management/lib/elasticsearch.js | 25 ----- .../index_management/lib/indices.api.ts | 64 +++++++++++ .../index_management/lib/indices.helpers.ts | 35 ++++++ .../lib/{random.js => random.ts} | 0 .../management/index_management/mapping.js | 8 +- .../management/index_management/settings.js | 6 +- .../apis/management/index_management/stats.js | 6 +- .../management/index_management/templates.js | 4 +- x-pack/test/api_integration/services/index.ts | 2 + .../services/index_management.ts | 19 ++++ .../common/index_management/indices.ts | 103 +++++++++++++----- .../services/deployment_agnostic_services.ts | 1 + 14 files changed, 233 insertions(+), 158 deletions(-) delete mode 100644 x-pack/test/api_integration/apis/management/index_management/indices.helpers.js rename x-pack/test/api_integration/apis/management/index_management/{indices.js => indices.ts} (75%) create mode 100644 x-pack/test/api_integration/apis/management/index_management/lib/indices.api.ts create mode 100644 x-pack/test/api_integration/apis/management/index_management/lib/indices.helpers.ts rename x-pack/test/api_integration/apis/management/index_management/lib/{random.js => random.ts} (100%) create mode 100644 x-pack/test/api_integration/services/index_management.ts diff --git a/x-pack/test/api_integration/apis/management/index_management/indices.helpers.js b/x-pack/test/api_integration/apis/management/index_management/indices.helpers.js deleted file mode 100644 index 368272858ea2c..0000000000000 --- a/x-pack/test/api_integration/apis/management/index_management/indices.helpers.js +++ /dev/null @@ -1,53 +0,0 @@ -/* - * 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 { API_BASE_PATH } from './constants'; - -export const registerHelpers = ({ supertest }) => { - const executeActionOnIndices = (index, urlParam, args) => { - const indices = Array.isArray(index) ? index : [index]; - - return supertest - .post(`${API_BASE_PATH}/indices/${urlParam}`) - .set('kbn-xsrf', 'xxx') - .send({ indices, ...args }); - }; - - const closeIndex = (index) => executeActionOnIndices(index, 'close'); - - const openIndex = (index) => executeActionOnIndices(index, 'open'); - - const deleteIndex = (index) => executeActionOnIndices(index, 'delete'); - - const flushIndex = (index) => executeActionOnIndices(index, 'flush'); - - const refreshIndex = (index) => executeActionOnIndices(index, 'refresh'); - - const forceMerge = (index, args) => executeActionOnIndices(index, 'forcemerge', args); - - const unfreeze = (index) => executeActionOnIndices(index, 'unfreeze'); - - const clearCache = (index) => executeActionOnIndices(index, 'clear_cache'); - - const list = () => supertest.get(`${API_BASE_PATH}/indices`); - - const reload = (indexNames) => - supertest.post(`${API_BASE_PATH}/indices/reload`).set('kbn-xsrf', 'xxx').send({ indexNames }); - - return { - closeIndex, - openIndex, - deleteIndex, - flushIndex, - refreshIndex, - forceMerge, - unfreeze, - list, - reload, - clearCache, - }; -}; diff --git a/x-pack/test/api_integration/apis/management/index_management/indices.js b/x-pack/test/api_integration/apis/management/index_management/indices.ts similarity index 75% rename from x-pack/test/api_integration/apis/management/index_management/indices.js rename to x-pack/test/api_integration/apis/management/index_management/indices.ts index 8d012f7a02d41..aa2ff5966c4df 100644 --- a/x-pack/test/api_integration/apis/management/index_management/indices.js +++ b/x-pack/test/api_integration/apis/management/index_management/indices.ts @@ -7,19 +7,13 @@ import expect from '@kbn/expect'; -import { initElasticsearchHelpers } from './lib'; -import { registerHelpers } from './indices.helpers'; import { sortedExpectedIndexKeys } from './constants'; +import { indicesApi } from './lib/indices.api'; +import { indicesHelpers } from './lib/indices.helpers'; +import { FtrProviderContext } from '../../../ftr_provider_context'; -export default function ({ getService }) { - const supertest = getService('supertest'); - - const { - createIndex, - catIndex, - indexStats, - cleanUp: cleanUpEsResources, - } = initElasticsearchHelpers(getService); +export default function ({ getService }: FtrProviderContext) { + const { createIndex, deleteAllIndices, catIndex, indexStats } = indicesHelpers(getService); const { closeIndex, @@ -32,10 +26,10 @@ export default function ({ getService }) { list, reload, clearCache, - } = registerHelpers({ supertest }); + } = indicesApi(getService); describe('indices', () => { - after(() => Promise.all([cleanUpEsResources()])); + after(async () => await deleteAllIndices()); describe('clear cache', () => { it('should clear the cache on a single index', async () => { @@ -45,9 +39,6 @@ export default function ({ getService }) { }); describe('close', function () { - // The Cloud backend disallows users from closing indices. - this.tags(['skipCloud']); - it('should close an index', async () => { const index = await createIndex(); @@ -68,10 +59,6 @@ export default function ({ getService }) { }); describe('open', function () { - // The Cloud backend disallows users from closing indices, so there's no point testing - // the open behavior. - this.tags(['skipCloud']); - it('should open an index', async () => { const index = await createIndex(); @@ -98,12 +85,12 @@ export default function ({ getService }) { const index = await createIndex(); const { body: indices1 } = await catIndex(undefined, 'i'); - expect(indices1.map((index) => index.i)).to.contain(index); + expect(indices1.map((indexItem) => indexItem.i)).to.contain(index); - await deleteIndex([index]).expect(200); + await deleteIndex(index).expect(200); const { body: indices2 } = await catIndex(undefined, 'i'); - expect(indices2.map((index) => index.i)).not.to.contain(index); + expect(indices2.map((indexItem) => indexItem.i)).not.to.contain(index); }); it('should require index or indices to be provided', async () => { @@ -119,6 +106,7 @@ export default function ({ getService }) { const { body: { indices: indices1 }, } = await indexStats(index, 'flush'); + // @ts-ignore expect(indices1[index].total.flush.total).to.be(0); await flushIndex(index).expect(200); @@ -126,6 +114,7 @@ export default function ({ getService }) { const { body: { indices: indices2 }, } = await indexStats(index, 'flush'); + // @ts-ignore expect(indices2[index].total.flush.total).to.be(1); }); }); @@ -137,6 +126,7 @@ export default function ({ getService }) { const { body: { indices: indices1 }, } = await indexStats(index, 'refresh'); + // @ts-ignore const previousRefreshes = indices1[index].total.refresh.total; await refreshIndex(index).expect(200); @@ -144,6 +134,7 @@ export default function ({ getService }) { const { body: { indices: indices2 }, } = await indexStats(index, 'refresh'); + // @ts-ignore expect(indices2[index].total.refresh.total).to.be(previousRefreshes + 1); }); }); @@ -175,8 +166,6 @@ export default function ({ getService }) { }); describe('list', function () { - this.tags(['skipCloud']); - it('should list all the indices with the expected properties and data enrichers', async function () { // Create an index that we can assert against await createIndex('test_index'); @@ -185,7 +174,7 @@ export default function ({ getService }) { const { body: indices } = await list().expect(200); // Find the "test_index" created to verify expected keys - const indexCreated = indices.find((index) => index.name === 'test_index'); + const indexCreated = indices.find((index: { name: string }) => index.name === 'test_index'); const sortedReceivedKeys = Object.keys(indexCreated).sort(); @@ -194,19 +183,17 @@ export default function ({ getService }) { }); describe('reload', function () { - describe('(not on Cloud)', function () { - this.tags(['skipCloud']); - - it('should list all the indices with the expected properties and data enrichers', async function () { - // create an index to assert against, otherwise the test is flaky - await createIndex('reload-test-index'); - const { body } = await reload().expect(200); - - const indexCreated = body.find((index) => index.name === 'reload-test-index'); - const sortedReceivedKeys = Object.keys(indexCreated).sort(); - expect(sortedReceivedKeys).to.eql(sortedExpectedIndexKeys); - expect(body.length > 1).to.be(true); // to contrast it with the next test - }); + it('should list all the indices with the expected properties and data enrichers', async function () { + // create an index to assert against, otherwise the test is flaky + await createIndex('reload-test-index'); + const { body } = await reload().expect(200); + + const indexCreated = body.find( + (index: { name: string }) => index.name === 'reload-test-index' + ); + const sortedReceivedKeys = Object.keys(indexCreated).sort(); + expect(sortedReceivedKeys).to.eql(sortedExpectedIndexKeys); + expect(body.length > 1).to.be(true); // to contrast it with the next test }); it('should allow reloading only certain indices', async () => { diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js b/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js index d71085439e868..606fe5a3d8b89 100644 --- a/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js +++ b/x-pack/test/api_integration/apis/management/index_management/lib/elasticsearch.js @@ -5,8 +5,6 @@ * 2.0. */ -import { getRandomString } from './random'; - /** * Helpers to create and delete indices on the Elasticsearch instance * during our tests. @@ -14,9 +12,7 @@ import { getRandomString } from './random'; */ export const initElasticsearchHelpers = (getService) => { const es = getService('es'); - const esDeleteAllIndices = getService('esDeleteAllIndices'); - let indicesCreated = []; let datastreamCreated = []; let indexTemplatesCreated = []; let componentTemplatesCreated = []; @@ -40,22 +36,6 @@ export const initElasticsearchHelpers = (getService) => { console.log(`[Cleanup error] Error deleting ES resources: ${err.message}`); }); - const createIndex = (index = getRandomString(), body) => { - indicesCreated.push(index); - return es.indices.create({ index, body }).then(() => index); - }; - - const deleteAllIndices = async () => { - await esDeleteAllIndices(indicesCreated); - indicesCreated = []; - }; - - const catIndex = (index, h) => es.cat.indices({ index, format: 'json', h }, { meta: true }); - - const indexStats = (index, metric) => es.indices.stats({ index, metric }, { meta: true }); - - const cleanUp = () => deleteAllIndices(); - const catTemplate = (name) => es.cat.templates({ name, format: 'json' }, { meta: true }); const createIndexTemplate = (indexTemplate, shouldCacheTemplate) => { @@ -103,14 +83,9 @@ export const initElasticsearchHelpers = (getService) => { }); return { - createIndex, - deleteAllIndices, - catIndex, - indexStats, createDatastream, deleteDatastream, cleanupDatastreams, - cleanUp, catTemplate, createIndexTemplate, deleteIndexTemplate, diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/indices.api.ts b/x-pack/test/api_integration/apis/management/index_management/lib/indices.api.ts new file mode 100644 index 0000000000000..d75d3ec0527b6 --- /dev/null +++ b/x-pack/test/api_integration/apis/management/index_management/lib/indices.api.ts @@ -0,0 +1,64 @@ +/* + * 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 { API_BASE_PATH } from '../constants'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export function indicesApi(getService: FtrProviderContext['getService']) { + const supertest = getService('supertest'); + const executeActionOnIndices = ({ + index, + urlParam, + args, + }: { + index?: string | string[]; + urlParam: string; + args?: any; + }) => { + const indices = Array.isArray(index) ? index : [index]; + + return supertest + .post(`${API_BASE_PATH}/indices/${urlParam}`) + .set('kbn-xsrf', 'xxx') + .send({ indices, ...args }); + }; + + const closeIndex = (index: string) => executeActionOnIndices({ index, urlParam: 'close' }); + + const openIndex = (index: string) => executeActionOnIndices({ index, urlParam: 'open' }); + + const deleteIndex = (index?: string) => executeActionOnIndices({ index, urlParam: 'delete' }); + + const flushIndex = (index: string) => executeActionOnIndices({ index, urlParam: 'flush' }); + + const refreshIndex = (index: string) => executeActionOnIndices({ index, urlParam: 'refresh' }); + + const forceMerge = (index: string, args?: { maxNumSegments: number }) => + executeActionOnIndices({ index, urlParam: 'forcemerge', args }); + + const unfreeze = (index: string) => executeActionOnIndices({ index, urlParam: 'unfreeze' }); + + const clearCache = (index: string) => executeActionOnIndices({ index, urlParam: 'clear_cache' }); + + const list = () => supertest.get(`${API_BASE_PATH}/indices`); + + const reload = (indexNames?: string[]) => + supertest.post(`${API_BASE_PATH}/indices/reload`).set('kbn-xsrf', 'xxx').send({ indexNames }); + + return { + closeIndex, + openIndex, + deleteIndex, + flushIndex, + refreshIndex, + forceMerge, + unfreeze, + list, + reload, + clearCache, + }; +} diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/indices.helpers.ts b/x-pack/test/api_integration/apis/management/index_management/lib/indices.helpers.ts new file mode 100644 index 0000000000000..139e813d84ffe --- /dev/null +++ b/x-pack/test/api_integration/apis/management/index_management/lib/indices.helpers.ts @@ -0,0 +1,35 @@ +/* + * 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 { getRandomString } from './random'; +import { FtrProviderContext } from '../../../../ftr_provider_context'; + +export function indicesHelpers(getService: FtrProviderContext['getService']) { + const es = getService('es'); + const esDeleteAllIndices = getService('esDeleteAllIndices'); + + let indicesCreated: string[] = []; + + const createIndex = async (index: string = getRandomString(), mappings?: any) => { + indicesCreated.push(index); + await es.indices.create({ index, mappings }); + return index; + }; + + const deleteAllIndices = async () => { + await esDeleteAllIndices(indicesCreated); + indicesCreated = []; + }; + + const catIndex = (index?: string, h?: any) => + es.cat.indices({ index, format: 'json', h }, { meta: true }); + + const indexStats = (index: string, metric: string) => + es.indices.stats({ index, metric }, { meta: true }); + + return { createIndex, deleteAllIndices, catIndex, indexStats }; +} diff --git a/x-pack/test/api_integration/apis/management/index_management/lib/random.js b/x-pack/test/api_integration/apis/management/index_management/lib/random.ts similarity index 100% rename from x-pack/test/api_integration/apis/management/index_management/lib/random.js rename to x-pack/test/api_integration/apis/management/index_management/lib/random.ts diff --git a/x-pack/test/api_integration/apis/management/index_management/mapping.js b/x-pack/test/api_integration/apis/management/index_management/mapping.js index c18bc4c163526..21f908ac5e0a1 100644 --- a/x-pack/test/api_integration/apis/management/index_management/mapping.js +++ b/x-pack/test/api_integration/apis/management/index_management/mapping.js @@ -7,18 +7,18 @@ import expect from '@kbn/expect'; -import { initElasticsearchHelpers } from './lib'; +import { indicesHelpers } from './lib/indices.helpers'; import { registerHelpers } from './mapping.helpers'; export default function ({ getService }) { const supertest = getService('supertest'); - const { createIndex, cleanUp: cleanUpEsResources } = initElasticsearchHelpers(getService); + const { createIndex, deleteAllIndices } = indicesHelpers(getService); const { getIndexMapping } = registerHelpers({ supertest }); describe('mapping', () => { - after(() => Promise.all([cleanUpEsResources()])); + after(async () => await deleteAllIndices()); it('should fetch the index mapping', async () => { const mappings = { @@ -28,7 +28,7 @@ export default function ({ getService }) { createdAt: { type: 'date' }, }, }; - const index = await createIndex(undefined, { mappings }); + const index = await createIndex(undefined, mappings); const { body } = await getIndexMapping(index).expect(200); diff --git a/x-pack/test/api_integration/apis/management/index_management/settings.js b/x-pack/test/api_integration/apis/management/index_management/settings.js index 44ee80aaec7a2..fbffc203cff58 100644 --- a/x-pack/test/api_integration/apis/management/index_management/settings.js +++ b/x-pack/test/api_integration/apis/management/index_management/settings.js @@ -7,18 +7,18 @@ import expect from '@kbn/expect'; -import { initElasticsearchHelpers } from './lib'; +import { indicesHelpers } from './lib/indices.helpers'; import { registerHelpers } from './settings.helpers'; export default function ({ getService }) { const supertest = getService('supertest'); - const { createIndex, cleanUp: cleanUpEsResources } = initElasticsearchHelpers(getService); + const { createIndex, deleteAllIndices } = indicesHelpers(getService); const { getIndexSettings, updateIndexSettings } = registerHelpers({ supertest }); describe('settings', () => { - after(() => Promise.all([cleanUpEsResources()])); + after(async () => await deleteAllIndices()); it('should fetch an index settings', async () => { const index = await createIndex(); diff --git a/x-pack/test/api_integration/apis/management/index_management/stats.js b/x-pack/test/api_integration/apis/management/index_management/stats.js index c673f10461715..782b32a787323 100644 --- a/x-pack/test/api_integration/apis/management/index_management/stats.js +++ b/x-pack/test/api_integration/apis/management/index_management/stats.js @@ -7,18 +7,18 @@ import expect from '@kbn/expect'; -import { initElasticsearchHelpers } from './lib'; +import { indicesHelpers } from './lib/indices.helpers'; import { registerHelpers } from './stats.helpers'; export default function ({ getService }) { const supertest = getService('supertest'); - const { createIndex, cleanUp: cleanUpEsResources } = initElasticsearchHelpers(getService); + const { createIndex, deleteAllIndices } = indicesHelpers(getService); const { getIndexStats } = registerHelpers({ supertest }); describe('stats', () => { - after(() => Promise.all([cleanUpEsResources()])); + after(async () => await deleteAllIndices()); it('should fetch the index stats', async () => { const index = await createIndex(); diff --git a/x-pack/test/api_integration/apis/management/index_management/templates.js b/x-pack/test/api_integration/apis/management/index_management/templates.js index bb4007852b037..4882ecccf6346 100644 --- a/x-pack/test/api_integration/apis/management/index_management/templates.js +++ b/x-pack/test/api_integration/apis/management/index_management/templates.js @@ -13,7 +13,7 @@ import { registerHelpers } from './templates.helpers'; export default function ({ getService }) { const supertest = getService('supertest'); - const { cleanUp: cleanUpEsResources, catTemplate } = initElasticsearchHelpers(getService); + const { catTemplate } = initElasticsearchHelpers(getService); const { getAllTemplates, @@ -27,7 +27,7 @@ export default function ({ getService }) { // FAILING ES PROMOTION: https://github.com/elastic/kibana/issues/170980 describe.skip('index templates', () => { - after(() => Promise.all([cleanUpEsResources(), cleanUpTemplates()])); + after(async () => await cleanUpTemplates()); describe('get all', () => { const indexTemplate = getTemplatePayload(`template-${getRandomString()}`, [ diff --git a/x-pack/test/api_integration/services/index.ts b/x-pack/test/api_integration/services/index.ts index 6ef3e393a86e6..1f8d4576d908d 100644 --- a/x-pack/test/api_integration/services/index.ts +++ b/x-pack/test/api_integration/services/index.ts @@ -21,6 +21,7 @@ import { MachineLearningProvider } from './ml'; import { IngestManagerProvider } from '../../common/services/ingest_manager'; import { TransformProvider } from './transform'; import { IngestPipelinesProvider } from './ingest_pipelines'; +import { IndexManagementProvider } from './index_management'; export const services = { ...commonServices, @@ -37,4 +38,5 @@ export const services = { ingestManager: IngestManagerProvider, transform: TransformProvider, ingestPipelines: IngestPipelinesProvider, + indexManagement: IndexManagementProvider, }; diff --git a/x-pack/test/api_integration/services/index_management.ts b/x-pack/test/api_integration/services/index_management.ts new file mode 100644 index 0000000000000..98091076cc5a3 --- /dev/null +++ b/x-pack/test/api_integration/services/index_management.ts @@ -0,0 +1,19 @@ +/* + * 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'; +import { indicesApi } from '../apis/management/index_management/lib/indices.api'; +import { indicesHelpers } from '../apis/management/index_management/lib/indices.helpers'; + +export function IndexManagementProvider({ getService }: FtrProviderContext) { + return { + indices: { + api: indicesApi(getService), + helpers: indicesHelpers(getService), + }, + }; +} diff --git a/x-pack/test_serverless/api_integration/test_suites/common/index_management/indices.ts b/x-pack/test_serverless/api_integration/test_suites/common/index_management/indices.ts index 9c4fd7b196337..70de83c949cf5 100644 --- a/x-pack/test_serverless/api_integration/test_suites/common/index_management/indices.ts +++ b/x-pack/test_serverless/api_integration/test_suites/common/index_management/indices.ts @@ -5,10 +5,9 @@ * 2.0. */ -import expect from 'expect'; +import expect from '@kbn/expect'; import { FtrProviderContext } from '../../../ftr_provider_context'; -const API_BASE_PATH = '/api/index_management'; const INTERNAL_API_BASE_PATH = '/internal/index_management'; const expectedKeys = ['aliases', 'hidden', 'isFrozen', 'primary', 'replica', 'name'].sort(); @@ -16,22 +15,27 @@ export default function ({ getService }: FtrProviderContext) { const supertest = getService('supertest'); const es = getService('es'); const log = getService('log'); + const indexManagementService = getService('indexManagement'); describe('Indices', function () { - const indexName = `index-${Math.random()}`; + let indexName: string; + let reload: typeof indexManagementService['indices']['api']['reload']; + let list: typeof indexManagementService['indices']['api']['list']; + let deleteIndex: typeof indexManagementService['indices']['api']['deleteIndex']; + let createIndex: typeof indexManagementService['indices']['helpers']['createIndex']; + let deleteAllIndices: typeof indexManagementService['indices']['helpers']['deleteAllIndices']; + let catIndex: typeof indexManagementService['indices']['helpers']['catIndex']; before(async () => { - // Create a new index to test against - const indexExists = await es.indices.exists({ index: indexName }); - - // Index should not exist, but in the case that it already does, we bypass the create request - if (indexExists) { - return; - } - + ({ + indices: { + api: { reload, list, deleteIndex }, + helpers: { createIndex, deleteAllIndices, catIndex }, + }, + } = indexManagementService); log.debug(`Creating index: '${indexName}'`); try { - await es.indices.create({ index: indexName }); + indexName = await createIndex(); } catch (err) { log.debug('[Setup error] Error creating index'); throw err; @@ -41,28 +45,27 @@ export default function ({ getService }: FtrProviderContext) { after(async () => { // Cleanup index created for testing purposes try { - await es.indices.delete({ - index: indexName, - }); + await deleteAllIndices(); } catch (err) { log.debug('[Cleanup error] Error deleting index'); throw err; } }); - describe('get all', () => { - it('should list indices with the expected parameters', async () => { - const { body: indices } = await supertest - .get(`${API_BASE_PATH}/indices`) - .set('kbn-xsrf', 'xxx') - .set('x-elastic-internal-origin', 'xxx') - .expect(200); + describe('list', () => { + it('should list all the indices with the expected properties', async function () { + // Create an index that we can assert against + await createIndex('test_index'); - const indexFound = indices.find((index: { name: string }) => index.name === indexName); + // Verify indices request + const { body: indices } = await list().set('x-elastic-internal-origin', 'xxx').expect(200); - expect(indexFound).toBeTruthy(); + // Find the "test_index" created to verify expected keys + const indexCreated = indices.find((index: { name: string }) => index.name === 'test_index'); - expect(Object.keys(indexFound).sort()).toEqual(expectedKeys); + const sortedReceivedKeys = Object.keys(indexCreated).sort(); + + expect(sortedReceivedKeys).to.eql(expectedKeys); }); }); @@ -74,9 +77,9 @@ export default function ({ getService }: FtrProviderContext) { .set('x-elastic-internal-origin', 'xxx') .expect(200); - expect(index).toBeTruthy(); + expect(index).to.be.ok(); - expect(Object.keys(index).sort()).toEqual(expectedKeys); + expect(Object.keys(index).sort()).to.eql(expectedKeys); }); it('throws 404 for a non-existent index', async () => { @@ -118,9 +121,9 @@ export default function ({ getService }: FtrProviderContext) { .set('x-elastic-internal-origin', 'xxx') .expect(200); - expect(index).toBeTruthy(); + expect(index).to.be.ok(); - expect(Object.keys(index).sort()).toEqual(expectedKeys); + expect(Object.keys(index).sort()).to.eql(expectedKeys); }); it('fails to re-create the same index', async () => { @@ -134,5 +137,47 @@ export default function ({ getService }: FtrProviderContext) { .expect(400); }); }); + + describe('reload', function () { + it('should list all the indices with the expected properties', async function () { + // create an index to assert against, otherwise the test is flaky + await createIndex('reload-test-index'); + const { body } = await reload().set('x-elastic-internal-origin', 'xxx').expect(200); + + const indexCreated = body.find( + (index: { name: string }) => index.name === 'reload-test-index' + ); + const sortedReceivedKeys = Object.keys(indexCreated).sort(); + expect(sortedReceivedKeys).to.eql(expectedKeys); + expect(body.length > 1).to.be(true); // to contrast it with the next test + }); + + it('should allow reloading only certain indices', async () => { + const index = await createIndex(); + const { body } = await reload([index]).set('x-elastic-internal-origin', 'xxx'); + + expect(body.length === 1).to.be(true); + expect(body[0].name).to.be(index); + }); + }); + + describe('delete indices', () => { + it('should delete an index', async () => { + const index = await createIndex(); + + const { body: indices1 } = await catIndex(undefined, 'i'); + expect(indices1.map((indexItem) => indexItem.i)).to.contain(index); + + await deleteIndex(index).set('x-elastic-internal-origin', 'xxx').expect(200); + + const { body: indices2 } = await catIndex(undefined, 'i'); + expect(indices2.map((indexItem) => indexItem.i)).not.to.contain(index); + }); + + it('should require index or indices to be provided', async () => { + const { body } = await deleteIndex().set('x-elastic-internal-origin', 'xxx').expect(400); + expect(body.message).to.contain('expected value of type [string]'); + }); + }); }); } diff --git a/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts b/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts index 4721a6f71d10e..ce922732796fe 100644 --- a/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts +++ b/x-pack/test_serverless/shared/services/deployment_agnostic_services.ts @@ -21,6 +21,7 @@ const deploymentAgnosticApiIntegrationServices = _.pick(apiIntegrationServices, 'esSupertest', 'indexPatterns', 'ingestPipelines', + 'indexManagement', 'kibanaServer', 'ml', 'randomness',