Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[ci] run server integration tests #81427

Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
6130bb5
[ci] run server integration tests
spalger Oct 22, 2020
5c4703f
it seems the default params are long enough to wrap now
spalger Oct 22, 2020
1168e81
move the server integration test up one level
spalger Oct 22, 2020
d15170b
run correct setup script for task type
spalger Oct 22, 2020
d7a0601
fix KbnClient certificateAuthorities usage
spalger Oct 22, 2020
83696e7
cleanup option names of createKibanaSupertestProvider
spalger Oct 22, 2020
8879963
fix settings in functional_embedded config
spalger Oct 22, 2020
3c76593
fix other KbnClient usage
spalger Oct 22, 2020
abb3b75
put more distance between the kibana port and redirect port
spalger Oct 22, 2020
edd6d2b
Merge branch 'master' of github.com:elastic/kibana into implement/run…
spalger Oct 22, 2020
8d96efc
Merge branch 'master' of github.com:elastic/kibana into implement/run…
spalger Oct 22, 2020
ce6ac82
retry `getView()` internals faster so the whole method can be retried
spalger Oct 22, 2020
e4296b3
Merge branch 'master' of github.com:elastic/kibana into implement/run…
spalger Oct 22, 2020
f0736b4
Merge branch 'master' of github.com:elastic/kibana into implement/run…
spalger Oct 26, 2020
376274e
specify shorter find and retry timeouts for testSubjects.getAttribute()
spalger Oct 26, 2020
0afc737
resolve default values early so that they can be logged
spalger Oct 26, 2020
41c0df3
increase timeout for determining if setViewForm is open, it seems we'…
spalger Oct 26, 2020
56604d1
use longer timeout when we are more confident the popover should open
spalger Oct 26, 2020
4337dd9
unify logic of open/closeSetViewPopover() and add more comments
spalger Oct 26, 2020
a93ae57
Merge branch 'master' of github.com:elastic/kibana into implement/run…
spalger Oct 26, 2020
16a2c21
create reusable menu toggling helper
spalger Oct 26, 2020
1aa41d1
Merge branch 'master' of github.com:elastic/kibana into implement/run…
spalger Oct 26, 2020
ba8a483
improve log message to make searching for it easier
spalger Oct 26, 2020
464adb4
use better names for toggle managers
spalger Oct 26, 2020
4110faf
fix testsubject
spalger Oct 26, 2020
2daf6ec
Merge branch 'master' of github.com:elastic/kibana into implement/run…
spalger Oct 26, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion packages/kbn-dev-utils/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ export {
KBN_P12_PATH,
KBN_P12_PASSWORD,
} from './certs';
export { KbnClient } from './kbn_client';
export * from './kbn_client';
export * from './run';
export * from './axios';
export * from './stdio';
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-dev-utils/src/kbn_client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,5 @@
* under the License.
*/

export { KbnClient } from './kbn_client';
export * from './kbn_client';
export { uriencode } from './kbn_client_requester';
52 changes: 34 additions & 18 deletions packages/kbn-dev-utils/src/kbn_client/kbn_client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,37 +18,53 @@
*/

import { ToolingLog } from '../tooling_log';
import { KibanaConfig, KbnClientRequester, ReqOptions } from './kbn_client_requester';
import { KbnClientRequester, ReqOptions } from './kbn_client_requester';
import { KbnClientStatus } from './kbn_client_status';
import { KbnClientPlugins } from './kbn_client_plugins';
import { KbnClientVersion } from './kbn_client_version';
import { KbnClientSavedObjects } from './kbn_client_saved_objects';
import { KbnClientUiSettings, UiSettingValues } from './kbn_client_ui_settings';

export interface KbnClientOptions {
url: string;
certificateAuthorities?: Buffer[];
log: ToolingLog;
uiSettingDefaults?: UiSettingValues;
}

