Skip to content

Commit

Permalink
SNOW-856233 easy logging parser
Browse files Browse the repository at this point in the history
  • Loading branch information
sfc-gh-knozderko committed Sep 20, 2023
1 parent 48d2049 commit 241d358
Show file tree
Hide file tree
Showing 3 changed files with 218 additions and 0 deletions.
29 changes: 29 additions & 0 deletions lib/configuration/client_configuration.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
const Levels = Object.freeze({
Off: 'OFF',
Error: 'ERROR',
Warn: 'WARN',
Info: 'INFO',
Debug: 'DEBUG',
Trace: 'TRACE'
});

const allLevels = Object.values(Levels);

class ClientConfig {
constructor (logLevel, logPath) {
this.logLevel = logLevel;
this.logPath = logPath;
}
}

exports.ClientConfig = ClientConfig;

exports.Levels = Levels;

exports.levelFromString = function (value) {
const level = value.toUpperCase();
if (!allLevels.includes(level)) {
throw new Error('Unknown log level: ' + value);
}
return level;
};
50 changes: 50 additions & 0 deletions lib/configuration/configuration_parser.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
const Logger = require('../logger');
const fsPromises = require('fs/promises');
const clientConfiguration = require('./client_configuration');

exports.parse = async function (configFilePath) {
const configFile = await tryToFind(configFilePath);
return configFile == null ? null : tryToParse(configFile);
};

function tryToFind (filePath) {
if (!filePath) {
return Promise.resolve(null);
}
return fsPromises.readFile(filePath, { encoding: 'utf8' })
.catch(err => {
const errorMessage = 'Finding easy logging configuration failed';
Logger.getInstance().error(errorMessage + '\n' + err.toString());
throw new Error(errorMessage);
});
}

function tryToParse (configurationJson) {
try {
const parsedConfiguration = JSON.parse(configurationJson);
validate(parsedConfiguration);
return new clientConfiguration.ClientConfig(
logLevel(parsedConfiguration),
logPath(parsedConfiguration)
);
} catch (e) {
const errorMessage = 'Parsing easy logging configuration failed';
Logger.getInstance().error(errorMessage + '\n' + e.toString());
throw new Error(errorMessage);
}
}

function validate (configuration) {
const level = logLevel(configuration);
if (level != null) {
clientConfiguration.levelFromString(level);
}
}

function logLevel (configuration) {
return configuration.common.log_level;
}

function logPath (configuration) {
return configuration.common.log_path;
}
139 changes: 139 additions & 0 deletions test/unit/configuration/configuration_parser_test.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
const assert = require('assert');
const configurationParser = require('./../../../lib/configuration/configuration_parser');
const fsPromises = require('fs/promises');
const os = require('os');
const path = require('path');
const uuidV4 = require('uuid/v4');
const tempDir = path.join(os.tmpdir(), uuidV4());

describe('Configuration parsing tests', function () {

before(async function () {
await fsPromises.mkdir(tempDir, { recursive: false });
});

after(async function () {
await fsPromises.rm(tempDir, { recursive: true, force: true });
});

it('should parse json', async function () {
// given
const fileName = 'config.json';
const filePath = path.join(tempDir, fileName);
const fileContent = `{
"common": {
"log_level": "info",
"log_path": "/some-path/some-directory"
}
}`;
await fsPromises.writeFile(filePath, fileContent, { encoding: 'utf8' });

// when
const configuration = await configurationParser.parse(filePath);

// then
assert.equal(configuration.logLevel, 'info');
assert.equal(configuration.logPath, '/some-path/some-directory');
});

it('should fail when wrong level', async function () {
// given
const fileName = 'config_wrong_level.json';
const filePath = path.join(tempDir, fileName);
const fileContent = `{
"common": {
"log_level": "unknown",
"log_path": "/some-path/some-directory"
}
}`;
await fsPromises.writeFile(filePath, fileContent, { encoding: 'utf8' });

// expect
await assert.rejects(
async () => await configurationParser.parse(filePath),
(err) => {
assert.strictEqual(err.name, 'Error');
assert.strictEqual(err.message, 'Parsing easy logging configuration failed');
return true;
});
});

const noValueFileContents = [
`{
"common": {
"log_level": null,
"log_path": null
}
}`,
`{
"common": {}
}`
];

noValueFileContents.forEach((fileContent, index) => {
it('should parse config without values ' + index.toString(), async function () {
// given
const fileName = 'config_nulls_' + index.toString() + '.json';
const filePath = path.join(tempDir, fileName);
await fsPromises.writeFile(filePath, fileContent, { encoding: 'utf8' });

// when
const configuration = await configurationParser.parse(filePath);

// then
assert.equal(configuration.logLevel, null);
assert.equal(configuration.logPath, null);
});
});

const notGivenFileNames = [null, '', undefined];

notGivenFileNames.forEach((filePath, index) => {
it('should return null when config file not given ' + index.toString(), async function () {
// when
const configuration = await configurationParser.parse(filePath);

// then
assert.strictEqual(configuration, null);
});
});

it('should fail when config file does not exist', async function () {
// expect
await assert.rejects(
async () => await configurationParser.parse('./not-existing-config.json'),
(err) => {
assert.strictEqual(err.name, 'Error');
assert.strictEqual(err.message, 'Finding easy logging configuration failed');
return true;
});
});

const wrongFileContents = [
`{
"common": {
"log_level": "unknown",
"log_path": "/some-path/some-directory"
}
}`,
'{}'
];

wrongFileContents.forEach((fileContent, index) => {
it('should fail for wrong config content ' + index.toString(), async function () {
// given
const fileName = 'config_wrong_' + index.toString() + '.json';
const filePath = path.join(tempDir, fileName);
await fsPromises.writeFile(filePath, fileContent, { encoding: 'utf8' });

// expect
await assert.rejects(
async () => await configurationParser.parse(filePath),
(err) => {
assert.strictEqual(err.name, 'Error');
assert.strictEqual(err.message, 'Parsing easy logging configuration failed');
return true;
});
});
});
});

0 comments on commit 241d358

Please sign in to comment.