[SavedObjects] Create serverless roots for jest integration tests (#164157)

## Summary

Introduce basic utils for instantiating serverless servers ;). Also adds
a simple smoke test (that is currently skipped) demonstrating usage.

## How to test

Check this branch out locally, un`skip` the smoke test and run:

```
yarn test:jest_integration ./src/core/server/integration_tests/saved_objects/serverless/migrations
```

Note: the test cannot be unskipped as we are blocking on
https://github.com/elastic/kibana/pull/162673 but we would like to
prepare our tests so long --- they can be locally executed.

## Follow up

* Create Jest integration tests using these helpers for all migration
actions (see
`packages/core/saved-objects/core-saved-objects-migration-server-internal/src/zdt/actions`
and
`packages/core/saved-objects/core-saved-objects-migration-server-internal/src/actions`).
* Migrate our existing ZDT tests to run against serverless Elasticsearch

## Related

https://github.com/elastic/kibana/pull/162673

---------

Co-authored-by: kibanamachine <42973632+kibanamachine@users.noreply.github.com>
This commit is contained in:
Jean-Louis Leysens 2023-08-24 13:23:40 +02:00 committed by GitHub
parent 75644797c3
commit 178e201953
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
6 changed files with 176 additions and 1 deletions

View file

@ -12,7 +12,15 @@ export {
createRoot,
createRootWithCorePlugins,
createTestServers,
createTestServerlessInstances,
request,
} from './src';
export type { HttpMethod, TestElasticsearchUtils, TestKibanaUtils, TestUtils } from './src';
export type {
HttpMethod,
TestElasticsearchUtils,
TestKibanaUtils,
TestUtils,
TestServerlessESUtils,
TestServerlessKibanaUtils,
} from './src';

View file

@ -0,0 +1,100 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import { defaultsDeep } from 'lodash';
import { Cluster } from '@kbn/es';
import Path from 'path';
import { REPO_ROOT } from '@kbn/repo-info';
import { ToolingLog } from '@kbn/tooling-log';
import execa from 'execa';
import { CliArgs } from '@kbn/config';
import { createRoot, type TestElasticsearchUtils, type TestKibanaUtils } from './create_root';
export type TestServerlessESUtils = Pick<TestElasticsearchUtils, 'stop' | 'es'>;
export type TestServerlessKibanaUtils = TestKibanaUtils;
export interface TestServerlessUtils {
startES: () => Promise<TestServerlessESUtils>;
startKibana: (abortSignal?: AbortSignal) => Promise<TestServerlessKibanaUtils>;
}
/**
* See docs in {@link TestUtils}. This function provides the same utilities but
* configured for serverless.
*
* @note requires a Docker installation to be running
*/
export function createTestServerlessInstances({
adjustTimeout,
}: {
adjustTimeout: (timeout: number) => void;
}): TestServerlessUtils {
const esUtils = createServerlessES();
const kbUtils = createServerlessKibana();
adjustTimeout?.(120_000);
return {
startES: async () => {
const { stop } = await esUtils.start();
return {
es: esUtils.es,
stop,
};
},
startKibana: async (abortSignal) => {
abortSignal?.addEventListener('abort', async () => await kbUtils.shutdown());
await kbUtils.preboot();
const coreSetup = await kbUtils.setup();
const coreStart = await kbUtils.start();
return {
root: kbUtils,
coreSetup,
coreStart,
stop: kbUtils.shutdown.bind(kbUtils),
};
},
};
}
function createServerlessES() {
const log = new ToolingLog({
level: 'info',
writeTo: process.stdout,
});
const es = new Cluster({ log });
return {
es,
start: async () => {
await es.runServerless({
basePath: Path.join(REPO_ROOT, '.es/es_test_serverless'),
});
return {
stop: async () => {
// hack to stop the ES cluster
await execa('docker', ['container', 'stop', 'es01', 'es02', 'es03']);
},
};
},
};
}
const defaults = {
server: {
restrictInternalApis: true,
versioned: {
versionResolution: 'newest',
strictClientVersionCheck: false,
},
},
migrations: {
algorithm: 'zdt',
},
elasticsearch: {
serviceAccountToken: 'BEEF',
},
};
function createServerlessKibana(settings = {}, cliArgs: Partial<CliArgs> = {}) {
return createRoot(defaultsDeep(settings, defaults), { ...cliArgs, serverless: true });
}

View file

@ -15,4 +15,12 @@ export {
request,
} from './create_root';
export { createTestServerlessInstances } from './create_serverless_root';
export type {
TestServerlessUtils,
TestServerlessESUtils,
TestServerlessKibanaUtils,
} from './create_serverless_root';
export type { HttpMethod, TestElasticsearchUtils, TestKibanaUtils, TestUtils } from './create_root';

View file

@ -18,6 +18,7 @@
"@kbn/core-root-server-internal",
"@kbn/repo-info",
"@kbn/repo-packages",
"@kbn/es",
],
"exclude": [
"target/**/*",

View file

@ -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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
module.exports = {
// TODO replace the line below with
// preset: '@kbn/test/jest_integration_node
// to do so, we must fix all integration tests first
// see https://github.com/elastic/kibana/pull/130255/
preset: '@kbn/test/jest_integration',
rootDir: '../../../../../../..',
roots: ['<rootDir>/src/core/server/integration_tests/saved_objects/serverless/migrations'],
// must override to match all test given there is no `integration_tests` subfolder
testMatch: ['**/*.test.{js,mjs,ts,tsx}'],
};

View file

@ -0,0 +1,39 @@
/*
* 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 and the Server Side Public License, v 1; you may not use this file except
* in compliance with, at your election, the Elastic License 2.0 or the Server
* Side Public License, v 1.
*/
import {
request,
TestServerlessESUtils,
TestServerlessKibanaUtils,
createTestServerlessInstances,
} from '@kbn/core-test-helpers-kbn-server';
/**
* Until we merge https://github.com/elastic/kibana/pull/162673 this test should remain skipped.
*/
describe.skip('smoke', () => {
let serverlessES: TestServerlessESUtils;
let serverlessKibana: TestServerlessKibanaUtils;
let root: TestServerlessKibanaUtils['root'];
beforeEach(async () => {
const { startES, startKibana } = createTestServerlessInstances({
adjustTimeout: jest.setTimeout,
});
serverlessES = await startES();
serverlessKibana = await startKibana();
root = serverlessKibana.root;
});
afterEach(async () => {
await serverlessES?.stop();
await serverlessKibana?.stop();
});
test('it can start Kibana and ES serverless', async () => {
const { body } = await request.get(root, '/api/status').expect(200);
expect(body).toMatchObject({ status: { overall: { level: 'available' } } });
});
});