Fix 8.x 9 forward compat tests part ii (#207407)

## Summary

Follow up from https://github.com/elastic/kibana/pull/206624 aimed at
fixing failing compat tests:


https://buildkite.com/elastic/kibana-es-forward-compatibility-testing-9-dot-0/builds?branch=8.x

### Core

* Fixed jest integration tests, generated new archives
* Skipped the UA tests for 8.x -> 9 if ES >8, I assume these tests only
make sense if ES is on v8

### Security solution ES|QL

* Made the `metadata [...` test only run when ES is v8

### Kibana management

* Made the unfreeze test only run when ES is v8
This commit is contained in:
Jean-Louis Leysens 2025-01-22 11:26:54 +01:00 committed by GitHub
parent 7a48da7ba1
commit 4ca8cef44b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
8 changed files with 88 additions and 64 deletions

View file

@ -12,7 +12,7 @@ import {
type TestElasticsearchUtils,
type TestKibanaUtils,
} from '@kbn/core-test-helpers-kbn-server';
import { esTestConfig } from '@kbn/test';
import { esTestConfig, EsVersion } from '@kbn/test';
import { firstValueFrom, Subject } from 'rxjs';
import { CliArgs } from '@kbn/config';
import Semver from 'semver';
@ -93,25 +93,30 @@ describe('Version Compatibility', () => {
await expect(startServers({ customKibanaVersion: previousMinor() })).resolves.toBeUndefined();
});
it('should flag the incompatibility on version mismatch (ES is previous minor)', async () => {
const found$ = new Subject<void>();
consoleSpy.mockImplementation((str) => {
if (str.includes('is incompatible')) {
found$.next();
}
});
await Promise.race([
firstValueFrom(found$),
startServers({ customKibanaVersion: nextMinor() }).then(() => {
throw new Error(
'Kibana completed the bootstrap without finding the incompatibility message'
);
}),
new Promise((resolve, reject) =>
setTimeout(() => reject(new Error('Test timedout')), 5 * 60 * 1000)
),
]).finally(() => found$.complete());
});
const willRunESv9 = EsVersion.getDefault({ integrationTest: true }).matchRange('9');
(willRunESv9 ? it.skip : it)(
'should flag the incompatibility on version mismatch (ES is previous minor)',
async () => {
const found$ = new Subject<void>();
consoleSpy.mockImplementation((str) => {
if (str.includes('is incompatible')) {
found$.next();
}
});
await Promise.race([
firstValueFrom(found$),
startServers({ customKibanaVersion: nextMinor() }).then(() => {
throw new Error(
'Kibana completed the bootstrap without finding the incompatibility message'
);
}),
new Promise((resolve, reject) =>
setTimeout(() => reject(new Error('Test timedout')), 5 * 60 * 1000)
),
]).finally(() => found$.complete());
}
);
it('should ignore the version mismatch when option is set', async () => {
await expect(

View file

@ -19,6 +19,7 @@ import {
import type { ElasticsearchClient } from '@kbn/core-elasticsearch-server';
import { Root } from '@kbn/core-root-server-internal';
import { deterministicallyRegenerateObjectId } from '@kbn/core-saved-objects-migration-server-internal';
import { EsVersion } from '@kbn/test';
const logFilePath = Path.join(__dirname, 'rewriting_id.log');
@ -93,7 +94,8 @@ function createRoot() {
);
}
// FAILING: https://github.com/elastic/kibana/issues/98351
const willRunESv9 = EsVersion.getDefault({ integrationTest: true }).matchRange('9');
describe('migration v2', () => {
let esServer: TestElasticsearchUtils;
let root: Root;
@ -140,7 +142,9 @@ describe('migration v2', () => {
__dirname,
'..',
'archives',
'7.13.2_so_with_multiple_namespaces.zip'
willRunESv9
? '8.18.0_so_with_multiple_namespaces.zip'
: '7.13.2_so_with_multiple_namespaces.zip'
),
},
},

View file

@ -151,7 +151,8 @@ export default function ({ getService }: FtrProviderContext) {
});
});
describe('unfreeze', () => {
describe('unfreeze', function () {
this.onlyEsVersion('8');
it('should unfreeze an index', async () => {
const index = await createIndex();

View file

@ -289,6 +289,44 @@ export default ({ getService }: FtrProviderContext) => {
);
});
it('should deduplicate alerts correctly based on source document _id', async () => {
const id = uuidv4();
// document will fall into 2 rule execution windows
const doc1 = {
id,
'@timestamp': '2020-10-28T05:55:00.000Z',
agent: { name: 'test-1', type: 'auditbeat' },
};
const rule: EsqlRuleCreateProps = {
...getCreateEsqlRulesSchemaMock('rule-1', true),
// only _id and agent.name is projected at the end of query pipeline
query: `from ecs_compliant metadata _id ${internalIdPipe(id)} | keep _id, agent.name`,
from: 'now-45m',
interval: '30m',
};
await indexListOfDocuments([doc1]);
const { previewId } = await previewRule({
supertest,
rule,
timeframeEnd: new Date('2020-10-28T06:30:00.000Z'),
invocationCount: 2,
});
const previewAlerts = await getPreviewAlerts({
es,
previewId,
size: 10,
});
expect(previewAlerts.length).toBe(1);
});
});
describe('non-aggregating query rules ES 8.x only', function () {
this.onlyEsVersion('8');
it('should support deprecated [metadata _id] syntax', async () => {
const id = uuidv4();
const interval: [string, string] = ['2020-10-28T06:00:00.000Z', '2020-10-28T06:10:00.000Z'];
@ -326,41 +364,6 @@ export default ({ getService }: FtrProviderContext) => {
expect(previewAlerts.length).toBe(1);
});
it('should deduplicate alerts correctly based on source document _id', async () => {
const id = uuidv4();
// document will fall into 2 rule execution windows
const doc1 = {
id,
'@timestamp': '2020-10-28T05:55:00.000Z',
agent: { name: 'test-1', type: 'auditbeat' },
};
const rule: EsqlRuleCreateProps = {
...getCreateEsqlRulesSchemaMock('rule-1', true),
// only _id and agent.name is projected at the end of query pipeline
query: `from ecs_compliant metadata _id ${internalIdPipe(id)} | keep _id, agent.name`,
from: 'now-45m',
interval: '30m',
};
await indexListOfDocuments([doc1]);
const { previewId } = await previewRule({
supertest,
rule,
timeframeEnd: new Date('2020-10-28T06:30:00.000Z'),
invocationCount: 2,
});
const previewAlerts = await getPreviewAlerts({
es,
previewId,
size: 10,
});
expect(previewAlerts.length).toBe(1);
});
});
describe('esql query specific syntax', () => {

View file

@ -6,10 +6,10 @@
*/
import { commonFunctionalServices } from '@kbn/ftr-common-functional-services';
import { FtrConfigProviderContext } from '@kbn/test';
import { FtrConfigProviderContext, EsVersion } from '@kbn/test';
import path from 'node:path';
export default async function ({ readConfigFile }: FtrConfigProviderContext) {
export default async function ({ readConfigFile, log }: FtrConfigProviderContext) {
// Read the Kibana API integration tests config file so that we can utilize its services.
const kibanaAPITestsConfig = await readConfigFile(
require.resolve('@kbn/test-suites-src/api_integration/config')
@ -18,6 +18,18 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
require.resolve('../functional/config.base.js')
);
const esVersion = EsVersion.getDefault();
const willRunEsv9 = esVersion.matchRange('9');
let esTestCluster = {
...xPackFunctionalTestsConfig.get('esTestCluster'),
dataArchive: path.resolve(__dirname, './fixtures/data_archives/upgrade_assistant.zip'),
};
if (willRunEsv9) {
log.info(`Detected ES version ${esVersion}; not loading data archive`);
esTestCluster = undefined;
}
return {
testFiles: [require.resolve('./upgrade_assistant')],
servers: xPackFunctionalTestsConfig.get('servers'),
@ -36,9 +48,6 @@ export default async function ({ readConfigFile }: FtrConfigProviderContext) {
`--plugin-path=${path.resolve(__dirname, '../../../examples/developer_examples')}`,
],
},
esTestCluster: {
...xPackFunctionalTestsConfig.get('esTestCluster'),
dataArchive: path.resolve(__dirname, './fixtures/data_archives/upgrade_assistant.zip'),
},
esTestCluster,
};
}

View file

@ -35,6 +35,7 @@ export default function ({ getService }: FtrProviderContext) {
const es = getService('es');
describe('Kibana API Deprecations', function () {
this.onlyEsVersion('8');
// bail on first error in this suite since cases sequentially depend on each other
this.bail(true);

View file

@ -39,6 +39,7 @@ export default function ({ getService }: FtrProviderContext) {
};
describe('reindexing', function () {
this.onlyEsVersion('8');
// bail on first error in this suite since cases sequentially depend on each other
this.bail(true);