Skip to content

Commit

Permalink
add integration tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mshustov committed Jan 31, 2020
1 parent de25412 commit 003cd43
Show file tree
Hide file tree
Showing 3 changed files with 391 additions and 0 deletions.
220 changes: 220 additions & 0 deletions src/core/server/legacy/integration_tests/logging.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
/*
* 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 Fs from 'fs';
import Path from 'path';
import Util from 'util';
import del from 'del';

import * as kbnTestServer from '../../../../test_utils/kbn_server';
import { fromRoot } from '../../utils';
import {
getPlatformLoggingContent as _getPlatformLoggingContent,
getLegacyPlatformLoggingContent as _getLegacyPlatformLoggingContent,
} from '../../logging/integration_tests/utils';

import { LegacyLoggingConfig } from '../config/legacy_object_to_config_adapter';

const mkdir = Util.promisify(Fs.mkdir);
const truncate = Util.promisify(Fs.truncate);

const tempFolderPath = fromRoot('data/test/tmp-logging-service');
const platformDestination = Path.join(tempFolderPath, 'compatibility-np.txt');
const legacyPlatformDestination = Path.join(tempFolderPath, 'compatibility-lp.txt');

const getPlatformLoggingContent = () => _getPlatformLoggingContent(platformDestination);
const getLegacyPlatformLoggingContent = () =>
_getLegacyPlatformLoggingContent(legacyPlatformDestination);

function createRoot(legacyLoggingConfig: LegacyLoggingConfig = {}) {
return kbnTestServer.createRoot({
logging: {
// legacy platform config
silent: false,
dest: legacyPlatformDestination,
json: false,
...legacyLoggingConfig,
events: {
log: ['test-file-legacy'],
},
// platform config
appenders: {
file: {
kind: 'file',
path: platformDestination,
layout: {
kind: 'pattern',
},
},
},
loggers: [
{
context: 'test-file',
appenders: ['file'],
level: 'info',
},
],
},
});
}

describe('logging service', () => {
describe('compatibility', () => {
beforeAll(async () => {
await mkdir(tempFolderPath, { recursive: true });
});
afterAll(async () => {
await del(tempFolderPath);
});
afterEach(async () => {
await truncate(platformDestination);
await truncate(legacyPlatformDestination);
});
describe('uses configured loggers', () => {
let root: ReturnType<typeof createRoot>;
beforeAll(async () => {
root = createRoot();

await root.setup();
await root.start();
}, 30000);

afterAll(async () => {
await root.shutdown();
});

it('when context matches', async () => {
root.logger.get('test-file').info('handled by NP');

expect(await getPlatformLoggingContent()).toMatchInlineSnapshot(`
"[xxxx-xx-xxTxx:xx:xx.xxxZ][INFO ][test-file] handled by NP
"
`);

expect(await getLegacyPlatformLoggingContent()).toHaveLength(0);
});

it('falls back to the root legacy logger otherwise', async () => {
root.logger.get('test-file-legacy').info('handled by LP');

expect(await getLegacyPlatformLoggingContent()).toMatchInlineSnapshot(`
" log [xx:xx:xx.xxx] [info][test-file-legacy] handled by LP
"
`);
expect(await getPlatformLoggingContent()).toHaveLength(0);
});
});

describe('logging config respects legacy logging settings', () => {
it('"silent": true', async () => {
const root = createRoot({ silent: true });

await root.setup();
await root.start();

const platformLogger = root.logger.get('test-file');
platformLogger.info('info');
platformLogger.warn('warn');
platformLogger.error('error');

const legacyPlatformLogger = root.logger.get('test-file-legacy');
legacyPlatformLogger.info('info');
legacyPlatformLogger.warn('warn');
legacyPlatformLogger.error('error');

// calls shutdown to close write stream and flush logged messages
await root.shutdown();

expect(await getPlatformLoggingContent()).toMatchInlineSnapshot(`
"[xxxx-xx-xxTxx:xx:xx.xxxZ][INFO ][test-file] info
[xxxx-xx-xxTxx:xx:xx.xxxZ][WARN ][test-file] warn
[xxxx-xx-xxTxx:xx:xx.xxxZ][ERROR][test-file] error
"
`);

expect(await getLegacyPlatformLoggingContent()).toHaveLength(0);
});

it('"quiet": true', async () => {
const root = createRoot({ quiet: true });

await root.setup();
await root.start();

const platformLogger = root.logger.get('test-file');
platformLogger.info('info');
platformLogger.warn('warn');
platformLogger.error('error');

const legacyPlatformLogger = root.logger.get('test-file-legacy');
legacyPlatformLogger.info('info');
legacyPlatformLogger.warn('warn');
legacyPlatformLogger.error('error');

// calls shutdown to close write stream and flush logged messages
await root.shutdown();

expect(await getPlatformLoggingContent()).toMatchInlineSnapshot(`
"[xxxx-xx-xxTxx:xx:xx.xxxZ][INFO ][test-file] info
[xxxx-xx-xxTxx:xx:xx.xxxZ][WARN ][test-file] warn
[xxxx-xx-xxTxx:xx:xx.xxxZ][ERROR][test-file] error
"
`);

expect(await getLegacyPlatformLoggingContent()).toMatchInlineSnapshot(`
" log [xx:xx:xx.xxx] [error][test-file-legacy] error
"
`);
});

it('"verbose": true', async () => {
const root = createRoot({ verbose: true });

await root.setup();
await root.start();

const platformLogger = root.logger.get('test-file');
platformLogger.info('info');
platformLogger.warn('warn');
platformLogger.error('error');

const legacyPlatformLogger = root.logger.get('test-file-legacy');
legacyPlatformLogger.info('info');
legacyPlatformLogger.warn('warn');
legacyPlatformLogger.error('error');

// calls shutdown to close write stream and flush logged messages
await root.shutdown();

expect(await getPlatformLoggingContent()).toMatchInlineSnapshot(`
"[xxxx-xx-xxTxx:xx:xx.xxxZ][INFO ][test-file] info
[xxxx-xx-xxTxx:xx:xx.xxxZ][WARN ][test-file] warn
[xxxx-xx-xxTxx:xx:xx.xxxZ][ERROR][test-file] error
"
`);

expect(await getLegacyPlatformLoggingContent()).toMatchInlineSnapshot(`
" log [xx:xx:xx.xxx] [info][test-file-legacy] info
log [xx:xx:xx.xxx] [warning][test-file-legacy] warn
log [xx:xx:xx.xxx] [error][test-file-legacy] error
"
`);
});
});
});
});
114 changes: 114 additions & 0 deletions src/core/server/logging/integration_tests/logging.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,114 @@
/*
* 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 * as kbnTestServer from '../../../../test_utils/kbn_server';

function createRoot() {
return kbnTestServer.createRoot({
logging: {
silent: true, // set "true" in kbnTestServer
appenders: {
'test-console': {
kind: 'console',
layout: {
highlight: false,
kind: 'pattern',
pattern: '{level}|{context}|{message}',
},
},
},
loggers: [
{
context: 'parent',
appenders: ['test-console'],
level: 'warn',
},
{
context: 'parent.child',
appenders: ['test-console'],
level: 'error',
},
],
},
});
}

describe('logging service', () => {
describe('logs according to context hierarchy', () => {
let root: ReturnType<typeof createRoot>;
let mockConsoleLog: jest.SpyInstance;
beforeAll(async () => {
mockConsoleLog = jest.spyOn(global.console, 'log');
root = createRoot();

await root.setup();
}, 30000);

beforeEach(() => {
mockConsoleLog.mockClear();
});

afterAll(async () => {
mockConsoleLog.mockRestore();
await root.shutdown();
});

it('uses the most specific context', () => {
const logger = root.logger.get('parent.child');

logger.error('error from "parent.child" context');
logger.warn('warning from "parent.child" context');
logger.info('info from "parent.child" context');

expect(mockConsoleLog).toHaveBeenCalledTimes(1);
expect(mockConsoleLog).toHaveBeenCalledWith(
'ERROR|parent.child|error from "parent.child" context'
);
});

it('uses parent context', () => {
const logger = root.logger.get('parent.another-child');

logger.error('error from "parent.another-child" context');
logger.warn('warning from "parent.another-child" context');
logger.info('info from "parent.another-child" context');

expect(mockConsoleLog).toHaveBeenCalledTimes(2);
expect(mockConsoleLog).toHaveBeenNthCalledWith(
1,
'ERROR|parent.another-child|error from "parent.another-child" context'
);
expect(mockConsoleLog).toHaveBeenNthCalledWith(
2,
'WARN |parent.another-child|warning from "parent.another-child" context'
);
});

it('falls back to the root settings', () => {
const logger = root.logger.get('fallback');

logger.error('error from "fallback" context');
logger.warn('warning from fallback" context');
logger.info('info from "fallback" context');

// output muted by silent: true
expect(mockConsoleLog).toHaveBeenCalledTimes(0);
});
});
});
57 changes: 57 additions & 0 deletions src/core/server/logging/integration_tests/utils.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/*
* 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 Fs from 'fs';
import Util from 'util';
const readFile = Util.promisify(Fs.readFile);

function replaceAllNumbers(input: string) {
return input.replace(/\d/g, 'x');
}

function replaceTimestamp(input: string) {
return input.replace(/\[(.*?)\]/, (full, key) => `[${replaceAllNumbers(key)}]`);
}

function stripColors(input: string) {
return input.replace(/\u001b[^m]+m/g, '');
}

export function normalizePlatformLogging(input: string) {
return replaceTimestamp(input);
}

export function normalizeLegacyPlatformLogging(input: string) {
return replaceTimestamp(stripColors(input));
}

export async function getPlatformLoggingContent(path: string) {
const fileContent = await readFile(path, 'utf-8');
return fileContent
.split('\n')
.map(s => normalizePlatformLogging(s))
.join('\n');
}

export async function getLegacyPlatformLoggingContent(path: string) {
const fileContent = await readFile(path, 'utf-8');
return fileContent
.split('\n')
.map(s => normalizeLegacyPlatformLogging(s))
.join('\n');
}

0 comments on commit 003cd43

Please sign in to comment.