mirror of
https://github.com/elastic/kibana.git
synced 2025-04-23 17:28:26 -04:00
* fix comment * introduce core provider plugin for integration tests * platform functional tests use core_provider_plugin for testing * add 3 scenario for licensing plugins: server, client, legacy * remove unused code * run all licensing_plugin tests on CI * remove duplicated config * address comments * declare global type for core provider
This commit is contained in:
parent
7e541053f6
commit
f464641a1a
25 changed files with 579 additions and 235 deletions
|
@ -57,11 +57,12 @@ export default async function({ readConfigFile }) {
|
|||
...functionalConfig.get('kbnTestServer'),
|
||||
serverArgs: [
|
||||
...functionalConfig.get('kbnTestServer.serverArgs'),
|
||||
|
||||
// Required to load new platform plugins via `--plugin-path` flag.
|
||||
'--env.name=development',
|
||||
...plugins.map(
|
||||
pluginDir => `--plugin-path=${path.resolve(__dirname, 'plugins', pluginDir)}`
|
||||
),
|
||||
// Required to load new platform plugins via `--plugin-path` flag.
|
||||
'--env.name=development',
|
||||
],
|
||||
},
|
||||
};
|
||||
|
|
|
@ -22,9 +22,6 @@ import { CorePluginAPluginSetup } from '../../core_plugin_a/public/plugin';
|
|||
|
||||
declare global {
|
||||
interface Window {
|
||||
corePluginB?: string;
|
||||
hasAccessToInjectedMetadata?: boolean;
|
||||
receivedStartServices?: boolean;
|
||||
env?: PluginInitializerContext['env'];
|
||||
}
|
||||
}
|
||||
|
@ -39,12 +36,6 @@ export class CorePluginBPlugin
|
|||
window.env = pluginContext.env;
|
||||
}
|
||||
public setup(core: CoreSetup, deps: CorePluginBDeps) {
|
||||
window.corePluginB = `Plugin A said: ${deps.core_plugin_a.getGreeting()}`;
|
||||
window.hasAccessToInjectedMetadata = 'getInjectedVar' in core.injectedMetadata;
|
||||
core.getStartServices().then(([coreStart, plugins]) => {
|
||||
window.receivedStartServices = 'overlays' in coreStart;
|
||||
});
|
||||
|
||||
core.application.register({
|
||||
id: 'bar',
|
||||
title: 'Bar',
|
||||
|
@ -53,6 +44,12 @@ export class CorePluginBPlugin
|
|||
return renderApp(context, params);
|
||||
},
|
||||
});
|
||||
|
||||
return {
|
||||
sayHi() {
|
||||
return `Plugin A said: ${deps.core_plugin_a.getGreeting()}`;
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
public start() {}
|
||||
|
|
36
test/plugin_functional/plugins/core_provider_plugin/index.ts
Normal file
36
test/plugin_functional/plugins/core_provider_plugin/index.ts
Normal file
|
@ -0,0 +1,36 @@
|
|||
/*
|
||||
* 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 { resolve } from 'path';
|
||||
import { Legacy } from '../../../../kibana';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function CoreProviderPlugin(kibana: any) {
|
||||
const config: Legacy.PluginSpecOptions = {
|
||||
id: 'core-provider',
|
||||
require: [],
|
||||
publicDir: resolve(__dirname, 'public'),
|
||||
init: (server: Legacy.Server) => ({}),
|
||||
uiExports: {
|
||||
hacks: [resolve(__dirname, 'public/index')],
|
||||
},
|
||||
};
|
||||
|
||||
return new kibana.Plugin(config);
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
{
|
||||
"name": "core_provider_plugin",
|
||||
"version": "1.0.0",
|
||||
"main": "target/test/plugin_functional/plugins/core_provider_plugin",
|
||||
"kibana": {
|
||||
"version": "kibana",
|
||||
"templateVersion": "1.0.0"
|
||||
},
|
||||
"license": "Apache-2.0",
|
||||
"scripts": {
|
||||
"kbn": "node ../../../../scripts/kbn.js",
|
||||
"build": "rm -rf './target' && tsc"
|
||||
},
|
||||
"devDependencies": {
|
||||
"typescript": "3.5.3"
|
||||
}
|
||||
}
|
|
@ -16,6 +16,13 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
import { UiSettingsPlugin } from './plugin';
|
||||
import { npSetup, npStart } from 'ui/new_platform';
|
||||
import '../types';
|
||||
|
||||
export const plugin = () => new UiSettingsPlugin();
|
||||
window.__coreProvider = {
|
||||
setup: npSetup,
|
||||
start: npStart,
|
||||
testUtils: {
|
||||
delay: (ms: number) => new Promise(res => setTimeout(res, ms)),
|
||||
},
|
||||
};
|
|
@ -0,0 +1,14 @@
|
|||
{
|
||||
"extends": "../../../../tsconfig.json",
|
||||
"compilerOptions": {
|
||||
"outDir": "./target",
|
||||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"index.ts",
|
||||
"types.ts",
|
||||
"public/**/*.ts",
|
||||
"../../../../typings/**/*",
|
||||
],
|
||||
"exclude": []
|
||||
}
|
|
@ -16,22 +16,22 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
import { CoreSetup, Plugin } from 'kibana/public';
|
||||
import { LegacyCoreSetup, LegacyCoreStart } from 'kibana/public';
|
||||
|
||||
declare global {
|
||||
interface Window {
|
||||
uiSettingsPlugin?: Record<string, any>;
|
||||
uiSettingsPluginValue?: string;
|
||||
__coreProvider: {
|
||||
setup: {
|
||||
core: LegacyCoreSetup;
|
||||
plugins: Record<string, any>;
|
||||
};
|
||||
start: {
|
||||
core: LegacyCoreStart;
|
||||
plugins: Record<string, any>;
|
||||
};
|
||||
testUtils: {
|
||||
delay: (ms: number) => Promise<void>;
|
||||
};
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class UiSettingsPlugin implements Plugin {
|
||||
public setup(core: CoreSetup) {
|
||||
window.uiSettingsPlugin = core.uiSettings.getAll().ui_settings_plugin;
|
||||
window.uiSettingsPluginValue = core.uiSettings.get('ui_settings_plugin');
|
||||
}
|
||||
|
||||
public start() {}
|
||||
public stop() {}
|
||||
}
|
|
@ -4,5 +4,5 @@
|
|||
"kibanaVersion": "kibana",
|
||||
"configPath": ["ui_settings_plugin"],
|
||||
"server": true,
|
||||
"ui": true
|
||||
"ui": false
|
||||
}
|
||||
|
|
|
@ -5,9 +5,6 @@
|
|||
"skipLibCheck": true
|
||||
},
|
||||
"include": [
|
||||
"index.ts",
|
||||
"public/**/*.ts",
|
||||
"public/**/*.tsx",
|
||||
"server/**/*.ts",
|
||||
"../../../../typings/**/*",
|
||||
],
|
||||
|
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
import expect from '@kbn/expect';
|
||||
import { PluginFunctionalProviderContext } from '../../services';
|
||||
import '../../../../test/plugin_functional/plugins/core_provider_plugin/types';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ getService, getPageObjects }: PluginFunctionalProviderContext) {
|
||||
|
@ -31,22 +32,35 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider
|
|||
await PageObjects.common.navigateToApp('settings');
|
||||
});
|
||||
|
||||
it('should attach string to window.corePluginB', async () => {
|
||||
const corePluginB = await browser.execute('return window.corePluginB');
|
||||
expect(corePluginB).to.equal(`Plugin A said: Hello from Plugin A!`);
|
||||
it('should run the new platform plugins', async () => {
|
||||
expect(
|
||||
await browser.execute(() => {
|
||||
return window.__coreProvider.setup.plugins.core_plugin_b.sayHi();
|
||||
})
|
||||
).to.be('Plugin A said: Hello from Plugin A!');
|
||||
});
|
||||
});
|
||||
|
||||
describe('have injectedMetadata service provided', function describeIndexTests() {
|
||||
describe('should have access to the core services', function describeIndexTests() {
|
||||
before(async () => {
|
||||
await PageObjects.common.navigateToApp('bar');
|
||||
await PageObjects.common.navigateToApp('settings');
|
||||
});
|
||||
|
||||
it('should attach boolean to window.hasAccessToInjectedMetadata', async () => {
|
||||
const hasAccessToInjectedMetadata = await browser.execute(
|
||||
'return window.hasAccessToInjectedMetadata'
|
||||
);
|
||||
expect(hasAccessToInjectedMetadata).to.equal(true);
|
||||
it('to injectedMetadata service', async () => {
|
||||
expect(
|
||||
await browser.execute(() => {
|
||||
return window.__coreProvider.setup.core.injectedMetadata.getKibanaBuildNumber();
|
||||
})
|
||||
).to.be.a('number');
|
||||
});
|
||||
|
||||
it('to start services via coreSetup.getStartServices', async () => {
|
||||
expect(
|
||||
await browser.executeAsync(async cb => {
|
||||
const [coreStart] = await window.__coreProvider.setup.core.getStartServices();
|
||||
cb(Boolean(coreStart.overlays));
|
||||
})
|
||||
).to.be(true);
|
||||
});
|
||||
});
|
||||
|
||||
|
@ -61,16 +75,5 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider
|
|||
expect(envData.packageInfo.version).to.be.a('string');
|
||||
});
|
||||
});
|
||||
|
||||
describe('have access to start services via coreSetup.getStartServices', function describeIndexTests() {
|
||||
before(async () => {
|
||||
await PageObjects.common.navigateToApp('bar');
|
||||
});
|
||||
|
||||
it('should attach boolean to window.receivedStartServices', async () => {
|
||||
const receivedStartServices = await browser.execute('return window.receivedStartServices');
|
||||
expect(receivedStartServices).to.equal(true);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
import expect from '@kbn/expect';
|
||||
import { PluginFunctionalProviderContext } from '../../services';
|
||||
import '../../plugins/core_provider_plugin/types';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ getService, getPageObjects }: PluginFunctionalProviderContext) {
|
||||
|
@ -31,15 +32,30 @@ export default function({ getService, getPageObjects }: PluginFunctionalProvider
|
|||
});
|
||||
|
||||
it('client plugins have access to registered settings', async () => {
|
||||
const settings = await browser.execute('return window.uiSettingsPlugin');
|
||||
const settings = await browser.execute(() => {
|
||||
return window.__coreProvider.setup.core.uiSettings.getAll().ui_settings_plugin;
|
||||
});
|
||||
|
||||
expect(settings).to.eql({
|
||||
category: ['any'],
|
||||
description: 'just for testing',
|
||||
name: 'from_ui_settings_plugin',
|
||||
value: '2',
|
||||
});
|
||||
const settingsValue = await browser.execute('return window.uiSettingsPluginValue');
|
||||
|
||||
const settingsValue = await browser.execute(() => {
|
||||
return window.__coreProvider.setup.core.uiSettings.get('ui_settings_plugin');
|
||||
});
|
||||
|
||||
expect(settingsValue).to.be('2');
|
||||
|
||||
const settingsValueViaObservables = await browser.executeAsync(async (callback: Function) => {
|
||||
window.__coreProvider.setup.core.uiSettings
|
||||
.get$('ui_settings_plugin')
|
||||
.subscribe(v => callback(v));
|
||||
});
|
||||
|
||||
expect(settingsValueViaObservables).to.be('2');
|
||||
});
|
||||
|
||||
it('server plugins have access to registered settings', async () => {
|
||||
|
|
|
@ -35,4 +35,6 @@ require('@kbn/test').runTestsCli([
|
|||
require.resolve('../test/ui_capabilities/spaces_only/config'),
|
||||
require.resolve('../test/upgrade_assistant_integration/config'),
|
||||
require.resolve('../test/licensing_plugin/config'),
|
||||
require.resolve('../test/licensing_plugin/config.public'),
|
||||
require.resolve('../test/licensing_plugin/config.legacy'),
|
||||
]);
|
||||
|
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../services';
|
||||
import { PublicLicenseJSON } from '../../../plugins/licensing/server';
|
||||
|
||||
const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
|
||||
|
||||
export default function({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esSupertestWithoutAuth = getService('esSupertestWithoutAuth');
|
||||
const security = getService('security');
|
||||
const PageObjects = getPageObjects(['common', 'security']);
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
const scenario = {
|
||||
async setup() {
|
||||
await security.role.create('license_manager-role', {
|
||||
elasticsearch: {
|
||||
cluster: ['all'],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
base: ['all'],
|
||||
spaces: ['*'],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await security.user.create('license_manager_user', {
|
||||
password: 'license_manager_user-password',
|
||||
roles: ['license_manager-role'],
|
||||
full_name: 'license_manager user',
|
||||
});
|
||||
|
||||
// ensure we're logged out so we can login as the appropriate users
|
||||
await PageObjects.security.forceLogout();
|
||||
await PageObjects.security.login('license_manager_user', 'license_manager_user-password');
|
||||
},
|
||||
|
||||
async teardown() {
|
||||
await security.role.delete('license_manager-role');
|
||||
},
|
||||
|
||||
async startBasic() {
|
||||
const response = await esSupertestWithoutAuth
|
||||
.post('/_license/start_basic?acknowledge=true')
|
||||
.auth('license_manager_user', 'license_manager_user-password')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.basic_was_started).to.be(true);
|
||||
},
|
||||
|
||||
async startTrial() {
|
||||
const response = await esSupertestWithoutAuth
|
||||
.post('/_license/start_trial?acknowledge=true')
|
||||
.auth('license_manager_user', 'license_manager_user-password')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.trial_was_started).to.be(true);
|
||||
},
|
||||
|
||||
async deleteLicense() {
|
||||
const response = await esSupertestWithoutAuth
|
||||
.delete('/_license')
|
||||
.auth('license_manager_user', 'license_manager_user-password')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.acknowledged).to.be(true);
|
||||
},
|
||||
|
||||
async getLicense(): Promise<PublicLicenseJSON> {
|
||||
// > --xpack.licensing.api_polling_frequency set in test config
|
||||
// to wait for Kibana server to re-fetch the license from Elasticsearch
|
||||
await delay(1000);
|
||||
|
||||
const { body } = await supertest.get('/api/licensing/info').expect(200);
|
||||
return body;
|
||||
},
|
||||
};
|
||||
|
||||
describe('changes in license types', () => {
|
||||
after(async () => {
|
||||
await scenario.startBasic();
|
||||
});
|
||||
|
||||
it('provides changes in license types', async () => {
|
||||
await scenario.setup();
|
||||
const initialLicense = await scenario.getLicense();
|
||||
expect(initialLicense.license?.type).to.be('basic');
|
||||
// security enabled explicitly in test config
|
||||
expect(initialLicense.features?.security).to.eql({
|
||||
isAvailable: true,
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
const {
|
||||
body: legacyInitialLicense,
|
||||
headers: legacyInitialLicenseHeaders,
|
||||
} = await supertest.get('/api/xpack/v1/info').expect(200);
|
||||
|
||||
expect(legacyInitialLicense.license?.type).to.be('basic');
|
||||
expect(legacyInitialLicense.features).to.have.property('security');
|
||||
expect(legacyInitialLicenseHeaders['kbn-xpack-sig']).to.be.a('string');
|
||||
|
||||
// license hasn't changed
|
||||
const refetchedLicense = await scenario.getLicense();
|
||||
expect(refetchedLicense.license?.type).to.be('basic');
|
||||
expect(refetchedLicense.signature).to.be(initialLicense.signature);
|
||||
|
||||
const {
|
||||
body: legacyRefetchedLicense,
|
||||
headers: legacyRefetchedLicenseHeaders,
|
||||
} = await supertest.get('/api/xpack/v1/info').expect(200);
|
||||
|
||||
expect(legacyRefetchedLicense.license?.type).to.be('basic');
|
||||
expect(legacyRefetchedLicenseHeaders['kbn-xpack-sig']).to.be(
|
||||
legacyInitialLicenseHeaders['kbn-xpack-sig']
|
||||
);
|
||||
|
||||
// server allows to request trial only once.
|
||||
// other attempts will throw 403
|
||||
await scenario.startTrial();
|
||||
const trialLicense = await scenario.getLicense();
|
||||
expect(trialLicense.license?.type).to.be('trial');
|
||||
expect(trialLicense.signature).to.not.be(initialLicense.signature);
|
||||
|
||||
expect(trialLicense.features?.security).to.eql({
|
||||
isAvailable: true,
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
const { body: legacyTrialLicense, headers: legacyTrialLicenseHeaders } = await supertest
|
||||
.get('/api/xpack/v1/info')
|
||||
.expect(200);
|
||||
|
||||
expect(legacyTrialLicense.license?.type).to.be('trial');
|
||||
expect(legacyTrialLicense.features).to.have.property('security');
|
||||
expect(legacyTrialLicenseHeaders['kbn-xpack-sig']).to.not.be(
|
||||
legacyInitialLicenseHeaders['kbn-xpack-sig']
|
||||
);
|
||||
|
||||
await scenario.startBasic();
|
||||
const basicLicense = await scenario.getLicense();
|
||||
expect(basicLicense.license?.type).to.be('basic');
|
||||
expect(basicLicense.signature).not.to.be(initialLicense.signature);
|
||||
|
||||
expect(basicLicense.features?.security).to.eql({
|
||||
isAvailable: true,
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
const { body: legacyBasicLicense, headers: legacyBasicLicenseHeaders } = await supertest
|
||||
.get('/api/xpack/v1/info')
|
||||
.expect(200);
|
||||
expect(legacyBasicLicense.license?.type).to.be('basic');
|
||||
expect(legacyBasicLicense.features).to.have.property('security');
|
||||
expect(legacyBasicLicenseHeaders['kbn-xpack-sig']).to.not.be(
|
||||
legacyInitialLicenseHeaders['kbn-xpack-sig']
|
||||
);
|
||||
|
||||
await scenario.deleteLicense();
|
||||
const inactiveLicense = await scenario.getLicense();
|
||||
expect(inactiveLicense.signature).to.not.be(initialLicense.signature);
|
||||
expect(inactiveLicense).to.not.have.property('license');
|
||||
expect(inactiveLicense.features?.security).to.eql({
|
||||
isAvailable: false,
|
||||
isEnabled: true,
|
||||
});
|
||||
// banner shown only when license expired not just deleted
|
||||
await testSubjects.missingOrFail('licenseExpiredBanner');
|
||||
});
|
||||
});
|
||||
}
|
15
x-pack/test/licensing_plugin/config.legacy.ts
Normal file
15
x-pack/test/licensing_plugin/config.legacy.ts
Normal file
|
@ -0,0 +1,15 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
|
||||
|
||||
export default async function({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const commonConfig = await readConfigFile(require.resolve('./config'));
|
||||
|
||||
return {
|
||||
...commonConfig.getAll(),
|
||||
testFiles: [require.resolve('./legacy')],
|
||||
};
|
||||
}
|
29
x-pack/test/licensing_plugin/config.public.ts
Normal file
29
x-pack/test/licensing_plugin/config.public.ts
Normal file
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import path from 'path';
|
||||
import { KIBANA_ROOT } from '@kbn/test';
|
||||
import { FtrConfigProviderContext } from '@kbn/test/types/ftr';
|
||||
|
||||
export default async function({ readConfigFile }: FtrConfigProviderContext) {
|
||||
const commonConfig = await readConfigFile(require.resolve('./config'));
|
||||
|
||||
return {
|
||||
...commonConfig.getAll(),
|
||||
testFiles: [require.resolve('./public')],
|
||||
kbnTestServer: {
|
||||
serverArgs: [
|
||||
...commonConfig.get('kbnTestServer.serverArgs'),
|
||||
|
||||
// Required to load new platform plugin provider via `--plugin-path` flag.
|
||||
'--env.name=development',
|
||||
`--plugin-path=${path.resolve(
|
||||
KIBANA_ROOT,
|
||||
'test/plugin_functional/plugins/core_provider_plugin'
|
||||
)}`,
|
||||
],
|
||||
},
|
||||
};
|
||||
}
|
|
@ -22,7 +22,7 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) {
|
|||
};
|
||||
|
||||
return {
|
||||
testFiles: [require.resolve('./apis')],
|
||||
testFiles: [require.resolve('./server')],
|
||||
servers,
|
||||
services,
|
||||
pageObjects,
|
||||
|
@ -43,7 +43,7 @@ export default async function({ readConfigFile }: FtrConfigProviderContext) {
|
|||
...functionalTestsConfig.get('kbnTestServer'),
|
||||
serverArgs: [
|
||||
...functionalTestsConfig.get('kbnTestServer.serverArgs'),
|
||||
'--xpack.licensing.api_polling_frequency=300',
|
||||
'--xpack.licensing.api_polling_frequency=100',
|
||||
],
|
||||
},
|
||||
|
||||
|
|
16
x-pack/test/licensing_plugin/legacy/index.ts
Normal file
16
x-pack/test/licensing_plugin/legacy/index.ts
Normal file
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../services';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Legacy licensing plugin', function() {
|
||||
this.tags('ciGroup2');
|
||||
// MUST BE LAST! CHANGES LICENSE TYPE!
|
||||
loadTestFile(require.resolve('./updates'));
|
||||
});
|
||||
}
|
71
x-pack/test/licensing_plugin/legacy/updates.ts
Normal file
71
x-pack/test/licensing_plugin/legacy/updates.ts
Normal file
|
@ -0,0 +1,71 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../services';
|
||||
import { createScenario } from '../scenario';
|
||||
import '../../../../test/plugin_functional/plugins/core_provider_plugin/types';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function(ftrContext: FtrProviderContext) {
|
||||
const { getService } = ftrContext;
|
||||
const supertest = getService('supertest');
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
const scenario = createScenario(ftrContext);
|
||||
|
||||
describe('changes in license types', () => {
|
||||
after(async () => {
|
||||
await scenario.startBasic();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
await scenario.teardown();
|
||||
});
|
||||
|
||||
it('provides changes in license types', async () => {
|
||||
await scenario.setup();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
const {
|
||||
body: legacyInitialLicense,
|
||||
headers: legacyInitialLicenseHeaders,
|
||||
} = await supertest.get('/api/xpack/v1/info').expect(200);
|
||||
|
||||
expect(legacyInitialLicense.license?.type).to.be('basic');
|
||||
expect(legacyInitialLicense.features).to.have.property('security');
|
||||
expect(legacyInitialLicenseHeaders['kbn-xpack-sig']).to.be.a('string');
|
||||
|
||||
await scenario.startTrial();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
const { body: legacyTrialLicense, headers: legacyTrialLicenseHeaders } = await supertest
|
||||
.get('/api/xpack/v1/info')
|
||||
.expect(200);
|
||||
|
||||
expect(legacyTrialLicense.license?.type).to.be('trial');
|
||||
expect(legacyTrialLicense.features).to.have.property('security');
|
||||
expect(legacyTrialLicenseHeaders['kbn-xpack-sig']).to.not.be(
|
||||
legacyInitialLicenseHeaders['kbn-xpack-sig']
|
||||
);
|
||||
|
||||
await scenario.startBasic();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
const { body: legacyBasicLicense, headers: legacyBasicLicenseHeaders } = await supertest
|
||||
.get('/api/xpack/v1/info')
|
||||
.expect(200);
|
||||
expect(legacyBasicLicense.license?.type).to.be('basic');
|
||||
expect(legacyBasicLicense.features).to.have.property('security');
|
||||
expect(legacyBasicLicenseHeaders['kbn-xpack-sig']).to.not.be(
|
||||
legacyInitialLicenseHeaders['kbn-xpack-sig']
|
||||
);
|
||||
|
||||
await scenario.deleteLicense();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
// banner shown only when license expired not just deleted
|
||||
await testSubjects.missingOrFail('licenseExpiredBanner');
|
||||
});
|
||||
});
|
||||
}
|
16
x-pack/test/licensing_plugin/public/index.ts
Normal file
16
x-pack/test/licensing_plugin/public/index.ts
Normal file
|
@ -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;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
|
||||
import { FtrProviderContext } from '../services';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Licensing plugin public client', function() {
|
||||
this.tags('ciGroup2');
|
||||
// MUST BE LAST! CHANGES LICENSE TYPE!
|
||||
loadTestFile(require.resolve('./updates'));
|
||||
});
|
||||
}
|
112
x-pack/test/licensing_plugin/public/updates.ts
Normal file
112
x-pack/test/licensing_plugin/public/updates.ts
Normal file
|
@ -0,0 +1,112 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../services';
|
||||
import { LicensingPluginSetup } from '../../../plugins/licensing/public';
|
||||
import { createScenario } from '../scenario';
|
||||
import '../../../../test/plugin_functional/plugins/core_provider_plugin/types';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function(ftrContext: FtrProviderContext) {
|
||||
const { getService } = ftrContext;
|
||||
const testSubjects = getService('testSubjects');
|
||||
const browser = getService('browser');
|
||||
|
||||
const scenario = createScenario(ftrContext);
|
||||
|
||||
describe('changes in license types', () => {
|
||||
after(async () => {
|
||||
await scenario.startBasic();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
await scenario.teardown();
|
||||
});
|
||||
|
||||
it('provides changes in license types', async () => {
|
||||
await scenario.setup();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
expect(
|
||||
await browser.executeAsync(async (cb: Function) => {
|
||||
const { setup, testUtils } = window.__coreProvider;
|
||||
// this call enforces signature check to detect license update
|
||||
// and causes license re-fetch
|
||||
await setup.core.http.get('/');
|
||||
await testUtils.delay(100);
|
||||
|
||||
const licensing: LicensingPluginSetup = setup.plugins.licensing;
|
||||
licensing.license$.subscribe(license => cb(license.type));
|
||||
})
|
||||
).to.be('basic');
|
||||
|
||||
// license hasn't changed
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
expect(
|
||||
await browser.executeAsync(async (cb: Function) => {
|
||||
const { setup, testUtils } = window.__coreProvider;
|
||||
// this call enforces signature check to detect license update
|
||||
// and causes license re-fetch
|
||||
await setup.core.http.get('/');
|
||||
await testUtils.delay(100);
|
||||
|
||||
const licensing: LicensingPluginSetup = setup.plugins.licensing;
|
||||
licensing.license$.subscribe(license => cb(license.type));
|
||||
})
|
||||
).to.be('basic');
|
||||
|
||||
await scenario.startTrial();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
expect(
|
||||
await browser.executeAsync(async (cb: Function) => {
|
||||
const { setup, testUtils } = window.__coreProvider;
|
||||
// this call enforces signature check to detect license update
|
||||
// and causes license re-fetch
|
||||
await setup.core.http.get('/');
|
||||
await testUtils.delay(100);
|
||||
|
||||
const licensing: LicensingPluginSetup = setup.plugins.licensing;
|
||||
licensing.license$.subscribe(license => cb(license.type));
|
||||
})
|
||||
).to.be('trial');
|
||||
|
||||
await scenario.startBasic();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
expect(
|
||||
await browser.executeAsync(async (cb: Function) => {
|
||||
const { setup, testUtils } = window.__coreProvider;
|
||||
// this call enforces signature check to detect license update
|
||||
// and causes license re-fetch
|
||||
await setup.core.http.get('/');
|
||||
await testUtils.delay(100);
|
||||
|
||||
const licensing: LicensingPluginSetup = setup.plugins.licensing;
|
||||
licensing.license$.subscribe(license => cb(license.type));
|
||||
})
|
||||
).to.be('basic');
|
||||
|
||||
await scenario.deleteLicense();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
|
||||
expect(
|
||||
await browser.executeAsync(async (cb: Function) => {
|
||||
const { setup, testUtils } = window.__coreProvider;
|
||||
// this call enforces signature check to detect license update
|
||||
// and causes license re-fetch
|
||||
await setup.core.http.get('/');
|
||||
await testUtils.delay(100);
|
||||
|
||||
const licensing: LicensingPluginSetup = setup.plugins.licensing;
|
||||
licensing.license$.subscribe(license => cb(license.type));
|
||||
})
|
||||
).to.be(null);
|
||||
|
||||
// banner shown only when license expired not just deleted
|
||||
await testSubjects.missingOrFail('licenseExpiredBanner');
|
||||
});
|
||||
});
|
||||
}
|
91
x-pack/test/licensing_plugin/scenario.ts
Normal file
91
x-pack/test/licensing_plugin/scenario.ts
Normal file
|
@ -0,0 +1,91 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from './services';
|
||||
import { PublicLicenseJSON } from '../../plugins/licensing/server';
|
||||
import '../../../test/plugin_functional/plugins/core_provider_plugin/types';
|
||||
|
||||
const delay = (ms: number) => new Promise(res => setTimeout(res, ms));
|
||||
|
||||
export function createScenario({ getService, getPageObjects }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
const esSupertestWithoutAuth = getService('esSupertestWithoutAuth');
|
||||
const security = getService('security');
|
||||
const PageObjects = getPageObjects(['common', 'security']);
|
||||
|
||||
const scenario = {
|
||||
async setup() {
|
||||
await security.role.create('license_manager-role', {
|
||||
elasticsearch: {
|
||||
cluster: ['all'],
|
||||
},
|
||||
kibana: [
|
||||
{
|
||||
base: ['all'],
|
||||
spaces: ['*'],
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
await security.user.create('license_manager_user', {
|
||||
password: 'license_manager_user-password',
|
||||
roles: ['license_manager-role'],
|
||||
full_name: 'license_manager user',
|
||||
});
|
||||
|
||||
// ensure we're logged out so we can login as the appropriate users
|
||||
await PageObjects.security.logout();
|
||||
await PageObjects.security.login('license_manager_user', 'license_manager_user-password');
|
||||
},
|
||||
|
||||
// make sure a license is present, otherwise the security is not available anymore.
|
||||
async teardown() {
|
||||
await security.role.delete('license_manager-role');
|
||||
await security.user.delete('license_manager_user');
|
||||
},
|
||||
|
||||
// elasticsearch allows to downgrade a license only once. other attempts will throw 403.
|
||||
async startBasic() {
|
||||
const response = await esSupertestWithoutAuth
|
||||
.post('/_license/start_basic?acknowledge=true')
|
||||
.auth('license_manager_user', 'license_manager_user-password')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.basic_was_started).to.be(true);
|
||||
},
|
||||
|
||||
// elasticsearch allows to request trial only once. other attempts will throw 403.
|
||||
async startTrial() {
|
||||
const response = await esSupertestWithoutAuth
|
||||
.post('/_license/start_trial?acknowledge=true')
|
||||
.auth('license_manager_user', 'license_manager_user-password')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.trial_was_started).to.be(true);
|
||||
},
|
||||
|
||||
async deleteLicense() {
|
||||
const response = await esSupertestWithoutAuth
|
||||
.delete('/_license')
|
||||
.auth('license_manager_user', 'license_manager_user-password')
|
||||
.expect(200);
|
||||
|
||||
expect(response.body.acknowledged).to.be(true);
|
||||
},
|
||||
|
||||
async getLicense(): Promise<PublicLicenseJSON> {
|
||||
const { body } = await supertest.get('/api/licensing/info').expect(200);
|
||||
return body;
|
||||
},
|
||||
|
||||
async waitForPluginToDetectLicenseUpdate() {
|
||||
// > --xpack.licensing.api_polling_frequency set in test config
|
||||
// to wait for Kibana server to re-fetch the license from Elasticsearch
|
||||
await delay(500);
|
||||
},
|
||||
};
|
||||
return scenario;
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../services';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
|
@ -6,13 +6,14 @@
|
|||
|
||||
import { FtrProviderContext } from '../services';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ loadTestFile }: FtrProviderContext) {
|
||||
describe('Licensing plugin', function() {
|
||||
describe('Licensing plugin server client', function() {
|
||||
this.tags('ciGroup2');
|
||||
loadTestFile(require.resolve('./info'));
|
||||
loadTestFile(require.resolve('./header'));
|
||||
|
||||
// MUST BE LAST! CHANGES LICENSE TYPE!
|
||||
loadTestFile(require.resolve('./changes'));
|
||||
loadTestFile(require.resolve('./updates'));
|
||||
});
|
||||
}
|
|
@ -7,6 +7,7 @@
|
|||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../services';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function({ getService }: FtrProviderContext) {
|
||||
const supertest = getService('supertest');
|
||||
|
78
x-pack/test/licensing_plugin/server/updates.ts
Normal file
78
x-pack/test/licensing_plugin/server/updates.ts
Normal file
|
@ -0,0 +1,78 @@
|
|||
/*
|
||||
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
|
||||
* or more contributor license agreements. Licensed under the Elastic License;
|
||||
* you may not use this file except in compliance with the Elastic License.
|
||||
*/
|
||||
import expect from '@kbn/expect';
|
||||
import { FtrProviderContext } from '../services';
|
||||
import { createScenario } from '../scenario';
|
||||
import '../../../../test/plugin_functional/plugins/core_provider_plugin/types';
|
||||
|
||||
// eslint-disable-next-line import/no-default-export
|
||||
export default function(ftrContext: FtrProviderContext) {
|
||||
const { getService } = ftrContext;
|
||||
const testSubjects = getService('testSubjects');
|
||||
|
||||
const scenario = createScenario(ftrContext);
|
||||
|
||||
describe('changes in license types', () => {
|
||||
after(async () => {
|
||||
await scenario.startBasic();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
await scenario.teardown();
|
||||
});
|
||||
|
||||
it('provides changes in license types', async () => {
|
||||
await scenario.setup();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
const initialLicense = await scenario.getLicense();
|
||||
expect(initialLicense.license?.type).to.be('basic');
|
||||
// security enabled explicitly in test config
|
||||
expect(initialLicense.features?.security).to.eql({
|
||||
isAvailable: true,
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
// license hasn't changed
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
const refetchedLicense = await scenario.getLicense();
|
||||
expect(refetchedLicense.license?.type).to.be('basic');
|
||||
expect(refetchedLicense.signature).to.be(initialLicense.signature);
|
||||
|
||||
await scenario.startTrial();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
const trialLicense = await scenario.getLicense();
|
||||
expect(trialLicense.license?.type).to.be('trial');
|
||||
expect(trialLicense.signature).to.not.be(initialLicense.signature);
|
||||
|
||||
expect(trialLicense.features?.security).to.eql({
|
||||
isAvailable: true,
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
await scenario.startBasic();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
const basicLicense = await scenario.getLicense();
|
||||
expect(basicLicense.license?.type).to.be('basic');
|
||||
expect(basicLicense.signature).not.to.be(initialLicense.signature);
|
||||
|
||||
expect(basicLicense.features?.security).to.eql({
|
||||
isAvailable: true,
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
await scenario.deleteLicense();
|
||||
await scenario.waitForPluginToDetectLicenseUpdate();
|
||||
const inactiveLicense = await scenario.getLicense();
|
||||
expect(inactiveLicense.signature).to.not.be(initialLicense.signature);
|
||||
expect(inactiveLicense).to.not.have.property('license');
|
||||
expect(inactiveLicense.features?.security).to.eql({
|
||||
isAvailable: false,
|
||||
isEnabled: true,
|
||||
});
|
||||
|
||||
// banner shown only when license expired not just deleted
|
||||
await testSubjects.missingOrFail('licenseExpiredBanner');
|
||||
});
|
||||
});
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue