Skip to content

Commit

Permalink
[Data Discovery] Run API integration tests in Serverless (#163550)
Browse files Browse the repository at this point in the history
## Summary

This PR copies the Data Discovery API integration tests to
`test_serverless`. They are currently in the common folder and will run
once for each project type in CI, but we could instead move them to a
specific project if we don't want to run them three times each.

In the future these should run as deployment-agnostic tests, but support
does not yet exist (see #161574), so in the meantime they've been
duplicated and modified in place. I've left `TODO` comments where test
files have been modified so we know what needs to be addressed once they
are converted to deployment-agnostic tests.

Part of #162347.

### Checklist

- [ ] ~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~
- [x] [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)~

### 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)

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
  • Loading branch information
davismcphee and kibanamachine authored Aug 29, 2023
1 parent 4f87b43 commit c288c8b
Show file tree
Hide file tree
Showing 71 changed files with 6,028 additions and 0 deletions.
6 changes: 6 additions & 0 deletions .github/CODEOWNERS
Validating CODEOWNERS rules …
Original file line number Diff line number Diff line change
Expand Up @@ -826,6 +826,12 @@ packages/kbn-yarn-lock-validator @elastic/kibana-operations
/x-pack/test/stack_functional_integration/apps/ccs/ccs_discover.js @elastic/kibana-data-discovery
/x-pack/test/stack_functional_integration/apps/management/_index_pattern_create.js @elastic/kibana-data-discovery
/x-pack/test/upgrade/apps/discover @elastic/kibana-data-discovery
/x-pack/test_serverless/api_integration/test_suites/common/data_views @elastic/kibana-data-discovery
/x-pack/test_serverless/api_integration/test_suites/common/data_view_field_editor @elastic/kibana-data-discovery
/x-pack/test_serverless/api_integration/test_suites/common/kql_telemetry @elastic/kibana-data-discovery
/x-pack/test_serverless/api_integration/test_suites/common/scripts_tests @elastic/kibana-data-discovery
/x-pack/test_serverless/api_integration/test_suites/common/search_oss @elastic/kibana-data-discovery
/x-pack/test_serverless/api_integration/test_suites/common/search_xpack @elastic/kibana-data-discovery

# Visualizations
/src/plugins/visualize/ @elastic/kibana-visualizations
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,173 @@
/*
* 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 { ELASTIC_HTTP_VERSION_HEADER } from '@kbn/core-http-common';
import { getErrorCodeFromErrorReason } from '@kbn/data-view-field-editor-plugin/public/lib/runtime_field_validation';
import {
FIELD_PREVIEW_PATH,
INITIAL_REST_VERSION,
} from '@kbn/data-view-field-editor-plugin/common/constants';
import type { FtrProviderContext } from '../../../ftr_provider_context';

const INDEX_NAME = 'api-integration-test-field-preview';

export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const es = getService('es');
const svlCommonApi = getService('svlCommonApi');

const document = { foo: 1, bar: 'hello' };

const createIndex = async () => {
await es.indices.create({
index: INDEX_NAME,
body: {
mappings: {
properties: {
foo: {
type: 'integer',
},
bar: {
type: 'keyword',
},
},
},
},
});
};

const deleteIndex = async () => {
await es.indices.delete({
index: INDEX_NAME,
});
};

describe('Field preview', function () {
before(async () => await createIndex());
after(async () => await deleteIndex());

describe('should return the script value', () => {
const tests = [
{
context: 'keyword_field',
script: {
source: 'emit("test")',
},
expected: 'test',
},
{
context: 'long_field',
script: {
source: 'emit(doc["foo"].value + 1)',
},
expected: 2,
},
{
context: 'keyword_field',
script: {
source: 'emit(doc["bar"].value + " world")',
},
expected: 'hello world',
},
];

tests.forEach((test) => {
it(`> ${test.context}`, async () => {
const payload = {
script: test.script,
document,
context: test.context,
index: INDEX_NAME,
};

const { body: response } = await supertest
.post(FIELD_PREVIEW_PATH)
.set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION)
// TODO: API requests in Serverless require internal request headers
.set(svlCommonApi.getInternalRequestHeader())
.send(payload)
.set('kbn-xsrf', 'xxx')
.expect(200);

expect(response.values).eql([test.expected]);
});
});
});

describe('payload validation', () => {
it('should require a script', async () => {
await supertest
.post(FIELD_PREVIEW_PATH)
.set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION)
// TODO: API requests in Serverless require internal request headers
.set(svlCommonApi.getInternalRequestHeader())
.send({
context: 'keyword_field',
index: INDEX_NAME,
})
.set('kbn-xsrf', 'xxx')
.expect(400);
});

it('should require a context', async () => {
await supertest
.post(FIELD_PREVIEW_PATH)
.set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION)
// TODO: API requests in Serverless require internal request headers
.set(svlCommonApi.getInternalRequestHeader())
.send({
script: { source: 'emit("hello")' },
index: INDEX_NAME,
})
.set('kbn-xsrf', 'xxx')
.expect(400);
});

it('should require an index', async () => {
await supertest
.post(FIELD_PREVIEW_PATH)
.set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION)
// TODO: API requests in Serverless require internal request headers
.set(svlCommonApi.getInternalRequestHeader())
.send({
script: { source: 'emit("hello")' },
context: 'keyword_field',
})
.set('kbn-xsrf', 'xxx')
.expect(400);
});
});

describe('Error messages', () => {
// As ES does not return error codes we will add a test to make sure its error message string
// does not change overtime as we rely on it to extract our own error code.
// If this test fail we'll need to update the "getErrorCodeFromErrorReason()" handler
// TODO: `response.error?.caused_by?.reason` returns
// `class_cast_exception: Cannot cast from [int] to [java.lang.String].`
// in Serverless, which causes `getErrorCodeFromErrorReason` to fail
it.skip('should detect a script casting error', async () => {
const { body: response } = await supertest
.post(FIELD_PREVIEW_PATH)
.set(ELASTIC_HTTP_VERSION_HEADER, INITIAL_REST_VERSION)
// TODO: API requests in Serverless require internal request headers
.set(svlCommonApi.getInternalRequestHeader())
.send({
script: { source: 'emit(123)' }, // We send a long but the type is "keyword"
context: 'keyword_field',
index: INDEX_NAME,
})
.set('kbn-xsrf', 'xxx');

const errorCode = getErrorCodeFromErrorReason(response.error?.caused_by?.reason);

expect(errorCode).be('CAST_ERROR');
});
});
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* 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 type { FtrProviderContext } from '../../../ftr_provider_context';

export default function ({ loadTestFile }: FtrProviderContext) {
describe('index pattern field editor', () => {
loadTestFile(require.resolve('./field_preview'));
});
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
/*
* 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 {
DATA_VIEW_PATH_LEGACY,
SERVICE_KEY_LEGACY,
DATA_VIEW_PATH,
SERVICE_KEY,
SERVICE_PATH,
SERVICE_PATH_LEGACY,
} from '@kbn/data-views-plugin/server';

const legacyConfig = {
name: 'legacy index pattern api',
path: DATA_VIEW_PATH_LEGACY,
basePath: SERVICE_PATH_LEGACY,
serviceKey: SERVICE_KEY_LEGACY,
};

export const dataViewConfig = {
name: 'data view api',
path: DATA_VIEW_PATH,
basePath: SERVICE_PATH,
serviceKey: SERVICE_KEY,
};

export const configArray = [legacyConfig, dataViewConfig];
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
* 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 type { FtrProviderContext } from '../../../../../ftr_provider_context';

export default function ({ loadTestFile }: FtrProviderContext) {
describe('create_index_pattern', () => {
loadTestFile(require.resolve('./validation'));
loadTestFile(require.resolve('./main'));
});
}
Loading

0 comments on commit c288c8b

Please sign in to comment.