Skip to content

Commit

Permalink
[8.x] [Streams] Adding the first integration test (elastic#201293) (e…
Browse files Browse the repository at this point in the history
…lastic#202661)

# Backport

This will backport the following commits from `main` to `8.x`:
- [[Streams] Adding the first integration test
(elastic#201293)](elastic#201293)

<!--- Backport version: 9.4.3 -->

### Questions ?
Please refer to the [Backport tool
documentation](https://github.com/sqren/backport)

<!--BACKPORT [{"author":{"name":"Chris
Cowan","email":"[email protected]"},"sourceCommit":{"committedDate":"2024-11-26T09:43:25Z","message":"[Streams]
Adding the first integration test (elastic#201293)\n\n## Summary\r\n\r\nThis PR
introduces the first integration test for the Streams project.\r\nThis
test covers the following basic functionality:\r\n\r\n- Enable
streams\r\n- Index a document to `logs`\r\n- Create a `logs.nginx` for
that reroutes based on `log.logger ==\r\n'nginx'`\r\n- Index a document
to `logs.nginx`\r\n- Create a `logs.nginx.access` that reroutes based on
`log.level ==\r\n'info'`\r\n- Index a document to
`log.nginx.access`\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>\r\nCo-authored-by:
Elastic Machine
<[email protected]>\r\nCo-authored-by: Joe Reuter
<[email protected]>","sha":"aebd13ec678d620c1822d313ea5c9bb6d219a149","branchLabelMapping":{"^v9.0.0$":"main","^v8.18.0$":"8.x","^v(\\d+).(\\d+).\\d+$":"$1.$2"}},"sourcePullRequest":{"labels":["release_note:skip","Team:Observability","v9.0.0","backport:prev-minor","v8.18.0","Feature:Streams"],"title":"[Streams]
Adding the first integration
test","number":201293,"url":"https://github.com/elastic/kibana/pull/201293","mergeCommit":{"message":"[Streams]
Adding the first integration test (elastic#201293)\n\n## Summary\r\n\r\nThis PR
introduces the first integration test for the Streams project.\r\nThis
test covers the following basic functionality:\r\n\r\n- Enable
streams\r\n- Index a document to `logs`\r\n- Create a `logs.nginx` for
that reroutes based on `log.logger ==\r\n'nginx'`\r\n- Index a document
to `logs.nginx`\r\n- Create a `logs.nginx.access` that reroutes based on
`log.level ==\r\n'info'`\r\n- Index a document to
`log.nginx.access`\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>\r\nCo-authored-by:
Elastic Machine
<[email protected]>\r\nCo-authored-by: Joe Reuter
<[email protected]>","sha":"aebd13ec678d620c1822d313ea5c9bb6d219a149"}},"sourceBranch":"main","suggestedTargetBranches":["8.x"],"targetPullRequestStates":[{"branch":"main","label":"v9.0.0","branchLabelMappingKey":"^v9.0.0$","isSourceBranch":true,"state":"MERGED","url":"https://github.com/elastic/kibana/pull/201293","number":201293,"mergeCommit":{"message":"[Streams]
Adding the first integration test (elastic#201293)\n\n## Summary\r\n\r\nThis PR
introduces the first integration test for the Streams project.\r\nThis
test covers the following basic functionality:\r\n\r\n- Enable
streams\r\n- Index a document to `logs`\r\n- Create a `logs.nginx` for
that reroutes based on `log.logger ==\r\n'nginx'`\r\n- Index a document
to `logs.nginx`\r\n- Create a `logs.nginx.access` that reroutes based on
`log.level ==\r\n'info'`\r\n- Index a document to
`log.nginx.access`\r\n\r\n---------\r\n\r\nCo-authored-by: kibanamachine
<[email protected]>\r\nCo-authored-by:
Elastic Machine
<[email protected]>\r\nCo-authored-by: Joe Reuter
<[email protected]>","sha":"aebd13ec678d620c1822d313ea5c9bb6d219a149"}},{"branch":"8.x","label":"v8.18.0","branchLabelMappingKey":"^v8.18.0$","isSourceBranch":false,"state":"NOT_CREATED"}]}]
BACKPORT-->

Co-authored-by: Chris Cowan <[email protected]>
  • Loading branch information
kibanamachine and simianhacker authored Dec 3, 2024
1 parent 1b7c2e8 commit cca3939
Show file tree
Hide file tree
Showing 6 changed files with 240 additions and 0 deletions.
1 change: 1 addition & 0 deletions .buildkite/ftr_oblt_stateful_configs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ enabled:
- x-pack/test/api_integration/apis/synthetics/config.ts
- x-pack/test/api_integration/apis/uptime/config.ts
- x-pack/test/api_integration/apis/entity_manager/config.ts
- x-pack/test/api_integration/apis/streams/config.ts
- x-pack/test/apm_api_integration/basic/config.ts
- x-pack/test/apm_api_integration/cloud/config.ts
- x-pack/test/apm_api_integration/rules/config.ts
Expand Down
16 changes: 16 additions & 0 deletions x-pack/test/api_integration/apis/streams/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
/*
* 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 { FtrConfigProviderContext } from '@kbn/test';

export default async function ({ readConfigFile }: FtrConfigProviderContext) {
const baseIntegrationTestsConfig = await readConfigFile(require.resolve('../../config.ts'));
return {
...baseIntegrationTestsConfig.getAll(),
testFiles: [require.resolve('.')],
};
}
140 changes: 140 additions & 0 deletions x-pack/test/api_integration/apis/streams/full_flow.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
/*
* 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 {
deleteStream,
enableStreams,
fetchDocument,
forkStream,
indexDocument,
} from './helpers/requests';
import { FtrProviderContext } from '../../ftr_provider_context';
import { waitForDocumentInIndex } from '../../../alerting_api_integration/observability/helpers/alerting_wait_for_helpers';
import { cleanUpRootStream } from './helpers/cleanup';

export default function ({ getService }: FtrProviderContext) {
const supertest = getService('supertest');
const esClient = getService('es');
const retryService = getService('retry');
const logger = getService('log');

describe('Basic functionality', () => {
after(async () => {
await deleteStream(supertest, 'logs.nginx');
await cleanUpRootStream(esClient);
});

// Note: Each step is dependent on the previous
describe('Full flow', () => {
it('Enable streams', async () => {
await enableStreams(supertest);
});

it('Index a JSON document to logs, should go to logs', async () => {
const doc = {
'@timestamp': '2024-01-01T00:00:00.000Z',
message: JSON.stringify({
'log.level': 'info',
'log.logger': 'nginx',
message: 'test',
}),
};
const response = await indexDocument(esClient, 'logs', doc);
expect(response.result).to.eql('created');
await waitForDocumentInIndex({ esClient, indexName: 'logs', retryService, logger });

const result = await fetchDocument(esClient, 'logs', response._id);
expect(result._index).to.match(/^\.ds\-logs-.*/);
expect(result._source).to.eql({
'@timestamp': '2024-01-01T00:00:00.000Z',
message: 'test',
log: { level: 'info', logger: 'nginx' },
});
});

it('Fork logs to logs.nginx', async () => {
const body = {
stream: {
id: 'logs.nginx',
fields: [],
processing: [],
},
condition: {
field: 'log.logger',
operator: 'eq',
value: 'nginx',
},
};
const response = await forkStream(supertest, 'logs', body);
expect(response).to.have.property('acknowledged', true);
});

it('Index an Nginx access log message, should goto logs.nginx', async () => {
const doc = {
'@timestamp': '2024-01-01T00:00:10.000Z',
message: JSON.stringify({
'log.level': 'info',
'log.logger': 'nginx',
message: 'test',
}),
};
const response = await indexDocument(esClient, 'logs', doc);
expect(response.result).to.eql('created');
await waitForDocumentInIndex({ esClient, indexName: 'logs.nginx', retryService, logger });

const result = await fetchDocument(esClient, 'logs.nginx', response._id);
expect(result._index).to.match(/^\.ds\-logs.nginx-.*/);
expect(result._source).to.eql({
'@timestamp': '2024-01-01T00:00:10.000Z',
message: 'test',
log: { level: 'info', logger: 'nginx' },
});
});

it('Fork logs to logs.nginx.access', async () => {
const body = {
stream: {
id: 'logs.nginx.access',
fields: [],
processing: [],
},
condition: { field: 'log.level', operator: 'eq', value: 'info' },
};
const response = await forkStream(supertest, 'logs.nginx', body);
expect(response).to.have.property('acknowledged', true);
});

it('Index an Nginx access log message, should goto logs.nginx.access', async () => {
const doc = {
'@timestamp': '2024-01-01T00:00:20.000Z',
message: JSON.stringify({
'log.level': 'info',
'log.logger': 'nginx',
message: 'test',
}),
};
const response = await indexDocument(esClient, 'logs', doc);
expect(response.result).to.eql('created');
await waitForDocumentInIndex({
esClient,
indexName: 'logs.nginx.access',
retryService,
logger,
});

const result = await fetchDocument(esClient, 'logs.nginx.access', response._id);
expect(result._index).to.match(/^\.ds\-logs.nginx.access-.*/);
expect(result._source).to.eql({
'@timestamp': '2024-01-01T00:00:20.000Z',
message: 'test',
log: { level: 'info', logger: 'nginx' },
});
});
});
});
}
26 changes: 26 additions & 0 deletions x-pack/test/api_integration/apis/streams/helpers/cleanup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* 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 { Client } from '@elastic/elasticsearch';

/**
DELETE .kibana_streams
DELETE _data_stream/logs
DELETE /_index_template/logs@stream
DELETE /_component_template/[email protected]
DELETE /_ingest/pipeline/logs@json-pipeline
DELETE /_ingest/pipeline/[email protected]
DELETE /_ingest/pipeline/[email protected]
*/

export async function cleanUpRootStream(esClient: Client) {
await esClient.indices.delete({ index: '.kibana_streams' });
await esClient.indices.deleteDataStream({ name: 'logs' });
await esClient.indices.deleteIndexTemplate({ name: 'logs@stream' });
await esClient.cluster.deleteComponentTemplate({ name: '[email protected]' });
await esClient.ingest.deletePipeline({ id: 'logs@stream.*' });
}
43 changes: 43 additions & 0 deletions x-pack/test/api_integration/apis/streams/helpers/requests.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
/*
* 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 { Client } from '@elastic/elasticsearch';
import { JsonObject } from '@kbn/utility-types';
import { Agent } from 'supertest';
import expect from '@kbn/expect';
import { SearchTotalHits } from '@elastic/elasticsearch/lib/api/typesWithBodyKey';

export async function enableStreams(supertest: Agent) {
const req = supertest.post('/api/streams/_enable').set('kbn-xsrf', 'xxx');
const response = await req.send().expect(200);
return response.body;
}

export async function indexDocument(esClient: Client, index: string, document: JsonObject) {
const response = await esClient.index({ index, document });
return response;
}

export async function fetchDocument(esClient: Client, index: string, id: string) {
const query = {
ids: { values: [id] },
};
const response = await esClient.search({ index, query });
expect((response.hits.total as SearchTotalHits).value).to.eql(1);
return response.hits.hits[0];
}

export async function forkStream(supertest: Agent, root: string, body: JsonObject) {
const req = supertest.post(`/api/streams/${root}/_fork`).set('kbn-xsrf', 'xxx');
const response = await req.send(body).expect(200);
return response.body;
}

export async function deleteStream(supertest: Agent, id: string) {
const req = supertest.delete(`/api/streams/${id}`).set('kbn-xsrf', 'xxx');
const response = await req.send().expect(200);
return response.body;
}
14 changes: 14 additions & 0 deletions x-pack/test/api_integration/apis/streams/index.ts
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('Streams Endpoints', () => {
loadTestFile(require.resolve('./full_flow'));
});
}

0 comments on commit cca3939

Please sign in to comment.