export class KbnClient {
private readonly requester = new KbnClientRequester(this.log, this.kibanaConfig);
readonly status = new KbnClientStatus(this.requester);
readonly plugins = new KbnClientPlugins(this.status);
readonly version = new KbnClientVersion(this.status);
readonly savedObjects = new KbnClientSavedObjects(this.log, this.requester);
readonly uiSettings = new KbnClientUiSettings(this.log, this.requester, this.uiSettingDefaults);
readonly status: KbnClientStatus;
readonly plugins: KbnClientPlugins;
readonly version: KbnClientVersion;
readonly savedObjects: KbnClientSavedObjects;
readonly uiSettings: KbnClientUiSettings;

private readonly requester: KbnClientRequester;
private readonly log: ToolingLog;
private readonly uiSettingDefaults?: UiSettingValues;

/**
* Basic Kibana server client that implements common behaviors for talking
* to the Kibana server from dev tooling.
*
* @param log ToolingLog
* @param kibanaUrls Array of kibana server urls to send requests to
* @param uiSettingDefaults Map of uiSetting values that will be merged with all uiSetting resets
*/
constructor(
private readonly log: ToolingLog,
private readonly kibanaConfig: KibanaConfig,
private readonly uiSettingDefaults?: UiSettingValues
) {
if (!kibanaConfig.url) {
throw new Error('missing Kibana urls');
constructor(options: KbnClientOptions) {
if (!options.url) {
throw new Error('missing Kibana url');
}
if (!options.log) {
throw new Error('missing ToolingLog');
}

this.log = options.log;
this.requester = new KbnClientRequester(this.log, {
url: options.url,
certificateAuthorities: options.certificateAuthorities,
});
this.status = new KbnClientStatus(this.requester);
this.plugins = new KbnClientPlugins(this.status);
this.version = new KbnClientVersion(this.status);
this.savedObjects = new KbnClientSavedObjects(this.log, this.requester);
this.uiSettings = new KbnClientUiSettings(this.log, this.requester, this.uiSettingDefaults);
}

/**
Expand Down
24 changes: 10 additions & 14 deletions packages/kbn-dev-utils/src/kbn_client/kbn_client_requester.ts
Original file line number Diff line number Diff line change
Expand Up @@ -69,31 +69,27 @@ const delay = (ms: number) =>
setTimeout(resolve, ms);
});

export interface KibanaConfig {
interface Options {
url: string;
ssl?: {
enabled: boolean;
key: string;
certificate: string;
certificateAuthorities: string;
};
certificateAuthorities?: Buffer[];
}

export class KbnClientRequester {
private readonly url: string;
private readonly httpsAgent: Https.Agent | null;
constructor(private readonly log: ToolingLog, private readonly kibanaConfig: KibanaConfig) {

constructor(private readonly log: ToolingLog, options: Options) {
this.url = options.url;
this.httpsAgent =
kibanaConfig.ssl && kibanaConfig.ssl.enabled
Url.parse(options.url).protocol === 'https:'
? new Https.Agent({
cert: kibanaConfig.ssl.certificate,
key: kibanaConfig.ssl.key,
ca: kibanaConfig.ssl.certificateAuthorities,
ca: options.certificateAuthorities,
})
: null;
}

private pickUrl() {
return this.kibanaConfig.url;
return this.url;
}

public resolveUrl(relativeUrl: string = '/') {
Expand Down Expand Up @@ -132,7 +128,7 @@ export class KbnClientRequester {
errorMessage = `Conflict on GET (path=${options.path}, attempt=${attempt}/${maxAttempts})`;
this.log.error(errorMessage);
} else if (requestedRetries || failedToGetResponse) {
errorMessage = `[${description}] request failed (attempt=${attempt}/${maxAttempts})`;
errorMessage = `[${description}] request failed (attempt=${attempt}/${maxAttempts}): ${error.message}`;
this.log.error(errorMessage);
} else {
throw error;
Expand Down
2 changes: 1 addition & 1 deletion packages/kbn-es-archiver/src/es_archiver.ts
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ export class EsArchiver {
this.client = client;
this.dataDir = dataDir;
this.log = log;
this.kbnClient = new KbnClient(log, { url: kibanaUrl });
this.kbnClient = new KbnClient({ log, url: kibanaUrl });
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,14 +38,7 @@ const urlPartsSchema = () =>
password: Joi.string(),
pathname: Joi.string().regex(/^\//, 'start with a /'),
hash: Joi.string().regex(/^\//, 'start with a /'),
ssl: Joi.object()
.keys({
enabled: Joi.boolean().default(false),
certificate: Joi.string().optional(),
certificateAuthorities: Joi.string().optional(),
key: Joi.string().optional(),
})
.default(),
certificateAuthorities: Joi.array().items(Joi.binary()).optional(),
})
.default();

Expand Down
8 changes: 6 additions & 2 deletions test/common/services/kibana_server/kibana_server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,13 @@ export function KibanaServerProvider({ getService }: FtrProviderContext) {
const config = getService('config');
const lifecycle = getService('lifecycle');
const url = Url.format(config.get('servers.kibana'));
const ssl = config.get('servers.kibana').ssl;
const defaults = config.get('uiSettings.defaults');
const kbn = new KbnClient(log, { url, ssl }, defaults);
const kbn = new KbnClient({
log,
url,
certificateAuthorities: config.get('servers.kibana.certificateAuthorities'),
uiSettingDefaults: defaults,
});

if (defaults) {
lifecycle.beforeTests.add(async () => {
Expand Down
32 changes: 10 additions & 22 deletions test/functional/page_objects/time_picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,18 @@ export type CommonlyUsed =

export function TimePickerProvider({ getService, getPageObjects }: FtrProviderContext) {
const log = getService('log');
const retry = getService('retry');
const find = getService('find');
const browser = getService('browser');
const testSubjects = getService('testSubjects');
const { header } = getPageObjects(['header']);
const kibanaServer = getService('kibanaServer');
const MenuToggle = getService('MenuToggle');

const quickSelectTimeMenuToggle = new MenuToggle({
name: 'QuickSelectTime Menu',
menuTestSubject: 'superDatePickerQuickMenu',
toggleButtonTestSubject: 'superDatePickerToggleQuickMenuButton',
});

class TimePicker {
defaultStartTime = 'Sep 19, 2015 @ 06:31:44.000';
Expand Down Expand Up @@ -158,30 +164,12 @@ export function TimePickerProvider({ getService, getPageObjects }: FtrProviderCo
return await find.existsByCssSelector('.euiDatePickerRange--readOnly');
}

public async isQuickSelectMenuOpen() {
return await testSubjects.exists('superDatePickerQuickMenu');
}

public async openQuickSelectTimeMenu() {
log.debug('openQuickSelectTimeMenu');
const isMenuOpen = await this.isQuickSelectMenuOpen();
if (!isMenuOpen) {
log.debug('opening quick select menu');
await retry.try(async () => {
await testSubjects.click('superDatePickerToggleQuickMenuButton');
});
}
await quickSelectTimeMenuToggle.open();
}

public async closeQuickSelectTimeMenu() {
log.debug('closeQuickSelectTimeMenu');
const isMenuOpen = await this.isQuickSelectMenuOpen();
if (isMenuOpen) {
log.debug('closing quick select menu');
await retry.try(async () => {
await testSubjects.click('superDatePickerToggleQuickMenuButton');
});
}
await quickSelectTimeMenuToggle.close();
}

public async getRefreshConfig(keepQuickSelectOpen = false) {
Expand Down Expand Up @@ -283,10 +271,10 @@ export function TimePickerProvider({ getService, getPageObjects }: FtrProviderCo
public async pauseAutoRefresh() {
log.debug('pauseAutoRefresh');
const refreshConfig = await this.getRefreshConfig(true);

if (!refreshConfig.isPaused) {
log.debug('pause auto refresh');
await testSubjects.click('superDatePickerToggleRefreshButton');
await this.closeQuickSelectTimeMenu();
}

await this.closeQuickSelectTimeMenu();
Expand Down
24 changes: 20 additions & 4 deletions test/functional/services/common/test_subjects.ts
Original file line number Diff line number Diff line change
Expand Up @@ -170,11 +170,27 @@ export function TestSubjectsProvider({ getService }: FtrProviderContext) {
public async getAttribute(
selector: string,
attribute: string,
timeout?: number
options?:
| number
| {
findTimeout?: number;
tryTimeout?: number;
}
): Promise<string> {
return await retry.try(async () => {
log.debug(`TestSubjects.getAttribute(${selector}, ${attribute})`);
const element = await this.find(selector, timeout);
const findTimeout =
(typeof options === 'number' ? options : options?.findTimeout) ??
config.get('timeouts.find');

const tryTimeout =
(typeof options !== 'number' ? options?.tryTimeout : undefined) ??
config.get('timeouts.try');

log.debug(
`TestSubjects.getAttribute(${selector}, ${attribute}, tryTimeout=${tryTimeout}, findTimeout=${findTimeout})`
);

return await retry.tryForTime(tryTimeout, async () => {
const element = await this.find(selector, findTimeout);
return await element.getAttribute(attribute);
});
}
Expand Down
2 changes: 2 additions & 0 deletions test/functional/services/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ import {
import { ListingTableProvider } from './listing_table';
import { SavedQueryManagementComponentProvider } from './saved_query_management_component';
import { KibanaSupertestProvider } from './supertest';
import { MenuToggleProvider } from './menu_toggle';

export const services = {
...commonServiceProviders,
Expand Down Expand Up @@ -93,4 +94,5 @@ export const services = {
elasticChart: ElasticChartProvider,
supertest: KibanaSupertestProvider,
managementMenu: ManagementMenuProvider,
MenuToggle: MenuToggleProvider,
};
77 changes: 77 additions & 0 deletions test/functional/services/menu_toggle.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
/*
* Licensed to Elasticsearch B.V. under one or more contributor
* license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright
* ownership. Elasticsearch B.V. licenses this file to you under
* the Apache License, Version 2.0 (the "License"); you may
* not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/

import { FtrProviderContext } from '../ftr_provider_context';

export function MenuToggleProvider({ getService }: FtrProviderContext) {
const log = getService('log');
const retry = getService('retry');
const testSubjects = getService('testSubjects');

interface Options {
name: string;
menuTestSubject: string;
toggleButtonTestSubject: string;
}

return class MenuToggle {
private readonly name: string;
private readonly menuTestSubject: string;
private readonly toggleButtonTestSubject: string;

constructor(options: Options) {
this.name = options.name;
this.menuTestSubject = options.menuTestSubject;
this.toggleButtonTestSubject = options.toggleButtonTestSubject;
}

async open() {
await this.setState(true);
}

async close() {
await this.setState(false);
}

private async setState(expectedState: boolean) {
log.debug(
`setting menu open state [name=${this.name}] [state=${expectedState ? 'open' : 'closed'}]`
);

await retry.try(async () => {
// if the menu is clearly in the expected state already, bail out quickly if so
const isOpen = await testSubjects.exists(this.menuTestSubject, { timeout: 500 });
if (isOpen === expectedState) {
return;
}

// toggle the view state by clicking the button
await testSubjects.click(this.toggleButtonTestSubject);

if (expectedState === true) {
// wait for up to 10 seconds for the menu to show up, otherwise fail and retry
await testSubjects.existOrFail(this.menuTestSubject, { timeout: 10000 });
} else {
// wait for the form to hide, otherwise fail and retry
await testSubjects.waitForDeleted(this.menuTestSubject);
}
});
}
};
}
5 changes: 5 additions & 0 deletions test/scripts/server_integration.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
#!/usr/bin/env bash

source test/scripts/jenkins_test_setup_oss.sh

yarn run grunt run:serverIntegrationTests
4 changes: 3 additions & 1 deletion test/server_integration/http/ssl/config.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,20 +23,22 @@ import { createKibanaSupertestProvider } from '../../services';

export default async function ({ readConfigFile }) {
const httpConfig = await readConfigFile(require.resolve('../../config'));
const certificateAuthorities = [readFileSync(CA_CERT_PATH)];

return {
testFiles: [require.resolve('./')],
services: {
...httpConfig.get('services'),
supertest: createKibanaSupertestProvider({
certificateAuthorities: [readFileSync(CA_CERT_PATH)],
certificateAuthorities,
}),
},
servers: {
...httpConfig.get('servers'),
kibana: {
...httpConfig.get('servers.kibana'),
protocol: 'https',
certificateAuthorities,
},
},
junit: {
Expand Down
Loading