From e8c3a0dc41b735ca7a7064a4578a5c4616285b74 Mon Sep 17 00:00:00 2001 From: "nkl199@yahoo.co.uk" Date: Mon, 17 Feb 2020 16:10:02 +0000 Subject: [PATCH] fix config validator for permitted properties Signed-off-by: nkl199@yahoo.co.uk --- .../caliper-fabric/lib/configValidator.js | 19 ++++++++--- .../caliper-fabric/test/configValidator.js | 33 ++++++++++++++++--- .../fabric_tests/phase1/networkconfig.yaml | 2 +- .../fabric_tests/phase2/networkconfig.yaml | 2 +- .../fabric_tests/phase3/networkconfig.yaml | 2 +- .../fabric_tests/phase4/networkconfig.yaml | 2 +- .../fabric_tests/phase5/networkconfig.yaml | 2 +- .../fabric/myWorkspace/networkconfig.yaml | 2 +- 8 files changed, 48 insertions(+), 16 deletions(-) diff --git a/packages/caliper-fabric/lib/configValidator.js b/packages/caliper-fabric/lib/configValidator.js index 8f86d8fb8f..d63b1e4daf 100644 --- a/packages/caliper-fabric/lib/configValidator.js +++ b/packages/caliper-fabric/lib/configValidator.js @@ -39,6 +39,12 @@ class ConfigValidator { throw new Error('Use of service discovery is only valid with a `caliper-flow-only-test` flag'); } + // registrar requirement removed if only-test + let requireRegistrar = 'required'; + if (flowOptions.performTest && (!flowOptions.performInit && !flowOptions.performInstall)) { + requireRegistrar = 'optional'; + } + let tls; // undefined => we don't know yet // the TLS setting might not be known after the individual section if they are missing // the first existing node will determine its value, and after that every node is validated against that value @@ -53,7 +59,7 @@ class ConfigValidator { cas = Object.keys(config.certificateAuthorities); for (let ca of cas) { try { - ConfigValidator.validateCertificateAuthority(config.certificateAuthorities[ca], tls); + ConfigValidator.validateCertificateAuthority(config.certificateAuthorities[ca], tls, requireRegistrar); tls = (tls || false) || config.certificateAuthorities[ca].url.startsWith('https://'); } catch (err) { throw new Error(`Invalid "${ca}" CA configuration: ${err.message}`); @@ -159,7 +165,7 @@ class ConfigValidator { const schema = j.object().keys({ // simple attributes name: j.string().min(1).required(), - version: j.string().valid('1.0').required(), + version: j.string().regex(/\d+.\d+.\d$/).required(), 'mutual-tls': j.boolean().valid(mutualTlsValid).optional(), wallet: j.string().min(1).optional(), caliper: j.object().keys({ @@ -206,6 +212,7 @@ class ConfigValidator { const binary = !!config.configBinary; const def = !!config.definition; const ordererModif = discovery ? 'optional' : 'required'; + const peerModif = discovery ? 'optional' : 'required'; let binaryModif; let defModif; @@ -306,7 +313,7 @@ class ConfigValidator { })[defModif](), orderers: j.array().sparse(false).items(j.string().valid(validOrderers)).unique()[ordererModif](), - peers: j.object().keys(createPeersSchema()).required(), + peers: j.object().keys(createPeersSchema()).required()[peerModif](), // leave this embedded, so the validation error messages are more meaningful chaincodes: j.array().sparse(false).items(j.object().keys({ @@ -358,11 +365,13 @@ class ConfigValidator { * Validates the given CA configuration object. * @param {object} config The configuration object. * @param {boolean} tls Indicates whether TLS is enabled or known at this point. + * @param {string} requireRegistrar Indicates whether a registrar is optional or required. */ - static validateCertificateAuthority(config, tls) { + static validateCertificateAuthority(config, tls, requireRegistrar) { let urlRegex = tls === undefined ? /^(https|http):\/\// : (tls ? /^https:\/\// : /^http:\/\//); const schema = j.object().keys({ + caName: j.string().optional(), url: j.string().uri().regex(urlRegex).required(), httpOptions: j.object().optional(), @@ -380,7 +389,7 @@ class ConfigValidator { registrar: j.array().items(j.object().keys({ enrollId: j.string().min(1).required(), enrollSecret: j.string().min(1).required() - })).min(1).sparse(false).unique('enrollId').required() + })).min(1).sparse(false).unique('enrollId').required()[requireRegistrar]() }); let options = { diff --git a/packages/caliper-fabric/test/configValidator.js b/packages/caliper-fabric/test/configValidator.js index 1cabaad30b..2da920fab1 100644 --- a/packages/caliper-fabric/test/configValidator.js +++ b/packages/caliper-fabric/test/configValidator.js @@ -69,7 +69,7 @@ describe('Class: ConfigValidator', () => { describe('Function: validateNetwork', () => { let config = { name: 'Fabric', - version: '1.0', + version: '1.0.0', 'mutual-tls': false, caliper: { blockchain: 'fabric' @@ -437,7 +437,7 @@ describe('Class: ConfigValidator', () => { // good practice for auto complete and easy backup let config = { name: 'Fabric', - version: '1.0', + version: '1.0.0', 'mutual-tls': false, wallet: '/path', caliper: { @@ -502,8 +502,8 @@ describe('Class: ConfigValidator', () => { call.should.throw(err); }); - it('should throw for an invalid string value', () => { - const err = 'child "version" fails because ["version" must be one of [1.0]]'; + it('should throw for an invalid string value (non-semver)', () => { + const err = 'child "version" fails because ["version" with value "2.0" fails to match the required pattern: /\\d+.\\d+.\\d$/]'; config.version = '2.0'; call.should.throw(err); }); @@ -825,22 +825,45 @@ describe('Class: ConfigValidator', () => { }; let configString = JSON.stringify(config); + let configNoRegistrar = { + url: 'https://localhost:7054', + httpOptions: { + verify: false + }, + tlsCACerts: { + path: 'my/path/tocert' + } + }; + let configStringNoRegistrar = JSON.stringify(configNoRegistrar); + // reset the local config before every test beforeEach(() => { config = JSON.parse(configString); + configNoRegistrar = JSON.parse(configStringNoRegistrar); }); /** * Wraps the actual call, so "should" can call this function without parameters */ function call() { - ConfigValidator.validateCertificateAuthority(config, tls); + ConfigValidator.validateCertificateAuthority(config, tls, 'required'); + } + + /** + * Wraps the actual call, so "should" can call this function without parameters + */ + function callNoRegistrar() { + ConfigValidator.validateCertificateAuthority(configNoRegistrar, tls, 'optional'); } it('should not throw for a valid value', () => { call.should.not.throw(); }); + it('should not throw for a valid value', () => { + callNoRegistrar.should.not.throw(); + }); + it('should throw for an unknown child property', () => { const err = '"unknown" is not allowed'; config.unknown = ''; diff --git a/packages/caliper-tests-integration/fabric_tests/phase1/networkconfig.yaml b/packages/caliper-tests-integration/fabric_tests/phase1/networkconfig.yaml index ec062b1e6d..7d1db403cf 100644 --- a/packages/caliper-tests-integration/fabric_tests/phase1/networkconfig.yaml +++ b/packages/caliper-tests-integration/fabric_tests/phase1/networkconfig.yaml @@ -13,7 +13,7 @@ # name: Fabric -version: "1.0" +version: "1.0.0" caliper: blockchain: fabric diff --git a/packages/caliper-tests-integration/fabric_tests/phase2/networkconfig.yaml b/packages/caliper-tests-integration/fabric_tests/phase2/networkconfig.yaml index 166ab6a9b5..f8bcec6ac3 100644 --- a/packages/caliper-tests-integration/fabric_tests/phase2/networkconfig.yaml +++ b/packages/caliper-tests-integration/fabric_tests/phase2/networkconfig.yaml @@ -13,7 +13,7 @@ # name: Fabric -version: "1.0" +version: "1.0.0" mutual-tls: true caliper: diff --git a/packages/caliper-tests-integration/fabric_tests/phase3/networkconfig.yaml b/packages/caliper-tests-integration/fabric_tests/phase3/networkconfig.yaml index fb2f075a87..bd3c24081f 100644 --- a/packages/caliper-tests-integration/fabric_tests/phase3/networkconfig.yaml +++ b/packages/caliper-tests-integration/fabric_tests/phase3/networkconfig.yaml @@ -13,7 +13,7 @@ # name: Fabric -version: "1.0" +version: "1.0.0" mutual-tls: true caliper: diff --git a/packages/caliper-tests-integration/fabric_tests/phase4/networkconfig.yaml b/packages/caliper-tests-integration/fabric_tests/phase4/networkconfig.yaml index fb2f075a87..bd3c24081f 100644 --- a/packages/caliper-tests-integration/fabric_tests/phase4/networkconfig.yaml +++ b/packages/caliper-tests-integration/fabric_tests/phase4/networkconfig.yaml @@ -13,7 +13,7 @@ # name: Fabric -version: "1.0" +version: "1.0.0" mutual-tls: true caliper: diff --git a/packages/caliper-tests-integration/fabric_tests/phase5/networkconfig.yaml b/packages/caliper-tests-integration/fabric_tests/phase5/networkconfig.yaml index bc9bb58238..5b9b855b2d 100644 --- a/packages/caliper-tests-integration/fabric_tests/phase5/networkconfig.yaml +++ b/packages/caliper-tests-integration/fabric_tests/phase5/networkconfig.yaml @@ -13,7 +13,7 @@ # name: Fabric -version: "1.0" +version: "1.0.0" caliper: blockchain: fabric diff --git a/packages/caliper-tests-integration/generator_tests/fabric/myWorkspace/networkconfig.yaml b/packages/caliper-tests-integration/generator_tests/fabric/myWorkspace/networkconfig.yaml index 10ab49c8e3..f12f2a11d8 100644 --- a/packages/caliper-tests-integration/generator_tests/fabric/myWorkspace/networkconfig.yaml +++ b/packages/caliper-tests-integration/generator_tests/fabric/myWorkspace/networkconfig.yaml @@ -13,7 +13,7 @@ # name: Fabric -version: "1.0" +version: "1.0.0" mutual-tls: true caliper: