[6.x] [Tests] Add http integration test setup (#22114)

* [Tests] Add http integration test setup

* Base path tests

* SSL tests

* Eslint fixes

* Remove env from config schema

* Rename folders so no_rewrite and rewrite match configs/tests

* wip

* Use self-signed cert for SSL test

* Improve basepath tests

* Run base path proxy server in dev mode for now

* Remove env from x-pack reporting config

* Remove redundant base-path tests

* Test SSL with redirectHttpFromPort set

* Test SSL with redirectHttpFromPort set

* Flesh out comments

* Remove some cruft

* Add SSL tests to CI run
This commit is contained in:
Aleh Zasypkin 2018-08-17 10:42:38 +02:00 committed by GitHub
parent e07b7e80d1
commit 8e696b7369
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
17 changed files with 341 additions and 47 deletions

View file

@ -25,7 +25,7 @@ export async function runKibanaServer({ procs, config, options }) {
await procs.run('kibana', {
cmd: getKibanaCmd(installDir),
args: collectCliArgs(config, options),
args: filterCliArgs(collectCliArgs(config, options)),
env: {
FORCE_COLOR: 1,
...process.env,
@ -45,7 +45,8 @@ function getKibanaCmd(installDir) {
return KIBANA_EXEC;
}
/* When installDir is passed, we run from a built version of Kibana,
/**
* When installDir is passed, we run from a built version of Kibana,
* which uses different command line arguments. If installDir is not
* passed, we run from source code. We also allow passing in extra
* Kibana server options, so we tack those on here.
@ -58,14 +59,33 @@ function collectCliArgs(config, { installDir, extraKbnOpts }) {
return pipe(
serverArgs,
args => (installDir ? args.filter(a => a !== '--oss') : args),
args => {
return installDir ? [...args, ...buildArgs] : [KIBANA_EXEC_PATH, ...args, ...sourceArgs];
},
args => (installDir ? [...buildArgs, ...args] : [KIBANA_EXEC_PATH, ...sourceArgs, ...args]),
args => args.concat(extraKbnOpts || [])
);
}
/*
/**
* Filter the cli args to remove duplications and
* overridden options
*/
function filterCliArgs(args) {
return args.reduce((acc, val, ind) => {
// If original argv has a later basepath setting, skip this val.
if (isBasePathSettingOverridden(args, val, ind)) {
return acc;
}
// Check if original argv has a later setting that overrides
// the current val. If so, skip this val.
if (findIndexFrom(args, ++ind, opt => opt.split('=')[0] === val.split('=')[0]) > -1) {
return acc;
}
return [...acc, val];
}, []);
}
/**
* Apply each function in fns to the result of the
* previous function. The first function's input
* is the arr array.
@ -75,3 +95,20 @@ function pipe(arr, ...fns) {
return fn(acc);
}, arr);
}
function isBasePathSettingOverridden(args, val, ind) {
const key = val.split('=')[0];
const basePathKeys = ['--no-base-path', '--server.basePath'];
if (basePathKeys.includes(key)) {
if (findIndexFrom(args, ++ind, opt => basePathKeys.includes(opt.split('=')[0])) > -1) {
return true;
}
}
return false;
}
function findIndexFrom(array, index, ...args) {
return [...array].slice(index).findIndex(...args);
}

View file

@ -121,9 +121,6 @@ export const schema = Joi.object().keys({
serverArgs: Joi.array(),
}).default(),
// env allows generic data, but should be removed
env: Joi.object().default(),
chromedriver: Joi.object().keys({
url: Joi.string().uri({ scheme: /https?/ }).default('http://localhost:9515')
}).default(),

View file

@ -165,6 +165,19 @@ module.exports = function (grunt) {
],
},
serverIntegrationTests: {
cmd: process.execPath,
args: [
'scripts/functional_tests',
'--config', 'test/server_integration/http/ssl/config.js',
'--config', 'test/server_integration/http/ssl_redirect/config.js',
'--esFrom', 'source',
'--bail',
'--debug',
'--kibana-install-dir', `./build/oss/kibana-${PKG_VERSION}-${process.platform}-x86_64`,
],
},
panelActionTests: {
cmd: process.execPath,
args: [
@ -185,7 +198,7 @@ module.exports = function (grunt) {
'--bail',
'--debug',
'--',
'--server.maxPayloadBytes=1648576',
'--server.maxPayloadBytes=1648576', //default is 1048576
],
},

View file

@ -43,7 +43,6 @@ export default async function ({ readConfigFile }) {
junit: {
reportName: 'API Integration Tests'
},
env: commonConfig.get('env'),
esTestCluster: commonConfig.get('esTestCluster'),
kbnTestServer: {
...functionalConfig.get('kbnTestServer'),

View file

@ -112,8 +112,6 @@ export default async function ({ readConfigFile }) {
},
servers: commonConfig.get('servers'),
env: commonConfig.get('env'),
esTestCluster: commonConfig.get('esTestCluster'),
kbnTestServer: {

View file

@ -0,0 +1,54 @@
/*
* 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 {
KibanaSupertestProvider,
KibanaSupertestWithoutAuthProvider,
ElasticsearchSupertestProvider,
} from './services';
export default async function ({ readConfigFile }) {
const commonConfig = await readConfigFile(require.resolve('../common/config'));
const functionalConfig = await readConfigFile(require.resolve('../functional/config'));
return {
services: {
es: commonConfig.get('services.es'),
esArchiver: commonConfig.get('services.esArchiver'),
retry: commonConfig.get('services.retry'),
supertest: KibanaSupertestProvider,
supertestWithoutAuth: KibanaSupertestWithoutAuthProvider,
esSupertest: ElasticsearchSupertestProvider,
},
servers: commonConfig.get('servers'),
junit: {
reportName: 'Integration Tests'
},
esTestCluster: commonConfig.get('esTestCluster'),
kbnTestServer: {
...functionalConfig.get('kbnTestServer'),
serverArgs: [
...functionalConfig.get('kbnTestServer.serverArgs'),
'--optimize.enabled=true',
'--elasticsearch.healthCheck.delay=3600000',
'--server.xsrf.disableProtection=true',
],
},
};
}

View file

@ -0,0 +1,49 @@
/*
* 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.
*/
export default async function ({ readConfigFile }) {
const httpConfig = await readConfigFile(require.resolve('../../config'));
return {
testFiles: [
require.resolve('./'),
],
services: httpConfig.get('services'),
servers: {
...httpConfig.get('servers'),
kibana: {
...httpConfig.get('servers.kibana'),
protocol: 'https',
},
},
junit: {
reportName: 'Http SSL Integration Tests',
},
esTestCluster: httpConfig.get('esTestCluster'),
kbnTestServer: {
...httpConfig.get('kbnTestServer'),
serverArgs: [
...httpConfig.get('kbnTestServer.serverArgs'),
'--server.ssl.enabled=true',
`--server.ssl.key=${require.resolve('../../../dev_certs/server.key')}`,
`--server.ssl.certificate=${require.resolve('../../../dev_certs/server.crt')}`,
],
},
};
}

View file

@ -0,0 +1,29 @@
/*
* 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.
*/
export default function ({ getService }) {
const supertest = getService('supertest');
describe('kibana server with ssl', () => {
it('handles requests using ssl', async () => {
await supertest.get('/')
.expect(302);
});
});
}

View file

@ -0,0 +1,65 @@
/*
* 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 { KibanaSupertestProvider } from '../../services';
export default async function ({ readConfigFile }) {
const httpConfig = await readConfigFile(require.resolve('../../config'));
const redirectPort = httpConfig.get('servers.kibana.port') + 1;
const supertestOptions = {
...httpConfig.get('servers.kibana'),
port: redirectPort,
// test with non ssl protocol
protocol: 'http',
};
return {
testFiles: [
require.resolve('./'),
],
services: {
...httpConfig.get('services'),
//eslint-disable-next-line new-cap
supertest: (arg) => KibanaSupertestProvider(arg, supertestOptions),
},
servers: {
...httpConfig.get('servers'),
kibana: {
...httpConfig.get('servers.kibana'),
// start the server with https
protocol: 'https',
},
},
junit: {
reportName: 'Http SSL Integration Tests',
},
esTestCluster: httpConfig.get('esTestCluster'),
kbnTestServer: {
...httpConfig.get('kbnTestServer'),
serverArgs: [
...httpConfig.get('kbnTestServer.serverArgs'),
'--server.ssl.enabled=true',
`--server.ssl.key=${require.resolve('../../../dev_certs/server.key')}`,
`--server.ssl.certificate=${require.resolve('../../../dev_certs/server.crt')}`,
`--server.ssl.redirectHttpFromPort=${redirectPort}`,
],
},
};
}

View file

@ -17,26 +17,19 @@
* under the License.
*/
import * as kbnTestServer from '../test_utils/kbn_server';
const basePath = '/kibana';
export default function ({ getService }) {
const supertest = getService('supertest');
describe('Server basePath config', () => {
let kbnServer;
beforeAll(async () => {
kbnServer = kbnTestServer.createServer({ server: { basePath } });
await kbnServer.ready();
return kbnServer;
});
describe('kibana server with ssl', () => {
it('redirects http requests at redirect port to https', async () => {
await supertest.get('/')
.expect('location', 'https://localhost:5620/')
.expect(302);
afterAll(async () => await kbnServer.close());
test('appends the basePath to root redirect', async () => {
const resp = await kbnServer.inject({
url: '/',
method: 'GET'
await supertest.get('/')
.redirects(1)
.expect('location', '/app/kibana')
.expect(302);
});
expect(resp).toHaveProperty('statusCode', 200);
expect(resp.payload).toMatch(/defaultRoute = '\/kibana\/app\/kibana'/);
});
});
}

View file

@ -0,0 +1,20 @@
/*
* 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.
*/
export { KibanaSupertestProvider, KibanaSupertestWithoutAuthProvider, ElasticsearchSupertestProvider } from './supertest';

View file

@ -0,0 +1,54 @@
/*
* 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 { readFileSync } from 'fs';
import { format as formatUrl } from 'url';
import supertestAsPromised from 'supertest-as-promised';
export function KibanaSupertestProvider({ getService }, options) {
const config = getService('config');
const kibanaServerUrl = options ? formatUrl(options) : formatUrl(config.get('servers.kibana'));
const kibanaServerCert = config.get('kbnTestServer.serverArgs')
.filter(arg => arg.startsWith('--server.ssl.certificate'))
.map(arg => arg.split('=').pop())
.map(path => readFileSync(path))
.shift();
return kibanaServerCert
? supertestAsPromised.agent(kibanaServerUrl, { ca: kibanaServerCert })
: supertestAsPromised(kibanaServerUrl);
}
export function KibanaSupertestWithoutAuthProvider({ getService }) {
const config = getService('config');
const kibanaServerConfig = config.get('servers.kibana');
return supertestAsPromised(formatUrl({
...kibanaServerConfig,
auth: false
}));
}
export function ElasticsearchSupertestProvider({ getService }) {
const config = getService('config');
const elasticSearchServerUrl = formatUrl(config.get('servers.elasticsearch'));
return supertestAsPromised(elasticSearchServerUrl);
}

View file

@ -35,7 +35,6 @@ export default async function ({ readConfigFile }) {
junit: {
reportName: 'X-Pack API Integration Tests',
},
env: xPackFunctionalTestsConfig.get('env'),
kbnTestServer: {
...xPackFunctionalTestsConfig.get('kbnTestServer'),
serverArgs: [

View file

@ -76,14 +76,6 @@ export default async function ({ readConfigFile }) {
},
};
const env = {
kibana: {
server: {
uuid: '5b2de169-2785-441b-ae8c-186a1936b17d', // Kibana UUID for "primary" cluster in monitoring data
}
}
};
return {
// list paths to the files that contain your plugins tests
testFiles: [
@ -145,8 +137,6 @@ export default async function ({ readConfigFile }) {
servers,
env,
esTestCluster: {
license: 'trial',
from: 'snapshot',
@ -160,7 +150,7 @@ export default async function ({ readConfigFile }) {
...kibanaCommonConfig.get('kbnTestServer'),
serverArgs: [
...kibanaCommonConfig.get('kbnTestServer.serverArgs'),
`--server.uuid=${env.kibana.server.uuid}`,
'--server.uuid=5b2de169-2785-441b-ae8c-186a1936b17d',
`--server.port=${servers.kibana.port}`,
`--elasticsearch.url=${formatUrl(servers.elasticsearch)}`,
'--xpack.xpack_main.telemetry.enabled=false',

View file

@ -24,7 +24,6 @@ export async function getReportingApiConfig({ readConfigFile }) {
junit: {
reportName: 'X-Pack Reporting API Tests',
},
env: apiConfig.get('env'),
esTestCluster: apiConfig.get('esTestCluster'),
kbnTestServer: {
...apiConfig.get('kbnTestServer'),

View file

@ -12,7 +12,6 @@ export async function getFunctionalConfig({ readConfigFile }) {
services: xPackFunctionalTestsConfig.get('services'),
pageObjects: xPackFunctionalTestsConfig.get('pageObjects'),
servers: xPackFunctionalTestsConfig.get('servers'),
env: xPackFunctionalTestsConfig.get('env'),
esTestCluster: xPackFunctionalTestsConfig.get('esTestCluster'),
apps: xPackFunctionalTestsConfig.get('apps'),
esArchiver: {

View file

@ -23,7 +23,6 @@ export default async function ({ readConfigFile }) {
junit: {
reportName: 'X-Pack SAML API Integration Tests',
},
env: xPackAPITestsConfig.get('env'),
esTestCluster: {
...xPackAPITestsConfig.get('esTestCluster'),