added support for logging as required for reporting; introduced off and json as two more log levels; small bug fixes
This commit is contained in:
Родитель
80d0f7190a
Коммит
693dda2ac8
15
README.md
15
README.md
|
@ -53,26 +53,23 @@ node cli.js
|
|||
|
||||
#### Command usage:
|
||||
```
|
||||
MacBook-Pro:openapi-validation-tools someUser$ >node cli.js -h
|
||||
bash-3.2$ node cli.js
|
||||
Commands:
|
||||
live-test <spec-path> Performs live testing of x-ms-examples provided
|
||||
for operations in the spec. This command will be
|
||||
making live calls to the service that is
|
||||
described in the given swagger spec.
|
||||
validate-example <spec-path> Performs validation of x-ms-examples and
|
||||
examples present in the spec.
|
||||
validate-spec <spec-path> Performs semantic validation of the spec.
|
||||
|
||||
Options:
|
||||
--version Show version number [boolean]
|
||||
-j, --json Show json output [boolean]
|
||||
-l, --logLevel Set the logging level for console.
|
||||
[choices: "error", "warn", "info", "verbose", "debug", "silly"] [default:
|
||||
"error"]
|
||||
[choices: "off", "json", "error", "warn", "info", "verbose", "debug", "silly"]
|
||||
[default: "warn"]
|
||||
-f, --logFilepath Set the log file path. It must be an absolute filepath. By
|
||||
default the logs will stored in a timestamp based log file
|
||||
at "C:\Users\<username>\oav_output".
|
||||
at "/Users/amarz/oav_output".
|
||||
-h, --help Show help [boolean]
|
||||
|
||||
bash-3.2$
|
||||
```
|
||||
|
||||
---
|
||||
|
|
13
cli.js
13
cli.js
|
@ -16,11 +16,10 @@ yargs
|
|||
.version("0.1.0")
|
||||
.commandDir('lib/commands')
|
||||
.option('h', {alias: 'help'})
|
||||
.option('j', {alias: 'json', describe: 'Show json output', boolean: true})
|
||||
.option('l', {
|
||||
alias: 'logLevel',
|
||||
describe: 'Set the logging level for console.',
|
||||
choices: ['json', 'error', 'warn', 'info' , 'verbose', 'debug', 'silly'],
|
||||
choices: ['off', 'json', 'error', 'warn', 'info' , 'verbose', 'debug', 'silly'],
|
||||
default: 'warn'
|
||||
})
|
||||
.option('f', {
|
||||
|
@ -28,16 +27,10 @@ yargs
|
|||
describe: `Set the log file path. It must be an absolute filepath. ` +
|
||||
`By default the logs will stored in a timestamp based log file at "${defaultLogDir}".`
|
||||
})
|
||||
.global(['h', 'j', 'l', 'f'])
|
||||
.global(['h', 'l', 'f'])
|
||||
.help()
|
||||
.argv;
|
||||
|
||||
//setting console logging level to the value provided by the user.
|
||||
//log.consoleLogLevel = yargs.argv.l;
|
||||
|
||||
//setting the logFilePath if provided.
|
||||
log.filepath = yargs.argv.f || logFilepath;
|
||||
|
||||
if (yargs.argv._.length === 0 && yargs.argv.h === false && yargs.argv.j === false) {
|
||||
if (yargs.argv._.length === 0 && yargs.argv.h === false) {
|
||||
yargs.coerce('help', function(arg) {return true;}).argv;
|
||||
}
|
|
@ -7,30 +7,30 @@ var util = require('util'),
|
|||
log = require('../util/logging'),
|
||||
validate = require('../../validate');
|
||||
|
||||
exports.command = 'live-test <spec-path>';
|
||||
// exports.command = 'live-test <spec-path>';
|
||||
|
||||
exports.describe = 'Performs live testing of x-ms-examples provided for operations in the spec. ' +
|
||||
'This command will be making live calls to the service that is described in the given swagger spec.';
|
||||
// exports.describe = 'Performs live testing of x-ms-examples provided for operations in the spec. ' +
|
||||
// 'This command will be making live calls to the service that is described in the given swagger spec.';
|
||||
|
||||
exports.builder = {
|
||||
o: {
|
||||
alias: 'operationIds',
|
||||
describe: 'A comma separated string of operationIds for which the examples ' +
|
||||
'need to be validated. If operationIds are not provided then the entire spec will be validated. ' +
|
||||
'Example: "StorageAccounts_Create, StorageAccounts_List, Usages_List".',
|
||||
string: true
|
||||
}
|
||||
};
|
||||
// exports.builder = {
|
||||
// o: {
|
||||
// alias: 'operationIds',
|
||||
// describe: 'A comma separated string of operationIds for which the examples ' +
|
||||
// 'need to be validated. If operationIds are not provided then the entire spec will be validated. ' +
|
||||
// 'Example: "StorageAccounts_Create, StorageAccounts_List, Usages_List".',
|
||||
// string: true
|
||||
// }
|
||||
// };
|
||||
|
||||
exports.handler = function (argv) {
|
||||
log.debug(argv);
|
||||
let specPath = argv.specPath;
|
||||
let operationIds = argv.operationIds;
|
||||
if (specPath.match(/.*composite.*/ig) !== null) {
|
||||
return validate.validateExamplesInCompositeSpec(specPath);
|
||||
} else {
|
||||
return new ExecutionEngine().liveTest(specPath, operationIds);
|
||||
}
|
||||
}
|
||||
// exports.handler = function (argv) {
|
||||
// log.debug(argv);
|
||||
// let specPath = argv.specPath;
|
||||
// let operationIds = argv.operationIds;
|
||||
// if (specPath.match(/.*composite.*/ig) !== null) {
|
||||
// return validate.validateExamplesInCompositeSpec(specPath);
|
||||
// } else {
|
||||
// return new ExecutionEngine().liveTest(specPath, operationIds);
|
||||
// }
|
||||
// }
|
||||
|
||||
exports = module.exports;
|
||||
// exports = module.exports;
|
|
@ -24,11 +24,12 @@ exports.handler = function (argv) {
|
|||
log.debug(argv);
|
||||
let specPath = argv.specPath;
|
||||
let operationIds = argv.operationIds;
|
||||
let json = argv.json;
|
||||
let consoleLogLevel = argv.logLevel;
|
||||
let logfilepath = argv.f;
|
||||
if (specPath.match(/.*composite.*/ig) !== null) {
|
||||
return validate.validateExamplesInCompositeSpec(specPath);
|
||||
return validate.validateExamplesInCompositeSpec(specPath, consoleLogLevel, logfilepath);
|
||||
} else {
|
||||
return validate.validateExamples(specPath, operationIds, json);
|
||||
return validate.validateExamples(specPath, operationIds, consoleLogLevel, logfilepath);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -13,11 +13,13 @@ exports.describe = 'Performs semantic validation of the spec.';
|
|||
exports.handler = function (argv) {
|
||||
log.debug(argv);
|
||||
let specPath = argv.specPath;
|
||||
let json = argv.json;
|
||||
let consoleLogLevel = argv.logLevel;
|
||||
let logfilepath = argv.f;
|
||||
|
||||
if (specPath.match(/.*composite.*/ig) !== null) {
|
||||
return validate.validateCompositeSpec(specPath, json);
|
||||
return validate.validateCompositeSpec(specPath, consoleLogLevel, logfilepath);
|
||||
} else {
|
||||
return validate.validateSpec(specPath, json);
|
||||
return validate.validateSpec(specPath, consoleLogLevel, logfilepath);
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -140,6 +140,8 @@ class SpecValidator {
|
|||
let self = this;
|
||||
self.specValidationResult.validateSpec = {};
|
||||
self.specValidationResult.validateSpec.isValid = true;
|
||||
self.specValidationResult.validateSpec.errors = [];
|
||||
self.specValidationResult.validateSpec.warnings = []
|
||||
if (!self.swaggerApi) {
|
||||
let msg = `Please call "specValidator.initialize()" before calling this method, so that swaggerApi is populated.`;
|
||||
let e = self.constructErrorObject(ErrorCodes.InitializationError, msg)
|
||||
|
@ -154,8 +156,7 @@ class SpecValidator {
|
|||
if (validationResult.errors && validationResult.errors.length) {
|
||||
self.specValidationResult.validateSpec.isValid = false;
|
||||
let e = self.constructErrorObject(ErrorCodes.SemanticValidationError, `The spec ${self.specPath} has semantic validation errors.`, validationResult.errors);
|
||||
//self.specValidationResult.validateSpec.error = e;
|
||||
self.specValidationResult.validateSpec.error = ValidationResponse.constructErrors(e, self.specPath, self.getProviderNamespace());
|
||||
self.specValidationResult.validateSpec.errors = ValidationResponse.constructErrors(e, self.specPath, self.getProviderNamespace());
|
||||
log.error(Constants.Errors);
|
||||
log.error('------');
|
||||
self.updateValidityStatus();
|
||||
|
@ -166,7 +167,7 @@ class SpecValidator {
|
|||
if (validationResult.warnings && validationResult.warnings.length > 0) {
|
||||
let warnings = ValidationResponse.sanitizeWarnings(validationResult.warnings);
|
||||
if (warnings && warnings.length) {
|
||||
self.specValidationResult.validateSpec.warning = warnings;
|
||||
self.specValidationResult.validateSpec.warnings = warnings;
|
||||
log.warn(Constants.Warnings);
|
||||
log.warn('--------');
|
||||
log.warn(util.inspect(warnings));
|
||||
|
|
|
@ -35,13 +35,14 @@ function getTimeStamp() {
|
|||
+ pad(now.getSeconds());
|
||||
}
|
||||
var customLogLevels = {
|
||||
json: 0,
|
||||
error: 1,
|
||||
warn: 2,
|
||||
info: 3,
|
||||
verbose: 4,
|
||||
debug: 5,
|
||||
silly: 6
|
||||
off: 0,
|
||||
json: 1,
|
||||
error: 2,
|
||||
warn: 3,
|
||||
info: 4,
|
||||
verbose: 5,
|
||||
debug: 6,
|
||||
silly: 7
|
||||
};
|
||||
|
||||
var logger = new (winston.Logger)({
|
||||
|
|
48
validate.js
48
validate.js
|
@ -44,23 +44,16 @@ exports.getDocumentsFromCompositeSwagger = function getDocumentsFromCompositeSwa
|
|||
});
|
||||
};
|
||||
|
||||
exports.validateSpec = function validateSpec(specPath, json, consoleLogLevel, logFilepath) {
|
||||
if (consoleLogLevel) { log.consoleLogLevel = consoleLogLevel; }
|
||||
if (logFilepath) {
|
||||
log.filepath = logFilepath;
|
||||
} else {
|
||||
log.filepath = log.filepath;
|
||||
}
|
||||
if (json) {
|
||||
log.consoleLogLevel = 'json';
|
||||
}
|
||||
exports.validateSpec = function validateSpec(specPath, consoleLogLevel, logFilepath) {
|
||||
log.consoleLogLevel = consoleLogLevel || log.consoleLevel;
|
||||
log.filepath = logFilepath || log.filepath;
|
||||
let validator = new SpecValidator(specPath);
|
||||
exports.finalValidationResult[specPath] = validator.specValidationResult;
|
||||
return validator.initialize().then(function () {
|
||||
log.info(`Semantically validating ${specPath}:\n`);
|
||||
return validator.validateSpec().then(function (result) {
|
||||
exports.updateEndResultOfSingleValidation(validator);
|
||||
exports.logDetailedInfo(validator, json);
|
||||
exports.logDetailedInfo(validator);
|
||||
return Promise.resolve(validator.specValidationResult);
|
||||
});
|
||||
}).catch(function (err) {
|
||||
|
@ -69,10 +62,12 @@ exports.validateSpec = function validateSpec(specPath, json, consoleLogLevel, lo
|
|||
});
|
||||
};
|
||||
|
||||
exports.validateCompositeSpec = function validateCompositeSpec(compositeSpecPath, json) {
|
||||
exports.validateCompositeSpec = function validateCompositeSpec(compositeSpecPath, consoleLogLevel, logFilepath) {
|
||||
log.consoleLogLevel = consoleLogLevel || log.consoleLevel;
|
||||
log.filepath = logFilepath || log.filepath;
|
||||
return exports.getDocumentsFromCompositeSwagger(compositeSpecPath).then(function (docs) {
|
||||
let promiseFactories = docs.map(function (doc) {
|
||||
return exports.validateSpec(doc, json);
|
||||
return function () { return exports.validateSpec(doc, consoleLogLevel, logFilepath) };
|
||||
});
|
||||
return utils.executePromisesSequentially(promiseFactories);
|
||||
}).catch(function (err) {
|
||||
|
@ -81,23 +76,16 @@ exports.validateCompositeSpec = function validateCompositeSpec(compositeSpecPath
|
|||
});
|
||||
};
|
||||
|
||||
exports.validateExamples = function validateExamples(specPath, operationIds, json, consoleLogLevel, logFilepath) {
|
||||
if (consoleLogLevel) { log.consoleLogLevel = consoleLogLevel; }
|
||||
if (logFilepath) {
|
||||
log.filepath = logFilepath;
|
||||
} else {
|
||||
log.filepath = log.filepath;
|
||||
}
|
||||
if (json) {
|
||||
log.consoleLogLevel = 'json';
|
||||
}
|
||||
exports.validateExamples = function validateExamples(specPath, operationIds, consoleLogLevel, logFilepath) {
|
||||
log.consoleLogLevel = consoleLogLevel || log.consoleLevel;
|
||||
log.filepath = logFilepath || log.filepath;
|
||||
let validator = new SpecValidator(specPath);
|
||||
exports.finalValidationResult[specPath] = validator.specValidationResult;
|
||||
return validator.initialize().then(function () {
|
||||
log.info(`Validating "examples" and "x-ms-examples" in ${specPath}:\n`);
|
||||
validator.validateOperations(operationIds);
|
||||
exports.updateEndResultOfSingleValidation(validator);
|
||||
exports.logDetailedInfo(validator, json);
|
||||
exports.logDetailedInfo(validator);
|
||||
return Promise.resolve(validator.specValidationResult);
|
||||
}).catch(function (err) {
|
||||
log.error(err);
|
||||
|
@ -105,10 +93,12 @@ exports.validateExamples = function validateExamples(specPath, operationIds, jso
|
|||
});
|
||||
};
|
||||
|
||||
exports.validateExamplesInCompositeSpec = function validateExamplesInCompositeSpec(compositeSpecPath, json) {
|
||||
exports.validateExamplesInCompositeSpec = function validateExamplesInCompositeSpec(compositeSpecPath, consoleLogLevel, logFilepath) {
|
||||
log.consoleLogLevel = consoleLogLevel || log.consoleLevel;
|
||||
log.filepath = logFilepath || log.filepath;
|
||||
return exports.getDocumentsFromCompositeSwagger(compositeSpecPath).then(function (docs) {
|
||||
let promiseFactories = docs.map(function (doc) {
|
||||
return exports.validateExamples(doc, json);
|
||||
return function () { return exports.validateExamples(doc, consoleLogLevel, logFilepath); }
|
||||
});
|
||||
return utils.executePromisesSequentially(promiseFactories);
|
||||
}).catch(function (err) {
|
||||
|
@ -119,7 +109,7 @@ exports.validateExamplesInCompositeSpec = function validateExamplesInCompositeSp
|
|||
|
||||
exports.updateEndResultOfSingleValidation = function updateEndResultOfSingleValidation(validator) {
|
||||
if (validator.specValidationResult.validityStatus) {
|
||||
if (log.consoleLogLevel !== 'json') {
|
||||
if (!(log.consoleLogLevel === 'json' || log.consoleLogLevel === 'off')) {
|
||||
let consoleLevel = log.consoleLogLevel;
|
||||
log.consoleLogLevel = 'info';
|
||||
log.info('No Errors were found.');
|
||||
|
@ -132,8 +122,8 @@ exports.updateEndResultOfSingleValidation = function updateEndResultOfSingleVali
|
|||
return;
|
||||
};
|
||||
|
||||
exports.logDetailedInfo = function logDetailedInfo(validator, json) {
|
||||
if (json) {
|
||||
exports.logDetailedInfo = function logDetailedInfo(validator) {
|
||||
if (log.consoleLogLevel === 'json') {
|
||||
console.dir(validator.specValidationResult, { depth: null, colors: true });
|
||||
}
|
||||
log.silly('############################');
|
||||
|
|
Загрузка…
Ссылка в новой задаче