From 44e0f86e1d1f223a0e03ddf86af52e4ae076a364 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 21 Jan 2020 15:52:43 -0500 Subject: [PATCH 01/68] GPII-4273: Working version of revision requester and its tests --- .../flowManager/src/FlowManager.js | 19 ++ .../flowManager/src/GpiiRevisionRequester.js | 53 ++++++ .../test/GpiiRevisionRequesterTests.js | 164 ++++++++++++++++++ 3 files changed, 236 insertions(+) create mode 100644 gpii/node_modules/flowManager/src/GpiiRevisionRequester.js create mode 100644 gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index ea576829e..462b74d28 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -40,6 +40,7 @@ require("gpii-user-errors"); fluid.defaults("gpii.flowManager", { gradeNames: ["kettle.app"], + solutionsRegistryUrl: null, components: { // TODO: Make this use the solutions registry data source by default? solutionsRegistryDataSource: { @@ -231,6 +232,10 @@ fluid.defaults("gpii.flowManager.local", { }, listeners: { "onCreate.registerInstance": "gpii.singleInstance.registerInstance", + "onCreate.computeSolutionRegistryUrl": { + funcName: "gpii.flowManager.local.computeSolutionRegistryUrl", + args: ["{that}"] + }, "onCreate.mountWebSocketsSettingsHandler": { funcName: "gpii.flowManager.local.mountWebSocketsSettingsHandler", args: ["{webSocketsSettingsHandlerComponent}"] @@ -358,6 +363,20 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { } }; +/** + * Retrieve the revision of the repository from the CBFM and construct the full + * URL of the associated solutions registry document + * @param {Component} that - An instance of gpii.flowManager.local. + */ +gpii.flowManager.local.computeSolutionRegistryUrl = function (localFlowManger) { + // Make the request for the version + ; + // then construct and save the full url to the git repo + ; + // on failure, set the full url to null. + ; +} + /** * The add-on grade containing http endpoints that will be attached to the local flow manager when the * "suppressHttpEndpoints" flag is turned on. diff --git a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js new file mode 100644 index 000000000..bb2854b20 --- /dev/null +++ b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js @@ -0,0 +1,53 @@ +/*! +GPII Full SHA Revision DataSource + +Copyright 2020 OCAD University + +Licensed under the New BSD license. You may not use this file except in +compliance with this License. + +You may obtain a copy of the License at +https://github.com/GPII/universal/blob/master/LICENSE.txt +*/ + +"use strict"; + +var fluid = require("infusion"), + gpii = fluid.registerNamespace("gpii"); + +require("kettle"); + +fluid.registerNamespace("gpii.revisionRequester"); + +fluid.defaults("gpii.revisionRequester", { + gradeNames: ["fluid.component"], + + // Prepend CBFM host/port distributed down from, e.g., gpii.flowManager.config.untrusted + url: "/revision", + components: { + gpiiRevisionDataSource: { + type: "kettle.dataSource.URL", + options: { + url: "{revisionRequester}.options.url" + } + } + }, + invokers: { + getRevision: { + funcName: "gpii.revisionRequester.getRevision", + args: ["{that}"] + } + } +}); + +gpii.revisionRequester.getRevision = function (that) { + var togo = fluid.promise(); + + var revisionPromise = that.gpiiRevisionDataSource.get(); + revisionPromise.then(function (revision) { + fluid.promise.follow(revisionPromise, togo); + }, function (err) { + togo.resolve(err) + }); + return togo; +}; diff --git a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js new file mode 100644 index 000000000..a14b6dea6 --- /dev/null +++ b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js @@ -0,0 +1,164 @@ +/*! +GPII revision request tests + +Copyright 2020 OCAD University + +Licensed under the New BSD license. You may not use this file except in +compliance with this License. + +You may obtain a copy of the License at +https://github.com/GPII/universal/blob/master/LICENSE.txt +*/ + +"use strict"; + +var fluid = fluid || require("infusion"), + gpii = fluid.registerNamespace("gpii"), + kettle = require("kettle"), + nock = require("nock"); + +fluid.require("%gpii-universal/gpii/node_modules/testing/src/NockUtils.js"); +require("../src/GpiiRevisionRequester.js"); + +kettle.loadTestingSupport(); + +fluid.registerNamespace("gpii.tests.revisionRequester"); + +gpii.tests.revisionRequester.hostname = "http://gpii.net"; +gpii.tests.revisionRequester.path = "/revision"; + +// Set up mock cloud request/response +gpii.tests.revisionRequester.setUpNock = function (config) { + var cloudMock = nock(gpii.tests.revisionRequester.hostname); + cloudMock.log(console.log); + + // mock GET request + cloudMock.get(gpii.tests.revisionRequester.path) + .reply(config.status, config.response); +}; + +// Revision requester customized for testing +fluid.defaults("gpii.tests.revisionRequester", { + gradeNames: ["gpii.revisionRequester"], + cloudUrl: gpii.tests.revisionRequester.hostname, + url: gpii.tests.revisionRequester.hostname + gpii.tests.revisionRequester.path +}); + +// Base testEnvironment +fluid.defaults("gpii.tests.revisionRequesterTests", { + gradeNames: ["fluid.test.testEnvironment"], + testCaseHolderGrade: null, // supplied by individual tests + distributeOptions: { + testCaseHolderGrade: { + source: "{that}.options.testCaseHolderGrade", + target: "{that > testCaseHolder}.type" + } + }, + components: { + revisionRequester: { + type: "gpii.tests.revisionRequester" + }, + testCaseHolder: { + type: "fluid.test.testCaseHolder" + } + } +}); + +// 1. Successful retrieval +gpii.tests.revisionRequester.success = { + nockConfig: { + url: gpii.tests.revisionRequester.hostname + gpii.tests.revisionRequester.path, + type: "get", + status: 200, + response: {"sha256": "2602bdf868aec49993d8780feec42d4e9f995e21"} + } +}; + +fluid.defaults("gpii.tests.revisionRequester.testCaseHolder.success", { + gradeNames: "fluid.test.testCaseHolder", + modules: [{ + name: "Revision requester module tests - successful retrieval", + expect: 1, + tests: [{ + name: "Response: valid revision", + sequence: [{ + task: "{revisionRequester}.getRevision", + resolve: "jqUnit.assertDeepEq", + resolveArgs: [ + "The response is the expected revision", + gpii.tests.revisionRequester.success.nockConfig.response, + "{arguments}.0" + ] + }] + }] + }] +}); + +fluid.defaults("gpii.tests.revisionRequesterTests.success", { + gradeNames: ["gpii.tests.revisionRequesterTests", "gpii.test.testWithNock"], + testCaseHolderGrade: "gpii.tests.revisionRequester.testCaseHolder.success", + invokers: { + setUpNock: { + funcName: "gpii.tests.revisionRequester.setUpNock", + args: gpii.tests.revisionRequester.success.nockConfig + } + } +}); + +// 2. Retrieval of malformed or missing revision +gpii.tests.revisionRequester.missingRevision = { + nockConfig: { + url: gpii.tests.revisionRequester.hostname + gpii.tests.revisionRequester.path, + type: "get", + status: 404, + response: { + isError: true, + statusCode: 404, + message: "Error retrieving full git revision: Missing revision value" + } + }, + expected: { + isError: true, + statusCode: 404, + // FIXME: Find out where in nock "while executing HTTP GET on url http://gpii.net/revision" + // is coming from, and get rid of it. + message: "Error retrieving full git revision: Missing revision value while executing HTTP GET on url http://gpii.net/revision" + } +}; + +fluid.defaults("gpii.tests.revisionRequester.testCaseHolder.missingRevision", { + gradeNames: "fluid.test.testCaseHolder", + modules: [{ + name: "Revision requester module tests - missing revision", + expect: 1, + tests: [{ + name: "Response: missing revision", + sequence: [{ + task: "{revisionRequester}.getRevision", + resolve: "jqUnit.assertDeepEq", + resolveArgs: [ + "The response is expected as missing", + gpii.tests.revisionRequester.missingRevision.expected, + "{arguments}.0" + ] + }] + }] + }] +}); + +fluid.defaults("gpii.tests.revisionRequesterTests.missingRevision", { + gradeNames: ["gpii.tests.revisionRequesterTests", "gpii.test.testWithNock"], + testCaseHolderGrade: "gpii.tests.revisionRequester.testCaseHolder.missingRevision", + invokers: { + setUpNock: { + funcName: "gpii.tests.revisionRequester.setUpNock", + args: gpii.tests.revisionRequester.missingRevision.nockConfig + } + } +}); + +// Run all tests +fluid.test.runTests([ + "gpii.tests.revisionRequesterTests.success", + "gpii.tests.revisionRequesterTests.missingRevision" +]); From 06104ec6be10cd6b95c7fa37ba09f000af479939 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 21 Jan 2020 16:16:25 -0500 Subject: [PATCH 02/68] GPII-4273: Improved require statement to import GpiiRevisionRequester.js --- .../node_modules/flowManager/test/GpiiRevisionRequesterTests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js index a14b6dea6..22d334254 100644 --- a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js +++ b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js @@ -18,7 +18,7 @@ var fluid = fluid || require("infusion"), nock = require("nock"); fluid.require("%gpii-universal/gpii/node_modules/testing/src/NockUtils.js"); -require("../src/GpiiRevisionRequester.js"); +fluid.require("%flowManager/src/GpiiRevisionRequester.js"); kettle.loadTestingSupport(); From 1541231c51410675f693595812d1b747d1cf7533 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 22 Jan 2020 10:00:37 -0500 Subject: [PATCH 03/68] GPII-4273: Fixed lint errors --- gpii/node_modules/flowManager/src/GpiiRevisionRequester.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js index bb2854b20..299fb6c3a 100644 --- a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js +++ b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js @@ -42,12 +42,12 @@ fluid.defaults("gpii.revisionRequester", { gpii.revisionRequester.getRevision = function (that) { var togo = fluid.promise(); - + var revisionPromise = that.gpiiRevisionDataSource.get(); - revisionPromise.then(function (revision) { + revisionPromise.then(function (/*revision*/) { fluid.promise.follow(revisionPromise, togo); }, function (err) { - togo.resolve(err) + togo.resolve(err); }); return togo; }; From 81be7b4b7079dd2d96f4d6875945a6759316588e Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 23 Jan 2020 10:06:51 -0500 Subject: [PATCH 04/68] GPII-4273: Improved specification of the URL members --- .../flowManager/src/GpiiRevisionRequester.js | 23 ++++++++++++++----- .../test/GpiiRevisionRequesterTests.js | 5 ++-- 2 files changed, 19 insertions(+), 9 deletions(-) diff --git a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js index 299fb6c3a..bb0b50291 100644 --- a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js +++ b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js @@ -17,30 +17,41 @@ var fluid = require("infusion"), require("kettle"); -fluid.registerNamespace("gpii.revisionRequester"); +fluid.registerNamespace("gpii.flowmanager.revisionRequester"); -fluid.defaults("gpii.revisionRequester", { +fluid.defaults("gpii.flowmanager.revisionRequester", { gradeNames: ["fluid.component"], // Prepend CBFM host/port distributed down from, e.g., gpii.flowManager.config.untrusted - url: "/revision", + cloudUrl: null, + urlTemplate: "%cloudUrl/revision", + + // Compute url from CBFM base URL and template + revisionGetUrl: { + expander: { + funcName: "fluid.stringTemplate", + args: ["{that}.options.urlTemplate", { + cloudUrl: "{that}.options.cloudUrl" + }] + } + }, components: { gpiiRevisionDataSource: { type: "kettle.dataSource.URL", options: { - url: "{revisionRequester}.options.url" + url: "{revisionRequester}.options.revisionGetUrl" } } }, invokers: { getRevision: { - funcName: "gpii.revisionRequester.getRevision", + funcName: "gpii.flowmanager.revisionRequester.getRevision", args: ["{that}"] } } }); -gpii.revisionRequester.getRevision = function (that) { +gpii.flowmanager.revisionRequester.getRevision = function (that) { var togo = fluid.promise(); var revisionPromise = that.gpiiRevisionDataSource.get(); diff --git a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js index 22d334254..09ba8eee6 100644 --- a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js +++ b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js @@ -39,9 +39,8 @@ gpii.tests.revisionRequester.setUpNock = function (config) { // Revision requester customized for testing fluid.defaults("gpii.tests.revisionRequester", { - gradeNames: ["gpii.revisionRequester"], - cloudUrl: gpii.tests.revisionRequester.hostname, - url: gpii.tests.revisionRequester.hostname + gpii.tests.revisionRequester.path + gradeNames: ["gpii.flowmanager.revisionRequester"], + cloudUrl: gpii.tests.revisionRequester.hostname }); // Base testEnvironment From 0bb842d6032c71a00a2b256c8f25de34021999d6 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 24 Jan 2020 14:55:02 -0500 Subject: [PATCH 05/68] GPII-4273: Added documentation for GpiiRevisionRequester's getRevision() --- gpii/node_modules/flowManager/src/GpiiRevisionRequester.js | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js index bb0b50291..9cfa1b35b 100644 --- a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js +++ b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js @@ -51,6 +51,13 @@ fluid.defaults("gpii.flowmanager.revisionRequester", { } }); +/** + * Retrieve the respository revision's full SHA256 from the cloud. + * @param {Component} that - An instance of gpii.flowManager.revisionRequester. + * @return {Promise} A promise whose resolved value is eiher the revision or, if + * there is an error, an object with an "isError: true" property. The revision + * has the form { "sha256": "86a83d2f93a6f8f954a4fef618ca6aea1399c980" }. + */ gpii.flowmanager.revisionRequester.getRevision = function (that) { var togo = fluid.promise(); From 0f416fcd6460d4ce5ca657f46bc4537a1f0b60bd Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 24 Jan 2020 16:38:06 -0500 Subject: [PATCH 06/68] GPII-4273: LFM modified to run in development and production configurations --- .../gpii.flowManager.config.local.base.json5 | 16 ++++++++++ ...ii.flowManager.config.untrusted.base.json5 | 5 +++ .../flowManager/src/FlowManager.js | 32 ++++++++++++++----- scripts/vagrantCloudBasedContainers.sh | 7 +++- .../production/CloudStatusProductionTests.js | 21 +++++++++++- 5 files changed, 71 insertions(+), 10 deletions(-) diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index b7814ffb0..88b066f6f 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -5,6 +5,22 @@ "flowManager.local": { "record": ["gpii.flowManager.local"], "target": "{that flowManager}.options.gradeNames" + }, + "flowManager.local.gpiiRevisionCloudURL": { + "record": "http://localhost:8081", + "target": "{that flowManager gpiiRevisionRequester}.options.cloudUrl" + }, + "flowManager.local.solutionsRegistryRepositoryPrefix": { + "record": "https://raw.githubusercontent.com/GPII/universal/", + "target": "{that flowManager}.options.solutionsRegistryRepositoryPrefix" + }, + "flowManager.local.solutionsRegistryRepositorySuffix": { + "record": "/testData/solutions/", + "target": "{that flowManager}.options.solutionsRegistryRepositorySuffix" + }, + "flowManager.local.solutionsRegistryRepositoryFile": { + "record": "win32.json5", // "%solutions.json5" ?? + "target": "{that flowManager}.options.solutionsRegistryRepositoryFile" } } }, diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 index 5ae7cfa1b..16bffe14e 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 @@ -19,6 +19,11 @@ "flowManager.clientCredentialFilePath": { "record": "%gpii-universal/testData/clientCredentials/pilot.json", "target": "{that flowManager settingsDataSource}.options.clientCredentialFilePath" + }, + "flowManager.local.gpiiRevisionCloudURL": { + "record": "@expand:kettle.resolvers.env(GPII_CLOUD_URL)", + "target": "{that flowManager gpiiRevisionRequester}.options.cloudUrl", + "priority": "after:flowManager.envCloudURL" } } }, diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 462b74d28..2e5a9adb8 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -28,6 +28,7 @@ require("./DefaultSettingsLoader.js"); require("./PSPChannel.js"); require("./SettingsDataSource.js"); require("./UntrustedFlowManager.js"); +require("./GpiiRevisionRequester.js"); require("preferencesServer"); require("lifecycleManager"); @@ -81,6 +82,11 @@ fluid.defaults("gpii.flowManager.local", { // The "suppressHttpEndpoints" flag is to indicate whether to hide un-needed localhost http endpoints. // It is turned on in production configs. suppressHttpEndpoints: false, + // For retrieving the solutions registry from the source code repository, + // distributed from gpii.flowManager.config.local.base + solutionsRegistryRepositoryPrefix: "", + solutionsRegistryRepositorySuffix: "", + solutionsRegistryRepositoryFile: "", members: { /* The resolved value is an object containing data for performing reset actions: { @@ -194,6 +200,9 @@ fluid.defaults("gpii.flowManager.local", { }, userErrors: { type: "gpii.userErrors" + }, + gpiiRevisionRequester: { + type: "gpii.flowmanager.revisionRequester" } }, requestHandlers: { @@ -367,15 +376,22 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { * Retrieve the revision of the repository from the CBFM and construct the full * URL of the associated solutions registry document * @param {Component} that - An instance of gpii.flowManager.local. + * @return {Promise} - A promise: when resolved with no error, sets the LFM's + * solutionRegistryDataSource URL. If there is an error, the URL left undefined. */ -gpii.flowManager.local.computeSolutionRegistryUrl = function (localFlowManger) { - // Make the request for the version - ; - // then construct and save the full url to the git repo - ; - // on failure, set the full url to null. - ; -} +gpii.flowManager.local.computeSolutionRegistryUrl = function (that) { + var revisionPromise = that.gpiiRevisionRequester.getRevision(); + revisionPromise.then(function (revision) { + if (!revision.isError) { + that.solutionsRegistryDataSource.options.URL = + that.options.solutionsRegistryRepositoryPrefix + + revision.sha256 + + that.options.solutionsRegistryRepositorySuffix + + that.options.solutionsRegistryRepositoryFile; + } + }); + return revisionPromise; +}; /** * The add-on grade containing http endpoints that will be attached to the local flow manager when the diff --git a/scripts/vagrantCloudBasedContainers.sh b/scripts/vagrantCloudBasedContainers.sh index 830323f83..10514759a 100755 --- a/scripts/vagrantCloudBasedContainers.sh +++ b/scripts/vagrantCloudBasedContainers.sh @@ -27,6 +27,11 @@ fi UNIVERSAL_IMAGE=vagrant-universal +# The following SHA256 is not the actual latest revision that is used in +# in production. This is here for the tests, and written to the file +# gpii-revision.json at the root universal folder. See the Dockerfile. +GITFULLREV="$(git rev-parse HEAD)" + COUCHDB_IMAGE=couchdb COUCHDB_PORT=5984 COUCHDB_HEALTHCHECK_DELAY=2 @@ -73,7 +78,7 @@ if [ "$NO_REBUILD" != "true" ] ; then docker rmi -f $UNIVERSAL_IMAGE 2>/dev/null || true # Build image - docker build -t $UNIVERSAL_IMAGE . + docker build --build-arg gitFullRev="$GITFULLREV" -t $UNIVERSAL_IMAGE . fi # Start the CouchDB container diff --git a/tests/production/CloudStatusProductionTests.js b/tests/production/CloudStatusProductionTests.js index 3ab0ca0a1..bc8e56a35 100644 --- a/tests/production/CloudStatusProductionTests.js +++ b/tests/production/CloudStatusProductionTests.js @@ -39,15 +39,22 @@ fluid.registerNamespace("gpii.tests.productionConfigTesting"); require("../shared/DevelopmentTestDefs.js"); require("./ProductionTestsUtils.js"); +gpii.tests.productionConfigTesting.validGpiiRevision = require( + fluid.module.resolvePath( + "%gpii-universal/gpii-revision.json" + ) +); + // Flowmanager tests for: // /user/%gpiiKey/login and /user/%gpiiKey/logout (as defined in gpii.tests.development.testDefs), // /health, // /ready, +// /revision gpii.tests.productionConfigTesting.testDefs = fluid.transform(gpii.tests.development.testDefs, function (testDefIn) { var testDef = fluid.extend(true, {}, testDefIn, { name: "Flow Manager production tests -- status, login, and logout", config: gpii.tests.productionConfigTesting.config, - expect: 6, + expect: 8, components: { healthRequest: { type: "gpii.tests.productionConfigTesting.cloudStatusRequest", @@ -62,6 +69,13 @@ gpii.tests.productionConfigTesting.testDefs = fluid.transform(gpii.tests.develop path: "/ready", expectedPayload: {"isReady": true} } + }, + revisionRequest: { + type: "gpii.tests.productionConfigTesting.cloudStatusRequest", + options: { + path: "/revision", + expectedPayload: gpii.tests.productionConfigTesting.validGpiiRevision + } } }, sequenceGrade: "gpii.tests.productionConfigTesting.cloudStatusSequence" @@ -83,6 +97,11 @@ fluid.defaults("gpii.tests.productionConfigTesting.cloudStatus", { }, { event: "{readyRequest}.events.onComplete", listener: "gpii.tests.productionConfigTesting.testResponse" + }, { + func: "{revisionRequest}.sendToCBFM" + }, { + event: "{revisionRequest}.events.onComplete", + listener: "gpii.tests.productionConfigTesting.testResponse" }, { funcName: "fluid.log", args: ["Cloud status tests end"]} ] From a0c721f3ecdd2cd2bf28d70a1274e943e772d358 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 28 Jan 2020 16:01:30 -0500 Subject: [PATCH 07/68] GPII-4273: (GPII-4273iii) Fixed untrusted config files Also, rationalized capitalization of "URL" --- .../configs/gpii.flowManager.config.local.base.json5 | 2 +- .../gpii.flowManager.config.untrusted.base.json5 | 10 +++++++--- .../flowManager/src/GpiiRevisionRequester.js | 6 +++--- .../flowManager/test/GpiiRevisionRequesterTests.js | 2 +- 4 files changed, 12 insertions(+), 8 deletions(-) diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index 88b066f6f..b29ad64f0 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -8,7 +8,7 @@ }, "flowManager.local.gpiiRevisionCloudURL": { "record": "http://localhost:8081", - "target": "{that flowManager gpiiRevisionRequester}.options.cloudUrl" + "target": "{that flowManager gpiiRevisionRequester}.options.cloudURL" }, "flowManager.local.solutionsRegistryRepositoryPrefix": { "record": "https://raw.githubusercontent.com/GPII/universal/", diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 index 16bffe14e..04e3fd86a 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 @@ -20,10 +20,14 @@ "record": "%gpii-universal/testData/clientCredentials/pilot.json", "target": "{that flowManager settingsDataSource}.options.clientCredentialFilePath" }, - "flowManager.local.gpiiRevisionCloudURL": { + "flowManager.defaultRevisionCloudURL": { + "record": "http://localhost:8084", + "target": "{that flowManager gpiiRevisionRequester}.options.cloudURL" + }, + "flowManager.gpiiRevisionCloudURL": { "record": "@expand:kettle.resolvers.env(GPII_CLOUD_URL)", - "target": "{that flowManager gpiiRevisionRequester}.options.cloudUrl", - "priority": "after:flowManager.envCloudURL" + "target": "{that flowManager gpiiRevisionRequester}.options.cloudURL", + "priority": "after:flowManager.defaultRevisionCloudURL" } } }, diff --git a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js index 9cfa1b35b..da18f593a 100644 --- a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js +++ b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js @@ -23,15 +23,15 @@ fluid.defaults("gpii.flowmanager.revisionRequester", { gradeNames: ["fluid.component"], // Prepend CBFM host/port distributed down from, e.g., gpii.flowManager.config.untrusted - cloudUrl: null, - urlTemplate: "%cloudUrl/revision", + cloudURL: null, + urlTemplate: "%cloudURL/revision", // Compute url from CBFM base URL and template revisionGetUrl: { expander: { funcName: "fluid.stringTemplate", args: ["{that}.options.urlTemplate", { - cloudUrl: "{that}.options.cloudUrl" + cloudURL: "{that}.options.cloudURL" }] } }, diff --git a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js index 09ba8eee6..603b3d065 100644 --- a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js +++ b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js @@ -40,7 +40,7 @@ gpii.tests.revisionRequester.setUpNock = function (config) { // Revision requester customized for testing fluid.defaults("gpii.tests.revisionRequester", { gradeNames: ["gpii.flowmanager.revisionRequester"], - cloudUrl: gpii.tests.revisionRequester.hostname + cloudURL: gpii.tests.revisionRequester.hostname }); // Base testEnvironment From 52ed7cb33becd1c065e0795391f28abed1633fd4 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 29 Jan 2020 11:51:58 -0500 Subject: [PATCH 08/68] GPII-4273: (GPII-4273iii) Used platform reporter for the solutions registry file name --- .../configs/gpii.flowManager.config.local.base.json5 | 4 ---- gpii/node_modules/flowManager/src/FlowManager.js | 7 +++---- 2 files changed, 3 insertions(+), 8 deletions(-) diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index b29ad64f0..449081a36 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -17,10 +17,6 @@ "flowManager.local.solutionsRegistryRepositorySuffix": { "record": "/testData/solutions/", "target": "{that flowManager}.options.solutionsRegistryRepositorySuffix" - }, - "flowManager.local.solutionsRegistryRepositoryFile": { - "record": "win32.json5", // "%solutions.json5" ?? - "target": "{that flowManager}.options.solutionsRegistryRepositoryFile" } } }, diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 2e5a9adb8..e02551e50 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -41,7 +41,6 @@ require("gpii-user-errors"); fluid.defaults("gpii.flowManager", { gradeNames: ["kettle.app"], - solutionsRegistryUrl: null, components: { // TODO: Make this use the solutions registry data source by default? solutionsRegistryDataSource: { @@ -86,7 +85,6 @@ fluid.defaults("gpii.flowManager.local", { // distributed from gpii.flowManager.config.local.base solutionsRegistryRepositoryPrefix: "", solutionsRegistryRepositorySuffix: "", - solutionsRegistryRepositoryFile: "", members: { /* The resolved value is an object containing data for performing reset actions: { @@ -383,11 +381,12 @@ gpii.flowManager.local.computeSolutionRegistryUrl = function (that) { var revisionPromise = that.gpiiRevisionRequester.getRevision(); revisionPromise.then(function (revision) { if (!revision.isError) { - that.solutionsRegistryDataSource.options.URL = + var platform = that.deviceReporter.platformReporter.reportPlatform(); + that.solutionsRegistryDataSource.options.repositoryURL = that.options.solutionsRegistryRepositoryPrefix + revision.sha256 + that.options.solutionsRegistryRepositorySuffix + - that.options.solutionsRegistryRepositoryFile; + platform.id + ".json5"; } }); return revisionPromise; From 28b2cc42dd1aa7048a8b1920f258493c69c71ff4 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 31 Jan 2020 18:14:32 -0500 Subject: [PATCH 09/68] GPII-4273: (GPII-4273iv) Added repositorySolutionsLoader component The repositorySolutionsLoader fetches the solutions registry from the source code repository and saves it to a local file. NOTE: code still rough. --- .../gpii.flowManager.config.local.base.json5 | 8 +- .../flowManager/src/FlowManager.js | 15 +- .../src/RepositorySolutionsLoader.js | 136 +++++++++++++ .../test/RepositorySolutionsLoaderTests.js | 184 ++++++++++++++++++ .../flowManager/test/data/darwin.json5 | 119 +++++++++++ 5 files changed, 453 insertions(+), 9 deletions(-) create mode 100644 gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js create mode 100644 gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js create mode 100644 gpii/node_modules/flowManager/test/data/darwin.json5 diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index 449081a36..07d1aa108 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -11,12 +11,12 @@ "target": "{that flowManager gpiiRevisionRequester}.options.cloudURL" }, "flowManager.local.solutionsRegistryRepositoryPrefix": { - "record": "https://raw.githubusercontent.com/GPII/universal/", - "target": "{that flowManager}.options.solutionsRegistryRepositoryPrefix" + "record": "https://raw.githubusercontent.com/GPII/universal", + "target": "{that flowManager repositorySolutionsLoader}.options.urlPrefix" }, "flowManager.local.solutionsRegistryRepositorySuffix": { - "record": "/testData/solutions/", - "target": "{that flowManager}.options.solutionsRegistryRepositorySuffix" + "record": "/testData/solutions", + "target": "{that flowManager repositorySolutionsLoader}.options.urlSuffix" } } }, diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index e02551e50..618e78bde 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -29,6 +29,7 @@ require("./PSPChannel.js"); require("./SettingsDataSource.js"); require("./UntrustedFlowManager.js"); require("./GpiiRevisionRequester.js"); +require("./RepositorySolutionsLoader.js"); require("preferencesServer"); require("lifecycleManager"); @@ -201,6 +202,9 @@ fluid.defaults("gpii.flowManager.local", { }, gpiiRevisionRequester: { type: "gpii.flowmanager.revisionRequester" + }, + repositorySolutionsLoader: { + type: "gpii.flowManager.repositorySolutionsLoader" } }, requestHandlers: { @@ -378,15 +382,16 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { * solutionRegistryDataSource URL. If there is an error, the URL left undefined. */ gpii.flowManager.local.computeSolutionRegistryUrl = function (that) { + debugger; var revisionPromise = that.gpiiRevisionRequester.getRevision(); revisionPromise.then(function (revision) { if (!revision.isError) { + debugger; var platform = that.deviceReporter.platformReporter.reportPlatform(); - that.solutionsRegistryDataSource.options.repositoryURL = - that.options.solutionsRegistryRepositoryPrefix + - revision.sha256 + - that.options.solutionsRegistryRepositorySuffix + - platform.id + ".json5"; + that.repositorySolutionsLoader.gpiiRevision = revision.sha256; + that.repositorySolutionsLoader.fileName = platform.id + ".json5"; + debugger; + return that.repositorySolutionsLoader.getSolutions(); } }); return revisionPromise; diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js new file mode 100644 index 000000000..1fd018c58 --- /dev/null +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -0,0 +1,136 @@ +/*! +GPII Full SHA Revision DataSource + +Copyright 2020 OCAD University + +Licensed under the New BSD license. You may not use this file except in +compliance with this License. + +You may obtain a copy of the License at +https://github.com/GPII/universal/blob/master/LICENSE.txt +*/ + +"use strict"; + +var fluid = require("infusion"), + fs = require("fs"), + gpii = fluid.registerNamespace("gpii"); + +require("kettle"); + +fluid.registerNamespace("gpii.flowManager.repositorySolutionsLoader"); + +fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { + gradeNames: ["kettle.dataSource.URL"], + urlTemplate: "%prefix/%revision/%suffix/%fileName", + url: { + expander: { + funcName: "fluid.stringTemplate", + args: ["{that}.options.urlTemplate", { + prefix: "{that}.options.urlPrefix", + suffix: "{that}.options.urlSuffix" + }] + } + }, + termMap: { + revision: "%directRevision", + fileName: "%directFileName" + }, + // prefix and suffix are distributed from a config file such as + // e.g., gpii.flowManager.config.local + urlPrefix: "", + urlSuffix: "", + + folderPath: "%gpii-universal/testData/solutions/", // move to appropriate config + + members: { + // Revision and name of the solutions registry file are set by the + // local flowManger at startup; see LFM.computeSolutionsRegistryURL() + gpiiRevision: "", + fileName: "", + + solutionsRegistry: null + }, + components: { + encoding: { + type: "kettle.dataSource.encoding.JSON5" + } + }, + invokers: { + getSolutions: { + funcName: "gpii.flowManager.repositorySolutionsLoader.getSolutions", + args: ["{that}"] + }, + saveToDisk: { + funcName: "gpii.flowManager.repositorySolutionsLoader.saveToDisk", + args: ["{arguments}.0", "{arguments}.1", "{arguments}.2"] + // solutions, path to folder, file name + } + } +}); + +/** + * Retrieve the solutions registry JSON file from the source code repository. + * @param {Component} that - An instance of gpii.flowManager.repositorySolutionsLoader. + * @return {Promise} A promise whose resolved value is eiher the solutions + * registry, or, if there is an error, an object with an "isError: true" + * property. + */ +gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that) { + var togo = fluid.promise(); + + if (that.gpiiRevision && that.fileName) { // need this test? + debugger; + var solutionsPromise = that.get({ + directRevision: that.gpiiRevision, + directFileName: that.fileName + }); + solutionsPromise.then(function (solutions) { + debugger; + that.solutionsRegistry = solutions; // write out the file? + fluid.promise.follow(solutionsPromise, togo); + var actualPath = fluid.module.resolvePath(that.options.folderPath); + that.saveToDisk(solutions, actualPath, that.fileName); + }, function (err) { + debugger; + fluid.log( + "Error retrieving solutions from repository: " + err + that.options.url + ); + togo.resolve(err); + }); + } else { + var msg = "Error retrieving solutions from repository: missing " + if (!that.gpiiRevision && !that.fileName) { + msg += "revision and file name"; + } + else if (!that.gpiiRevision) { + msg += "revision"; + } + else { + msg += "file name"; + } + fluid.log(msg); + togo.resolve({isError: true, message: msg, statusCode: 404}); + } + return togo; +}; + +/** + * Save the solutions registry as a local JSON5 file. If the given folder does + * not exist, the error is logged and the function returns. + * @param {Object} solutions - A set of solutions registry entries. + * @param {String} path - Full path to the folder to write to. + * @param {Stirng} fileName - Name of the file. + */ +gpii.flowManager.repositorySolutionsLoader.saveToDisk = function (solutions, path, fileName) { + if (!fs.existsSync(path)) { + debugger; + fluid.log("Folder to store solutions '", fileName, "' is missing: '" , path, "'"); + return; + } else { + debugger; + fileName = "foo" + fileName; + fs.writeFileSync(path + fileName, JSON.stringify(solutions, null, 4)); + } +}; + diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js new file mode 100644 index 000000000..9f151cc3a --- /dev/null +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -0,0 +1,184 @@ +/*! +GPII download and save solutions registry from source code repositoyr + +Copyright 2020 OCAD University + +Licensed under the New BSD license. You may not use this file except in +compliance with this License. + +You may obtain a copy of the License at +https://github.com/GPII/universal/blob/master/LICENSE.txt +*/ + +"use strict"; + +var fluid = fluid || require("infusion"), + gpii = fluid.registerNamespace("gpii"), + kettle = require("kettle"), + nock = require("nock"); + +fluid.require("%gpii-universal/gpii/node_modules/testing/src/NockUtils.js"); +fluid.require("%flowManager/src/RepositorySolutionsLoader.js"); + +kettle.loadTestingSupport(); + +fluid.registerNamespace("gpii.tests.repositorySolutionsLoader"); + +gpii.tests.repositorySolutionsLoader.hostname = "http://gpii.net"; +gpii.tests.repositorySolutionsLoader.prefix = "prefix", +gpii.tests.repositorySolutionsLoader.revision = "32759c38f9e1a5a38072f8c5e60b02a5d20969d7"; +gpii.tests.repositorySolutionsLoader.suffix = "suffix"; +gpii.tests.repositorySolutionsLoader.fileName = "darwin.json5"; +gpii.tests.repositorySolutionsLoader.path = "/" + + gpii.tests.repositorySolutionsLoader.prefix + "/" + + gpii.tests.repositorySolutionsLoader.revision + "/" + + gpii.tests.repositorySolutionsLoader.suffix + "/" + + gpii.tests.repositorySolutionsLoader.fileName; + +gpii.tests.repositorySolutionsLoader.folderPath = "%flowManager/test/data/" +gpii.tests.repositorySolutionsLoader.solutions = fluid.require( + gpii.tests.repositorySolutionsLoader.folderPath + + gpii.tests.repositorySolutionsLoader.fileName +); + +// Set up mock cloud request/response +gpii.tests.repositorySolutionsLoader.setUpNock = function (config) { + debugger; + var cloudMock = nock(gpii.tests.repositorySolutionsLoader.hostname); + cloudMock.log(console.log); + + // mock GET request + var foo = cloudMock.get(gpii.tests.repositorySolutionsLoader.path) + .reply(config.status, config.response); +}; + +// Repository loader customized for testing +fluid.defaults("gpii.tests.repositorySolutionsLoader", { + gradeNames: ["gpii.flowManager.repositorySolutionsLoader"], + urlPrefix: "http://gpii.net/" + gpii.tests.repositorySolutionsLoader.prefix, + urlSuffix: gpii.tests.repositorySolutionsLoader.suffix, + folderPath: gpii.tests.repositorySolutionsLoader.folderPath, + members: { + gpiiRevision: gpii.tests.repositorySolutionsLoader.revision, + fileName: gpii.tests.repositorySolutionsLoader.fileName + } +}); + +// Base testEnvironment +fluid.defaults("gpii.tests.repositorySolutionsLoaderTests", { + gradeNames: ["fluid.test.testEnvironment"], + testCaseHolderGrade: null, // supplied by individual tests + distributeOptions: { + testCaseHolderGrade: { + source: "{that}.options.testCaseHolderGrade", + target: "{that > testCaseHolder}.type" + } + }, + components: { + repositorySolutionsLoader: { + type: "gpii.tests.repositorySolutionsLoader" + }, + testCaseHolder: { + type: "fluid.test.testCaseHolder" + } + } +}); + +// 1. Successful retrieval +gpii.tests.repositorySolutionsLoader.success = { + nockConfig: { + url: gpii.tests.repositorySolutionsLoader.hostname + gpii.tests.repositorySolutionsLoader.path, + type: "get", + status: 200, + response: gpii.tests.repositorySolutionsLoader.solutions + } +}; + +fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { + gradeNames: "fluid.test.testCaseHolder", + modules: [{ + name: "Repository solutions loader module tests - successful retrieval", + expect: 1, + tests: [{ + name: "Response: solutions loaded", + sequence: [{ + task: "{repositorySolutionsLoader}.getSolutions", + resolve: "jqUnit.assertDeepEq", + resolveArgs: [ + "The response is the expected solutions", + gpii.tests.repositorySolutionsLoader.success.nockConfig.response, + "{arguments}.0" + ] + }] + }] + }] +}); + +fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.success", { + gradeNames: ["gpii.tests.repositorySolutionsLoaderTests", "gpii.test.testWithNock"], + testCaseHolderGrade: "gpii.tests.repositorySolutionsLoader.testCaseHolder.success", + invokers: { + setUpNock: { + funcName: "gpii.tests.repositorySolutionsLoader.setUpNock", + args: gpii.tests.repositorySolutionsLoader.success.nockConfig + } + } +}); + +// 2. Retrieval of malformed or missing revision +gpii.tests.repositorySolutionsLoader.missingRevision = { + nockConfig: { + url: gpii.tests.repositorySolutionsLoader.hostname + gpii.tests.repositorySolutionsLoader.path, + type: "get", + status: 404, + response: { + isError: true, + statusCode: 404, + message: "Error retrieving full git revision: Missing revision value" + } + }, + expected: { + isError: true, + statusCode: 404, + // FIXME: Find out where in nock "while executing HTTP GET on url http://gpii.net/revision" + // is coming from, and get rid of it. + message: "Error retrieving full git revision: Missing revision value while executing HTTP GET on url http://gpii.net/revision" + } +}; + +fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevision", { + gradeNames: "fluid.test.testCaseHolder", + modules: [{ + name: "Revision requester module tests - missing revision", + expect: 1, + tests: [{ + name: "Response: missing revision", + sequence: [{ + task: "{repositorySolutionsLoader}.getRevision", + resolve: "jqUnit.assertDeepEq", + resolveArgs: [ + "The response is expected as missing", + gpii.tests.repositorySolutionsLoader.missingRevision.expected, + "{arguments}.0" + ] + }] + }] + }] +}); + +fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingRevision", { + gradeNames: ["gpii.tests.repositorySolutionsLoaderTests", "gpii.test.testWithNock"], + testCaseHolderGrade: "gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevision", + invokers: { + setUpNock: { + funcName: "gpii.tests.repositorySolutionsLoader.setUpNock", + args: gpii.tests.repositorySolutionsLoader.missingRevision.nockConfig + } + } +}); + +// Run all tests +fluid.test.runTests([ + "gpii.tests.repositorySolutionsLoaderTests.success"/*, + "gpii.tests.repositorySolutionsLoaderTests.missingRevision"*/ +]); diff --git a/gpii/node_modules/flowManager/test/data/darwin.json5 b/gpii/node_modules/flowManager/test/data/darwin.json5 new file mode 100644 index 000000000..edf23e1bd --- /dev/null +++ b/gpii/node_modules/flowManager/test/data/darwin.json5 @@ -0,0 +1,119 @@ +{ + "fakemag1": { + "name": "Fake Magnifier 1", + "contexts": { + "OS": [ + { + "id": "darwin" + } + ] + }, + "capabilities": [ + "http://registry\\.gpii\\.net/common/magnification/enabled" + ], + "settingsHandlers": { + "configuration": { + "type": "gpii.settingsHandlers.JSONSettingsHandler", + "liveness": "live", + "options": { + "filename": "/tmp/fakemag1.settings.json" + }, + "capabilitiesTransformations": { + "magnification": "http://registry\\.gpii\\.net/common/magnification" + } + } + }, + "configure": [ + "settings.configuration" + ], + "restore": [ + "settings.configuration" + ], + "start": [], + "stop": [], + "isInstalled": [ + { + "type": "gpii.deviceReporter.alwaysInstalled" + } + ] + }, + "fakemag2": { + "name": "Fake Magnifier 2 - fully featured", + "contexts": { + "OS": [ + { + "id": "darwin" + } + ] + }, + "capabilities": [ + "http://registry\\.gpii\\.net/common/magnification/enabled" + ], + "settingsHandlers": { + "configuration": { + "type": "gpii.settingsHandlers.JSONSettingsHandler", + "liveness": "live", + "options": { + "filename": "/tmp/fakemag2.settings.json" + }, + "capabilitiesTransformations": { + "magnification": "http://registry\\.gpii\\.net/common/magnification", + "invert": "http://registry\\.gpii\\.net/common/invertColours" + } + } + }, + "configure": [ + "settings.configuration" + ], + "restore": [ + "settings.configuration" + ], + "start": [], + "stop": [], + "isInstalled": [ + { + "type": "gpii.deviceReporter.alwaysInstalled" + } + ] + }, + "fakescreenreader1": { + "name": "fake screenreader", + "contexts": { + "OS": [ + { + "id": "darwin" + } + ] + }, + "capabilities": [ + "http://registry\\.gpii\\.net/common/screenReaderTTS/enabled" + ], + "settingsHandlers": { + "configuration": { + "type": "gpii.settingsHandlers.JSONSettingsHandler", + "liveness": "live", + "options": { + "filename": "/tmp/fakescreenreader1.json" + }, + "capabilitiesTransformations": { + "pitch": "http://registry\\.gpii\\.net/common/pitch", + "volumeTTS": "http://registry\\.gpii\\.net/common/volumeTTS", + "rate": "http://registry\\.gpii\\.net/common/speechRate" + } + } + }, + "configure": [ + "settings.configuration" + ], + "restore": [ + "settings.configuration" + ], + "start": [], + "stop": [], + "isInstalled": [ + { + "type": "gpii.deviceReporter.alwaysInstalled" + } + ] + } +} \ No newline at end of file From 76f6453a3a4bf2a2e6ce208846db215cc3e85f24 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 4 Feb 2020 16:19:43 -0500 Subject: [PATCH 10/68] GPII-4273: (GPII-4273iv) Added more tests --- .../gpii.flowManager.config.local.base.json5 | 4 +- .../flowManager/src/FlowManager.js | 9 +- .../src/RepositorySolutionsLoader.js | 53 ++++--- .../test/RepositorySolutionsLoaderTests.js | 147 +++++++++++++++--- .../flowManager/test/data/darwin.json5 | 2 +- 5 files changed, 163 insertions(+), 52 deletions(-) diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index 07d1aa108..aa62f60d0 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -17,7 +17,9 @@ "flowManager.local.solutionsRegistryRepositorySuffix": { "record": "/testData/solutions", "target": "{that flowManager repositorySolutionsLoader}.options.urlSuffix" - } + }, + "flowManager.local.solutionsRegistryFolder": { + } }, "mergeConfigs": [ diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 618e78bde..cbce23265 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -382,16 +382,13 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { * solutionRegistryDataSource URL. If there is an error, the URL left undefined. */ gpii.flowManager.local.computeSolutionRegistryUrl = function (that) { - debugger; var revisionPromise = that.gpiiRevisionRequester.getRevision(); revisionPromise.then(function (revision) { if (!revision.isError) { - debugger; var platform = that.deviceReporter.platformReporter.reportPlatform(); - that.repositorySolutionsLoader.gpiiRevision = revision.sha256; - that.repositorySolutionsLoader.fileName = platform.id + ".json5"; - debugger; - return that.repositorySolutionsLoader.getSolutions(); + var gpiiRevision = revision.sha256; + var fileName = platform.id + ".json5"; + return that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName); } }); return revisionPromise; diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 1fd018c58..089b07ca8 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -36,19 +36,16 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { revision: "%directRevision", fileName: "%directFileName" }, - // prefix and suffix are distributed from a config file such as - // e.g., gpii.flowManager.config.local + // The URL prefix and suffix are distributed from a config file such as + // e.g., gpii.flowManager.config.local.base, as is the path to the local + // folder in which to save the contents of the downloaded solutions registry + // file. urlPrefix: "", urlSuffix: "", - - folderPath: "%gpii-universal/testData/solutions/", // move to appropriate config - + solutionsRegistryfolderPath: "", members: { - // Revision and name of the solutions registry file are set by the - // local flowManger at startup; see LFM.computeSolutionsRegistryURL() - gpiiRevision: "", - fileName: "", - + // Contents of the solutions registry file downloaded from the source + // code repository solutionsRegistry: null }, components: { @@ -59,7 +56,8 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { invokers: { getSolutions: { funcName: "gpii.flowManager.repositorySolutionsLoader.getSolutions", - args: ["{that}"] + args: ["{that}", "{arguments}.0", "{arguments}.1"] + // gpii revision, base file name }, saveToDisk: { funcName: "gpii.flowManager.repositorySolutionsLoader.saveToDisk", @@ -71,26 +69,31 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { /** * Retrieve the solutions registry JSON file from the source code repository. - * @param {Component} that - An instance of gpii.flowManager.repositorySolutionsLoader. + * @param {Component} that - An instance of gpii.flowManager.repositorySolutionsLoader: + * @param {Component} that.solutionsRegistry - The contents of the solutions + * registry fetched from the source code repository. + * @param {String} gpiiRevision - the SHA256 revision of the repository to fetch. + * @param {String} fileName - the name of the json file containing the + * solutions registry * @return {Promise} A promise whose resolved value is eiher the solutions * registry, or, if there is an error, an object with an "isError: true" * property. */ -gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that) { +gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName) { var togo = fluid.promise(); - - if (that.gpiiRevision && that.fileName) { // need this test? + debugger; + if (gpiiRevision && fileName) { debugger; var solutionsPromise = that.get({ - directRevision: that.gpiiRevision, - directFileName: that.fileName + directRevision: gpiiRevision, + directFileName: fileName }); solutionsPromise.then(function (solutions) { debugger; - that.solutionsRegistry = solutions; // write out the file? + that.solutionsRegistry = solutions; fluid.promise.follow(solutionsPromise, togo); - var actualPath = fluid.module.resolvePath(that.options.folderPath); - that.saveToDisk(solutions, actualPath, that.fileName); + var actualPath = fluid.module.resolvePath(that.options.solutionsRegistryfolderPath); + that.saveToDisk(solutions, actualPath, fileName); }, function (err) { debugger; fluid.log( @@ -99,11 +102,11 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that) { togo.resolve(err); }); } else { - var msg = "Error retrieving solutions from repository: missing " - if (!that.gpiiRevision && !that.fileName) { + var msg = "Error retrieving solutions from repository: missing "; + if (!gpiiRevision && !fileName) { msg += "revision and file name"; } - else if (!that.gpiiRevision) { + else if (!gpiiRevision) { msg += "revision"; } else { @@ -130,7 +133,7 @@ gpii.flowManager.repositorySolutionsLoader.saveToDisk = function (solutions, pat } else { debugger; fileName = "foo" + fileName; - fs.writeFileSync(path + fileName, JSON.stringify(solutions, null, 4)); + var fileContents = JSON.stringify(solutions, null, 4) + "\n"; + fs.writeFileSync(path + fileName, fileContents); } }; - diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js index 9f151cc3a..a7db72b33 100644 --- a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -25,7 +25,7 @@ kettle.loadTestingSupport(); fluid.registerNamespace("gpii.tests.repositorySolutionsLoader"); gpii.tests.repositorySolutionsLoader.hostname = "http://gpii.net"; -gpii.tests.repositorySolutionsLoader.prefix = "prefix", +gpii.tests.repositorySolutionsLoader.prefix = "prefix"; gpii.tests.repositorySolutionsLoader.revision = "32759c38f9e1a5a38072f8c5e60b02a5d20969d7"; gpii.tests.repositorySolutionsLoader.suffix = "suffix"; gpii.tests.repositorySolutionsLoader.fileName = "darwin.json5"; @@ -35,20 +35,20 @@ gpii.tests.repositorySolutionsLoader.path = "/" + gpii.tests.repositorySolutionsLoader.suffix + "/" + gpii.tests.repositorySolutionsLoader.fileName; -gpii.tests.repositorySolutionsLoader.folderPath = "%flowManager/test/data/" +gpii.tests.repositorySolutionsLoader.solutionsRegistryfolderPath = "%flowManager/test/data/"; gpii.tests.repositorySolutionsLoader.solutions = fluid.require( - gpii.tests.repositorySolutionsLoader.folderPath + + gpii.tests.repositorySolutionsLoader.solutionsRegistryfolderPath + gpii.tests.repositorySolutionsLoader.fileName ); // Set up mock cloud request/response gpii.tests.repositorySolutionsLoader.setUpNock = function (config) { - debugger; + var cloudMock = nock(gpii.tests.repositorySolutionsLoader.hostname); cloudMock.log(console.log); // mock GET request - var foo = cloudMock.get(gpii.tests.repositorySolutionsLoader.path) + cloudMock.get(gpii.tests.repositorySolutionsLoader.path) .reply(config.status, config.response); }; @@ -57,11 +57,7 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader", { gradeNames: ["gpii.flowManager.repositorySolutionsLoader"], urlPrefix: "http://gpii.net/" + gpii.tests.repositorySolutionsLoader.prefix, urlSuffix: gpii.tests.repositorySolutionsLoader.suffix, - folderPath: gpii.tests.repositorySolutionsLoader.folderPath, - members: { - gpiiRevision: gpii.tests.repositorySolutionsLoader.revision, - fileName: gpii.tests.repositorySolutionsLoader.fileName - } + solutionsRegistryfolderPath: gpii.tests.repositorySolutionsLoader.solutionsRegistryfolderPath }); // Base testEnvironment @@ -103,6 +99,10 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { name: "Response: solutions loaded", sequence: [{ task: "{repositorySolutionsLoader}.getSolutions", + args: [ + gpii.tests.repositorySolutionsLoader.revision, + gpii.tests.repositorySolutionsLoader.fileName + ], resolve: "jqUnit.assertDeepEq", resolveArgs: [ "The response is the expected solutions", @@ -125,7 +125,7 @@ fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.success", { } }); -// 2. Retrieval of malformed or missing revision +// 2. Failure due to missing revision gpii.tests.repositorySolutionsLoader.missingRevision = { nockConfig: { url: gpii.tests.repositorySolutionsLoader.hostname + gpii.tests.repositorySolutionsLoader.path, @@ -134,15 +134,13 @@ gpii.tests.repositorySolutionsLoader.missingRevision = { response: { isError: true, statusCode: 404, - message: "Error retrieving full git revision: Missing revision value" + message: "Error retrieving solutions from repository: missing revision" } }, expected: { isError: true, statusCode: 404, - // FIXME: Find out where in nock "while executing HTTP GET on url http://gpii.net/revision" - // is coming from, and get rid of it. - message: "Error retrieving full git revision: Missing revision value while executing HTTP GET on url http://gpii.net/revision" + message: "Error retrieving solutions from repository: missing revision" } }; @@ -154,10 +152,14 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevis tests: [{ name: "Response: missing revision", sequence: [{ - task: "{repositorySolutionsLoader}.getRevision", + task: "{repositorySolutionsLoader}.getSolutions", + args: [ + null, + gpii.tests.repositorySolutionsLoader.fileName + ], resolve: "jqUnit.assertDeepEq", resolveArgs: [ - "The response is expected as missing", + "The revision is expected as missing", gpii.tests.repositorySolutionsLoader.missingRevision.expected, "{arguments}.0" ] @@ -177,8 +179,115 @@ fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingRevision", { } }); +// 3. Failure due to missing file name +gpii.tests.repositorySolutionsLoader.missingFileName = { + nockConfig: { + url: gpii.tests.repositorySolutionsLoader.hostname + gpii.tests.repositorySolutionsLoader.path, + type: "get", + status: 404, + response: { + isError: true, + statusCode: 404, + message: "Error retrieving solutions from repository: missing file name" + } + }, + expected: { + isError: true, + statusCode: 404, + message: "Error retrieving solutions from repository: missing file name" + } +}; + +fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingFileName", { + gradeNames: "fluid.test.testCaseHolder", + modules: [{ + name: "Revision requester module tests - missing file name", + expect: 1, + tests: [{ + name: "Response: missing revision", + sequence: [{ + task: "{repositorySolutionsLoader}.getSolutions", + args: [ + gpii.tests.repositorySolutionsLoader.revision, + null + ], + resolve: "jqUnit.assertDeepEq", + resolveArgs: [ + "The file naem is expected as missing", + gpii.tests.repositorySolutionsLoader.missingFileName.expected, + "{arguments}.0" + ] + }] + }] + }] +}); + +fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingFileName", { + gradeNames: ["gpii.tests.repositorySolutionsLoaderTests", "gpii.test.testWithNock"], + testCaseHolderGrade: "gpii.tests.repositorySolutionsLoader.testCaseHolder.missingFileName", + invokers: { + setUpNock: { + funcName: "gpii.tests.repositorySolutionsLoader.setUpNock", + args: gpii.tests.repositorySolutionsLoader.missingFileName.nockConfig + } + } +}); + +// 4. Failure due to missing revision and file name +gpii.tests.repositorySolutionsLoader.missingRevisionAndFileName = { + nockConfig: { + url: gpii.tests.repositorySolutionsLoader.hostname + gpii.tests.repositorySolutionsLoader.path, + type: "get", + status: 404, + response: { + isError: true, + statusCode: 404, + message: "Error retrieving solutions from repository: missing revision and file name" + } + }, + expected: { + isError: true, + statusCode: 404, + message: "Error retrieving solutions from repository: missing revision and file name" + } +}; + +fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevisionAndFileName", { + gradeNames: "fluid.test.testCaseHolder", + modules: [{ + name: "Revision requester module tests - missing revision and file name", + expect: 1, + tests: [{ + name: "Response: missing revision and file name", + sequence: [{ + task: "{repositorySolutionsLoader}.getSolutions", + args: [null, null], + resolve: "jqUnit.assertDeepEq", + resolveArgs: [ + "The revision and file name are expected as missing", + gpii.tests.repositorySolutionsLoader.missingRevisionAndFileName.expected, + "{arguments}.0" + ] + }] + }] + }] +}); + +fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingRevisionAndFileName", { + gradeNames: ["gpii.tests.repositorySolutionsLoaderTests", "gpii.test.testWithNock"], + testCaseHolderGrade: "gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevisionAndFileName", + invokers: { + setUpNock: { + funcName: "gpii.tests.repositorySolutionsLoader.setUpNock", + args: gpii.tests.repositorySolutionsLoader.missingRevisionAndFileName.nockConfig + } + } +}); + // Run all tests fluid.test.runTests([ - "gpii.tests.repositorySolutionsLoaderTests.success"/*, - "gpii.tests.repositorySolutionsLoaderTests.missingRevision"*/ + "gpii.tests.repositorySolutionsLoaderTests.success", + "gpii.tests.repositorySolutionsLoaderTests.missingRevision", + "gpii.tests.repositorySolutionsLoaderTests.missingFileName", + "gpii.tests.repositorySolutionsLoaderTests.missingRevisionAndFileName" ]); diff --git a/gpii/node_modules/flowManager/test/data/darwin.json5 b/gpii/node_modules/flowManager/test/data/darwin.json5 index edf23e1bd..7bd475de8 100644 --- a/gpii/node_modules/flowManager/test/data/darwin.json5 +++ b/gpii/node_modules/flowManager/test/data/darwin.json5 @@ -116,4 +116,4 @@ } ] } -} \ No newline at end of file +} From 9066f8f8113451c87a938663875e48de2a46775d Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 4 Feb 2020 17:00:18 -0500 Subject: [PATCH 11/68] GPII-4273: (GPII-4273iv) Fixed config file error, and typo in options member --- .../configs/gpii.flowManager.config.local.base.json5 | 4 +++- .../flowManager/src/RepositorySolutionsLoader.js | 4 ++-- .../flowManager/test/RepositorySolutionsLoaderTests.js | 6 +++--- 3 files changed, 8 insertions(+), 6 deletions(-) diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index aa62f60d0..7cb03c7a9 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -19,7 +19,9 @@ "target": "{that flowManager repositorySolutionsLoader}.options.urlSuffix" }, "flowManager.local.solutionsRegistryFolder": { - + "record": "%gpii-universal/testData/solutions", + "target": "{that flowManager repositorySolutionsLoader}.options.solutionsRegistryFolderPath" + } } }, "mergeConfigs": [ diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 089b07ca8..2260f418f 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -42,7 +42,7 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { // file. urlPrefix: "", urlSuffix: "", - solutionsRegistryfolderPath: "", + solutionsRegistryFolderPath: "", members: { // Contents of the solutions registry file downloaded from the source // code repository @@ -92,7 +92,7 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe debugger; that.solutionsRegistry = solutions; fluid.promise.follow(solutionsPromise, togo); - var actualPath = fluid.module.resolvePath(that.options.solutionsRegistryfolderPath); + var actualPath = fluid.module.resolvePath(that.options.solutionsRegistryFolderPath); that.saveToDisk(solutions, actualPath, fileName); }, function (err) { debugger; diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js index a7db72b33..875ea2238 100644 --- a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -35,9 +35,9 @@ gpii.tests.repositorySolutionsLoader.path = "/" + gpii.tests.repositorySolutionsLoader.suffix + "/" + gpii.tests.repositorySolutionsLoader.fileName; -gpii.tests.repositorySolutionsLoader.solutionsRegistryfolderPath = "%flowManager/test/data/"; +gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath = "%flowManager/test/data/"; gpii.tests.repositorySolutionsLoader.solutions = fluid.require( - gpii.tests.repositorySolutionsLoader.solutionsRegistryfolderPath + + gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath + gpii.tests.repositorySolutionsLoader.fileName ); @@ -57,7 +57,7 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader", { gradeNames: ["gpii.flowManager.repositorySolutionsLoader"], urlPrefix: "http://gpii.net/" + gpii.tests.repositorySolutionsLoader.prefix, urlSuffix: gpii.tests.repositorySolutionsLoader.suffix, - solutionsRegistryfolderPath: gpii.tests.repositorySolutionsLoader.solutionsRegistryfolderPath + solutionsRegistryFolderPath: gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath }); // Base testEnvironment From c47f65a31c8232945b41128dbb52746ac5fd3665 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 5 Feb 2020 10:44:24 -0500 Subject: [PATCH 12/68] GPII-4273: (GPII-4273iv) Added latest tests to "all-tests.js" --- tests/all-tests.js | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/all-tests.js b/tests/all-tests.js index 673cc631a..4fecccb19 100644 --- a/tests/all-tests.js +++ b/tests/all-tests.js @@ -63,6 +63,7 @@ var testIncludes = [ "../gpii/node_modules/flowManager/test/PrefsServerDataSourceTests.js", "../gpii/node_modules/flowManager/test/PSPChannelTests.js", "../gpii/node_modules/flowManager/test/SettingsDataSourceTests.js", + "../gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js", "../gpii/node_modules/gpii-db-operation/test/DbDataStoreTests.js", "../gpii/node_modules/gpii-ini-file/test/iniFileTests.js", "../gpii/node_modules/gpii-oauth2/gpii-oauth2-authz-server/test/authGrantFinderTests.js", From b07a486c155fa3d03d2e79991ac5594d7b562f6b Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 5 Feb 2020 13:38:01 -0500 Subject: [PATCH 13/68] GPII-4273: (GPII-4273iv) Added test checking writing solutions registry file --- .../src/RepositorySolutionsLoader.js | 2 +- .../test/RepositorySolutionsLoaderTests.js | 28 ++++++++++++++----- 2 files changed, 22 insertions(+), 8 deletions(-) diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 2260f418f..95bf38ba9 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -134,6 +134,6 @@ gpii.flowManager.repositorySolutionsLoader.saveToDisk = function (solutions, pat debugger; fileName = "foo" + fileName; var fileContents = JSON.stringify(solutions, null, 4) + "\n"; - fs.writeFileSync(path + fileName, fileContents); + fs.writeFileSync(path + fileName, fileContents, "utf-8"); } }; diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js index 875ea2238..b4cf323dc 100644 --- a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -15,7 +15,8 @@ https://github.com/GPII/universal/blob/master/LICENSE.txt var fluid = fluid || require("infusion"), gpii = fluid.registerNamespace("gpii"), kettle = require("kettle"), - nock = require("nock"); + nock = require("nock"), + jqUnit = require("node-jqunit"); fluid.require("%gpii-universal/gpii/node_modules/testing/src/NockUtils.js"); fluid.require("%flowManager/src/RepositorySolutionsLoader.js"); @@ -52,10 +53,19 @@ gpii.tests.repositorySolutionsLoader.setUpNock = function (config) { .reply(config.status, config.response); }; +gpii.tests.repositorySolutionsLoader.testFetchAndSave = function (testName, response, expected, path, fileName) { + // Check the response + jqUnit.assertDeepEq(testName, expected, response); + + // Check the file written + var savedSolutions = fluid.require(path + "foo" + fileName); + jqUnit.assertDeepEq("Checking file written", expected, savedSolutions); +}; + // Repository loader customized for testing fluid.defaults("gpii.tests.repositorySolutionsLoader", { gradeNames: ["gpii.flowManager.repositorySolutionsLoader"], - urlPrefix: "http://gpii.net/" + gpii.tests.repositorySolutionsLoader.prefix, + urlPrefix: gpii.tests.repositorySolutionsLoader.hostname + "/" + gpii.tests.repositorySolutionsLoader.prefix, urlSuffix: gpii.tests.repositorySolutionsLoader.suffix, solutionsRegistryFolderPath: gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath }); @@ -93,7 +103,7 @@ gpii.tests.repositorySolutionsLoader.success = { fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { gradeNames: "fluid.test.testCaseHolder", modules: [{ - name: "Repository solutions loader module tests - successful retrieval", + name: "Repository solutions loader module tests - successful retrieval and save", expect: 1, tests: [{ name: "Response: solutions loaded", @@ -103,11 +113,13 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { gpii.tests.repositorySolutionsLoader.revision, gpii.tests.repositorySolutionsLoader.fileName ], - resolve: "jqUnit.assertDeepEq", + resolve: "gpii.tests.repositorySolutionsLoader.testFetchAndSave" /*jqUnit.assertDeepEq"*/, resolveArgs: [ - "The response is the expected solutions", + "The response and written file are both the expected solutions", gpii.tests.repositorySolutionsLoader.success.nockConfig.response, - "{arguments}.0" + "{arguments}.0", + gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath, + gpii.tests.repositorySolutionsLoader.fileName ] }] }] @@ -161,7 +173,9 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevis resolveArgs: [ "The revision is expected as missing", gpii.tests.repositorySolutionsLoader.missingRevision.expected, - "{arguments}.0" + "{arguments}.0", + gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath, + gpii.tests.repositorySolutionsLoader.fileName ] }] }] From ce79b5b1517f058c90489327abc57e6047e2e854 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 5 Feb 2020 13:55:04 -0500 Subject: [PATCH 14/68] GPII-4273: (GPII-4273iv) Removed writing of local solutions registry file --- .../src/RepositorySolutionsLoader.js | 32 ------------------- .../test/RepositorySolutionsLoaderTests.js | 22 +++---------- 2 files changed, 5 insertions(+), 49 deletions(-) diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 95bf38ba9..c4a510915 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -13,7 +13,6 @@ https://github.com/GPII/universal/blob/master/LICENSE.txt "use strict"; var fluid = require("infusion"), - fs = require("fs"), gpii = fluid.registerNamespace("gpii"); require("kettle"); @@ -58,11 +57,6 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { funcName: "gpii.flowManager.repositorySolutionsLoader.getSolutions", args: ["{that}", "{arguments}.0", "{arguments}.1"] // gpii revision, base file name - }, - saveToDisk: { - funcName: "gpii.flowManager.repositorySolutionsLoader.saveToDisk", - args: ["{arguments}.0", "{arguments}.1", "{arguments}.2"] - // solutions, path to folder, file name } } }); @@ -81,21 +75,15 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { */ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName) { var togo = fluid.promise(); - debugger; if (gpiiRevision && fileName) { - debugger; var solutionsPromise = that.get({ directRevision: gpiiRevision, directFileName: fileName }); solutionsPromise.then(function (solutions) { - debugger; that.solutionsRegistry = solutions; fluid.promise.follow(solutionsPromise, togo); - var actualPath = fluid.module.resolvePath(that.options.solutionsRegistryFolderPath); - that.saveToDisk(solutions, actualPath, fileName); }, function (err) { - debugger; fluid.log( "Error retrieving solutions from repository: " + err + that.options.url ); @@ -117,23 +105,3 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe } return togo; }; - -/** - * Save the solutions registry as a local JSON5 file. If the given folder does - * not exist, the error is logged and the function returns. - * @param {Object} solutions - A set of solutions registry entries. - * @param {String} path - Full path to the folder to write to. - * @param {Stirng} fileName - Name of the file. - */ -gpii.flowManager.repositorySolutionsLoader.saveToDisk = function (solutions, path, fileName) { - if (!fs.existsSync(path)) { - debugger; - fluid.log("Folder to store solutions '", fileName, "' is missing: '" , path, "'"); - return; - } else { - debugger; - fileName = "foo" + fileName; - var fileContents = JSON.stringify(solutions, null, 4) + "\n"; - fs.writeFileSync(path + fileName, fileContents, "utf-8"); - } -}; diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js index b4cf323dc..06c715a0e 100644 --- a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -15,8 +15,7 @@ https://github.com/GPII/universal/blob/master/LICENSE.txt var fluid = fluid || require("infusion"), gpii = fluid.registerNamespace("gpii"), kettle = require("kettle"), - nock = require("nock"), - jqUnit = require("node-jqunit"); + nock = require("nock"); fluid.require("%gpii-universal/gpii/node_modules/testing/src/NockUtils.js"); fluid.require("%flowManager/src/RepositorySolutionsLoader.js"); @@ -53,15 +52,6 @@ gpii.tests.repositorySolutionsLoader.setUpNock = function (config) { .reply(config.status, config.response); }; -gpii.tests.repositorySolutionsLoader.testFetchAndSave = function (testName, response, expected, path, fileName) { - // Check the response - jqUnit.assertDeepEq(testName, expected, response); - - // Check the file written - var savedSolutions = fluid.require(path + "foo" + fileName); - jqUnit.assertDeepEq("Checking file written", expected, savedSolutions); -}; - // Repository loader customized for testing fluid.defaults("gpii.tests.repositorySolutionsLoader", { gradeNames: ["gpii.flowManager.repositorySolutionsLoader"], @@ -103,7 +93,7 @@ gpii.tests.repositorySolutionsLoader.success = { fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { gradeNames: "fluid.test.testCaseHolder", modules: [{ - name: "Repository solutions loader module tests - successful retrieval and save", + name: "Repository solutions loader module tests - successful retrieval", expect: 1, tests: [{ name: "Response: solutions loaded", @@ -113,13 +103,11 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { gpii.tests.repositorySolutionsLoader.revision, gpii.tests.repositorySolutionsLoader.fileName ], - resolve: "gpii.tests.repositorySolutionsLoader.testFetchAndSave" /*jqUnit.assertDeepEq"*/, + resolve: "jqUnit.assertDeepEq", resolveArgs: [ - "The response and written file are both the expected solutions", + "The response is the expected solutions", gpii.tests.repositorySolutionsLoader.success.nockConfig.response, - "{arguments}.0", - gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath, - gpii.tests.repositorySolutionsLoader.fileName + "{arguments}.0" ] }] }] From 2fbacf71b5b075f9281fb0ea157ceba4e42b0379 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 5 Feb 2020 16:42:23 -0500 Subject: [PATCH 15/68] GPII-4273: (GPII-4273iii) Removed cruft and improved function name --- gpii/node_modules/flowManager/src/FlowManager.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index cbce23265..2b88fae7d 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -82,10 +82,6 @@ fluid.defaults("gpii.flowManager.local", { // The "suppressHttpEndpoints" flag is to indicate whether to hide un-needed localhost http endpoints. // It is turned on in production configs. suppressHttpEndpoints: false, - // For retrieving the solutions registry from the source code repository, - // distributed from gpii.flowManager.config.local.base - solutionsRegistryRepositoryPrefix: "", - solutionsRegistryRepositorySuffix: "", members: { /* The resolved value is an object containing data for performing reset actions: { @@ -243,8 +239,8 @@ fluid.defaults("gpii.flowManager.local", { }, listeners: { "onCreate.registerInstance": "gpii.singleInstance.registerInstance", - "onCreate.computeSolutionRegistryUrl": { - funcName: "gpii.flowManager.local.computeSolutionRegistryUrl", + "onCreate.loadSolutionsFromRepository": { + funcName: "gpii.flowManager.local.loadSolutionsFromRepository", args: ["{that}"] }, "onCreate.mountWebSocketsSettingsHandler": { @@ -378,10 +374,14 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { * Retrieve the revision of the repository from the CBFM and construct the full * URL of the associated solutions registry document * @param {Component} that - An instance of gpii.flowManager.local. - * @return {Promise} - A promise: when resolved with no error, sets the LFM's + * @param {Component} that.repositorySolutionsLoader - An instance of + * gpii.flowManager.repositorySolutionsLoader that does the actual fetch. + * @return {Promise} - A promise: when resolved with no error, loads the relevant + * solutions registry file from the source code repository. It is stored + * in the respositorySolutionsLoader's solutionsRegistry member. * solutionRegistryDataSource URL. If there is an error, the URL left undefined. */ -gpii.flowManager.local.computeSolutionRegistryUrl = function (that) { +gpii.flowManager.local.loadSolutionsFromRepository = function (that) { var revisionPromise = that.gpiiRevisionRequester.getRevision(); revisionPromise.then(function (revision) { if (!revision.isError) { From 575797f807ef60121f8cab071d8dec1de86ff408 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 7 Feb 2020 13:50:23 -0500 Subject: [PATCH 16/68] GPII-4273: (GPII-4273iii) Added solutions ID to solutions registry member --- .../flowManager/src/RepositorySolutionsLoader.js | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index c4a510915..dec098149 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -13,6 +13,7 @@ https://github.com/GPII/universal/blob/master/LICENSE.txt "use strict"; var fluid = require("infusion"), + path = require("path"), gpii = fluid.registerNamespace("gpii"); require("kettle"); @@ -75,18 +76,20 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { */ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName) { var togo = fluid.promise(); + if (gpiiRevision && fileName) { var solutionsPromise = that.get({ directRevision: gpiiRevision, directFileName: fileName }); solutionsPromise.then(function (solutions) { - that.solutionsRegistry = solutions; + var registryId = path.basename(fileName, path.extname(fileName)); + var taggedRegistry = {}; + taggedRegistry[registryId] = solutions; + that.solutionsRegistry = fluid.freezeRecursive(taggedRegistry); fluid.promise.follow(solutionsPromise, togo); }, function (err) { - fluid.log( - "Error retrieving solutions from repository: " + err + that.options.url - ); + fluid.log("Error retrieving solutions from repository: ", err, ", ", that.options.url); togo.resolve(err); }); } else { From 97a9ceefa72782a0fd2984b35b46eae0f0a2fb2e Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 10 Feb 2020 14:32:34 -0500 Subject: [PATCH 17/68] GPII-4273: (GPII-4273iv) Repository solutions registry fetch part of 'flowManagerReady' interlock (debugging) --- .../flowManager/src/FlowManager.js | 38 +++++++++++++++---- .../flowManager/src/MatchMaking.js | 2 + .../src/RepositorySolutionsLoader.js | 5 ++- .../src/SolutionsRegistryDataSource.js | 5 +++ 4 files changed, 42 insertions(+), 8 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 2b88fae7d..677dced39 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -225,8 +225,10 @@ fluid.defaults("gpii.flowManager.local", { noUserLoggedIn: null, getDefaultSettingsData: null, defaultSettingsDataLoaded: null, + loadedSolutionsFromRepository: null, flowManagerReady: { events: { + "loadedSolutionsFromRepository": "loadedSolutionsFromRepository", "defaultSettingsDataLoaded": "defaultSettingsDataLoaded", "kettleReady": "{kettle.server}.events.onListen" } @@ -241,7 +243,7 @@ fluid.defaults("gpii.flowManager.local", { "onCreate.registerInstance": "gpii.singleInstance.registerInstance", "onCreate.loadSolutionsFromRepository": { funcName: "gpii.flowManager.local.loadSolutionsFromRepository", - args: ["{that}"] + args: ["{that}", "{that}.events.loadedSolutionsFromRepository"] }, "onCreate.mountWebSocketsSettingsHandler": { funcName: "gpii.flowManager.local.mountWebSocketsSettingsHandler", @@ -289,6 +291,7 @@ gpii.flowManager.local.mountWebSocketsSettingsHandler = function (webSocketsSett }; gpii.flowManager.local.noUserLoggedIn = function (lifecycleManager, noUserLoggedInEvent) { + fluid.log("TRACE: LFM flowManagerReady.loginWithNoUser listener ... START"); var promise = lifecycleManager.addToUserLogonRequestQueue({ gpiiKey: "noUser", logonState: "login" @@ -323,19 +326,21 @@ gpii.flowManager.convertDefaultSettingsToSnapshot = function (that, defaultSetti }; gpii.flowManager.local.resetAtStart = function (lifecycleManager, resetAtStart, defaultSettingsDataPromise, resetSuccessEvent, resetErrorEvent) { + fluid.log("TRACE: LFM noUserLoggedIn.resetAtStart listener ... START"); defaultSettingsDataPromise.then(function (defaultSettingsData) { var defaultSnapshot = defaultSettingsData.defaultSnapshot; if (resetAtStart && defaultSnapshot) { - fluid.log("Resetting on system startup to default settings: ", defaultSnapshot); + fluid.log("TRACE: Resetting on system startup to default settings: ", defaultSnapshot); var resetPromise = lifecycleManager.restoreSnapshot(defaultSnapshot); resetPromise.then(function () { - fluid.log("Resetting on system startup completes successfully."); + fluid.log("TRACE: Resetting on system startup completes successfully."); resetSuccessEvent.fire(); }, function (error) { - fluid.log("Resetting on system startup fails with the error: ", error); + fluid.log("TRACE: Resetting on system startup fails with the error: ", error); resetErrorEvent.fire(error); }); } else { + fluid.log("TRACE: LFM noUserLoggedIn.resetAtStart listener success ... END"); resetSuccessEvent.fire(); } }); @@ -374,21 +379,40 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { * Retrieve the revision of the repository from the CBFM and construct the full * URL of the associated solutions registry document * @param {Component} that - An instance of gpii.flowManager.local. + * @param {Component} that.gpiiRevisionRequester - An instance of + * gpii.flowManager.revisionRequester used to access the Cloudbased + * FlowManager's "/revision" endpoint. + * @param {Component} that.deviceReporter - An instance of + * gpii.deviceReporter used to for the platform information. * @param {Component} that.repositorySolutionsLoader - An instance of * gpii.flowManager.repositorySolutionsLoader that does the actual fetch. + * @param {Component} that.solutionsRegistryDataSource - An instance of + * kettle.dataSource whose fullSolutionsRegistry member will be set to the + * solutions registry fetched by the repositorySolutionsLoader, on success. + * If repositorySolutionsLoader is unsuccessful, the + * solutionsRegistryDataSource is left untouched. + * @param {Event} loadedFromRepositoryEvent - Event to fire when done loading, + * even on failure. * @return {Promise} - A promise: when resolved with no error, loads the relevant * solutions registry file from the source code repository. It is stored * in the respositorySolutionsLoader's solutionsRegistry member. - * solutionRegistryDataSource URL. If there is an error, the URL left undefined. */ -gpii.flowManager.local.loadSolutionsFromRepository = function (that) { +gpii.flowManager.local.loadSolutionsFromRepository = function (that, loadedFromRepositoryEvent) { + fluid.log("TRACE: LFM onCreate gets github revision from CBFM ... START"); var revisionPromise = that.gpiiRevisionRequester.getRevision(); revisionPromise.then(function (revision) { + fluid.log("TRACE: LFM gets github revision from CBFM ... END"); if (!revision.isError) { var platform = that.deviceReporter.platformReporter.reportPlatform(); var gpiiRevision = revision.sha256; var fileName = platform.id + ".json5"; - return that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName); + fluid.log("TRACE: LFM loads solutions registry from github ... START"); + var loadingPromise = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName); + loadingPromise.then(function () { + fluid.log("TRACE: LFM loads solutions registry from github (", that.solutionsRegistryDataSource.id, ") ... END"); + that.solutionsRegistryDataSource.fullSolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; + loadedFromRepositoryEvent.fire(); + }); } }); return revisionPromise; diff --git a/gpii/node_modules/flowManager/src/MatchMaking.js b/gpii/node_modules/flowManager/src/MatchMaking.js index c96c9b476..596580660 100644 --- a/gpii/node_modules/flowManager/src/MatchMaking.js +++ b/gpii/node_modules/flowManager/src/MatchMaking.js @@ -92,6 +92,8 @@ * is fired with the modified mmpayload. */ gpii.flowManager.getSolutions = function (solutionsRegistryDataSource, deviceContext, event, onError) { + fluid.log("TRACE: MatchMaker accessing LFM's solutionsRegistryDataSource (", solutionsRegistryDataSource.id, ")"); + var os = fluid.get(deviceContext, "OS.id"); var promise = solutionsRegistryDataSource.get({}); promise.then(function (solutions) { diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index dec098149..0108df401 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -66,7 +66,8 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { * Retrieve the solutions registry JSON file from the source code repository. * @param {Component} that - An instance of gpii.flowManager.repositorySolutionsLoader: * @param {Component} that.solutionsRegistry - The contents of the solutions - * registry fetched from the source code repository. + * registry fetched from the source code repository, set herein (will be + * `null` on failure). * @param {String} gpiiRevision - the SHA256 revision of the repository to fetch. * @param {String} fileName - the name of the json file containing the * solutions registry @@ -75,6 +76,7 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { * property. */ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName) { + fluid.log("TRACE: RepositorySolutionsLoader loads solutions registry from github ... START"); var togo = fluid.promise(); if (gpiiRevision && fileName) { @@ -83,6 +85,7 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe directFileName: fileName }); solutionsPromise.then(function (solutions) { + fluid.log("TRACE: RepositorySolutionsLoader loads solutions registry from github ... END"); var registryId = path.basename(fileName, path.extname(fileName)); var taggedRegistry = {}; taggedRegistry[registryId] = solutions; diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 1f81a4c72..9c31afd97 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -50,6 +50,7 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { // TODO: Add an invoker to reload once we are "more live". gpii.flowManager.solutionsRegistry.dataSource.loadSolutionsRegistry = function (that) { + fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... START"); if (!that.options.path) { fluid.fail("The solutionsRegistry datasource ", that, " needs a \"path\" option pointing to the solution entries folder"); } @@ -59,6 +60,7 @@ gpii.flowManager.solutionsRegistry.dataSource.loadSolutionsRegistry = function ( } that.fullSolutionsRegistry = fluid.freezeRecursive(require(url)); + fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... END"); }; /** @@ -71,9 +73,11 @@ gpii.flowManager.solutionsRegistry.dataSource.loadSolutionsRegistry = function ( * @return {Promise} A promise that will be resolved with results (see above) or rejected on error. */ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOptions) { + fluid.log("TRACE: SolutionsRegistryDataSource onCreate fetch local solutions (", that.id, ") ... START"); var promise = fluid.promise(); if (requestOptions.os) { // if "os" is defined, return only solution registry entries for that OS if (requestOptions.os in that.fullSolutionsRegistry) { + fluid.log("TRACE: SolutionsRegistryDataSource fetch local solutions (", that.id, ") ... END"); promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); } else { promise.reject({ @@ -83,6 +87,7 @@ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOp }); } } else { // if no "os" is requested, return the full solutions registry + fluid.log("TRACE: SolutionsRegistryDataSource fetch local solutions (", that.id, ")... END"); promise.resolve(that.fullSolutionsRegistry); } return promise; From b8d2743284e06471af21602ef38a791c56d2b8fe Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 10 Feb 2020 15:44:47 -0500 Subject: [PATCH 18/68] GPII-4273: (GPII-4273iv) Debugging: removing some tests --- tests/all-tests.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/all-tests.js b/tests/all-tests.js index 4fecccb19..0cd646931 100644 --- a/tests/all-tests.js +++ b/tests/all-tests.js @@ -44,7 +44,7 @@ var testIncludes = [ "./ResetAtStartTests.js", "./StartupAPITests.js", "./SuppressHttpEndpointsTests.js", - "./UntrustedBrowserChannelTests.js", +// "./UntrustedBrowserChannelTests.js", "./UntrustedDevelopmentTests.js", "./UntrustedPSPIntegrationTests.js", "./UntrustedResetAtStartTests.js", @@ -58,7 +58,7 @@ var testIncludes = [ "../gpii/node_modules/deviceReporter/test/StaticDeviceReporterTests.js", "../gpii/node_modules/eventLog/test/all-tests.js", "../gpii/node_modules/flatMatchMaker/test/FlatMatchMakerTests.js", - "../gpii/node_modules/flowManager/test/BrowserChannelTests.js", +// "../gpii/node_modules/flowManager/test/BrowserChannelTests.js", "../gpii/node_modules/flowManager/test/DefaultSettingsLoaderTests.js", "../gpii/node_modules/flowManager/test/PrefsServerDataSourceTests.js", "../gpii/node_modules/flowManager/test/PSPChannelTests.js", From 013ccfc28a92a7eddbba4f5822d9b68f25607608 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 11 Feb 2020 16:08:03 -0500 Subject: [PATCH 19/68] GPII-4273: (GPII-4273iv) Handles failure to fetch repository solutions registry --- .../flowManager/src/FlowManager.js | 20 +++++++++++-------- .../src/RepositorySolutionsLoader.js | 1 + .../test/RepositorySolutionsLoaderTests.js | 3 ++- 3 files changed, 15 insertions(+), 9 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 677dced39..0802b7b70 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -228,9 +228,9 @@ fluid.defaults("gpii.flowManager.local", { loadedSolutionsFromRepository: null, flowManagerReady: { events: { - "loadedSolutionsFromRepository": "loadedSolutionsFromRepository", "defaultSettingsDataLoaded": "defaultSettingsDataLoaded", - "kettleReady": "{kettle.server}.events.onListen" + "kettleReady": "{kettle.server}.events.onListen", + "loadedSolutionsFromRepository": "loadedSolutionsFromRepository" } }, // Fired only when: @@ -241,15 +241,10 @@ fluid.defaults("gpii.flowManager.local", { }, listeners: { "onCreate.registerInstance": "gpii.singleInstance.registerInstance", - "onCreate.loadSolutionsFromRepository": { - funcName: "gpii.flowManager.local.loadSolutionsFromRepository", - args: ["{that}", "{that}.events.loadedSolutionsFromRepository"] - }, "onCreate.mountWebSocketsSettingsHandler": { funcName: "gpii.flowManager.local.mountWebSocketsSettingsHandler", args: ["{webSocketsSettingsHandlerComponent}"] }, - // Fire "getDefaultSettingsData" event to trigger promise transform chain that does: // 1. Read default settings from the reset to default file; // 2. Calculate defaultLifecycleInstructions and defaultSnapshot based on the default settings; @@ -260,6 +255,10 @@ fluid.defaults("gpii.flowManager.local", { listener: "fluid.promise.fireTransformEvent", args: ["{that}.events.getDefaultSettingsData"] }, + "onCreate.loadSolutionsFromRepository": { + funcName: "gpii.flowManager.local.loadSolutionsFromRepository", + args: ["{that}", "{that}.events.loadedSolutionsFromRepository"] + }, "getDefaultSettingsData.loadDefaultSettngs": { listener: "{defaultSettingsLoader}.get", priority: "first" @@ -410,7 +409,12 @@ gpii.flowManager.local.loadSolutionsFromRepository = function (that, loadedFromR var loadingPromise = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName); loadingPromise.then(function () { fluid.log("TRACE: LFM loads solutions registry from github (", that.solutionsRegistryDataSource.id, ") ... END"); - that.solutionsRegistryDataSource.fullSolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; + // If the repository's solutions registry was loaded + // successfully, use it. Otherwise use the older technique of + // loading from the local hard drive. + if (that.repositorySolutionsLoader.solutionsRegistry !== null) { + that.solutionsRegistryDataSource.fullSolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; + } loadedFromRepositoryEvent.fire(); }); } diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 0108df401..6aae05580 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -43,6 +43,7 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { urlPrefix: "", urlSuffix: "", solutionsRegistryFolderPath: "", + protocol: "https:", // default members: { // Contents of the solutions registry file downloaded from the source // code repository diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js index 06c715a0e..3942cf75e 100644 --- a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -57,7 +57,8 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader", { gradeNames: ["gpii.flowManager.repositorySolutionsLoader"], urlPrefix: gpii.tests.repositorySolutionsLoader.hostname + "/" + gpii.tests.repositorySolutionsLoader.prefix, urlSuffix: gpii.tests.repositorySolutionsLoader.suffix, - solutionsRegistryFolderPath: gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath + solutionsRegistryFolderPath: gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath, + protocol: "http:" }); // Base testEnvironment From d99c9366bb0cc325ea46183fcbe40ab607808d7e Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 11 Feb 2020 16:37:37 -0500 Subject: [PATCH 20/68] GPII-4273: (GPII-4273iv) Debugging: putting tests back Browser channel tests configured to defeat loading solutions registry from the repository so as to use the canned solutions registry defined specifically for the tests. --- ...gpii.flowManager.tests.browserChannel.config.json5 | 6 ++++++ .../flowManager/test/shared/BrowserChannelTestDefs.js | 11 +++++++++++ tests/all-tests.js | 4 ++-- ...s.acceptance.untrusted.browserChannel.config.json5 | 6 ++++++ 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 index fee8f3f4c..5028946e7 100644 --- a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 +++ b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 @@ -18,6 +18,12 @@ "funcName": "gpii.tests.flowManager.browserChannel.reportPlatform" }, "target": "{that deviceReporter platformReporter}.options.invokers.reportPlatform" + }, + "browserChannel.tests.repositorySolutionsLoader": { + "record": { + "funcName": "gpii.tests.flowManager.browserChannel.getRepositorySolutions" + }, + "target": "{that flowManager repositorySolutionsLoader}.options.invokers.getSolutions" } } }, diff --git a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js index 398a79c9f..492f5f0db 100644 --- a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js +++ b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js @@ -53,6 +53,17 @@ gpii.tests.flowManager.browserChannel.reportPlatform = function () { }; }; +// Glorified no-op to gracefully fail fetching the solutions registry in the +// source code repository in order to use the canned registry set up for these +// tests +gpii.tests.flowManager.browserChannel.getRepositorySolutions = function (repositorySolutionsLoader) { + fluid.log("TRACE: RepositorySolutionsLoader defeating loading from repository ... END"); + var togo = fluid.promise(); + repositorySolutionsLoader.solutionsRegistry = null; + togo.resolve(repositorySolutionsLoader.solutionsRegistry); + return togo; +}; + gpii.tests.flowManager.browserChannel.checkConnectionRequest = function (data, request) { request.events.onReceiveMessage.addListener(function (message, request) { fluid.log("BrowserChannel checkConnectionRequest got onReceiveMessage ", message); diff --git a/tests/all-tests.js b/tests/all-tests.js index 0cd646931..4fecccb19 100644 --- a/tests/all-tests.js +++ b/tests/all-tests.js @@ -44,7 +44,7 @@ var testIncludes = [ "./ResetAtStartTests.js", "./StartupAPITests.js", "./SuppressHttpEndpointsTests.js", -// "./UntrustedBrowserChannelTests.js", + "./UntrustedBrowserChannelTests.js", "./UntrustedDevelopmentTests.js", "./UntrustedPSPIntegrationTests.js", "./UntrustedResetAtStartTests.js", @@ -58,7 +58,7 @@ var testIncludes = [ "../gpii/node_modules/deviceReporter/test/StaticDeviceReporterTests.js", "../gpii/node_modules/eventLog/test/all-tests.js", "../gpii/node_modules/flatMatchMaker/test/FlatMatchMakerTests.js", -// "../gpii/node_modules/flowManager/test/BrowserChannelTests.js", + "../gpii/node_modules/flowManager/test/BrowserChannelTests.js", "../gpii/node_modules/flowManager/test/DefaultSettingsLoaderTests.js", "../gpii/node_modules/flowManager/test/PrefsServerDataSourceTests.js", "../gpii/node_modules/flowManager/test/PSPChannelTests.js", diff --git a/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 b/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 index eaf5edf3e..264ab8f9a 100644 --- a/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 +++ b/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 @@ -18,6 +18,12 @@ "funcName": "gpii.tests.flowManager.browserChannel.reportPlatform" }, "target": "{that localConfig deviceReporter platformReporter}.options.invokers.reportPlatform" + }, + "browserChannel.tests.repositorySolutionsLoader": { + "record": { + "funcName": "gpii.tests.flowManager.browserChannel.getRepositorySolutions" + }, + "target": "{that flowManager repositorySolutionsLoader}.options.invokers.getSolutions" } } }, From b460d5f99a52eabb59388c16decca64544026725 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 13 Feb 2020 11:19:27 -0500 Subject: [PATCH 21/68] GPII-4273: (GPII-4273iv) Reworked flowManagerReady sequence --- .../node_modules/flowManager/src/FlowManager.js | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 0802b7b70..e1f2b720f 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -225,12 +225,10 @@ fluid.defaults("gpii.flowManager.local", { noUserLoggedIn: null, getDefaultSettingsData: null, defaultSettingsDataLoaded: null, - loadedSolutionsFromRepository: null, flowManagerReady: { events: { "defaultSettingsDataLoaded": "defaultSettingsDataLoaded", - "kettleReady": "{kettle.server}.events.onListen", - "loadedSolutionsFromRepository": "loadedSolutionsFromRepository" + "kettleReady": "{kettle.server}.events.onListen" } }, // Fired only when: @@ -245,6 +243,10 @@ fluid.defaults("gpii.flowManager.local", { funcName: "gpii.flowManager.local.mountWebSocketsSettingsHandler", args: ["{webSocketsSettingsHandlerComponent}"] }, + "onCreate.loadSolutionsFromRepository": { + funcName: "gpii.flowManager.local.loadSolutionsFromRepository", + args: ["{that}"] + }, // Fire "getDefaultSettingsData" event to trigger promise transform chain that does: // 1. Read default settings from the reset to default file; // 2. Calculate defaultLifecycleInstructions and defaultSnapshot based on the default settings; @@ -255,10 +257,6 @@ fluid.defaults("gpii.flowManager.local", { listener: "fluid.promise.fireTransformEvent", args: ["{that}.events.getDefaultSettingsData"] }, - "onCreate.loadSolutionsFromRepository": { - funcName: "gpii.flowManager.local.loadSolutionsFromRepository", - args: ["{that}", "{that}.events.loadedSolutionsFromRepository"] - }, "getDefaultSettingsData.loadDefaultSettngs": { listener: "{defaultSettingsLoader}.get", priority: "first" @@ -390,13 +388,11 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { * solutions registry fetched by the repositorySolutionsLoader, on success. * If repositorySolutionsLoader is unsuccessful, the * solutionsRegistryDataSource is left untouched. - * @param {Event} loadedFromRepositoryEvent - Event to fire when done loading, - * even on failure. * @return {Promise} - A promise: when resolved with no error, loads the relevant * solutions registry file from the source code repository. It is stored * in the respositorySolutionsLoader's solutionsRegistry member. */ -gpii.flowManager.local.loadSolutionsFromRepository = function (that, loadedFromRepositoryEvent) { +gpii.flowManager.local.loadSolutionsFromRepository = function (that) { fluid.log("TRACE: LFM onCreate gets github revision from CBFM ... START"); var revisionPromise = that.gpiiRevisionRequester.getRevision(); revisionPromise.then(function (revision) { @@ -415,7 +411,6 @@ gpii.flowManager.local.loadSolutionsFromRepository = function (that, loadedFromR if (that.repositorySolutionsLoader.solutionsRegistry !== null) { that.solutionsRegistryDataSource.fullSolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; } - loadedFromRepositoryEvent.fire(); }); } }); From 7c9763c500457b34b1e0291f58965ab7e3b98d86 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 13 Feb 2020 16:49:20 -0500 Subject: [PATCH 22/68] GPII-4273: (GPII-4273iv) Modified sequence leading up to flowManagerReady Also modified the TRACE log messages. --- .../flowManager/src/FlowManager.js | 31 +++++++++++++------ .../src/SolutionsRegistryDataSource.js | 7 ++--- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index e1f2b720f..3e7b1512c 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -243,16 +243,19 @@ fluid.defaults("gpii.flowManager.local", { funcName: "gpii.flowManager.local.mountWebSocketsSettingsHandler", args: ["{webSocketsSettingsHandlerComponent}"] }, - "onCreate.loadSolutionsFromRepository": { - funcName: "gpii.flowManager.local.loadSolutionsFromRepository", - args: ["{that}"] - }, // Fire "getDefaultSettingsData" event to trigger promise transform chain that does: // 1. Read default settings from the reset to default file; // 2. Calculate defaultLifecycleInstructions and defaultSnapshot based on the default settings; // 3. All default settings data are held in flowManager.defaultSettingsDataPromise. // Note: all of this machinery should be removed once we can update to the FLUID-6148 framework and we can // put all of this I/O into the "resources" block of a fluid.resourceLoader. + // + // Note 2: GPII-4273 - After the default settings have been converted, + // this used to trigger a "flowManagerReady.loginWithNoUser" event. With + // the potential loading of the solutions registry from the source code + // repository, that needs to happen just before the loginWithNoUser, and + // is handled via the getDefaultSettingsData.loadSolutionsFromRepository + // listener below. "onCreate.calculateDefaultSettingsData": { listener: "fluid.promise.fireTransformEvent", args: ["{that}.events.getDefaultSettingsData"] @@ -263,9 +266,14 @@ fluid.defaults("gpii.flowManager.local", { }, "getDefaultSettingsData.convertDefaultSettings": { listener: "gpii.flowManager.convertDefaultSettingsToSnapshot", - args: ["{that}", "{arguments}.0", "{that}.events.defaultSettingsDataLoaded"], + args: ["{that}", "{arguments}.0"], priority: "after:loadDefaultSettngs" }, + "getDefaultSettingsData.loadSolutionsFromRepository": { + listener: "gpii.flowManager.local.loadSolutionsFromRepository", + args: ["{that}", "{that}.events.defaultSettingsDataLoaded"], + priority: "after:convertDefaultSettings" + }, "flowManagerReady.loginWithNoUser": { listener: "gpii.flowManager.local.noUserLoggedIn", @@ -296,7 +304,7 @@ gpii.flowManager.local.noUserLoggedIn = function (lifecycleManager, noUserLogged promise.then(noUserLoggedInEvent.fire); }; -gpii.flowManager.convertDefaultSettingsToSnapshot = function (that, defaultSettings, defaultSettingsDataCreatedEvent) { +gpii.flowManager.convertDefaultSettingsToSnapshot = function (that, defaultSettings) { var promiseTogo = fluid.promise(); if (defaultSettings) { var matchMakingPromise = that.privateMatchMaker.doMatch("noUser", defaultSettings); @@ -313,11 +321,9 @@ gpii.flowManager.convertDefaultSettingsToSnapshot = function (that, defaultSetti defaultLifecycleInstructions: defaultLifecycleInstructions, defaultSnapshot: defaultSnapshot }); - defaultSettingsDataCreatedEvent.fire(); }); } else { promiseTogo.resolve({}); - defaultSettingsDataCreatedEvent.fire(); } fluid.promise.follow(promiseTogo, that.defaultSettingsDataPromise); }; @@ -388,11 +394,15 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { * solutions registry fetched by the repositorySolutionsLoader, on success. * If repositorySolutionsLoader is unsuccessful, the * solutionsRegistryDataSource is left untouched. + * @param {Event} defaultSettingsDataLoaded - Event that means that the default + * settings are configured, and that the solutions registry retrieval from + * the source code repository has been dealt with. This is fired at the + * resolution of the promise returned. * @return {Promise} - A promise: when resolved with no error, loads the relevant * solutions registry file from the source code repository. It is stored * in the respositorySolutionsLoader's solutionsRegistry member. */ -gpii.flowManager.local.loadSolutionsFromRepository = function (that) { +gpii.flowManager.local.loadSolutionsFromRepository = function (that, defaultSettingsDataLoaded) { fluid.log("TRACE: LFM onCreate gets github revision from CBFM ... START"); var revisionPromise = that.gpiiRevisionRequester.getRevision(); revisionPromise.then(function (revision) { @@ -411,7 +421,10 @@ gpii.flowManager.local.loadSolutionsFromRepository = function (that) { if (that.repositorySolutionsLoader.solutionsRegistry !== null) { that.solutionsRegistryDataSource.fullSolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; } + defaultSettingsDataLoaded.fire(); }); + } else { + defaultSettingsDataLoaded.fire(); } }); return revisionPromise; diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 9c31afd97..7b8359201 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -58,7 +58,6 @@ gpii.flowManager.solutionsRegistry.dataSource.loadSolutionsRegistry = function ( if (!fs.existsSync(url)) { fluid.fail("The path provided to the solutionsRegistry datasource (", url, ") has not been found on the file system"); } - that.fullSolutionsRegistry = fluid.freezeRecursive(require(url)); fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... END"); }; @@ -73,11 +72,11 @@ gpii.flowManager.solutionsRegistry.dataSource.loadSolutionsRegistry = function ( * @return {Promise} A promise that will be resolved with results (see above) or rejected on error. */ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOptions) { - fluid.log("TRACE: SolutionsRegistryDataSource onCreate fetch local solutions (", that.id, ") ... START"); + fluid.log("TRACE: SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); var promise = fluid.promise(); if (requestOptions.os) { // if "os" is defined, return only solution registry entries for that OS if (requestOptions.os in that.fullSolutionsRegistry) { - fluid.log("TRACE: SolutionsRegistryDataSource fetch local solutions (", that.id, ") ... END"); + fluid.log("TRACE: SolutionsRegistryDataSource return SPECIFIED solutions (", that.id, ") ... END"); promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); } else { promise.reject({ @@ -87,7 +86,7 @@ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOp }); } } else { // if no "os" is requested, return the full solutions registry - fluid.log("TRACE: SolutionsRegistryDataSource fetch local solutions (", that.id, ")... END"); + fluid.log("TRACE: SolutionsRegistryDataSource return ALL solutions (", that.id, ") ", that.fullSolutionsRegistry, "... END"); promise.resolve(that.fullSolutionsRegistry); } return promise; From c9813d654266f73f65cfecc4659d49f555309eeb Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 14 Feb 2020 15:14:50 -0500 Subject: [PATCH 23/68] GPII-4273: (GPII-4273iv) Reverted to flowManagerReady composite event that included loadedSolutionsFromRepository --- .../flowManager/src/FlowManager.js | 31 ++++++++++--------- .../src/RepositorySolutionsLoader.js | 7 +++-- .../src/SolutionsRegistryDataSource.js | 2 +- .../test/RepositorySolutionsLoaderTests.js | 10 ++++-- 4 files changed, 28 insertions(+), 22 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 3e7b1512c..eecd03cd1 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -223,10 +223,12 @@ fluid.defaults("gpii.flowManager.local", { preferencesSavedSuccess: null, preferencesSavedError: null, noUserLoggedIn: null, + loadedSolutionsFromRepository: null, getDefaultSettingsData: null, defaultSettingsDataLoaded: null, flowManagerReady: { events: { + "loadedSolutionsFromRepository": "loadedSolutionsFromRepository", "defaultSettingsDataLoaded": "defaultSettingsDataLoaded", "kettleReady": "{kettle.server}.events.onListen" } @@ -243,6 +245,10 @@ fluid.defaults("gpii.flowManager.local", { funcName: "gpii.flowManager.local.mountWebSocketsSettingsHandler", args: ["{webSocketsSettingsHandlerComponent}"] }, + "onCreate.loadSolutionsFromRepository": { + funcName: "gpii.flowManager.local.loadSolutionsFromRepository", + args: ["{that}", "{that}.events.loadedSolutionsFromRepository"] + }, // Fire "getDefaultSettingsData" event to trigger promise transform chain that does: // 1. Read default settings from the reset to default file; // 2. Calculate defaultLifecycleInstructions and defaultSnapshot based on the default settings; @@ -266,14 +272,9 @@ fluid.defaults("gpii.flowManager.local", { }, "getDefaultSettingsData.convertDefaultSettings": { listener: "gpii.flowManager.convertDefaultSettingsToSnapshot", - args: ["{that}", "{arguments}.0"], + args: ["{that}", "{arguments}.0", "{that}.events.defaultSettingsDataLoaded"], priority: "after:loadDefaultSettngs" }, - "getDefaultSettingsData.loadSolutionsFromRepository": { - listener: "gpii.flowManager.local.loadSolutionsFromRepository", - args: ["{that}", "{that}.events.defaultSettingsDataLoaded"], - priority: "after:convertDefaultSettings" - }, "flowManagerReady.loginWithNoUser": { listener: "gpii.flowManager.local.noUserLoggedIn", @@ -304,7 +305,7 @@ gpii.flowManager.local.noUserLoggedIn = function (lifecycleManager, noUserLogged promise.then(noUserLoggedInEvent.fire); }; -gpii.flowManager.convertDefaultSettingsToSnapshot = function (that, defaultSettings) { +gpii.flowManager.convertDefaultSettingsToSnapshot = function (that, defaultSettings, defaultSettingsDataCreatedEvent) { var promiseTogo = fluid.promise(); if (defaultSettings) { var matchMakingPromise = that.privateMatchMaker.doMatch("noUser", defaultSettings); @@ -321,9 +322,11 @@ gpii.flowManager.convertDefaultSettingsToSnapshot = function (that, defaultSetti defaultLifecycleInstructions: defaultLifecycleInstructions, defaultSnapshot: defaultSnapshot }); + defaultSettingsDataCreatedEvent.fire(); }); } else { promiseTogo.resolve({}); + defaultSettingsDataCreatedEvent.fire(); } fluid.promise.follow(promiseTogo, that.defaultSettingsDataPromise); }; @@ -394,15 +397,13 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { * solutions registry fetched by the repositorySolutionsLoader, on success. * If repositorySolutionsLoader is unsuccessful, the * solutionsRegistryDataSource is left untouched. - * @param {Event} defaultSettingsDataLoaded - Event that means that the default - * settings are configured, and that the solutions registry retrieval from - * the source code repository has been dealt with. This is fired at the - * resolution of the promise returned. + * @param {Event} loadedFromRepositoryEvent - Event to fire when done loading, + * even on failure. * @return {Promise} - A promise: when resolved with no error, loads the relevant * solutions registry file from the source code repository. It is stored * in the respositorySolutionsLoader's solutionsRegistry member. */ -gpii.flowManager.local.loadSolutionsFromRepository = function (that, defaultSettingsDataLoaded) { +gpii.flowManager.local.loadSolutionsFromRepository = function (that, loadedFromRepositoryEvent) { fluid.log("TRACE: LFM onCreate gets github revision from CBFM ... START"); var revisionPromise = that.gpiiRevisionRequester.getRevision(); revisionPromise.then(function (revision) { @@ -412,7 +413,7 @@ gpii.flowManager.local.loadSolutionsFromRepository = function (that, defaultSett var gpiiRevision = revision.sha256; var fileName = platform.id + ".json5"; fluid.log("TRACE: LFM loads solutions registry from github ... START"); - var loadingPromise = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName); + var loadingPromise = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName, platform.id); loadingPromise.then(function () { fluid.log("TRACE: LFM loads solutions registry from github (", that.solutionsRegistryDataSource.id, ") ... END"); // If the repository's solutions registry was loaded @@ -421,10 +422,10 @@ gpii.flowManager.local.loadSolutionsFromRepository = function (that, defaultSett if (that.repositorySolutionsLoader.solutionsRegistry !== null) { that.solutionsRegistryDataSource.fullSolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; } - defaultSettingsDataLoaded.fire(); + loadedFromRepositoryEvent.fire(); }); } else { - defaultSettingsDataLoaded.fire(); + loadedFromRepositoryEvent.fire(); } }); return revisionPromise; diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 6aae05580..9ce0373a2 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -72,11 +72,13 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { * @param {String} gpiiRevision - the SHA256 revision of the repository to fetch. * @param {String} fileName - the name of the json file containing the * solutions registry + * @param {String} platformId - the platform id for the solutions fetched, e.g., + * "win32". * @return {Promise} A promise whose resolved value is eiher the solutions * registry, or, if there is an error, an object with an "isError: true" * property. */ -gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName) { +gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName, platformId) { fluid.log("TRACE: RepositorySolutionsLoader loads solutions registry from github ... START"); var togo = fluid.promise(); @@ -87,9 +89,8 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe }); solutionsPromise.then(function (solutions) { fluid.log("TRACE: RepositorySolutionsLoader loads solutions registry from github ... END"); - var registryId = path.basename(fileName, path.extname(fileName)); var taggedRegistry = {}; - taggedRegistry[registryId] = solutions; + taggedRegistry[platformId] = solutions; that.solutionsRegistry = fluid.freezeRecursive(taggedRegistry); fluid.promise.follow(solutionsPromise, togo); }, function (err) { diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 7b8359201..2118346e7 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -76,7 +76,7 @@ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOp var promise = fluid.promise(); if (requestOptions.os) { // if "os" is defined, return only solution registry entries for that OS if (requestOptions.os in that.fullSolutionsRegistry) { - fluid.log("TRACE: SolutionsRegistryDataSource return SPECIFIED solutions (", that.id, ") ... END"); + fluid.log("TRACE: SolutionsRegistryDataSource return SPECIFIED [", requestOptions.os, "] solutions (", that.id, ") ... END"); promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); } else { promise.reject({ diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js index 3942cf75e..7dd0eadc3 100644 --- a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -28,6 +28,7 @@ gpii.tests.repositorySolutionsLoader.hostname = "http://gpii.net"; gpii.tests.repositorySolutionsLoader.prefix = "prefix"; gpii.tests.repositorySolutionsLoader.revision = "32759c38f9e1a5a38072f8c5e60b02a5d20969d7"; gpii.tests.repositorySolutionsLoader.suffix = "suffix"; +gpii.tests.repositorySolutionsLoader.platformId = "darwin"; gpii.tests.repositorySolutionsLoader.fileName = "darwin.json5"; gpii.tests.repositorySolutionsLoader.path = "/" + gpii.tests.repositorySolutionsLoader.prefix + "/" + @@ -102,7 +103,8 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { task: "{repositorySolutionsLoader}.getSolutions", args: [ gpii.tests.repositorySolutionsLoader.revision, - gpii.tests.repositorySolutionsLoader.fileName + gpii.tests.repositorySolutionsLoader.fileName, + gpii.tests.repositorySolutionsLoader.platformId ], resolve: "jqUnit.assertDeepEq", resolveArgs: [ @@ -156,7 +158,8 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevis task: "{repositorySolutionsLoader}.getSolutions", args: [ null, - gpii.tests.repositorySolutionsLoader.fileName + gpii.tests.repositorySolutionsLoader.fileName, + gpii.tests.repositorySolutionsLoader.platformId ], resolve: "jqUnit.assertDeepEq", resolveArgs: [ @@ -164,7 +167,8 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevis gpii.tests.repositorySolutionsLoader.missingRevision.expected, "{arguments}.0", gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath, - gpii.tests.repositorySolutionsLoader.fileName + gpii.tests.repositorySolutionsLoader.fileName, + gpii.tests.repositorySolutionsLoader.platformId ] }] }] From beb6da6f2fcb9393abc52b0d9839ec950702925d Mon Sep 17 00:00:00 2001 From: Cindy Qi Li Date: Thu, 20 Feb 2020 16:06:54 -0500 Subject: [PATCH 24/68] GPII-4273: Fix the failing production config test for login/logout process. --- gpii/node_modules/testing/src/RunTestDefs.js | 3 +- .../production/CloudStatusProductionTests.js | 74 ++++++------ .../production/LoginLogoutProductionTests.js | 107 ++++++++++++++++++ tests/production/all-tests.js | 1 + 4 files changed, 143 insertions(+), 42 deletions(-) create mode 100644 tests/production/LoginLogoutProductionTests.js diff --git a/gpii/node_modules/testing/src/RunTestDefs.js b/gpii/node_modules/testing/src/RunTestDefs.js index d17e5f693..eae59890b 100644 --- a/gpii/node_modules/testing/src/RunTestDefs.js +++ b/gpii/node_modules/testing/src/RunTestDefs.js @@ -88,7 +88,8 @@ gpii.test.testDefToEnvironment = function (testDef, environmentType, sequenceGra }; gpii.test.testDefToServerEnvironment = function (testDef) { - return gpii.test.testDefToEnvironment(testDef, "gpii.test.serverEnvironment", "gpii.test.standardServerSequenceGrade"); + var serverEnvironmentGrade = testDef.testEnvironmentGrade ? testDef.testEnvironmentGrade : "gpii.test.serverEnvironment"; + return gpii.test.testDefToEnvironment(testDef, serverEnvironmentGrade, "gpii.test.standardServerSequenceGrade"); }; gpii.test.testDefToCouchEnvironment = function (testDef) { diff --git a/tests/production/CloudStatusProductionTests.js b/tests/production/CloudStatusProductionTests.js index bc8e56a35..7f970dd66 100644 --- a/tests/production/CloudStatusProductionTests.js +++ b/tests/production/CloudStatusProductionTests.js @@ -1,5 +1,5 @@ /** -GPII Production Config tests +GPII Production Config tests - Cloud Status Requirements: * an internet connection @@ -10,7 +10,7 @@ Requirements: --- Copyright 2015 Raising the Floor - International -Copyright 2018, 2019 OCAD University +Copyright 2018-2020 OCAD University Licensed under the New BSD license. You may not use this file except in compliance with this License. @@ -36,7 +36,6 @@ gpii.loadTestingSupport(); fluid.registerNamespace("gpii.tests.productionConfigTesting"); -require("../shared/DevelopmentTestDefs.js"); require("./ProductionTestsUtils.js"); gpii.tests.productionConfigTesting.validGpiiRevision = require( @@ -45,43 +44,10 @@ gpii.tests.productionConfigTesting.validGpiiRevision = require( ) ); -// Flowmanager tests for: -// /user/%gpiiKey/login and /user/%gpiiKey/logout (as defined in gpii.tests.development.testDefs), +// Flowmanager tests for these http endpoints: // /health, // /ready, // /revision -gpii.tests.productionConfigTesting.testDefs = fluid.transform(gpii.tests.development.testDefs, function (testDefIn) { - var testDef = fluid.extend(true, {}, testDefIn, { - name: "Flow Manager production tests -- status, login, and logout", - config: gpii.tests.productionConfigTesting.config, - expect: 8, - components: { - healthRequest: { - type: "gpii.tests.productionConfigTesting.cloudStatusRequest", - options: { - path: "/health", - expectedPayload: {"isHealthy": true} - } - }, - readyRequest: { - type: "gpii.tests.productionConfigTesting.cloudStatusRequest", - options: { - path: "/ready", - expectedPayload: {"isReady": true} - } - }, - revisionRequest: { - type: "gpii.tests.productionConfigTesting.cloudStatusRequest", - options: { - path: "/revision", - expectedPayload: gpii.tests.productionConfigTesting.validGpiiRevision - } - } - }, - sequenceGrade: "gpii.tests.productionConfigTesting.cloudStatusSequence" - }); - return testDef; -}); fluid.defaults("gpii.tests.productionConfigTesting.cloudStatus", { gradeNames: ["fluid.test.sequenceElement"], @@ -113,12 +79,38 @@ fluid.defaults("gpii.tests.productionConfigTesting.cloudStatusSequence", { cloudStatus: { gradeNames: "gpii.tests.productionConfigTesting.cloudStatus", priority: "after:startServer" - }, - loginLogout: { - gradeNames: "gpii.tests.development.loginLogout", - priority: "after:cloudStatus" } } }); +gpii.tests.productionConfigTesting.testDefs = [{ + name: "Flow Manager production tests -- Cloud status", + config: gpii.tests.productionConfigTesting.config, + expect: 6, + components: { + healthRequest: { + type: "gpii.tests.productionConfigTesting.cloudStatusRequest", + options: { + path: "/health", + expectedPayload: {"isHealthy": true} + } + }, + readyRequest: { + type: "gpii.tests.productionConfigTesting.cloudStatusRequest", + options: { + path: "/ready", + expectedPayload: {"isReady": true} + } + }, + revisionRequest: { + type: "gpii.tests.productionConfigTesting.cloudStatusRequest", + options: { + path: "/revision", + expectedPayload: gpii.tests.productionConfigTesting.validGpiiRevision + } + } + }, + sequenceGrade: "gpii.tests.productionConfigTesting.cloudStatusSequence" +}]; + gpii.test.runServerTestDefs(gpii.tests.productionConfigTesting.testDefs); diff --git a/tests/production/LoginLogoutProductionTests.js b/tests/production/LoginLogoutProductionTests.js new file mode 100644 index 000000000..7c385b4df --- /dev/null +++ b/tests/production/LoginLogoutProductionTests.js @@ -0,0 +1,107 @@ +/** +GPII Production Config tests - Login/Logout process + +Requirements: +* an internet connection +* a cloud based flow manager +* a preferences server +* a CouchDB server + +--- + +Copyright 2015 Raising the Floor - International +Copyright 2018-2020 OCAD University + +Licensed under the New BSD license. You may not use this file except in +compliance with this License. + +The research leading to these results has received funding from the European Union's +Seventh Framework Programme (FP7/2007-2013) under grant agreement no. 289016. + +You may obtain a copy of the License at +https://github.com/GPII/universal/blob/master/LICENSE.txt + +WARNING: Do not run these tests directly. They are called from within the +"vagrantCloudBasedContainers.sh" after it has initialized the environment. +*/ + +"use strict"; + +var fluid = require("infusion"), + gpii = fluid.registerNamespace("gpii"); + +fluid.require("%gpii-universal"); + +gpii.loadTestingSupport(); + +fluid.registerNamespace("gpii.tests.productionConfigTesting"); + +require("../shared/DevelopmentTestDefs.js"); +require("./ProductionTestsUtils.js"); + +/** Flowmanager tests for the key in and key out processes: + * /user/%gpiiKey/login and /user/%gpiiKey/logout (as defined in gpii.tests.development.testDefs), + * + * Note: When Local Flow Manager starts, it now fetches Solution Registry and default settings file from remote URLs. + * This test needs to ensure the keyin/keyout test sequence starts when LFM is ready and noUser has been keyed into + * the system. To accomplish it, a special testEnvironment component is created to define an aggregate event + * "onSystemReady"that will be fired when: + * 1. The test server has been constructed; + * 2. The local flow manager initial actions have completed and is ready to process login/logout requests. + * The keyin/keyout test sequence will wait until "onSystemReady" is fired. + */ + +// The customized testEnvironment component that adds and listens to the aggregate event "onSystemReady" +fluid.defaults("gpii.tests.productionConfigTesting.testEnvironment", { + gradeNames: ["gpii.test.serverEnvironment"], + distributeOptions: { + "resetAtStartSuccess.escalate": { + record: { + resetAtStartSuccess: "{testEnvironment}.events.resetAtStartSuccess" + }, + target: "{that gpii.flowManager.local}.options.events" + }, + "productionConfigTesting.startServerSequence": { + record: [ + { // This sequence point is required because of a QUnit bug - it defers the start of sequence by 13ms "to avoid any current callbacks" in its words + func: "{testEnvironment}.events.constructServer.fire" + }, + { + event: "{testEnvironment}.events.onSystemReady", + listener: "fluid.identity" + } + ], + target: "{that gpii.test.startServerSequence}.options.sequence" + } + }, + events: { + resetAtStartSuccess: null, + onSystemReady: { + events: { + resetAtStartSuccess: "resetAtStartSuccess", + onServerReady: "onServerReady" + } + } + } +}); + +fluid.defaults("gpii.tests.productionConfigTesting.loginLogoutSequence", { + gradeNames: ["gpii.test.standardServerSequenceGrade"], + sequenceElements: { + loginLogout: { + gradeNames: "gpii.tests.development.loginLogout", + priority: "after:startServer" + } + } +}); + +gpii.tests.productionConfigTesting.keyInKeyOutTestDefs = fluid.transform(gpii.tests.development.testDefs, function (testDefIn) { + var testDef = fluid.extend(true, {}, testDefIn, { + config: gpii.tests.productionConfigTesting.config, + testEnvironmentGrade: "gpii.tests.productionConfigTesting.testEnvironment", + sequenceGrade: "gpii.tests.productionConfigTesting.loginLogoutSequence" + }); + return testDef; +}); + +gpii.test.runServerTestDefs(gpii.tests.productionConfigTesting.keyInKeyOutTestDefs); diff --git a/tests/production/all-tests.js b/tests/production/all-tests.js index a9fd06dd7..a2eafcd50 100644 --- a/tests/production/all-tests.js +++ b/tests/production/all-tests.js @@ -26,6 +26,7 @@ fluid.require("%gpii-universal", require); var testIncludes = [ "./CloudStatusProductionTests.js", + "./LoginLogoutProductionTests.js", "./SettingsGetProductionTests.js", "./SettingsPutProductionTests.js" ]; From 2fedddab07b15a35050f7687b4736c98451092b7 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 24 Feb 2020 09:48:05 -0500 Subject: [PATCH 25/68] GPII-4273: (GPII-4273iv/v) Refactored solutions registry data source --- .../gpii.flowManager.config.base.json5 | 1 - .../gpii.flowManager.config.local.base.json5 | 8 +- ...ii.flowManager.config.untrusted.base.json5 | 4 +- .../flowManager/src/FlowManager.js | 76 ++--------- .../src/RepositorySolutionsLoader.js | 2 - .../src/SolutionsRegistryDataSource.js | 119 +++++++++++++++++- ...wManager.tests.browserChannel.config.json5 | 2 +- ...ance.untrusted.browserChannel.config.json5 | 2 +- 8 files changed, 134 insertions(+), 80 deletions(-) diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.base.json5 index 30f65ca07..8e0d1b254 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.base.json5 @@ -7,7 +7,6 @@ "distributeOptions": { "flowManager.solutions": { "record": { - "type": "gpii.flowManager.solutionsRegistry.dataSource", "options": { "gradeNames": "gpii.flowManager.solutionsRegistry.dataSource.moduleTerms", "path": "%gpii-universal/testData/solutions/" diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index 7cb03c7a9..73c9e674c 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -8,19 +8,19 @@ }, "flowManager.local.gpiiRevisionCloudURL": { "record": "http://localhost:8081", - "target": "{that flowManager gpiiRevisionRequester}.options.cloudURL" + "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" }, "flowManager.local.solutionsRegistryRepositoryPrefix": { "record": "https://raw.githubusercontent.com/GPII/universal", - "target": "{that flowManager repositorySolutionsLoader}.options.urlPrefix" + "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.urlPrefix" }, "flowManager.local.solutionsRegistryRepositorySuffix": { "record": "/testData/solutions", - "target": "{that flowManager repositorySolutionsLoader}.options.urlSuffix" + "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.urlSuffix" }, "flowManager.local.solutionsRegistryFolder": { "record": "%gpii-universal/testData/solutions", - "target": "{that flowManager repositorySolutionsLoader}.options.solutionsRegistryFolderPath" + "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.solutionsRegistryFolderPath" } } }, diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 index 04e3fd86a..4695f275b 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 @@ -22,11 +22,11 @@ }, "flowManager.defaultRevisionCloudURL": { "record": "http://localhost:8084", - "target": "{that flowManager gpiiRevisionRequester}.options.cloudURL" + "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" }, "flowManager.gpiiRevisionCloudURL": { "record": "@expand:kettle.resolvers.env(GPII_CLOUD_URL)", - "target": "{that flowManager gpiiRevisionRequester}.options.cloudURL", + "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL", "priority": "after:flowManager.defaultRevisionCloudURL" } } diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index eecd03cd1..229def88d 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -28,7 +28,6 @@ require("./DefaultSettingsLoader.js"); require("./PSPChannel.js"); require("./SettingsDataSource.js"); require("./UntrustedFlowManager.js"); -require("./GpiiRevisionRequester.js"); require("./RepositorySolutionsLoader.js"); require("preferencesServer"); @@ -45,7 +44,7 @@ fluid.defaults("gpii.flowManager", { components: { // TODO: Make this use the solutions registry data source by default? solutionsRegistryDataSource: { - type: "kettle.dataSource", + type: "gpii.flowManager.solutionsRegistry.dataSource", options: { termMap: { "os": "%os", @@ -158,6 +157,14 @@ fluid.defaults("gpii.flowManager.local", { } }, components: { + solutionsRegistryDataSource: { + type: "gpii.flowManager.solutionsRegistry.dataSource.local", + options: { + events: { + solutionsRegistryReady: "{gpii.flowManager.local}.events.solutionsRegistryReady" + } + } + }, lifecycleManager: { type: "gpii.lifecycleManager", options: { @@ -195,12 +202,6 @@ fluid.defaults("gpii.flowManager.local", { }, userErrors: { type: "gpii.userErrors" - }, - gpiiRevisionRequester: { - type: "gpii.flowmanager.revisionRequester" - }, - repositorySolutionsLoader: { - type: "gpii.flowManager.repositorySolutionsLoader" } }, requestHandlers: { @@ -223,12 +224,12 @@ fluid.defaults("gpii.flowManager.local", { preferencesSavedSuccess: null, preferencesSavedError: null, noUserLoggedIn: null, - loadedSolutionsFromRepository: null, + solutionsRegistryReady: null, getDefaultSettingsData: null, defaultSettingsDataLoaded: null, flowManagerReady: { events: { - "loadedSolutionsFromRepository": "loadedSolutionsFromRepository", + "solutionsRegistryReady": "solutionsRegistryReady", "defaultSettingsDataLoaded": "defaultSettingsDataLoaded", "kettleReady": "{kettle.server}.events.onListen" } @@ -240,15 +241,12 @@ fluid.defaults("gpii.flowManager.local", { resetAtStartError: null }, listeners: { + onCreate: "fluid.log('MAKING A LOCAL FLOW MANAGER')", "onCreate.registerInstance": "gpii.singleInstance.registerInstance", "onCreate.mountWebSocketsSettingsHandler": { funcName: "gpii.flowManager.local.mountWebSocketsSettingsHandler", args: ["{webSocketsSettingsHandlerComponent}"] }, - "onCreate.loadSolutionsFromRepository": { - funcName: "gpii.flowManager.local.loadSolutionsFromRepository", - args: ["{that}", "{that}.events.loadedSolutionsFromRepository"] - }, // Fire "getDefaultSettingsData" event to trigger promise transform chain that does: // 1. Read default settings from the reset to default file; // 2. Calculate defaultLifecycleInstructions and defaultSnapshot based on the default settings; @@ -381,56 +379,6 @@ gpii.flowManager.local.savePreferences = function (that, gpiiKey, preferences) { } }; -/** - * Retrieve the revision of the repository from the CBFM and construct the full - * URL of the associated solutions registry document - * @param {Component} that - An instance of gpii.flowManager.local. - * @param {Component} that.gpiiRevisionRequester - An instance of - * gpii.flowManager.revisionRequester used to access the Cloudbased - * FlowManager's "/revision" endpoint. - * @param {Component} that.deviceReporter - An instance of - * gpii.deviceReporter used to for the platform information. - * @param {Component} that.repositorySolutionsLoader - An instance of - * gpii.flowManager.repositorySolutionsLoader that does the actual fetch. - * @param {Component} that.solutionsRegistryDataSource - An instance of - * kettle.dataSource whose fullSolutionsRegistry member will be set to the - * solutions registry fetched by the repositorySolutionsLoader, on success. - * If repositorySolutionsLoader is unsuccessful, the - * solutionsRegistryDataSource is left untouched. - * @param {Event} loadedFromRepositoryEvent - Event to fire when done loading, - * even on failure. - * @return {Promise} - A promise: when resolved with no error, loads the relevant - * solutions registry file from the source code repository. It is stored - * in the respositorySolutionsLoader's solutionsRegistry member. - */ -gpii.flowManager.local.loadSolutionsFromRepository = function (that, loadedFromRepositoryEvent) { - fluid.log("TRACE: LFM onCreate gets github revision from CBFM ... START"); - var revisionPromise = that.gpiiRevisionRequester.getRevision(); - revisionPromise.then(function (revision) { - fluid.log("TRACE: LFM gets github revision from CBFM ... END"); - if (!revision.isError) { - var platform = that.deviceReporter.platformReporter.reportPlatform(); - var gpiiRevision = revision.sha256; - var fileName = platform.id + ".json5"; - fluid.log("TRACE: LFM loads solutions registry from github ... START"); - var loadingPromise = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName, platform.id); - loadingPromise.then(function () { - fluid.log("TRACE: LFM loads solutions registry from github (", that.solutionsRegistryDataSource.id, ") ... END"); - // If the repository's solutions registry was loaded - // successfully, use it. Otherwise use the older technique of - // loading from the local hard drive. - if (that.repositorySolutionsLoader.solutionsRegistry !== null) { - that.solutionsRegistryDataSource.fullSolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; - } - loadedFromRepositoryEvent.fire(); - }); - } else { - loadedFromRepositoryEvent.fire(); - } - }); - return revisionPromise; -}; - /** * The add-on grade containing http endpoints that will be attached to the local flow manager when the * "suppressHttpEndpoints" flag is turned on. diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 9ce0373a2..5186587ae 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -13,7 +13,6 @@ https://github.com/GPII/universal/blob/master/LICENSE.txt "use strict"; var fluid = require("infusion"), - path = require("path"), gpii = fluid.registerNamespace("gpii"); require("kettle"); @@ -81,7 +80,6 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName, platformId) { fluid.log("TRACE: RepositorySolutionsLoader loads solutions registry from github ... START"); var togo = fluid.promise(); - if (gpiiRevision && fileName) { var solutionsPromise = that.get({ directRevision: gpiiRevision, diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 2118346e7..2e0cbcda3 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -18,15 +18,22 @@ var fluid = require("infusion"), gpii = fluid.registerNamespace("gpii"), - fs = require("fs"); - + fs = require("fs"), + os = require("os"); require("kettle"); +require("./GpiiRevisionRequester.js"); fluid.registerNamespace("gpii.flowManager.solutionsRegistry"); +// Solutions registry datasource used by the cloud based flow manager. It loads +// solutions only from the local file system fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { gradeNames: ["kettle.dataSource"], + termMap: { + "os": "%os", + "version": "%version" + }, components: { encoding: { type: "kettle.dataSource.encoding.none" @@ -43,13 +50,74 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { // options, directModel } }, + events: { + loadSolutions: null, + solutionsRegistryReady: null + }, + listeners: { + "onCreate.loadSolutions": { + listener: "fluid.promise.fireTransformEvent", + args: ["{that}.events.loadSolutions"] + }, + "loadSolutions.loadFromLocalDisk": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk", + args: ["{that}"], + priority: "first" + }, + "loadSolutions.solutionsLoaded": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", + args: ["{that}.events.solutionsRegistryReady"] + } + } +}); + +// Solutions registry datasource used by the local flow manager. It loads both +// solutions from the source code repository as well as the local file sysmtem. +fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { + gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource"], + platformId: os.platform(), + components: { + revisionRequester: { + type: "gpii.flowmanager.revisionRequester" + }, + repositorySolutionsLoader: { + type: "gpii.flowManager.repositorySolutionsLoader" + } + }, + members: { + repositorySolutionsRegistry: null + }, listeners: { - onCreate: "gpii.flowManager.solutionsRegistry.dataSource.loadSolutionsRegistry" + // The loadSolutions sequence inherits the relevant listeners from the + // "gpii.flowManager.solutionsRegistry.dataSource" base grade. + "onCreate.loadSolutions": { + listener: "fluid.promise.fireTransformEvent", + args: ["{that}.events.loadSolutions"] + }, + "loadSolutions.getRevision": { + listener: "{revisionRequester}.getRevision", + priority: "after:loadFromLocalDisk" + }, + "loadSolutions.loadFromRepository": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.loadFromRepository", + args: ["{that}", "{arguments}.0", "{that}.options.platformId"], + // revision + priority: "after:getRevision" + } } }); -// TODO: Add an invoker to reload once we are "more live". -gpii.flowManager.solutionsRegistry.dataSource.loadSolutionsRegistry = function (that) { +/** + * Load the solutions registry from the local file system -- the file system + * that this solutions registry data source is running on. + * + * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource. + * @param {String} that.options.path - The path to the solutions registry + * directory. + * @param {Object} that.fullSolutionsRegistry - This will be set to the + * collection of solution registries given by path. + */ +gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk = function (that) { fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... START"); if (!that.options.path) { fluid.fail("The solutionsRegistry datasource ", that, " needs a \"path\" option pointing to the solution entries folder"); @@ -92,6 +160,47 @@ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOp return promise; }; +/** + * Retrieve the solutions registry JSON file from the source code repository. + * If successful, sets the repositorySolutionsRegistry member to the fetched + * solutions registry. + * @param {Component} that - An instance of gpii.flowManager.solutionsRegistry.dataSource + * @param {Component} that.repositorySolutionsLoader - An instance of + * gpii.flowManager.repositorySolutionsLoader. + * @param {Object} that.repositorySolutionsRegistry - Set to point to the + * solutions registry retrieved from the respository, or null if + * none were retrieved. + * @param {Object} revision - the SHA256 revision of the repository in the form: + * { sha256: ... }. + * @param {String} platformId - the name of the platform, e.g., "win32". + * @return {Promise} A promise whose resolved value is eiher the solutions + * registry, or, if there is an error, an object with an "isError: true" + * property. + */ +gpii.flowManager.solutionsRegistry.dataSource.loadFromRepository = function (that, revision, platformId) { + fluid.log("TRACE: SRDS onCreate gets solutions from github ... START"); + var gpiiRevision = revision.sha256; + var fileName = platformId + ".json5"; + var togo = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName, platformId); + togo.then(function () { + // Either the repositorySolutionsLoader has retrieved the remote + // solutions registry or it is null. + that.repositorySolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; + fluid.log("TRACE: SRDS onCreate gets solutions from github ... END"); + }); + return togo; +}; + +/** + * Fire an event to indicate that the pipeline for loading the repository and + * local solutions registries has completed. + * @param {Event} solutionsRegistryReadyEvent - The event to fire. + */ +gpii.flowManager.solutionsRegistry.dataSource.finishedLoading = function (solutionsRegistryReadyEvent) { + fluid.log("TRACE: SRDS onCreate.loadSolutions ... DONE"); + solutionsRegistryReadyEvent.fire(); +}; + /** A mixin grade which automatically expands any %terms corresponding to module names registered in Infusion's module database */ // TODO: This is a duplicate of kettle.dataSource.file.moduleTerms - this should be rewritten after KETTLE-50 is resolved fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.moduleTerms", { diff --git a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 index 5028946e7..98ad3dfe6 100644 --- a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 +++ b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 @@ -23,7 +23,7 @@ "record": { "funcName": "gpii.tests.flowManager.browserChannel.getRepositorySolutions" }, - "target": "{that flowManager repositorySolutionsLoader}.options.invokers.getSolutions" + "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.invokers.getSolutions" } } }, diff --git a/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 b/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 index 264ab8f9a..49961c0a1 100644 --- a/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 +++ b/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 @@ -23,7 +23,7 @@ "record": { "funcName": "gpii.tests.flowManager.browserChannel.getRepositorySolutions" }, - "target": "{that flowManager repositorySolutionsLoader}.options.invokers.getSolutions" + "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.invokers.getSolutions" } } }, From a4e87bbe686f9695bc7f56971d54b24b30c3a81b Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 24 Feb 2020 11:17:10 -0500 Subject: [PATCH 26/68] GPII-4273: (GPII-4273iv/v) Fixed missing require --- gpii/node_modules/flowManager/src/FlowManager.js | 1 - gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 8b8ab39ae..a61e6049b 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -42,7 +42,6 @@ require("gpii-user-errors"); fluid.defaults("gpii.flowManager", { gradeNames: ["kettle.app"], components: { - // TODO: Make this use the solutions registry data source by default? solutionsRegistryDataSource: { type: "gpii.flowManager.solutionsRegistry.dataSource", options: { diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 2e0cbcda3..2816505f5 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -23,6 +23,7 @@ var fluid = require("infusion"), require("kettle"); require("./GpiiRevisionRequester.js"); +require("./RepositorySolutionsLoader.js"); fluid.registerNamespace("gpii.flowManager.solutionsRegistry"); From 9cbbc4a53eced19db62399c0ff8d08d8e399e533 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 24 Feb 2020 16:20:25 -0500 Subject: [PATCH 27/68] GPII-4273: (GPII-4273iv/v) Removed old comment --- gpii/node_modules/flowManager/src/FlowManager.js | 8 -------- 1 file changed, 8 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index a61e6049b..f5bce0cde 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -243,7 +243,6 @@ fluid.defaults("gpii.flowManager.local", { resetAtStartError: null }, listeners: { - onCreate: "fluid.log('MAKING A LOCAL FLOW MANAGER')", "onCreate.registerInstance": "gpii.singleInstance.registerInstance", "onCreate.mountWebSocketsSettingsHandler": { funcName: "gpii.flowManager.local.mountWebSocketsSettingsHandler", @@ -255,13 +254,6 @@ fluid.defaults("gpii.flowManager.local", { // 3. All default settings data are held in flowManager.defaultSettingsDataPromise. // Note: all of this machinery should be removed once we can update to the FLUID-6148 framework and we can // put all of this I/O into the "resources" block of a fluid.resourceLoader. - // - // Note 2: GPII-4273 - After the default settings have been converted, - // this used to trigger a "flowManagerReady.loginWithNoUser" event. With - // the potential loading of the solutions registry from the source code - // repository, that needs to happen just before the loginWithNoUser, and - // is handled via the getDefaultSettingsData.loadSolutionsFromRepository - // listener below. "onCreate.calculateDefaultSettingsData": { listener: "fluid.promise.fireTransformEvent", args: ["{that}.events.getDefaultSettingsData"] From 86be6bfa6fb2af3efc567c2f553c418945df46ad Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 25 Feb 2020 11:09:14 -0500 Subject: [PATCH 28/68] GPII-4273: (GPII-4273iv/v) Different getImpl() depending on type of SolutionsRegistryDataSource Also, for debugging, removed StartupAPITests.js from all-tests.js --- .../src/SolutionsRegistryDataSource.js | 47 ++++++++++++++++--- tests/all-tests.js | 2 +- 2 files changed, 42 insertions(+), 7 deletions(-) diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 2816505f5..6cc2a24ed 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -35,6 +35,7 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { "os": "%os", "version": "%version" }, + platformId: os.platform(), components: { encoding: { type: "kettle.dataSource.encoding.none" @@ -76,7 +77,6 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { // solutions from the source code repository as well as the local file sysmtem. fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource"], - platformId: os.platform(), components: { revisionRequester: { type: "gpii.flowmanager.revisionRequester" @@ -88,6 +88,12 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { members: { repositorySolutionsRegistry: null }, + invokers: { + getImpl: { + funcName: "gpii.flowManager.solutionsRegistry.dataSource.local.handle", + args: ["{that}"] + } + }, listeners: { // The loadSolutions sequence inherits the relevant listeners from the // "gpii.flowManager.solutionsRegistry.dataSource" base grade. @@ -132,13 +138,16 @@ gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk = function (that }; /** - * Handler for get requests of solutions registry. It will return either a full solution registry, - * or if an 'os' is provided in the requestOptions, only the entries for that os will be returned + * Handler for get requests of solutions registry. It will return either a full + * solution registry, or if an 'os' is provided in the requestOptions, only the + * entries for that os will be returned. * * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource. - * @param {Object} requestOptions - Currently the only request option supported is "os". If provided, - * the returned solutions registry will be filtered by OS version. - * @return {Promise} A promise that will be resolved with results (see above) or rejected on error. + * @param {Object} requestOptions - Currently the only request option supported + * is "os". If provided, the returned solutions registry will be + * filtered by OS version. + * @return {Promise} A promise that will be resolved with results (see above) or + * rejected on error. */ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOptions) { fluid.log("TRACE: SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); @@ -192,6 +201,32 @@ gpii.flowManager.solutionsRegistry.dataSource.loadFromRepository = function (tha return togo; }; +/** + * Handler for get requests of solutions registry running with the gpii-app + * client and associated with the local flow manager. The solutions registry + * returned depends on whether the repository solutions registry waa + * successfully retrieved: + * - if the solutions registry has been downloaded from the source code + * repository, return it, + * - otherwise, return the solutions as retrieved from the local file system. + * + * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource. + * @return {Promise} A promise that will be resolved with results (see above) or + * rejected on error. + */ +gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that) { + fluid.log("TRACE: LFM SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); + var promise = fluid.promise(); + if (that.repositorySolutionsRegistry) { + fluid.log("TRACE: LFM SolutionsRegistryDataSource return repository solutions (", that.id, "... END"); + promise.resolve(that.repositorySolutionsRegistry); + } else { + fluid.log("TRACE: LFM SolutionsRegistryDataSource returns local file system solutions (", that.id, ") ... END"); + promise.resolve(that.fullSolutionsRegistry[that.options.platformId]); + } + return promise; +}; + /** * Fire an event to indicate that the pipeline for loading the repository and * local solutions registries has completed. diff --git a/tests/all-tests.js b/tests/all-tests.js index feec81e3c..d98b12b37 100644 --- a/tests/all-tests.js +++ b/tests/all-tests.js @@ -42,7 +42,7 @@ var testIncludes = [ "./PayloadSizeTest.js", "./PSPIntegrationTests.js", "./ResetAtStartTests.js", - "./StartupAPITests.js", +// "./StartupAPITests.js", "./SuppressHttpEndpointsTests.js", "./UntrustedBrowserChannelTests.js", "./UntrustedDevelopmentTests.js", From afe44755c442b0f85aa8e1c5d1dc6c9a501e8402 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 25 Feb 2020 14:15:28 -0500 Subject: [PATCH 29/68] GPII-4273: (GPII-4273iv/v) Improved comments --- .../flowManager/src/SolutionsRegistryDataSource.js | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 6cc2a24ed..630297047 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -96,7 +96,9 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { }, listeners: { // The loadSolutions sequence inherits the relevant listeners from the - // "gpii.flowManager.solutionsRegistry.dataSource" base grade. + // "gpii.flowManager.solutionsRegistry.dataSource" base grade. The + // resulting sequence is: loadFromLocalDisk (base), getRevision, + // loadFromRepository, solutionsLoaded (base). "onCreate.loadSolutions": { listener: "fluid.promise.fireTransformEvent", args: ["{that}.events.loadSolutions"] @@ -106,7 +108,7 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { priority: "after:loadFromLocalDisk" }, "loadSolutions.loadFromRepository": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.loadFromRepository", + listener: "gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository", args: ["{that}", "{arguments}.0", "{that}.options.platformId"], // revision priority: "after:getRevision" @@ -187,7 +189,7 @@ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOp * registry, or, if there is an error, an object with an "isError: true" * property. */ -gpii.flowManager.solutionsRegistry.dataSource.loadFromRepository = function (that, revision, platformId) { +gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = function (that, revision, platformId) { fluid.log("TRACE: SRDS onCreate gets solutions from github ... START"); var gpiiRevision = revision.sha256; var fileName = platformId + ".json5"; From dc8e7c9ebc82eb91248a080fc4cd9313f31e7603 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 27 Feb 2020 09:18:10 -0500 Subject: [PATCH 30/68] GPII-4273: (GPII-4273iv) Incorporated Cindy's refactoring --- .../src/SolutionsRegistryDataSource.js | 167 ++++++++++-------- 1 file changed, 98 insertions(+), 69 deletions(-) diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 630297047..2c8c51d6c 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -2,6 +2,7 @@ * GPII Solutions Registry Datasource * * Copyright 2016 RtF-I + * Copyright 2020 OCAD University * * Licensed under the New BSD license. You may not use this file except in * compliance with this License. @@ -27,15 +28,14 @@ require("./RepositorySolutionsLoader.js"); fluid.registerNamespace("gpii.flowManager.solutionsRegistry"); -// Solutions registry datasource used by the cloud based flow manager. It loads -// solutions only from the local file system +// The base solutions registry data source, containing information and functions +// shared by derived grades. fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { gradeNames: ["kettle.dataSource"], termMap: { "os": "%os", "version": "%version" }, - platformId: os.platform(), components: { encoding: { type: "kettle.dataSource.encoding.none" @@ -44,12 +44,10 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { members: { fullSolutionsRegistry: null }, - readOnlyGrade: "gpii.flowManager.solutionsRegistry.dataSource", invokers: { - getImpl: { - funcName: "gpii.flowManager.solutionsRegistry.dataSource.handle", - args: ["{that}", "{arguments}.1", "{arguments}.2"] - // options, directModel + loadFromLocalDisk: { + funcName: "gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk", + args: ["{that}"] } }, events: { @@ -60,58 +58,6 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { "onCreate.loadSolutions": { listener: "fluid.promise.fireTransformEvent", args: ["{that}.events.loadSolutions"] - }, - "loadSolutions.loadFromLocalDisk": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk", - args: ["{that}"], - priority: "first" - }, - "loadSolutions.solutionsLoaded": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", - args: ["{that}.events.solutionsRegistryReady"] - } - } -}); - -// Solutions registry datasource used by the local flow manager. It loads both -// solutions from the source code repository as well as the local file sysmtem. -fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { - gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource"], - components: { - revisionRequester: { - type: "gpii.flowmanager.revisionRequester" - }, - repositorySolutionsLoader: { - type: "gpii.flowManager.repositorySolutionsLoader" - } - }, - members: { - repositorySolutionsRegistry: null - }, - invokers: { - getImpl: { - funcName: "gpii.flowManager.solutionsRegistry.dataSource.local.handle", - args: ["{that}"] - } - }, - listeners: { - // The loadSolutions sequence inherits the relevant listeners from the - // "gpii.flowManager.solutionsRegistry.dataSource" base grade. The - // resulting sequence is: loadFromLocalDisk (base), getRevision, - // loadFromRepository, solutionsLoaded (base). - "onCreate.loadSolutions": { - listener: "fluid.promise.fireTransformEvent", - args: ["{that}.events.loadSolutions"] - }, - "loadSolutions.getRevision": { - listener: "{revisionRequester}.getRevision", - priority: "after:loadFromLocalDisk" - }, - "loadSolutions.loadFromRepository": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository", - args: ["{that}", "{arguments}.0", "{that}.options.platformId"], - // revision - priority: "after:getRevision" } } }); @@ -128,6 +74,7 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { */ gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk = function (that) { fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... START"); + debugger; if (!that.options.path) { fluid.fail("The solutionsRegistry datasource ", that, " needs a \"path\" option pointing to the solution entries folder"); } @@ -139,20 +86,46 @@ gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk = function (that fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... END"); }; +// Solutions registry data source used by the Cloud Based Flow Manager +fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.cloud", { + gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource"], + readOnlyGrade: "gpii.flowManager.solutionsRegistry.dataSource.cloud", + invokers: { + getImpl: { + funcName: "gpii.flowManager.solutionsRegistry.dataSource.cloud.handle", + args: ["{that}", "{arguments}.1", "{arguments}.2"] + // options, directModel + } + }, + listeners: { + "loadSolutions.loadFromLocalDisk": { + listener: "{that}.loadFromLocalDisk", + priority: "first" + }, + "loadSolutions.solutionsLoaded": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", + args: ["{that}.events.solutionsRegistryReady"], + priority: "after:loadFromLocalDisk" + } + } +}); + /** - * Handler for get requests of solutions registry. It will return either a full - * solution registry, or if an 'os' is provided in the requestOptions, only the - * entries for that os will be returned. + * Handler for get requests to the solutions registry used by the Cloud Based + * Flow Manager. It will return either an object containing solutions registries + * for all platforms, or, if a platform is provided, only the solutions registry + * for that platform will be returned. * - * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource. + * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource.cloud * @param {Object} requestOptions - Currently the only request option supported * is "os". If provided, the returned solutions registry will be * filtered by OS version. * @return {Promise} A promise that will be resolved with results (see above) or * rejected on error. */ -gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOptions) { +gpii.flowManager.solutionsRegistry.dataSource.cloud.handle = function (that, requestOptions) { fluid.log("TRACE: SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); + debugger; var promise = fluid.promise(); if (requestOptions.os) { // if "os" is defined, return only solution registry entries for that OS if (requestOptions.os in that.fullSolutionsRegistry) { @@ -172,6 +145,52 @@ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOp return promise; }; +// Solutions registry datasource used by the Local Flow Manager. It loads both +// solutions from the source code repository as well as the local file sysmtem. +fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { + gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource"], + components: { + revisionRequester: { + type: "gpii.flowmanager.revisionRequester" + }, + repositorySolutionsLoader: { + type: "gpii.flowManager.repositorySolutionsLoader" + } + }, + platformId: os.platform(), + readOnlyGrade: "gpii.flowManager.solutionsRegistry.dataSource.local", + members: { + repositorySolutionsRegistry: null + }, + invokers: { + getImpl: { + funcName: "gpii.flowManager.solutionsRegistry.dataSource.local.handle", + args: ["{that}"] + } + }, + listeners: { + "loadSolutions.loadFromLocalDisk": { + listener: "{that}.loadFromLocalDisk", + priority: "first" + }, + "loadSolutions.getRevision": { + listener: "{revisionRequester}.getRevision", + priority: "after:loadFromLocalDisk" + }, + "loadSolutions.loadFromRepository": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository", + args: ["{that}", "{arguments}.0", "{that}.options.platformId"], + // revision + priority: "after:getRevision" + }, + "loadSolutions.solutionsLoaded": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", + args: ["{that}.events.solutionsRegistryReady"], + priority: "after:loadFromRepository" + } + } +}); + /** * Retrieve the solutions registry JSON file from the source code repository. * If successful, sets the repositorySolutionsRegistry member to the fetched @@ -191,13 +210,19 @@ gpii.flowManager.solutionsRegistry.dataSource.handle = function (that, requestOp */ gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = function (that, revision, platformId) { fluid.log("TRACE: SRDS onCreate gets solutions from github ... START"); + debugger; var gpiiRevision = revision.sha256; var fileName = platformId + ".json5"; var togo = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName, platformId); togo.then(function () { - // Either the repositorySolutionsLoader has retrieved the remote - // solutions registry or it is null. - that.repositorySolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; + // If the solutions registry has been successfully retrieved from the + // repository, replace (or add) the one in the fullSolutionsRegistry + // with it. Otherwise, leave the fullSolutionsRegistry as is. + if (that.repositorySolutionsLoader.solutionsRegistry) { + var newFullSolutions = that.fullSolutionsRegistry; + newFullSolutions[platformId] = that.repositorySolutionsLoader.solutionsRegistry; + that.fullSolutionsRegistry = fluid.freezeRecursive(newFullSolutions); + } fluid.log("TRACE: SRDS onCreate gets solutions from github ... END"); }); return togo; @@ -216,7 +241,7 @@ gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = functio * @return {Promise} A promise that will be resolved with results (see above) or * rejected on error. */ -gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that) { +gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, requestOptions) { fluid.log("TRACE: LFM SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); var promise = fluid.promise(); if (that.repositorySolutionsRegistry) { @@ -232,10 +257,14 @@ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that) { /** * Fire an event to indicate that the pipeline for loading the repository and * local solutions registries has completed. + * NOTE: (JS) This is here for debugging, and will be called directly from the + * transform event pipeline defined in the listeners block of the relevant + * solutions registry data source. * @param {Event} solutionsRegistryReadyEvent - The event to fire. */ gpii.flowManager.solutionsRegistry.dataSource.finishedLoading = function (solutionsRegistryReadyEvent) { fluid.log("TRACE: SRDS onCreate.loadSolutions ... DONE"); + debugger; solutionsRegistryReadyEvent.fire(); }; From ee2d432fcabde4dd828cc2150a19fca84c6be3c9 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 27 Feb 2020 18:00:40 -0500 Subject: [PATCH 31/68] GPII-4273: (GPII-4273iv) Modified to respect latest SolutionsRegistryDataSource grade heirarchy --- .../flowManager/src/FlowManager.js | 2 +- .../src/RepositorySolutionsLoader.js | 3 +- .../src/SolutionsRegistryDataSource.js | 97 ++++++++++++------- .../test/shared/BrowserChannelTestDefs.js | 5 +- 4 files changed, 68 insertions(+), 39 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index f5bce0cde..513eaf48e 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -43,7 +43,7 @@ fluid.defaults("gpii.flowManager", { gradeNames: ["kettle.app"], components: { solutionsRegistryDataSource: { - type: "gpii.flowManager.solutionsRegistry.dataSource", + type: "gpii.flowManager.solutionsRegistry.dataSource.cloud", options: { termMap: { "os": "%os", diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 5186587ae..cbe77bf0a 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -92,6 +92,7 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe that.solutionsRegistry = fluid.freezeRecursive(taggedRegistry); fluid.promise.follow(solutionsPromise, togo); }, function (err) { + fluid.log("TRACE: RepositorySolutionsLoader failed to download solutions registry from github ... END"); fluid.log("Error retrieving solutions from repository: ", err, ", ", that.options.url); togo.resolve(err); }); @@ -106,7 +107,7 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe else { msg += "file name"; } - fluid.log(msg); + fluid.log("TRACE: " + msg + "... END"); togo.resolve({isError: true, message: msg, statusCode: 404}); } return togo; diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 2c8c51d6c..82d957db9 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -19,8 +19,7 @@ var fluid = require("infusion"), gpii = fluid.registerNamespace("gpii"), - fs = require("fs"), - os = require("os"); + fs = require("fs"); require("kettle"); require("./GpiiRevisionRequester.js"); @@ -74,7 +73,6 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { */ gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk = function (that) { fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... START"); - debugger; if (!that.options.path) { fluid.fail("The solutionsRegistry datasource ", that, " needs a \"path\" option pointing to the solution entries folder"); } @@ -125,7 +123,6 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.cloud", { */ gpii.flowManager.solutionsRegistry.dataSource.cloud.handle = function (that, requestOptions) { fluid.log("TRACE: SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); - debugger; var promise = fluid.promise(); if (requestOptions.os) { // if "os" is defined, return only solution registry entries for that OS if (requestOptions.os in that.fullSolutionsRegistry) { @@ -155,9 +152,11 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { }, repositorySolutionsLoader: { type: "gpii.flowManager.repositorySolutionsLoader" + }, + platformReporter: { + type: "gpii.platformReporter.native" } }, - platformId: os.platform(), readOnlyGrade: "gpii.flowManager.solutionsRegistry.dataSource.local", members: { repositorySolutionsRegistry: null @@ -165,7 +164,8 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { invokers: { getImpl: { funcName: "gpii.flowManager.solutionsRegistry.dataSource.local.handle", - args: ["{that}"] + args: ["{that}", "{arguments}.1"] + // options } }, listeners: { @@ -179,7 +179,7 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { }, "loadSolutions.loadFromRepository": { listener: "gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository", - args: ["{that}", "{arguments}.0", "{that}.options.platformId"], + args: ["{that}", "{arguments}.0", "{that}.platformReporter"], // revision priority: "after:getRevision" }, @@ -203,53 +203,83 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { * none were retrieved. * @param {Object} revision - the SHA256 revision of the repository in the form: * { sha256: ... }. - * @param {String} platformId - the name of the platform, e.g., "win32". + * @param {Component} platformReporter - used to get the name of the platform, + * e.g., "win32". * @return {Promise} A promise whose resolved value is eiher the solutions * registry, or, if there is an error, an object with an "isError: true" * property. */ -gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = function (that, revision, platformId) { +gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = function (that, revision, platformReporter) { fluid.log("TRACE: SRDS onCreate gets solutions from github ... START"); - debugger; var gpiiRevision = revision.sha256; + var platformId = platformReporter.reportPlatform().id; var fileName = platformId + ".json5"; var togo = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName, platformId); togo.then(function () { - // If the solutions registry has been successfully retrieved from the - // repository, replace (or add) the one in the fullSolutionsRegistry - // with it. Otherwise, leave the fullSolutionsRegistry as is. - if (that.repositorySolutionsLoader.solutionsRegistry) { - var newFullSolutions = that.fullSolutionsRegistry; - newFullSolutions[platformId] = that.repositorySolutionsLoader.solutionsRegistry; - that.fullSolutionsRegistry = fluid.freezeRecursive(newFullSolutions); - } + // Either the solutions registry has been successfully retrieved from the + // repository, or it hasn't. Set that.repositorySolutionsRegistry to + // whatever the result. + that.repositorySolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; fluid.log("TRACE: SRDS onCreate gets solutions from github ... END"); }); return togo; }; /** - * Handler for get requests of solutions registry running with the gpii-app - * client and associated with the local flow manager. The solutions registry - * returned depends on whether the repository solutions registry waa - * successfully retrieved: - * - if the solutions registry has been downloaded from the source code - * repository, return it, - * - otherwise, return the solutions as retrieved from the local file system. - * - * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource. + * Handler for get requests when running with the gpii-app client and the Local + * Flow Manager. If a solutions registry was retrieved from the source code + * repository, it is used to mask the equivalent platform in the full set of + * solutions registries. This handler will return either an object containing + * solutions registries for all platforms, or, if a platform is provided, only + * the solutions registry for that platform will be returned. + * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource.local + instance. + * @param {Object} that.repositorySolutionsRegistry - The solutions registry + * for the client platform previously as from the repository. + * @param {Object} that.fullSolutionsRegistry - The solutions registries loaded + * from the local file system. + * @param {Object} requestOptions - Currently the only request option supported + * is "os". If provided, the returned solutions registry will be filtered + * by OS version. * @return {Promise} A promise that will be resolved with results (see above) or - * rejected on error. + * rejected on error. */ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, requestOptions) { fluid.log("TRACE: LFM SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); var promise = fluid.promise(); - if (that.repositorySolutionsRegistry) { - fluid.log("TRACE: LFM SolutionsRegistryDataSource return repository solutions (", that.id, "... END"); - promise.resolve(that.repositorySolutionsRegistry); + if (requestOptions && requestOptions.os) { + if (that.repositorySolutionsRegistry && (requestOptions.os in that.repositorySolutionsRegistry)) { + fluid.log("TRACE: LFM SolutionsRegistryDataSource with OS (", requestOptions.os, "), return repository solutions (", that.id, "... END"); + promise.resolve(that.repositorySolutionsRegistry); + } else if (requestOptions.os in that.fullSolutionsRegistry) { + fluid.log("TRACE: LFM SolutionsRegistryDataSource with OS (", requestOptions.os, "), returns local file system solutions (", that.id, ") ... END"); + promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); + } else { + fluid.log("TRACE: LFM SolutionsRegistryDataSource no such OS (", requestOptions.os, "); (", that.id, ") ... END"); + promise.reject({ + isError: true, + message: "The requested OS (" + requestOptions.os + ") was not present in the solutions registry", + statusCode: 404 + }); + } } else { - fluid.log("TRACE: LFM SolutionsRegistryDataSource returns local file system solutions (", that.id, ") ... END"); - promise.resolve(that.fullSolutionsRegistry[that.options.platformId]); + // No platform requested -- return all of the solutions registries, but + // substitute repositorySolutionsRegistry into fullSolutionsRegistry if + // available. + // NOTE: (JS) could do this substitution during the + // onCreate.loadSolutions listener pipeline, but the loadFromLocalDisk() + // invoker is public -- it could be called at any time and wipe out any + // previous substitution. + if (that.repositorySolutionsRegistry) { + fluid.log("TRACE: LFM SolutionsRegistryDataSource, returning ALL repository solutions MASKING (", that.id, ")... END"); + var fullSolutionsToReturn = fluid.copy(that.fullSolutionsRegistry); + var repoPlatform = fluid.keys(that.repositorySolutionsRegistry)[0]; + fluid.set(fullSolutionsToReturn, repoPlatform, that.repositorySolutionsRegistry[repoPlatform]); + promise.resolve(fluid.freezeRecursive(fullSolutionsToReturn)); + } else { + fluid.log("TRACE: LFM SolutionsRegistryDataSource, returning ALL repository solutions NOMASKING (", that.id, ")... END"); + promise.resolve(that.fullSolutionsRegistry); + } } return promise; }; @@ -264,7 +294,6 @@ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, req */ gpii.flowManager.solutionsRegistry.dataSource.finishedLoading = function (solutionsRegistryReadyEvent) { fluid.log("TRACE: SRDS onCreate.loadSolutions ... DONE"); - debugger; solutionsRegistryReadyEvent.fire(); }; diff --git a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js index 492f5f0db..7ac7b66c9 100644 --- a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js +++ b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js @@ -53,9 +53,8 @@ gpii.tests.flowManager.browserChannel.reportPlatform = function () { }; }; -// Glorified no-op to gracefully fail fetching the solutions registry in the -// source code repository in order to use the canned registry set up for these -// tests +// A no-op to gracefully fail fetching the solutions registry from the source +// code repository in order to use the canned registry set up for these tests. gpii.tests.flowManager.browserChannel.getRepositorySolutions = function (repositorySolutionsLoader) { fluid.log("TRACE: RepositorySolutionsLoader defeating loading from repository ... END"); var togo = fluid.promise(); From 22415f782b2b735d876f7db0408467f8b1548c82 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 2 Mar 2020 14:02:26 -0500 Subject: [PATCH 32/68] GPII-4273: (GPII-4273iv) Return the bare solutions when request is for a single platform --- .../flowManager/src/SolutionsRegistryDataSource.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 82d957db9..64be899e5 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -136,7 +136,7 @@ gpii.flowManager.solutionsRegistry.dataSource.cloud.handle = function (that, req }); } } else { // if no "os" is requested, return the full solutions registry - fluid.log("TRACE: SolutionsRegistryDataSource return ALL solutions (", that.id, ") ", that.fullSolutionsRegistry, "... END"); + fluid.log("TRACE: SolutionsRegistryDataSource return ALL solutions (", that.id, ") ... END"); promise.resolve(that.fullSolutionsRegistry); } return promise; @@ -250,7 +250,7 @@ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, req if (requestOptions && requestOptions.os) { if (that.repositorySolutionsRegistry && (requestOptions.os in that.repositorySolutionsRegistry)) { fluid.log("TRACE: LFM SolutionsRegistryDataSource with OS (", requestOptions.os, "), return repository solutions (", that.id, "... END"); - promise.resolve(that.repositorySolutionsRegistry); + promise.resolve(that.repositorySolutionsRegistry[requestOptions.os]); } else if (requestOptions.os in that.fullSolutionsRegistry) { fluid.log("TRACE: LFM SolutionsRegistryDataSource with OS (", requestOptions.os, "), returns local file system solutions (", that.id, ") ... END"); promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); From 31839fef1cf4bc9eb1fbca104cac0803e171193e Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 4 Mar 2020 14:29:42 -0500 Subject: [PATCH 33/68] GPII-4273: (GPII-4273iv) Removed tests for the startup API --- tests/StartupAPITests.js | 112 --------------------------------------- 1 file changed, 112 deletions(-) delete mode 100644 tests/StartupAPITests.js diff --git a/tests/StartupAPITests.js b/tests/StartupAPITests.js deleted file mode 100644 index 6bdd31a62..000000000 --- a/tests/StartupAPITests.js +++ /dev/null @@ -1,112 +0,0 @@ -/** -GPII Startup API Tests - -Copyright 2016 Raising the Floor - International - -Licensed under the New BSD license. You may not use this file except in -compliance with this License. - -You may obtain a copy of the License at -https://github.com/GPII/universal/blob/master/LICENSE.txt -*/ -"use strict"; - -(function () { - var fluid = require("infusion"), - kettle = fluid.registerNamespace("kettle"), - jqUnit = fluid.registerNamespace("jqUnit"), - gpii = fluid.registerNamespace("gpii"); - - fluid.require("%gpii-universal"); - - kettle.loadTestingSupport(); - - fluid.defaults("gpii.startupAPI.tests", { - gradeNames: ["fluid.test.testEnvironment"], - components: { - tester: { - type: "gpii.startupAPI.tests.testCaseHolder" - } - } - }); - - gpii.startupAPI.tests.defaultConfigName = function () { - var configs = gpii.queryConfigs(); - jqUnit.assertEquals("No Kettle Servers should be running.", configs.length, 0); - - gpii.start(); - configs = gpii.queryConfigs(); - jqUnit.assertEquals("One Kettle Server should be started on.", configs.length, 1); - jqUnit.assertEquals("Default Config should be dev all local.", configs[0].typeName, - "gpii.config.development.manualTesting"); - - gpii.stop(); - configs = gpii.queryConfigs(); - jqUnit.assertEquals("No Kettle Servers should be running.", configs.length, 0); - }; - - gpii.startupAPI.tests.customConfigName = function () { - var configs = gpii.queryConfigs(); - jqUnit.assertEquals("No Kettle Servers should be running.", configs.length, 0); - - gpii.start({ - configName: "gpii.config.development.dynamicDR.local", - configPath: "%gpii-universal/gpii/configs/shared" - }); - - configs = gpii.queryConfigs(); - jqUnit.assertEquals("One Kettle Server should be started on.", configs.length, 1); - jqUnit.assertEquals("Default Config should be dev all dr prod.", configs[0].typeName, - "gpii.config.development.dynamicDR.local"); - - gpii.stop(); - configs = gpii.queryConfigs(); - jqUnit.assertEquals("No Kettle Servers should be running.", configs.length, 0); - }; - - gpii.startupAPI.tests.configPath = function () { - var configs = gpii.queryConfigs(); - jqUnit.assertEquals("No Kettle Servers should be running.", configs.length, 0); - - gpii.start({ - configPath: "%gpii-universal/gpii/configs/shared", - configName: "gpii.config.development.local" - }); - - configs = gpii.queryConfigs(); - jqUnit.assertEquals("One Kettle Server should be started on.", configs.length, 1); - jqUnit.assertEquals("Default Config should be local install.", configs[0].typeName, - "gpii.config.development.local"); - - gpii.stop(); - configs = gpii.queryConfigs(); - jqUnit.assertEquals("No Kettle Servers should be running.", configs.length, 0); - }; - - fluid.defaults("gpii.startupAPI.tests.testCaseHolder", { - gradeNames: ["fluid.test.testCaseHolder"], - modules: [{ - name: "StartupAPITests", - tests: [ - { - expect: 4, - name: "gpii.startupAPI.tests.ConfigName - default config", - func: "gpii.startupAPI.tests.defaultConfigName" - }, - { - expect: 4, - name: "gpii.startupAPI.tests.ConfigName - custom config", - func: "gpii.startupAPI.tests.customConfigName" - }, - { - expect: 4, - name: "gpii.startupAPI.tests.configPath tests", - func: "gpii.startupAPI.tests.configPath" - } - ] - }] - }); - - module.exports = kettle.test.bootstrap("gpii.startupAPI.tests"); - -})(); From 1b15ec5b15580d42ec3f979d4e75631283ebfe33 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 5 Mar 2020 10:08:30 -0500 Subject: [PATCH 34/68] GPII-4273: (GPII-4273iv) Added tests for SolutionsRegistryDataSource --- .../test/SolutionsRegistryDataSourceTests.js | 261 ++++++++++++++++++ tests/all-tests.js | 1 + 2 files changed, 262 insertions(+) create mode 100644 gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js new file mode 100644 index 000000000..e3c8199a6 --- /dev/null +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -0,0 +1,261 @@ +/*! +GPII download and save solutions registry from source code repositoyr + +Copyright 2020 OCAD University + +Licensed under the New BSD license. You may not use this file except in +compliance with this License. + +You may obtain a copy of the License at +https://github.com/GPII/universal/blob/master/LICENSE.txt +*/ + +"use strict"; + +var fluid = fluid || require("infusion"), + kettle = require("kettle"), + jqUnit = fluid.registerNamespace("jqUnit"), + gpii = fluid.registerNamespace("gpii"); + +kettle.loadTestingSupport(); + +fluid.require("%flowManager/src/SolutionsRegistryDataSource.js"); +fluid.registerNamespace("gpii.tests.solutionsRegistry"); + +gpii.tests.solutionsRegistry = { + path: "%gpii-universal/testData/solutions", + platformIds: ["win32", "linux", "darwin", "android", "web"], + localPlatformId: "darwin", + localDarwinSolutions: require("./data/darwin.json5"), + requestOptions: { os: "darwin" } +}; + +gpii.tests.solutionsRegistry.checkAllRegistries = function (msg, platformIds, result) { + jqUnit.assertValue(msg, result); + jqUnit.assertDeepEq(msg, platformIds, fluid.keys(result)); +}; + +gpii.tests.solutionsRegistry.checkOneRegistry = function (msg, platformId, result) { + jqUnit.assertValue(msg, result); + // The platformId should be stripped out + jqUnit.assertFalse(msg, platformId in result); +}; + +gpii.tests.solutionsRegistry.checkNamedLocalRegistry = function (msg, localSolutions, result) { + jqUnit.assertValue(msg, result); + jqUnit.assertDeepEq(msg, localSolutions, result); +}; + +gpii.tests.solutionsRegistry.checkAllWithNamedRegistry = function (msg, platformIds, localPlatformId, localSolutions, result) { + gpii.tests.solutionsRegistry.checkAllRegistries(msg, platformIds, result); + jqUnit.assertDeepEq(msg, localSolutions, result[localPlatformId]); +}; + +// ======== Testing the solutions registry data source used by the CBFM ======== + +// Test solutions registry data source (CBFM) +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.cloud", { + gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource.cloud"] +}); + +fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { + gradeNames: "fluid.test.testCaseHolder", + components: { + solutionsRegistryDataSource: { + type: "gpii.tests.solutionsRegistry.dataSource.cloud", + options: { + path: gpii.tests.solutionsRegistry.path + } + } + }, + modules: [{ + name: "Solutions registry used by CBFM - file-based solutions", + expect: 2, + tests: [{ + name: "Solutions registry used with CBFM - retrieve all solutions", + sequence: [{ + task: "{solutionsRegistryDataSource}.get", + args: [{}], + resolve: "gpii.tests.solutionsRegistry.checkAllRegistries", + resolveArgs: [ + "Expecting all solutions registries", + gpii.tests.solutionsRegistry.platformIds, + "{arguments}.0" + ] + }] + }, { + name: "Solutions registry used with CBFM - retrieve one solution", + sequence: [{ + task: "{solutionsRegistryDataSource}.get", + args: [gpii.tests.solutionsRegistry.requestOptions], + resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", + resolveArgs: [ + "Expecting one solutions registry", + gpii.tests.solutionsRegistry.requestOptions.os, + "{arguments}.0" + ] + }] + }] + }] +}); + +// Test environment for CLFM solutions registry data source +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.cloud.env", { + gradeNames: ["fluid.test.testEnvironment"], + components: { + tester: { + type: "gpii.tests.solutionsRegistry.cloud.testCaseHolder" + } + } +}); + +kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.cloud.env"); + +// ======== Testing the solutions registry data source used by the LFM ======== + +// Test component for the LFM solutions registry data source mocking a load +// from the source code repository. +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.mockLoadFromRepository", { + gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource.local"], + components: { + revisionRequester: { + type: "gpii.flowmanager.revisionRequester", + options: { + cloudURL: "http://nowhere.com" + } + } + }, + listeners: { + "onCreate": { + listener: "gpii.tests.solutionsRegistry.dataSource.local.mockRepoLoad", + args: [ + "{that}", + gpii.tests.solutionsRegistry.localPlatformId, + gpii.tests.solutionsRegistry.localDarwinSolutions + ], + priority: "after:solutionsLoaded" + } + } +}); + +// Test component for the LFM solutions registry data source where it fails to +// load from the source code repository. +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.failLoadFromRepository", { + gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource.local"], + components: { + revisionRequester: { + type: "gpii.flowmanager.revisionRequester", + options: { + cloudURL: "http://nowhere.com" + } + } + }, + listeners: { + "onCreate": { + listener: "gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad", + args: ["{that}"], + priority: "after:solutionsLoaded" + } + } +}); + +fluid.defaults("gpii.tests.solutionsRegistry.local.testCaseHolder", { + gradeNames: "fluid.test.testCaseHolder", + components: { + solutionsRegistryMockRepoLoad: { + type: "gpii.tests.solutionsRegistry.dataSource.local.mockLoadFromRepository", + options: { + path: gpii.tests.solutionsRegistry.path + } + }, + solutionsRegistryNullRepoLoad: { + type: "gpii.tests.solutionsRegistry.dataSource.local.failLoadFromRepository", + options: { + path: gpii.tests.solutionsRegistry.path + } + } + }, + modules: [{ + name: "Solutions registry used by LFM - repository + file system based solutions", + expect: 2, + tests: [{ + name: "Solutions registry LFM - solutions loaded from repository and looking for named local registry", + sequence: [{ + task: "{solutionsRegistryMockRepoLoad}.get", + args: [gpii.tests.solutionsRegistry.requestOptions], + resolve: "gpii.tests.solutionsRegistry.checkNamedLocalRegistry", + resolveArgs: [ + "Expecting local named solutions registry", + gpii.tests.solutionsRegistry.localDarwinSolutions, + "{arguments}.0" + ] + }] + }, { + name: "Solutions registry used with LFM - solutions loaded from repository but looking for all registries", + sequence: [{ + task: "{solutionsRegistryMockRepoLoad}.get", + args: [{}], + resolve: "gpii.tests.solutionsRegistry.checkAllWithNamedRegistry", + resolveArgs: [ + "Expecting all solutions registries, but with local registry", + gpii.tests.solutionsRegistry.platformIds, + gpii.tests.solutionsRegistry.localPlatformId, + gpii.tests.solutionsRegistry.localDarwinSolutions, + "{arguments}.0" + ] + }] + }, { + name: "Solutions registry used with LFM - no solutions loaded from repository; looking for named registry", + sequence: [{ + task: "{solutionsRegistryNullRepoLoad}.get", + args: [gpii.tests.solutionsRegistry.requestOptions], + resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", + resolveArgs: [ + "Expecting one solutions registry", + gpii.tests.solutionsRegistry.requestOptions.os, + "{arguments}.0" + ] + }] + }, { + name: "Solutions registry used with LFM - no solutions loaded from repository; looking for all registries", + sequence: [{ + task: "{solutionsRegistryNullRepoLoad}.get", + args: [{}], + resolve: "gpii.tests.solutionsRegistry.checkAllRegistries", + resolveArgs: [ + "Expecting all solutions registries", + gpii.tests.solutionsRegistry.platformIds, + "{arguments}.0" + ] + }] + }] + }] +}); + +gpii.tests.solutionsRegistry.dataSource.local.mockRepoLoad = function (that, platformId, solutions) { + var promise = fluid.promise(); + var solutionsRegistry = {}; + solutionsRegistry[platformId] = solutions; + that.repositorySolutionsRegistry = solutionsRegistry; + promise.resolve(that.repositorySolutionsRegistry); + return promise; +}; + +gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad = function (that) { + var promise = fluid.promise(); + that.repositorySolutionsRegistry = null; + promise.resolve(that.repositorySolutionsRegistry); + return promise; +}; + +// Test environment for LFM solutions registry data source +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.env", { + gradeNames: ["fluid.test.testEnvironment"], + components: { + tester: { + type: "gpii.tests.solutionsRegistry.local.testCaseHolder" + } + } +}); + +kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.local.env"); diff --git a/tests/all-tests.js b/tests/all-tests.js index d9a846a36..99d5dbdad 100644 --- a/tests/all-tests.js +++ b/tests/all-tests.js @@ -59,6 +59,7 @@ var testIncludes = [ "../gpii/node_modules/flatMatchMaker/test/FlatMatchMakerTests.js", "../gpii/node_modules/flowManager/test/BrowserChannelTests.js", "../gpii/node_modules/flowManager/test/CaptureTests.js", + "../gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js", "../gpii/node_modules/flowManager/test/DefaultSettingsLoaderTests.js", "../gpii/node_modules/flowManager/test/PrefsServerDataSourceTests.js", "../gpii/node_modules/flowManager/test/PSPChannelTests.js", From 2e9e51b3ff56b035256feba1589bdd5d4cba926f Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 6 Mar 2020 14:43:13 -0500 Subject: [PATCH 35/68] GPII-4273: (GPII-4273iv) Waiting for solutions registry "ready" event in tests --- .../test/SolutionsRegistryDataSourceTests.js | 227 ++++++++++++------ 1 file changed, 156 insertions(+), 71 deletions(-) diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index e3c8199a6..6fffdf788 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -22,33 +22,40 @@ kettle.loadTestingSupport(); fluid.require("%flowManager/src/SolutionsRegistryDataSource.js"); fluid.registerNamespace("gpii.tests.solutionsRegistry"); +fluid.logObjectRenderChars = 4096; + gpii.tests.solutionsRegistry = { path: "%gpii-universal/testData/solutions", platformIds: ["win32", "linux", "darwin", "android", "web"], - localPlatformId: "darwin", - localDarwinSolutions: require("./data/darwin.json5"), + platformId: "darwin", + repositoryDarwinSolutions: require("./data/darwin.json5"), requestOptions: { os: "darwin" } }; +// Check that all platform ids are in the solutions registries (result). gpii.tests.solutionsRegistry.checkAllRegistries = function (msg, platformIds, result) { jqUnit.assertValue(msg, result); jqUnit.assertDeepEq(msg, platformIds, fluid.keys(result)); }; +// Check that the given platform id has been stripped out of the result. gpii.tests.solutionsRegistry.checkOneRegistry = function (msg, platformId, result) { jqUnit.assertValue(msg, result); // The platformId should be stripped out jqUnit.assertFalse(msg, platformId in result); }; -gpii.tests.solutionsRegistry.checkNamedLocalRegistry = function (msg, localSolutions, result) { +// equalityCheck is either jqUnit.assertDeepEq() or jqUnit.assertDeepNeq(). +gpii.tests.solutionsRegistry.checkNamedRegistry = function (msg, equalityCheck, expectedSolutions, result) { jqUnit.assertValue(msg, result); - jqUnit.assertDeepEq(msg, localSolutions, result); + equalityCheck(msg, expectedSolutions, result); }; -gpii.tests.solutionsRegistry.checkAllWithNamedRegistry = function (msg, platformIds, localPlatformId, localSolutions, result) { +// Check that all platform ids are in the solutions registries result, and that +// the single platformId/expectedSolutions is either deeply equal or not. +gpii.tests.solutionsRegistry.checkAllWithNamedRegistry = function (msg, platformIds, platformId, equalityCheck, expectedSolutions, result) { gpii.tests.solutionsRegistry.checkAllRegistries(msg, platformIds, result); - jqUnit.assertDeepEq(msg, localSolutions, result[localPlatformId]); + equalityCheck(msg, expectedSolutions, result[platformId]); }; // ======== Testing the solutions registry data source used by the CBFM ======== @@ -108,7 +115,6 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.cloud.env", { } } }); - kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.cloud.env"); // ======== Testing the solutions registry data source used by the LFM ======== @@ -121,19 +127,32 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.mockLoadFromReposi revisionRequester: { type: "gpii.flowmanager.revisionRequester", options: { - cloudURL: "http://nowhere.com" + cloudURL: "http://gpii.net" } } }, listeners: { - "onCreate": { + "loadSolutions.loadFromLocalDisk": { + listener: "{that}.loadFromLocalDisk", + priority: "first" + }, + "loadSolutions.getRevision": { + listener: "{revisionRequester}.getRevision", + priority: "after:loadFromLocalDisk" + }, + "loadSolutions.loadFromRepository": { listener: "gpii.tests.solutionsRegistry.dataSource.local.mockRepoLoad", args: [ "{that}", - gpii.tests.solutionsRegistry.localPlatformId, - gpii.tests.solutionsRegistry.localDarwinSolutions + gpii.tests.solutionsRegistry.platformId, + gpii.tests.solutionsRegistry.repositoryDarwinSolutions ], - priority: "after:solutionsLoaded" + priority: "after:getRevision" + }, + "loadSolutions.solutionsLoaded": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", + args: ["{that}.events.solutionsRegistryReady"], + priority: "after:loadFromRepository" } } }); @@ -146,20 +165,33 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.failLoadFromReposi revisionRequester: { type: "gpii.flowmanager.revisionRequester", options: { - cloudURL: "http://nowhere.com" + cloudURL: "http://gpii.net" } } }, listeners: { - "onCreate": { + "loadSolutions.loadFromLocalDisk": { + listener: "{that}.loadFromLocalDisk", + priority: "first" + }, + "loadSolutions.getRevision": { + listener: "{revisionRequester}.getRevision", + priority: "after:loadFromLocalDisk" + }, + "loadSolutions.loadFromRepository": { listener: "gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad", args: ["{that}"], - priority: "after:solutionsLoaded" + priority: "after:getRevision" + }, + "loadSolutions.solutionsLoaded": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", + args: ["{that}.events.solutionsRegistryReady"], + priority: "after:loadFromRepository" } } }); -fluid.defaults("gpii.tests.solutionsRegistry.local.testCaseHolder", { +fluid.defaults("gpii.tests.solutionsRegistry.local.repository.testCaseHolder", { gradeNames: "fluid.test.testCaseHolder", components: { solutionsRegistryMockRepoLoad: { @@ -167,7 +199,58 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.testCaseHolder", { options: { path: gpii.tests.solutionsRegistry.path } - }, + } + }, + modules: [{ + name: "Solutions registry used by LFM - repository + file system based solutions", + expect: 2, + tests: [{ + name: "Solutions registry LFM - solutions loaded from repository and looking for named registry", + sequence: [ + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named and all registries -- START"] }, + { + event: "{solutionsRegistryMockRepoLoad}.events.solutionsRegistryReady", + listener: "jqUnit.assert", + args: ["LFM solutionsRegistryMockRepoLoad ready"] + }, { + funcName: "{solutionsRegistryMockRepoLoad}.get", + args: [gpii.tests.solutionsRegistry.requestOptions] + }, { + event: "{solutionsRegistryMockRepoLoad}.events.onRead", + listener: "gpii.tests.solutionsRegistry.checkNamedRegistry", + args: [ + "Expecting repository named solutions registry", + jqUnit.assertDeepEq, + gpii.tests.solutionsRegistry.repositoryDarwinSolutions, + "{arguments}.0" + ] + }, + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named local registry -- END"] }, + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting all registries -- START"] }, + { + funcName: "{solutionsRegistryMockRepoLoad}.get", + args: [{}] + }, { + event: "{solutionsRegistryMockRepoLoad}.events.onRead", + listener: "gpii.tests.solutionsRegistry.checkAllWithNamedRegistry", + args: [ + "Expecting repository named solutions registry", + gpii.tests.solutionsRegistry.platformIds, + gpii.tests.solutionsRegistry.platformId, + jqUnit.assertDeepEq, + gpii.tests.solutionsRegistry.repositoryDarwinSolutions, + "{arguments}.0" + ] + }, + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting all registries -- START"] } + ] + }] + }] +}); + +fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", { + gradeNames: "fluid.test.testCaseHolder", + components: { solutionsRegistryNullRepoLoad: { type: "gpii.tests.solutionsRegistry.dataSource.local.failLoadFromRepository", options: { @@ -176,58 +259,48 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.testCaseHolder", { } }, modules: [{ - name: "Solutions registry used by LFM - repository + file system based solutions", + name: "Solutions registry used by LFM - only file system based solutions available", expect: 2, tests: [{ - name: "Solutions registry LFM - solutions loaded from repository and looking for named local registry", - sequence: [{ - task: "{solutionsRegistryMockRepoLoad}.get", - args: [gpii.tests.solutionsRegistry.requestOptions], - resolve: "gpii.tests.solutionsRegistry.checkNamedLocalRegistry", - resolveArgs: [ - "Expecting local named solutions registry", - gpii.tests.solutionsRegistry.localDarwinSolutions, - "{arguments}.0" - ] - }] - }, { - name: "Solutions registry used with LFM - solutions loaded from repository but looking for all registries", - sequence: [{ - task: "{solutionsRegistryMockRepoLoad}.get", - args: [{}], - resolve: "gpii.tests.solutionsRegistry.checkAllWithNamedRegistry", - resolveArgs: [ - "Expecting all solutions registries, but with local registry", - gpii.tests.solutionsRegistry.platformIds, - gpii.tests.solutionsRegistry.localPlatformId, - gpii.tests.solutionsRegistry.localDarwinSolutions, - "{arguments}.0" - ] - }] - }, { - name: "Solutions registry used with LFM - no solutions loaded from repository; looking for named registry", - sequence: [{ - task: "{solutionsRegistryNullRepoLoad}.get", - args: [gpii.tests.solutionsRegistry.requestOptions], - resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", - resolveArgs: [ - "Expecting one solutions registry", - gpii.tests.solutionsRegistry.requestOptions.os, - "{arguments}.0" - ] - }] - }, { - name: "Solutions registry used with LFM - no solutions loaded from repository; looking for all registries", - sequence: [{ - task: "{solutionsRegistryNullRepoLoad}.get", - args: [{}], - resolve: "gpii.tests.solutionsRegistry.checkAllRegistries", - resolveArgs: [ - "Expecting all solutions registries", - gpii.tests.solutionsRegistry.platformIds, - "{arguments}.0" - ] - }] + name: "Solutions registry used with LFM - no solutions loaded from repository", + sequence: [ + { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named local registry -- START"] }, + { + event: "{solutionsRegistryNullRepoLoad}.events.solutionsRegistryReady", + listener: "jqUnit.assert", + args: ["LFM solutionsRegistryNullRepoLoad ready"] + }, { + funcName: "{solutionsRegistryNullRepoLoad}.get", + args: [gpii.tests.solutionsRegistry.requestOptions] + }, { + event: "{solutionsRegistryNullRepoLoad}.events.onRead", + listener: "gpii.tests.solutionsRegistry.checkNamedRegistry", + args: [ + "Expecting local solutions registry", + jqUnit.assertDeepNeq, + gpii.tests.solutionsRegistry.repositoryDarwinSolutions, + "{arguments}.0" + ] + }, + { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named local registry -- END"] }, + { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting all registries -- START"] }, + { + funcName: "{solutionsRegistryNullRepoLoad}.get", + args: [{}] + }, { + event: "{solutionsRegistryNullRepoLoad}.events.onRead", + listener: "gpii.tests.solutionsRegistry.checkAllWithNamedRegistry", + args: [ + "Expecting local named solutions registry", + gpii.tests.solutionsRegistry.platformIds, + gpii.tests.solutionsRegistry.platformId, + jqUnit.assertDeepNeq, + gpii.tests.solutionsRegistry.repositoryDarwinSolutions, + "{arguments}.0" + ] + }, + { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting all registries -- END"] } + ] }] }] }); @@ -248,14 +321,26 @@ gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad = function (that) { return promise; }; -// Test environment for LFM solutions registry data source -fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.env", { +// Test environments for LFM solutions registry data source where solutions are +// fetched from the repository +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.repository.env", { gradeNames: ["fluid.test.testEnvironment"], components: { tester: { - type: "gpii.tests.solutionsRegistry.local.testCaseHolder" + type: "gpii.tests.solutionsRegistry.local.repository.testCaseHolder" } } }); +kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.local.repository.env"); -kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.local.env"); +// Test environments for LFM solutions registry data source where solutions are +// NOT fetched from the repository +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.noRepository.env", { + gradeNames: ["fluid.test.testEnvironment"], + components: { + tester: { + type: "gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder" + } + } +}); +kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.local.noRepository.env"); From 44ff1471d3ba0f1399a637b85ce6102c1e11dc73 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 6 Mar 2020 15:45:52 -0500 Subject: [PATCH 36/68] GPII-4273: (GPII-4273iv) Modified CBFM solutions registry tests Modified the tests to work in a similar way to those for the LFM solutions registry tests. --- .../test/SolutionsRegistryDataSourceTests.js | 193 ++++++++++-------- 1 file changed, 103 insertions(+), 90 deletions(-) diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index 6fffdf788..5752fbfbd 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -60,16 +60,11 @@ gpii.tests.solutionsRegistry.checkAllWithNamedRegistry = function (msg, platform // ======== Testing the solutions registry data source used by the CBFM ======== -// Test solutions registry data source (CBFM) -fluid.defaults("gpii.tests.solutionsRegistry.dataSource.cloud", { - gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource.cloud"] -}); - fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { gradeNames: "fluid.test.testCaseHolder", components: { solutionsRegistryDataSource: { - type: "gpii.tests.solutionsRegistry.dataSource.cloud", + type: "gpii.flowManager.solutionsRegistry.dataSource.cloud", options: { path: gpii.tests.solutionsRegistry.path } @@ -80,28 +75,44 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { expect: 2, tests: [{ name: "Solutions registry used with CBFM - retrieve all solutions", - sequence: [{ - task: "{solutionsRegistryDataSource}.get", - args: [{}], - resolve: "gpii.tests.solutionsRegistry.checkAllRegistries", - resolveArgs: [ - "Expecting all solutions registries", - gpii.tests.solutionsRegistry.platformIds, - "{arguments}.0" - ] - }] - }, { - name: "Solutions registry used with CBFM - retrieve one solution", - sequence: [{ - task: "{solutionsRegistryDataSource}.get", - args: [gpii.tests.solutionsRegistry.requestOptions], - resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", - resolveArgs: [ - "Expecting one solutions registry", - gpii.tests.solutionsRegistry.requestOptions.os, - "{arguments}.0" - ] - }] + sequence: [ + { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- START"] }, + + // For some reason, even though the solutionsRegistryReady event + // fires, this doesn't hear it. + // ... and doesn't appear to need to wait for it (?!) + /*{ + event: "{solutionsRegistryDataSource}.events.solutionsRegistryReady", + listener: "jqUnit.assert", + args: ["CBFM solutionsRegistryDataSource ready"] + },*/ { + funcName: "{solutionsRegistryDataSource}.get", + args: [gpii.tests.solutionsRegistry.requestOptions] + }, { + event: "{solutionsRegistryDataSource}.events.onRead", + listener: "gpii.tests.solutionsRegistry.checkOneRegistry", + args: [ + "Expecting one solutions registry", + gpii.tests.solutionsRegistry.requestOptions.os, + "{arguments}.0" + ] + }, + { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- END"] }, + { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting all registries -- START"] }, + { + funcName: "{solutionsRegistryDataSource}.get", + args: [{}] + }, { + event: "{solutionsRegistryDataSource}.events.onRead", + listener: "gpii.tests.solutionsRegistry.checkAllRegistries", + args: [ + "Expecting all solutions registries", + gpii.tests.solutionsRegistry.platformIds, + "{arguments}.0" + ] + }, + { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting all registries -- END"] } + ] }] }] }); @@ -157,39 +168,14 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.mockLoadFromReposi } }); -// Test component for the LFM solutions registry data source where it fails to -// load from the source code repository. -fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.failLoadFromRepository", { - gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource.local"], - components: { - revisionRequester: { - type: "gpii.flowmanager.revisionRequester", - options: { - cloudURL: "http://gpii.net" - } - } - }, - listeners: { - "loadSolutions.loadFromLocalDisk": { - listener: "{that}.loadFromLocalDisk", - priority: "first" - }, - "loadSolutions.getRevision": { - listener: "{revisionRequester}.getRevision", - priority: "after:loadFromLocalDisk" - }, - "loadSolutions.loadFromRepository": { - listener: "gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad", - args: ["{that}"], - priority: "after:getRevision" - }, - "loadSolutions.solutionsLoaded": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", - args: ["{that}.events.solutionsRegistryReady"], - priority: "after:loadFromRepository" - } - } -}); +gpii.tests.solutionsRegistry.dataSource.local.mockRepoLoad = function (that, platformId, solutions) { + var promise = fluid.promise(); + var solutionsRegistry = {}; + solutionsRegistry[platformId] = solutions; + that.repositorySolutionsRegistry = solutionsRegistry; + promise.resolve(that.repositorySolutionsRegistry); + return promise; +}; fluid.defaults("gpii.tests.solutionsRegistry.local.repository.testCaseHolder", { gradeNames: "fluid.test.testCaseHolder", @@ -248,6 +234,61 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.repository.testCaseHolder", { }] }); +// Test environment for LFM solutions registry data source where solutions are +// fetched from the repository +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.repository.env", { + gradeNames: ["fluid.test.testEnvironment"], + components: { + tester: { + type: "gpii.tests.solutionsRegistry.local.repository.testCaseHolder" + } + } +}); +kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.local.repository.env"); + + +// Test component for the LFM solutions registry data source where it fails to +// load from the source code repository. +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.failLoadFromRepository", { + gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource.local"], + components: { + revisionRequester: { + type: "gpii.flowmanager.revisionRequester", + options: { + cloudURL: "http://gpii.net" + } + } + }, + listeners: { + "loadSolutions.loadFromLocalDisk": { + listener: "{that}.loadFromLocalDisk", + priority: "first" + }, + "loadSolutions.getRevision": { + listener: "{revisionRequester}.getRevision", + priority: "after:loadFromLocalDisk" + }, + "loadSolutions.loadFromRepository": { + listener: "gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad", + args: ["{that}"], + priority: "after:getRevision" + }, + "loadSolutions.solutionsLoaded": { + listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", + args: ["{that}.events.solutionsRegistryReady"], + priority: "after:loadFromRepository" + } + } +}); + +gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad = function (that) { + var promise = fluid.promise(); + that.repositorySolutionsRegistry = null; + promise.resolve(that.repositorySolutionsRegistry); + return promise; +}; + + fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", { gradeNames: "fluid.test.testCaseHolder", components: { @@ -305,35 +346,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", }] }); -gpii.tests.solutionsRegistry.dataSource.local.mockRepoLoad = function (that, platformId, solutions) { - var promise = fluid.promise(); - var solutionsRegistry = {}; - solutionsRegistry[platformId] = solutions; - that.repositorySolutionsRegistry = solutionsRegistry; - promise.resolve(that.repositorySolutionsRegistry); - return promise; -}; - -gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad = function (that) { - var promise = fluid.promise(); - that.repositorySolutionsRegistry = null; - promise.resolve(that.repositorySolutionsRegistry); - return promise; -}; - -// Test environments for LFM solutions registry data source where solutions are -// fetched from the repository -fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.repository.env", { - gradeNames: ["fluid.test.testEnvironment"], - components: { - tester: { - type: "gpii.tests.solutionsRegistry.local.repository.testCaseHolder" - } - } -}); -kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.local.repository.env"); - -// Test environments for LFM solutions registry data source where solutions are +// Test environment for LFM solutions registry data source where solutions are // NOT fetched from the repository fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.noRepository.env", { gradeNames: ["fluid.test.testEnvironment"], From 1dfa82323c674929b204c2fd96fe67180d5ccfc7 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 9 Mar 2020 12:33:27 -0400 Subject: [PATCH 37/68] GPII-427333: (GPII-4273iv) Improved some test messages --- .../test/SolutionsRegistryDataSourceTests.js | 18 +++++++----------- 1 file changed, 7 insertions(+), 11 deletions(-) diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index 5752fbfbd..0c7939836 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -22,8 +22,6 @@ kettle.loadTestingSupport(); fluid.require("%flowManager/src/SolutionsRegistryDataSource.js"); fluid.registerNamespace("gpii.tests.solutionsRegistry"); -fluid.logObjectRenderChars = 4096; - gpii.tests.solutionsRegistry = { path: "%gpii-universal/testData/solutions", platformIds: ["win32", "linux", "darwin", "android", "web"], @@ -41,7 +39,6 @@ gpii.tests.solutionsRegistry.checkAllRegistries = function (msg, platformIds, re // Check that the given platform id has been stripped out of the result. gpii.tests.solutionsRegistry.checkOneRegistry = function (msg, platformId, result) { jqUnit.assertValue(msg, result); - // The platformId should be stripped out jqUnit.assertFalse(msg, platformId in result); }; @@ -54,6 +51,7 @@ gpii.tests.solutionsRegistry.checkNamedRegistry = function (msg, equalityCheck, // Check that all platform ids are in the solutions registries result, and that // the single platformId/expectedSolutions is either deeply equal or not. gpii.tests.solutionsRegistry.checkAllWithNamedRegistry = function (msg, platformIds, platformId, equalityCheck, expectedSolutions, result) { + console.log(platformId); gpii.tests.solutionsRegistry.checkAllRegistries(msg, platformIds, result); equalityCheck(msg, expectedSolutions, result[platformId]); }; @@ -177,7 +175,7 @@ gpii.tests.solutionsRegistry.dataSource.local.mockRepoLoad = function (that, pla return promise; }; -fluid.defaults("gpii.tests.solutionsRegistry.local.repository.testCaseHolder", { +fluid.defaults("gpii.tests.solutionsRegistry.local.mockRepository.testCaseHolder", { gradeNames: "fluid.test.testCaseHolder", components: { solutionsRegistryMockRepoLoad: { @@ -205,7 +203,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.repository.testCaseHolder", { event: "{solutionsRegistryMockRepoLoad}.events.onRead", listener: "gpii.tests.solutionsRegistry.checkNamedRegistry", args: [ - "Expecting repository named solutions registry", + "Expecting named solutions registry from repository", jqUnit.assertDeepEq, gpii.tests.solutionsRegistry.repositoryDarwinSolutions, "{arguments}.0" @@ -220,7 +218,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.repository.testCaseHolder", { event: "{solutionsRegistryMockRepoLoad}.events.onRead", listener: "gpii.tests.solutionsRegistry.checkAllWithNamedRegistry", args: [ - "Expecting repository named solutions registry", + "Expecting all solutions registries, but named registry is from repository", gpii.tests.solutionsRegistry.platformIds, gpii.tests.solutionsRegistry.platformId, jqUnit.assertDeepEq, @@ -236,16 +234,15 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.repository.testCaseHolder", { // Test environment for LFM solutions registry data source where solutions are // fetched from the repository -fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.repository.env", { +fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.mockRepository.env", { gradeNames: ["fluid.test.testEnvironment"], components: { tester: { - type: "gpii.tests.solutionsRegistry.local.repository.testCaseHolder" + type: "gpii.tests.solutionsRegistry.local.mockRepository.testCaseHolder" } } }); -kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.local.repository.env"); - +kettle.test.bootstrap("gpii.tests.solutionsRegistry.dataSource.local.mockRepository.env"); // Test component for the LFM solutions registry data source where it fails to // load from the source code repository. @@ -288,7 +285,6 @@ gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad = function (that) { return promise; }; - fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", { gradeNames: "fluid.test.testCaseHolder", components: { From 8738df41d5de2b82937615e471a1cd5642047896 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 9 Mar 2020 16:52:15 -0400 Subject: [PATCH 38/68] GPII-4273: (GPII-4273iv) Improved overlay code --- .../flowManager/src/SolutionsRegistryDataSource.js | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 64be899e5..70af85d70 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -271,13 +271,11 @@ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, req // invoker is public -- it could be called at any time and wipe out any // previous substitution. if (that.repositorySolutionsRegistry) { - fluid.log("TRACE: LFM SolutionsRegistryDataSource, returning ALL repository solutions MASKING (", that.id, ")... END"); - var fullSolutionsToReturn = fluid.copy(that.fullSolutionsRegistry); - var repoPlatform = fluid.keys(that.repositorySolutionsRegistry)[0]; - fluid.set(fullSolutionsToReturn, repoPlatform, that.repositorySolutionsRegistry[repoPlatform]); + fluid.log("TRACE: LFM SolutionsRegistryDataSource, returning ALL repository solutions OVERLAYING (", that.id, ")... END"); + var fullSolutionsToReturn = fluid.extend({}, that.fullSolutionsRegistry, that.repositorySolutionsRegistry); promise.resolve(fluid.freezeRecursive(fullSolutionsToReturn)); } else { - fluid.log("TRACE: LFM SolutionsRegistryDataSource, returning ALL repository solutions NOMASKING (", that.id, ")... END"); + fluid.log("TRACE: LFM SolutionsRegistryDataSource, returning ALL repository solutions NOOVERLAY (", that.id, ")... END"); promise.resolve(that.fullSolutionsRegistry); } } From 62342c0060a3611ad866555c26431c82f57b2e18 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 11 Mar 2020 13:28:26 -0400 Subject: [PATCH 39/68] GPII-4273: (GPII-4273iv) Removed version of get() that retrieved the full list of solutions registries - SolutionsRegistryDataSource no longer returns all of the solutions registries for all of the platforms. - Removed "fullSolutionsRegistry" member from match maker transform event interlock, - Modified JournalIntegrationTests and CaptureTests to no longer rely on the full list of solutions registries, but just the platform they are testing, - Removed debugging logs --- .../flowManager/src/FlowManager.js | 6 -- .../flowManager/src/MatchMaking.js | 17 ++-- .../src/RepositorySolutionsLoader.js | 4 - .../src/SolutionsRegistryDataSource.js | 88 ++++--------------- .../flowManager/test/CaptureTests.js | 31 ++++--- .../test/SolutionsRegistryDataSourceTests.js | 73 ++++----------- .../src/MatchMakerUtilities.js | 4 - tests/JournalIntegrationTests.js | 73 ++++++++------- 8 files changed, 97 insertions(+), 199 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index 513eaf48e..a9fc5f312 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -289,7 +289,6 @@ gpii.flowManager.local.mountWebSocketsSettingsHandler = function (webSocketsSett }; gpii.flowManager.local.noUserLoggedIn = function (lifecycleManager, noUserLoggedInEvent) { - fluid.log("TRACE: LFM flowManagerReady.loginWithNoUser listener ... START"); var promise = lifecycleManager.addToUserLogonRequestQueue({ gpiiKey: "noUser", logonState: "login" @@ -324,21 +323,16 @@ gpii.flowManager.convertDefaultSettingsToSnapshot = function (that, defaultSetti }; gpii.flowManager.local.resetAtStart = function (lifecycleManager, resetAtStart, defaultSettingsDataPromise, resetSuccessEvent, resetErrorEvent) { - fluid.log("TRACE: LFM noUserLoggedIn.resetAtStart listener ... START"); defaultSettingsDataPromise.then(function (defaultSettingsData) { var defaultSnapshot = defaultSettingsData.defaultSnapshot; if (resetAtStart && defaultSnapshot) { - fluid.log("TRACE: Resetting on system startup to default settings: ", defaultSnapshot); var resetPromise = lifecycleManager.restoreSnapshot(defaultSnapshot); resetPromise.then(function () { - fluid.log("TRACE: Resetting on system startup completes successfully."); resetSuccessEvent.fire(); }, function (error) { - fluid.log("TRACE: Resetting on system startup fails with the error: ", error); resetErrorEvent.fire(error); }); } else { - fluid.log("TRACE: LFM noUserLoggedIn.resetAtStart listener success ... END"); resetSuccessEvent.fire(); } }); diff --git a/gpii/node_modules/flowManager/src/MatchMaking.js b/gpii/node_modules/flowManager/src/MatchMaking.js index 079d404cc..0d051f5d5 100644 --- a/gpii/node_modules/flowManager/src/MatchMaking.js +++ b/gpii/node_modules/flowManager/src/MatchMaking.js @@ -94,20 +94,17 @@ * are also fired with the modified mmpayload. */ gpii.flowManager.getSolutions = function (solutionsRegistryDataSource, deviceContext, onSuccessEvent, onErrorEvent) { - fluid.log("TRACE: MatchMaker accessing LFM's solutionsRegistryDataSource (", solutionsRegistryDataSource.id, ")"); var promiseTogo = fluid.promise(); - var os = fluid.get(deviceContext, "OS.id"); - var promise = solutionsRegistryDataSource.get({}); - promise.then(function (solutions) { - var solutionsRegistryEntries = gpii.matchMakerFramework.filterSolutions(solutions[os], deviceContext); + var promise = solutionsRegistryDataSource.get({os: fluid.get(deviceContext, "OS.id")}); + promise.then(function (entries) { + var solutionsRegistryEntries = gpii.matchMakerFramework.filterSolutions(entries, deviceContext); fluid.log("Fetched filtered solutions registry entries: ", gpii.renderMegapayload({solutionsRegistryEntries: solutionsRegistryEntries})); promiseTogo.resolve({ - solutionsRegistryEntries: solutionsRegistryEntries, - solutions: solutions + solutionsRegistryEntries: solutionsRegistryEntries }); if (onSuccessEvent) { - onSuccessEvent.fire(solutionsRegistryEntries, solutions); + onSuccessEvent.fire(solutionsRegistryEntries); } }, function (error) { promiseTogo.reject(error); @@ -115,7 +112,6 @@ onErrorEvent.fire(error); } }); - return promiseTogo; }; @@ -188,8 +184,7 @@ gpiiKey: "{that}.gpiiKey", preferences: "{arguments}.preferences.0", deviceContext: "{arguments}.deviceContext.0", - solutionsRegistryEntries: "{arguments}.solutions.0", - fullSolutionsRegistry: "{arguments}.solutions.1" + solutionsRegistryEntries: "{arguments}.solutions.0" }] } }, diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index cbe77bf0a..0b04dd101 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -78,7 +78,6 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { * property. */ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName, platformId) { - fluid.log("TRACE: RepositorySolutionsLoader loads solutions registry from github ... START"); var togo = fluid.promise(); if (gpiiRevision && fileName) { var solutionsPromise = that.get({ @@ -86,13 +85,11 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe directFileName: fileName }); solutionsPromise.then(function (solutions) { - fluid.log("TRACE: RepositorySolutionsLoader loads solutions registry from github ... END"); var taggedRegistry = {}; taggedRegistry[platformId] = solutions; that.solutionsRegistry = fluid.freezeRecursive(taggedRegistry); fluid.promise.follow(solutionsPromise, togo); }, function (err) { - fluid.log("TRACE: RepositorySolutionsLoader failed to download solutions registry from github ... END"); fluid.log("Error retrieving solutions from repository: ", err, ", ", that.options.url); togo.resolve(err); }); @@ -107,7 +104,6 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe else { msg += "file name"; } - fluid.log("TRACE: " + msg + "... END"); togo.resolve({isError: true, message: msg, statusCode: 404}); } return togo; diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 70af85d70..6d724ba9a 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -72,7 +72,6 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource", { * collection of solution registries given by path. */ gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk = function (that) { - fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... START"); if (!that.options.path) { fluid.fail("The solutionsRegistry datasource ", that, " needs a \"path\" option pointing to the solution entries folder"); } @@ -81,7 +80,6 @@ gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk = function (that fluid.fail("The path provided to the solutionsRegistry datasource (", url, ") has not been found on the file system"); } that.fullSolutionsRegistry = fluid.freezeRecursive(require(url)); - fluid.log("TRACE: SolutionsRegistryDataSource creation (", that.id, ") ... END"); }; // Solutions registry data source used by the Cloud Based Flow Manager @@ -101,8 +99,7 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.cloud", { priority: "first" }, "loadSolutions.solutionsLoaded": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", - args: ["{that}.events.solutionsRegistryReady"], + listener: "{that}.events.solutionsRegistryReady", priority: "after:loadFromLocalDisk" } } @@ -111,33 +108,25 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.cloud", { /** * Handler for get requests to the solutions registry used by the Cloud Based * Flow Manager. It will return either an object containing solutions registries - * for all platforms, or, if a platform is provided, only the solutions registry - * for that platform will be returned. + * for the given platform. * * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource.cloud * @param {Object} requestOptions - Currently the only request option supported - * is "os". If provided, the returned solutions registry will be - * filtered by OS version. + * is "os". The returned solutions registry will be the solutions for + * the OS version provided. * @return {Promise} A promise that will be resolved with results (see above) or * rejected on error. */ gpii.flowManager.solutionsRegistry.dataSource.cloud.handle = function (that, requestOptions) { - fluid.log("TRACE: SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); var promise = fluid.promise(); - if (requestOptions.os) { // if "os" is defined, return only solution registry entries for that OS - if (requestOptions.os in that.fullSolutionsRegistry) { - fluid.log("TRACE: SolutionsRegistryDataSource return SPECIFIED [", requestOptions.os, "] solutions (", that.id, ") ... END"); - promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); - } else { - promise.reject({ - isError: true, - message: "The requested OS (" + requestOptions.os + ") was not present in the solutions registry", - statusCode: 404 - }); - } - } else { // if no "os" is requested, return the full solutions registry - fluid.log("TRACE: SolutionsRegistryDataSource return ALL solutions (", that.id, ") ... END"); - promise.resolve(that.fullSolutionsRegistry); + if (requestOptions.os && requestOptions.os in that.fullSolutionsRegistry) { + promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); + } else { + promise.reject({ + isError: true, + message: "The requested OS (" + requestOptions.os + ") was not present in the solutions registry", + statusCode: 404 + }); } return promise; }; @@ -184,8 +173,7 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { priority: "after:getRevision" }, "loadSolutions.solutionsLoaded": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", - args: ["{that}.events.solutionsRegistryReady"], + listener: "{that}.events.solutionsRegistryReady", priority: "after:loadFromRepository" } } @@ -210,7 +198,6 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { * property. */ gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = function (that, revision, platformReporter) { - fluid.log("TRACE: SRDS onCreate gets solutions from github ... START"); var gpiiRevision = revision.sha256; var platformId = platformReporter.reportPlatform().id; var fileName = platformId + ".json5"; @@ -220,7 +207,6 @@ gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = functio // repository, or it hasn't. Set that.repositorySolutionsRegistry to // whatever the result. that.repositorySolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; - fluid.log("TRACE: SRDS onCreate gets solutions from github ... END"); }); return togo; }; @@ -229,72 +215,34 @@ gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = functio * Handler for get requests when running with the gpii-app client and the Local * Flow Manager. If a solutions registry was retrieved from the source code * repository, it is used to mask the equivalent platform in the full set of - * solutions registries. This handler will return either an object containing - * solutions registries for all platforms, or, if a platform is provided, only - * the solutions registry for that platform will be returned. + * solutions registries. This handler will return the solutions registry for + * the given platform. * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource.local - instance. - * @param {Object} that.repositorySolutionsRegistry - The solutions registry - * for the client platform previously as from the repository. - * @param {Object} that.fullSolutionsRegistry - The solutions registries loaded - * from the local file system. + * instance. * @param {Object} requestOptions - Currently the only request option supported - * is "os". If provided, the returned solutions registry will be filtered - * by OS version. + * is "os". The returned solutions registry will be the solutions for the + * given OS version. * @return {Promise} A promise that will be resolved with results (see above) or * rejected on error. */ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, requestOptions) { - fluid.log("TRACE: LFM SolutionsRegistryDataSource return solutions (", that.id, ") ... START"); var promise = fluid.promise(); if (requestOptions && requestOptions.os) { if (that.repositorySolutionsRegistry && (requestOptions.os in that.repositorySolutionsRegistry)) { - fluid.log("TRACE: LFM SolutionsRegistryDataSource with OS (", requestOptions.os, "), return repository solutions (", that.id, "... END"); promise.resolve(that.repositorySolutionsRegistry[requestOptions.os]); } else if (requestOptions.os in that.fullSolutionsRegistry) { - fluid.log("TRACE: LFM SolutionsRegistryDataSource with OS (", requestOptions.os, "), returns local file system solutions (", that.id, ") ... END"); promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); } else { - fluid.log("TRACE: LFM SolutionsRegistryDataSource no such OS (", requestOptions.os, "); (", that.id, ") ... END"); promise.reject({ isError: true, message: "The requested OS (" + requestOptions.os + ") was not present in the solutions registry", statusCode: 404 }); } - } else { - // No platform requested -- return all of the solutions registries, but - // substitute repositorySolutionsRegistry into fullSolutionsRegistry if - // available. - // NOTE: (JS) could do this substitution during the - // onCreate.loadSolutions listener pipeline, but the loadFromLocalDisk() - // invoker is public -- it could be called at any time and wipe out any - // previous substitution. - if (that.repositorySolutionsRegistry) { - fluid.log("TRACE: LFM SolutionsRegistryDataSource, returning ALL repository solutions OVERLAYING (", that.id, ")... END"); - var fullSolutionsToReturn = fluid.extend({}, that.fullSolutionsRegistry, that.repositorySolutionsRegistry); - promise.resolve(fluid.freezeRecursive(fullSolutionsToReturn)); - } else { - fluid.log("TRACE: LFM SolutionsRegistryDataSource, returning ALL repository solutions NOOVERLAY (", that.id, ")... END"); - promise.resolve(that.fullSolutionsRegistry); - } } return promise; }; -/** - * Fire an event to indicate that the pipeline for loading the repository and - * local solutions registries has completed. - * NOTE: (JS) This is here for debugging, and will be called directly from the - * transform event pipeline defined in the listeners block of the relevant - * solutions registry data source. - * @param {Event} solutionsRegistryReadyEvent - The event to fire. - */ -gpii.flowManager.solutionsRegistry.dataSource.finishedLoading = function (solutionsRegistryReadyEvent) { - fluid.log("TRACE: SRDS onCreate.loadSolutions ... DONE"); - solutionsRegistryReadyEvent.fire(); -}; - /** A mixin grade which automatically expands any %terms corresponding to module names registered in Infusion's module database */ // TODO: This is a duplicate of kettle.dataSource.file.moduleTerms - this should be rewritten after KETTLE-50 is resolved fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.moduleTerms", { diff --git a/gpii/node_modules/flowManager/test/CaptureTests.js b/gpii/node_modules/flowManager/test/CaptureTests.js index 9d5147617..be8f0f5f5 100644 --- a/gpii/node_modules/flowManager/test/CaptureTests.js +++ b/gpii/node_modules/flowManager/test/CaptureTests.js @@ -53,16 +53,16 @@ gpii.tests.flowManager.capture.checkForInstalledMags = function (payload) { jqUnit.assertEquals("Check for Fake Mag 2", "Fake Magnifier 2 - fully featured", payload.fakemag2.name); }; -gpii.tests.flowManager.capture.adjustSolutions = function (solutionsRegistryDataSource) { +gpii.tests.flowManager.capture.adjustSolutions = function (solutionsRegistryDataSource, solutionsPayload) { var testDataFile = __dirname + "/data/capture_fakemag_settings.json"; var testDataFile2 = __dirname + "/data/capture_fakemag2_settings.json"; - // The solutions block is a read only data structure - var adjustedSolutions = fluid.copy(solutionsRegistryDataSource.fullSolutionsRegistry); - adjustedSolutions.darwin.fakemag2.settingsHandlers.configuration.options.filename = testDataFile2; - adjustedSolutions.darwin.fakemag1.settingsHandlers.configuration.options.filename = testDataFile; - adjustedSolutions.darwin.fakemag1.settingsHandlers.configuration1.options.filename = testDataFile; - solutionsRegistryDataSource.fullSolutionsRegistry = adjustedSolutions; + // The solutionsPayload block is a read only data structure + var adjustedSolutions = fluid.copy(solutionsPayload); + adjustedSolutions.fakemag2.settingsHandlers.configuration.options.filename = testDataFile2; + adjustedSolutions.fakemag1.settingsHandlers.configuration.options.filename = testDataFile; + adjustedSolutions.fakemag1.settingsHandlers.configuration1.options.filename = testDataFile; + solutionsRegistryDataSource.repositorySolutionsRegistry = fluid.freezeRecursive({"darwin": adjustedSolutions}); }; fluid.defaults("gpii.tests.flowManager.capture.tests", { @@ -72,10 +72,18 @@ fluid.defaults("gpii.tests.flowManager.capture.tests", { name: "Simple system capture", tests: [{ name: "Check for existing FakeMag Settings", - expect: 2, + expect: 3, sequence: [{ - funcName: "gpii.tests.flowManager.capture.adjustSolutions", - args: ["{config}.server.flowManager.solutionsRegistryDataSource"] + event: "{config}.server.flowManager.solutionsRegistryDataSource.events.solutionsRegistryReady", + listener: "jqUnit.assert", + args: ["Solutions registry ready"] + }, { + funcName: "{config}.server.flowManager.solutionsRegistryDataSource.get", + args: [{os: "darwin"}] + }, { + event: "{config}.server.flowManager.solutionsRegistryDataSource.events.onRead", + listener: "gpii.tests.flowManager.capture.adjustSolutions", + args: ["{config}.server.flowManager.solutionsRegistryDataSource", "{arguments}.0"] }, { task: "{config}.server.flowManager.capture.getSystemSettingsCapture", args: [], @@ -90,9 +98,6 @@ fluid.defaults("gpii.tests.flowManager.capture.tests", { name: "Testing get installed solutions", expect: 3, sequence: [{ - funcName: "gpii.tests.flowManager.capture.adjustSolutions", - args: ["{config}.server.flowManager.solutionsRegistryDataSource"] - }, { task: "{config}.server.flowManager.capture.getInstalledSolutionsForCurrentDevice", args: [], resolve: "gpii.tests.flowManager.capture.checkForInstalledMags", diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index 0c7939836..2064067ef 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -27,13 +27,8 @@ gpii.tests.solutionsRegistry = { platformIds: ["win32", "linux", "darwin", "android", "web"], platformId: "darwin", repositoryDarwinSolutions: require("./data/darwin.json5"), - requestOptions: { os: "darwin" } -}; - -// Check that all platform ids are in the solutions registries (result). -gpii.tests.solutionsRegistry.checkAllRegistries = function (msg, platformIds, result) { - jqUnit.assertValue(msg, result); - jqUnit.assertDeepEq(msg, platformIds, fluid.keys(result)); + requestOptions: { os: "darwin" }, + win32PlatformId: "win32" }; // Check that the given platform id has been stripped out of the result. @@ -48,14 +43,6 @@ gpii.tests.solutionsRegistry.checkNamedRegistry = function (msg, equalityCheck, equalityCheck(msg, expectedSolutions, result); }; -// Check that all platform ids are in the solutions registries result, and that -// the single platformId/expectedSolutions is either deeply equal or not. -gpii.tests.solutionsRegistry.checkAllWithNamedRegistry = function (msg, platformIds, platformId, equalityCheck, expectedSolutions, result) { - console.log(platformId); - gpii.tests.solutionsRegistry.checkAllRegistries(msg, platformIds, result); - equalityCheck(msg, expectedSolutions, result[platformId]); -}; - // ======== Testing the solutions registry data source used by the CBFM ======== fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { @@ -72,7 +59,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { name: "Solutions registry used by CBFM - file-based solutions", expect: 2, tests: [{ - name: "Solutions registry used with CBFM - retrieve all solutions", + name: "Solutions registry used with CBFM", sequence: [ { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- START"] }, @@ -95,21 +82,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { "{arguments}.0" ] }, - { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- END"] }, - { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting all registries -- START"] }, - { - funcName: "{solutionsRegistryDataSource}.get", - args: [{}] - }, { - event: "{solutionsRegistryDataSource}.events.onRead", - listener: "gpii.tests.solutionsRegistry.checkAllRegistries", - args: [ - "Expecting all solutions registries", - gpii.tests.solutionsRegistry.platformIds, - "{arguments}.0" - ] - }, - { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting all registries -- END"] } + { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- END"] } ] }] }] @@ -159,8 +132,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.mockLoadFromReposi priority: "after:getRevision" }, "loadSolutions.solutionsLoaded": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", - args: ["{that}.events.solutionsRegistryReady"], + listener: "{that}.events.solutionsRegistryReady.fire", priority: "after:loadFromRepository" } } @@ -191,7 +163,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.mockRepository.testCaseHolder tests: [{ name: "Solutions registry LFM - solutions loaded from repository and looking for named registry", sequence: [ - { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named and all registries -- START"] }, + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named repository registry -- START"] }, { event: "{solutionsRegistryMockRepoLoad}.events.solutionsRegistryReady", listener: "jqUnit.assert", @@ -209,20 +181,17 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.mockRepository.testCaseHolder "{arguments}.0" ] }, - { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named local registry -- END"] }, - { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting all registries -- START"] }, + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named repository registry -- END"] }, + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named local registry -- START"] }, { funcName: "{solutionsRegistryMockRepoLoad}.get", - args: [{}] + args: [{os: gpii.tests.solutionsRegistry.win32PlatformId}] }, { event: "{solutionsRegistryMockRepoLoad}.events.onRead", - listener: "gpii.tests.solutionsRegistry.checkAllWithNamedRegistry", + listener: "gpii.tests.solutionsRegistry.checkOneRegistry", args: [ - "Expecting all solutions registries, but named registry is from repository", - gpii.tests.solutionsRegistry.platformIds, - gpii.tests.solutionsRegistry.platformId, - jqUnit.assertDeepEq, - gpii.tests.solutionsRegistry.repositoryDarwinSolutions, + "Expecting named solutions registries, but from the local file system", + gpii.tests.solutionsRegistry.win32PlatformId, "{arguments}.0" ] }, @@ -271,8 +240,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.failLoadFromReposi priority: "after:getRevision" }, "loadSolutions.solutionsLoaded": { - listener: "gpii.flowManager.solutionsRegistry.dataSource.finishedLoading", - args: ["{that}.events.solutionsRegistryReady"], + listener: "{that}.events.solutionsRegistryReady.fire", priority: "after:loadFromRepository" } } @@ -301,7 +269,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", tests: [{ name: "Solutions registry used with LFM - no solutions loaded from repository", sequence: [ - { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named local registry -- START"] }, + { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named 'repository' registry -- START"] }, { event: "{solutionsRegistryNullRepoLoad}.events.solutionsRegistryReady", listener: "jqUnit.assert", @@ -319,20 +287,17 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", "{arguments}.0" ] }, - { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named local registry -- END"] }, - { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting all registries -- START"] }, + { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named 'repository' registry -- END"] }, + { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named local registry -- START"] }, { funcName: "{solutionsRegistryNullRepoLoad}.get", - args: [{}] + args: [{os: gpii.tests.solutionsRegistry.win32PlatformId}] }, { event: "{solutionsRegistryNullRepoLoad}.events.onRead", - listener: "gpii.tests.solutionsRegistry.checkAllWithNamedRegistry", + listener: "gpii.tests.solutionsRegistry.checkOneRegistry", args: [ "Expecting local named solutions registry", - gpii.tests.solutionsRegistry.platformIds, - gpii.tests.solutionsRegistry.platformId, - jqUnit.assertDeepNeq, - gpii.tests.solutionsRegistry.repositoryDarwinSolutions, + gpii.tests.solutionsRegistry.win32PlatformId, "{arguments}.0" ] }, diff --git a/gpii/node_modules/matchMakerFramework/src/MatchMakerUtilities.js b/gpii/node_modules/matchMakerFramework/src/MatchMakerUtilities.js index 2f56767ef..4623a628f 100644 --- a/gpii/node_modules/matchMakerFramework/src/MatchMakerUtilities.js +++ b/gpii/node_modules/matchMakerFramework/src/MatchMakerUtilities.js @@ -50,10 +50,6 @@ var fluid = fluid || require("infusion"), specialPreferences: gpii.matchMakerFramework.utils.findSpecialPreferences(initialPayload.preferences) }, fluid.copy(initialPayload)); gpii.matchMakerFramework.utils.addCapabilitiesInformation(matchMakerInput); - // remove full solutions registry from the payload, now that we've used it - // to avoid sending a too large payload to the matchmaker (see GPII-1880) - delete matchMakerInput.fullSolutionsRegistry; - return matchMakerInput; }; diff --git a/tests/JournalIntegrationTests.js b/tests/JournalIntegrationTests.js index 800e5c8e7..97abe2acb 100644 --- a/tests/JournalIntegrationTests.js +++ b/tests/JournalIntegrationTests.js @@ -17,6 +17,7 @@ var gpii = fluid.registerNamespace("gpii"); var jqUnit = require("node-jqunit"); var kettle = require("kettle"); + kettle.loadTestingSupport(); fluid.require("%gpii-universal"); @@ -307,50 +308,48 @@ fluid.defaults("gpii.tests.journal.testCaseHolder", { // Used on the first run where the settings handler crashes the whole system gpii.tests.journal.solutionsRegistryOverlay = { - win32: { - "com.microsoft.windows.cursors": { - settingsHandlers: { - explode: { - type: "gpii.tests.journal.explodingSettingsHandler", - supportedSettings: { - AppStarting: {} - }, - capabilitiesTransformations: { - AppStarting: { - transform: { - type: "fluid.transforms.value", - inputPath: "http://registry\\.gpii\\.net/common/cursorSize", - outputPath: "value" - } - } - } + "com.microsoft.windows.cursors": { + settingsHandlers: { + explode: { + type: "gpii.tests.journal.explodingSettingsHandler", + supportedSettings: { + AppStarting: {} }, - maybeThrow: { - type: "gpii.tests.journal.throwingSettingsHandler", - supportedSettings: { - AppStarting: {} - }, - capabilitiesTransformations: { - AppStarting: { - transform: { - type: "fluid.transforms.value", - inputPath: "http://registry\\.gpii\\.net/common/cursorSize", - outputPath: "value" - } + capabilitiesTransformations: { + AppStarting: { + transform: { + type: "fluid.transforms.value", + inputPath: "http://registry\\.gpii\\.net/common/cursorSize", + outputPath: "value" } } + } + }, + maybeThrow: { + type: "gpii.tests.journal.throwingSettingsHandler", + supportedSettings: { + AppStarting: {} }, - configure: { - supportedSettings: { - AppStarting: {} + capabilitiesTransformations: { + AppStarting: { + transform: { + type: "fluid.transforms.value", + inputPath: "http://registry\\.gpii\\.net/common/cursorSize", + outputPath: "value" + } } } }, - restore: ["settings.maybeThrow", "settings.configure"], - // It's necessary to execute settings.maybeThrow otherwise its entry does not appear in the snapshotted solutions - // registry block entered into the journal, and hence it cannot be found on the next turn - configure: ["settings.configure", "settings.maybeThrow", "settings.explode"] - } + configure: { + supportedSettings: { + AppStarting: {} + } + } + }, + restore: ["settings.maybeThrow", "settings.configure"], + // It's necessary to execute settings.maybeThrow otherwise its entry does not appear in the snapshotted solutions + // registry block entered into the journal, and hence it cannot be found on the next turn + configure: ["settings.configure", "settings.maybeThrow", "settings.explode"] } }; From fb8a3cf751e299d8477a84994ab8fde777a2298b Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 12 Mar 2020 16:42:36 -0400 Subject: [PATCH 40/68] GPII-4273: (GPII-4273iv) Used distributeOptions in config file for CaptureTests - Overrode the 'loadSolutions.loadFromRepository' listener in the solutions registry data source to use the solutions adjustor function defined in the test file instead. - Removed a log message missed from the last commit. --- .../flowManager/test/CaptureTests.js | 23 +++++++++++++------ ...anager.tests.capture.fakeData.config.json5 | 16 +++++++++++-- .../test/shared/BrowserChannelTestDefs.js | 1 - 3 files changed, 30 insertions(+), 10 deletions(-) diff --git a/gpii/node_modules/flowManager/test/CaptureTests.js b/gpii/node_modules/flowManager/test/CaptureTests.js index be8f0f5f5..e39dce994 100644 --- a/gpii/node_modules/flowManager/test/CaptureTests.js +++ b/gpii/node_modules/flowManager/test/CaptureTests.js @@ -47,22 +47,31 @@ gpii.tests.flowManager.capture.platformReporter = function () { }; }; +fluid.defaults("gpii.tests.flowManager.capture.platformReporter", { + gradeNames: "fluid.function" +}); + gpii.tests.flowManager.capture.checkForInstalledMags = function (payload) { jqUnit.assertEquals("There should be 2 solutions installed", 2, Object.keys(payload).length); jqUnit.assertEquals("Check for Fake Mag 1", "Fake Magnifier 1", payload.fakemag1.name); jqUnit.assertEquals("Check for Fake Mag 2", "Fake Magnifier 2 - fully featured", payload.fakemag2.name); }; -gpii.tests.flowManager.capture.adjustSolutions = function (solutionsRegistryDataSource, solutionsPayload) { +gpii.tests.flowManager.capture.adjustSolutions = function (solutionsRegistryDataSource, revision, platformReporter) { + var platformId = fluid.invokeGlobalFunction(platformReporter).id; var testDataFile = __dirname + "/data/capture_fakemag_settings.json"; var testDataFile2 = __dirname + "/data/capture_fakemag2_settings.json"; - // The solutionsPayload block is a read only data structure - var adjustedSolutions = fluid.copy(solutionsPayload); + // The full block is a read only data structure + var adjustedSolutions = fluid.copy(solutionsRegistryDataSource.fullSolutionsRegistry[platformId]); adjustedSolutions.fakemag2.settingsHandlers.configuration.options.filename = testDataFile2; adjustedSolutions.fakemag1.settingsHandlers.configuration.options.filename = testDataFile; adjustedSolutions.fakemag1.settingsHandlers.configuration1.options.filename = testDataFile; - solutionsRegistryDataSource.repositorySolutionsRegistry = fluid.freezeRecursive({"darwin": adjustedSolutions}); + + var adjustedRegistry = {}; + adjustedRegistry[platformId] = adjustedSolutions; + solutionsRegistryDataSource.repositorySolutionsRegistry = fluid.freezeRecursive(adjustedRegistry); + return fluid.promise().resolve(solutionsRegistryDataSource.repositorySolutionsRegistry); }; fluid.defaults("gpii.tests.flowManager.capture.tests", { @@ -72,7 +81,7 @@ fluid.defaults("gpii.tests.flowManager.capture.tests", { name: "Simple system capture", tests: [{ name: "Check for existing FakeMag Settings", - expect: 3, + expect: 4, sequence: [{ event: "{config}.server.flowManager.solutionsRegistryDataSource.events.solutionsRegistryReady", listener: "jqUnit.assert", @@ -82,8 +91,8 @@ fluid.defaults("gpii.tests.flowManager.capture.tests", { args: [{os: "darwin"}] }, { event: "{config}.server.flowManager.solutionsRegistryDataSource.events.onRead", - listener: "gpii.tests.flowManager.capture.adjustSolutions", - args: ["{config}.server.flowManager.solutionsRegistryDataSource", "{arguments}.0"] + listener: "jqUnit.assertValue", + args: ["Solutions registry read solutions", "{arguments}.0"] }, { task: "{config}.server.flowManager.capture.getSystemSettingsCapture", args: [], diff --git a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 index cc6b605a5..0ba54ad24 100644 --- a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 +++ b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 @@ -1,6 +1,7 @@ // // This configuration is used for testing the snappingshotting Capture API. Capturing setting will only -// ever happen on a users local machine, so there is only an untrusted test configuration. +// ever happen on a users local machine, so there is only an untrusted test configuration. Also, it +// will use the LFM's version of the solutions registry data source (gpii.flowManager.solutionsRegistry.dataSource.local) // { "type": "gpii.flowManager.tests.capture.fakeData.config", @@ -11,6 +12,17 @@ "target": "{that flowManager solutionsRegistryDataSource}.options.path", "priority": "after:flowManager.solutions" }, + "capture.loadRepositorySolutions": { + "record": { + "loadSolutions.loadFromRepository": { + "listener": "gpii.tests.flowManager.capture.adjustSolutions", + "args": ["{that}", "{arguments}.0", "gpii.tests.flowManager.capture.platformReporter"], + "priority": "after:getRevision" + } + }, + "target": "{that flowManager solutionsRegistryDataSource}.options.listeners", + "priority": "after:capture.solutionsRegistry" + }, "capture.deviceReporter": { "record": "%gpii-universal/gpii/node_modules/flowManager/test/data/capture_deviceReporter.json", "target": "{that deviceReporter installedSolutionsDataSource}.options.path", @@ -22,7 +34,7 @@ }, "target": "{that deviceReporter platformReporter}.options.invokers.reportPlatform", "priority": "after:development.installedSolutionsPath" - } + }, } }, "mergeConfigs": "%gpii-universal/gpii/configs/shared/gpii.config.untrusted.development.json5" diff --git a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js index 7ac7b66c9..f390559bf 100644 --- a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js +++ b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js @@ -56,7 +56,6 @@ gpii.tests.flowManager.browserChannel.reportPlatform = function () { // A no-op to gracefully fail fetching the solutions registry from the source // code repository in order to use the canned registry set up for these tests. gpii.tests.flowManager.browserChannel.getRepositorySolutions = function (repositorySolutionsLoader) { - fluid.log("TRACE: RepositorySolutionsLoader defeating loading from repository ... END"); var togo = fluid.promise(); repositorySolutionsLoader.solutionsRegistry = null; togo.resolve(repositorySolutionsLoader.solutionsRegistry); From 33774c37be9b11cf50a8fa55d8f8961c1f4314b0 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 12 Mar 2020 17:20:14 -0400 Subject: [PATCH 41/68] GPII-4273: (GPII-4273iv) Fixed lint error --- .../gpii.flowManager.tests.capture.fakeData.config.json5 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 index 0ba54ad24..c606b2a62 100644 --- a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 +++ b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 @@ -34,7 +34,7 @@ }, "target": "{that deviceReporter platformReporter}.options.invokers.reportPlatform", "priority": "after:development.installedSolutionsPath" - }, + } } }, "mergeConfigs": "%gpii-universal/gpii/configs/shared/gpii.config.untrusted.development.json5" From 58d31c1b550346866dcedcb37f488ae541da0d9d Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 13 Mar 2020 11:11:01 -0400 Subject: [PATCH 42/68] GPII-4273: (GPII-4273iii) Distribute platformReporter into SolutionsRegistryDataSource --- gpii/node_modules/flowManager/src/FlowManager.js | 6 ++++++ .../src/SolutionsRegistryDataSource.js | 15 +++++++++------ .../test/SolutionsRegistryDataSourceTests.js | 2 +- 3 files changed, 16 insertions(+), 7 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index a9fc5f312..e749c5364 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -153,6 +153,12 @@ fluid.defaults("gpii.flowManager.local", { "lifecycleManager.pspChannel.sessionBinder": { record: "gpii.pspChannel.sessionBinder", target: "{that lifecycleManager gpii.lifecycleManager.userSession}.options.gradeNames" + }, + "solutionsRegistryDataSource.platformReporter": { + record: { + platformReporter: "{gpii.flowManager.local}.deviceReporter.platformReporter" + }, + target: "{that solutionsRegistryDataSource}.options.components" } }, components: { diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 6d724ba9a..d80f18ce1 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -141,10 +141,12 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { }, repositorySolutionsLoader: { type: "gpii.flowManager.repositorySolutionsLoader" - }, - platformReporter: { - type: "gpii.platformReporter.native" } + // The platformReporter subcomponent is distributed down from local + // flowManager +// platformReporter: { +// type: "gpii.platformReporter.native" +// } }, readOnlyGrade: "gpii.flowManager.solutionsRegistry.dataSource.local", members: { @@ -190,7 +192,8 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { * solutions registry retrieved from the respository, or null if * none were retrieved. * @param {Object} revision - the SHA256 revision of the repository in the form: - * { sha256: ... }. + * { sha256: ... }. If the sha256 is missing, the + * result of the load is null. * @param {Component} platformReporter - used to get the name of the platform, * e.g., "win32". * @return {Promise} A promise whose resolved value is eiher the solutions @@ -204,8 +207,8 @@ gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = functio var togo = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName, platformId); togo.then(function () { // Either the solutions registry has been successfully retrieved from the - // repository, or it hasn't. Set that.repositorySolutionsRegistry to - // whatever the result. + // repository, or it hasn't (= null). Set that.repositorySolutionsRegistry + // to whatever the result. that.repositorySolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; }); return togo; diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index 2064067ef..be91cfeed 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -301,7 +301,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", "{arguments}.0" ] }, - { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting all registries -- END"] } + { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, named local registry -- END"] } ] }] }] From 8b72c7ec0f5b4341304365c470a2238bac01ee1c Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 17 Mar 2020 10:21:44 -0400 Subject: [PATCH 43/68] GPII-4273: (GPII-4273iv) Updated based on Cindy's review comments Modified the RepositorySolutionsLoader GET handler's promise: - resolves to a tagged solutions registry, (e.g., {"win32": ... }, - otherwise, all errors cause a reject. --- .../src/RepositorySolutionsLoader.js | 17 +++--- .../test/RepositorySolutionsLoaderTests.js | 57 +++++++++++-------- 2 files changed, 41 insertions(+), 33 deletions(-) diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 0b04dd101..2a51869cd 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -56,8 +56,8 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { invokers: { getSolutions: { funcName: "gpii.flowManager.repositorySolutionsLoader.getSolutions", - args: ["{that}", "{arguments}.0", "{arguments}.1"] - // gpii revision, base file name + args: ["{that}", "{arguments}.0", "{arguments}.1", "{arguments}.2"] + // gpii revision, base file name, platform ID } } }); @@ -70,16 +70,15 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { * `null` on failure). * @param {String} gpiiRevision - the SHA256 revision of the repository to fetch. * @param {String} fileName - the name of the json file containing the - * solutions registry - * @param {String} platformId - the platform id for the solutions fetched, e.g., - * "win32". + * solutions registry, e.g. "win32.json5" * @return {Promise} A promise whose resolved value is eiher the solutions * registry, or, if there is an error, an object with an "isError: true" * property. */ -gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName, platformId) { +gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName) { var togo = fluid.promise(); if (gpiiRevision && fileName) { + var platformId = fileName.substring(0, fileName.indexOf(".")); var solutionsPromise = that.get({ directRevision: gpiiRevision, directFileName: fileName @@ -88,10 +87,10 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe var taggedRegistry = {}; taggedRegistry[platformId] = solutions; that.solutionsRegistry = fluid.freezeRecursive(taggedRegistry); - fluid.promise.follow(solutionsPromise, togo); + togo.resolve(that.solutionsRegistry); }, function (err) { fluid.log("Error retrieving solutions from repository: ", err, ", ", that.options.url); - togo.resolve(err); + togo.reject(err); }); } else { var msg = "Error retrieving solutions from repository: missing "; @@ -104,7 +103,7 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe else { msg += "file name"; } - togo.resolve({isError: true, message: msg, statusCode: 404}); + togo.reject({isError: true, message: msg, statusCode: 404}); } return togo; }; diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js index 7dd0eadc3..e1df030d9 100644 --- a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -24,27 +24,38 @@ kettle.loadTestingSupport(); fluid.registerNamespace("gpii.tests.repositorySolutionsLoader"); -gpii.tests.repositorySolutionsLoader.hostname = "http://gpii.net"; -gpii.tests.repositorySolutionsLoader.prefix = "prefix"; -gpii.tests.repositorySolutionsLoader.revision = "32759c38f9e1a5a38072f8c5e60b02a5d20969d7"; -gpii.tests.repositorySolutionsLoader.suffix = "suffix"; -gpii.tests.repositorySolutionsLoader.platformId = "darwin"; -gpii.tests.repositorySolutionsLoader.fileName = "darwin.json5"; +gpii.tests.repositorySolutionsLoader = { + hostname: "http://gpii.net", + prefix: "prefix", + revision: "32759c38f9e1a5a38072f8c5e60b02a5d20969d7", + suffix: "suffix", + platformId: "darwin", + fileName: "darwin.json5", + solutionsRegistryFolderPath: "%flowManager/test/data/", + taggedSolutions: {} // filled in below +}; gpii.tests.repositorySolutionsLoader.path = "/" + gpii.tests.repositorySolutionsLoader.prefix + "/" + gpii.tests.repositorySolutionsLoader.revision + "/" + gpii.tests.repositorySolutionsLoader.suffix + "/" + gpii.tests.repositorySolutionsLoader.fileName; -gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath = "%flowManager/test/data/"; gpii.tests.repositorySolutionsLoader.solutions = fluid.require( gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath + gpii.tests.repositorySolutionsLoader.fileName ); +// The solutions registry files contain a set of solutions as an object. The +// RepositorySolutionsLoader tags the set with a platform ID and returns the +// tagged set as its payload. +fluid.set( + gpii.tests.repositorySolutionsLoader.taggedSolutions, + gpii.tests.repositorySolutionsLoader.platformId, + gpii.tests.repositorySolutionsLoader.solutions +); + // Set up mock cloud request/response gpii.tests.repositorySolutionsLoader.setUpNock = function (config) { - var cloudMock = nock(gpii.tests.repositorySolutionsLoader.hostname); cloudMock.log(console.log); @@ -103,13 +114,12 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { task: "{repositorySolutionsLoader}.getSolutions", args: [ gpii.tests.repositorySolutionsLoader.revision, - gpii.tests.repositorySolutionsLoader.fileName, - gpii.tests.repositorySolutionsLoader.platformId + gpii.tests.repositorySolutionsLoader.fileName ], resolve: "jqUnit.assertDeepEq", resolveArgs: [ - "The response is the expected solutions", - gpii.tests.repositorySolutionsLoader.success.nockConfig.response, + "Check response for tagged solutions", + gpii.tests.repositorySolutionsLoader.taggedSolutions, "{arguments}.0" ] }] @@ -158,12 +168,11 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevis task: "{repositorySolutionsLoader}.getSolutions", args: [ null, - gpii.tests.repositorySolutionsLoader.fileName, - gpii.tests.repositorySolutionsLoader.platformId + gpii.tests.repositorySolutionsLoader.fileName ], - resolve: "jqUnit.assertDeepEq", - resolveArgs: [ - "The revision is expected as missing", + reject: "jqUnit.assertDeepEq", + rejectArgs: [ + "Check missing revision", gpii.tests.repositorySolutionsLoader.missingRevision.expected, "{arguments}.0", gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath, @@ -211,16 +220,16 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingFileN name: "Revision requester module tests - missing file name", expect: 1, tests: [{ - name: "Response: missing revision", + name: "Response: missing file name", sequence: [{ task: "{repositorySolutionsLoader}.getSolutions", args: [ gpii.tests.repositorySolutionsLoader.revision, null ], - resolve: "jqUnit.assertDeepEq", - resolveArgs: [ - "The file naem is expected as missing", + reject: "jqUnit.assertDeepEq", + rejectArgs: [ + "Check missing file name", gpii.tests.repositorySolutionsLoader.missingFileName.expected, "{arguments}.0" ] @@ -269,9 +278,9 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevis sequence: [{ task: "{repositorySolutionsLoader}.getSolutions", args: [null, null], - resolve: "jqUnit.assertDeepEq", - resolveArgs: [ - "The revision and file name are expected as missing", + reject: "jqUnit.assertDeepEq", + rejectArgs: [ + "Check missing both revision and file name", gpii.tests.repositorySolutionsLoader.missingRevisionAndFileName.expected, "{arguments}.0" ] From cf2518776c65e4b0bf3b037108c92419620de005 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 17 Mar 2020 12:31:50 -0400 Subject: [PATCH 44/68] GPII-4273: (GPII-4273iv) Addressed review comments for capture tests --- .../flowManager/test/CaptureTests.js | 20 +++++-------------- 1 file changed, 5 insertions(+), 15 deletions(-) diff --git a/gpii/node_modules/flowManager/test/CaptureTests.js b/gpii/node_modules/flowManager/test/CaptureTests.js index e39dce994..d1a7ddd75 100644 --- a/gpii/node_modules/flowManager/test/CaptureTests.js +++ b/gpii/node_modules/flowManager/test/CaptureTests.js @@ -41,24 +41,21 @@ gpii.tests.flowManager.capture.checkForFakeMags = function (payload) { }, payload.fakemag2); }; +gpii.tests.flowManager.capture.platformId = "darwin"; gpii.tests.flowManager.capture.platformReporter = function () { return { - id: "darwin" + id: gpii.tests.flowManager.capture.platformId }; }; -fluid.defaults("gpii.tests.flowManager.capture.platformReporter", { - gradeNames: "fluid.function" -}); - gpii.tests.flowManager.capture.checkForInstalledMags = function (payload) { jqUnit.assertEquals("There should be 2 solutions installed", 2, Object.keys(payload).length); jqUnit.assertEquals("Check for Fake Mag 1", "Fake Magnifier 1", payload.fakemag1.name); jqUnit.assertEquals("Check for Fake Mag 2", "Fake Magnifier 2 - fully featured", payload.fakemag2.name); }; -gpii.tests.flowManager.capture.adjustSolutions = function (solutionsRegistryDataSource, revision, platformReporter) { - var platformId = fluid.invokeGlobalFunction(platformReporter).id; +gpii.tests.flowManager.capture.adjustSolutions = function (solutionsRegistryDataSource) { + var platformId = gpii.tests.flowManager.capture.platformId; var testDataFile = __dirname + "/data/capture_fakemag_settings.json"; var testDataFile2 = __dirname + "/data/capture_fakemag2_settings.json"; @@ -81,18 +78,11 @@ fluid.defaults("gpii.tests.flowManager.capture.tests", { name: "Simple system capture", tests: [{ name: "Check for existing FakeMag Settings", - expect: 4, + expect: 3, sequence: [{ event: "{config}.server.flowManager.solutionsRegistryDataSource.events.solutionsRegistryReady", listener: "jqUnit.assert", args: ["Solutions registry ready"] - }, { - funcName: "{config}.server.flowManager.solutionsRegistryDataSource.get", - args: [{os: "darwin"}] - }, { - event: "{config}.server.flowManager.solutionsRegistryDataSource.events.onRead", - listener: "jqUnit.assertValue", - args: ["Solutions registry read solutions", "{arguments}.0"] }, { task: "{config}.server.flowManager.capture.getSystemSettingsCapture", args: [], From 1dafa91e0584e0e0ab93bb8ca769317942806e1d Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 17 Mar 2020 17:48:16 -0400 Subject: [PATCH 45/68] GPII-4273: (GPII-4273iv) More changes to RepositorySolutionsLoader due to review comments Main change was to have the get() method's returned promise either resolve to the solutions registry fetched, or reject with an error. --- .../gpii.flowManager.config.local.base.json5 | 4 -- .../src/RepositorySolutionsLoader.js | 27 ++++---- .../test/RepositorySolutionsLoaderTests.js | 62 +++++++++---------- 3 files changed, 42 insertions(+), 51 deletions(-) diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index 73c9e674c..ff20a9188 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -17,10 +17,6 @@ "flowManager.local.solutionsRegistryRepositorySuffix": { "record": "/testData/solutions", "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.urlSuffix" - }, - "flowManager.local.solutionsRegistryFolder": { - "record": "%gpii-universal/testData/solutions", - "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.solutionsRegistryFolderPath" } } }, diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index 2a51869cd..b1b95598b 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -36,12 +36,9 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { fileName: "%directFileName" }, // The URL prefix and suffix are distributed from a config file such as - // e.g., gpii.flowManager.config.local.base, as is the path to the local - // folder in which to save the contents of the downloaded solutions registry - // file. + // e.g., gpii.flowManager.config.local.base. urlPrefix: "", urlSuffix: "", - solutionsRegistryFolderPath: "", protocol: "https:", // default members: { // Contents of the solutions registry file downloaded from the source @@ -56,8 +53,8 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { invokers: { getSolutions: { funcName: "gpii.flowManager.repositorySolutionsLoader.getSolutions", - args: ["{that}", "{arguments}.0", "{arguments}.1", "{arguments}.2"] - // gpii revision, base file name, platform ID + args: ["{that}", "{arguments}.0", "{arguments}.1"] + // gpii revision, file name } } }); @@ -69,16 +66,18 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { * registry fetched from the source code repository, set herein (will be * `null` on failure). * @param {String} gpiiRevision - the SHA256 revision of the repository to fetch. - * @param {String} fileName - the name of the json file containing the - * solutions registry, e.g. "win32.json5" + * @param {String} platformId - the platform matching the solutions registry + * that this is retrieving, e.g. "win32". It is used + * to construct the name of the solutions registry + * file. * @return {Promise} A promise whose resolved value is eiher the solutions * registry, or, if there is an error, an object with an "isError: true" * property. */ -gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, fileName) { +gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRevision, platformId) { var togo = fluid.promise(); - if (gpiiRevision && fileName) { - var platformId = fileName.substring(0, fileName.indexOf(".")); + if (gpiiRevision && platformId) { + var fileName = platformId + ".json5"; var solutionsPromise = that.get({ directRevision: gpiiRevision, directFileName: fileName @@ -94,14 +93,14 @@ gpii.flowManager.repositorySolutionsLoader.getSolutions = function (that, gpiiRe }); } else { var msg = "Error retrieving solutions from repository: missing "; - if (!gpiiRevision && !fileName) { - msg += "revision and file name"; + if (!gpiiRevision && !platformId) { + msg += "revision and platform ID"; } else if (!gpiiRevision) { msg += "revision"; } else { - msg += "file name"; + msg += "platform ID"; } togo.reject({isError: true, message: msg, statusCode: 404}); } diff --git a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js index e1df030d9..e557bb0fe 100644 --- a/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js +++ b/gpii/node_modules/flowManager/test/RepositorySolutionsLoaderTests.js @@ -69,7 +69,6 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader", { gradeNames: ["gpii.flowManager.repositorySolutionsLoader"], urlPrefix: gpii.tests.repositorySolutionsLoader.hostname + "/" + gpii.tests.repositorySolutionsLoader.prefix, urlSuffix: gpii.tests.repositorySolutionsLoader.suffix, - solutionsRegistryFolderPath: gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath, protocol: "http:" }); @@ -114,7 +113,7 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.success", { task: "{repositorySolutionsLoader}.getSolutions", args: [ gpii.tests.repositorySolutionsLoader.revision, - gpii.tests.repositorySolutionsLoader.fileName + gpii.tests.repositorySolutionsLoader.platformId ], resolve: "jqUnit.assertDeepEq", resolveArgs: [ @@ -168,16 +167,13 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevis task: "{repositorySolutionsLoader}.getSolutions", args: [ null, - gpii.tests.repositorySolutionsLoader.fileName + gpii.tests.repositorySolutionsLoader.platformId ], reject: "jqUnit.assertDeepEq", rejectArgs: [ "Check missing revision", gpii.tests.repositorySolutionsLoader.missingRevision.expected, - "{arguments}.0", - gpii.tests.repositorySolutionsLoader.solutionsRegistryFolderPath, - gpii.tests.repositorySolutionsLoader.fileName, - gpii.tests.repositorySolutionsLoader.platformId + "{arguments}.0" ] }] }] @@ -195,8 +191,8 @@ fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingRevision", { } }); -// 3. Failure due to missing file name -gpii.tests.repositorySolutionsLoader.missingFileName = { +// 3. Failure due to missing platform ID +gpii.tests.repositorySolutionsLoader.missingPlatformId = { nockConfig: { url: gpii.tests.repositorySolutionsLoader.hostname + gpii.tests.repositorySolutionsLoader.path, type: "get", @@ -204,23 +200,23 @@ gpii.tests.repositorySolutionsLoader.missingFileName = { response: { isError: true, statusCode: 404, - message: "Error retrieving solutions from repository: missing file name" + message: "Error retrieving solutions from repository: missing platform ID" } }, expected: { isError: true, statusCode: 404, - message: "Error retrieving solutions from repository: missing file name" + message: "Error retrieving solutions from repository: missing platform ID" } }; -fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingFileName", { +fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingPlatformId", { gradeNames: "fluid.test.testCaseHolder", modules: [{ - name: "Revision requester module tests - missing file name", + name: "Revision requester module tests - missing platform ID", expect: 1, tests: [{ - name: "Response: missing file name", + name: "Response: missing platform ID", sequence: [{ task: "{repositorySolutionsLoader}.getSolutions", args: [ @@ -229,8 +225,8 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingFileN ], reject: "jqUnit.assertDeepEq", rejectArgs: [ - "Check missing file name", - gpii.tests.repositorySolutionsLoader.missingFileName.expected, + "Check missing platform ID", + gpii.tests.repositorySolutionsLoader.missingPlatformId.expected, "{arguments}.0" ] }] @@ -238,19 +234,19 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingFileN }] }); -fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingFileName", { +fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingPlatformId", { gradeNames: ["gpii.tests.repositorySolutionsLoaderTests", "gpii.test.testWithNock"], - testCaseHolderGrade: "gpii.tests.repositorySolutionsLoader.testCaseHolder.missingFileName", + testCaseHolderGrade: "gpii.tests.repositorySolutionsLoader.testCaseHolder.missingPlatformId", invokers: { setUpNock: { funcName: "gpii.tests.repositorySolutionsLoader.setUpNock", - args: gpii.tests.repositorySolutionsLoader.missingFileName.nockConfig + args: gpii.tests.repositorySolutionsLoader.missingPlatformId.nockConfig } } }); -// 4. Failure due to missing revision and file name -gpii.tests.repositorySolutionsLoader.missingRevisionAndFileName = { +// 4. Failure due to missing revision and platform ID +gpii.tests.repositorySolutionsLoader.missingRevisionAndPlatformId = { nockConfig: { url: gpii.tests.repositorySolutionsLoader.hostname + gpii.tests.repositorySolutionsLoader.path, type: "get", @@ -258,30 +254,30 @@ gpii.tests.repositorySolutionsLoader.missingRevisionAndFileName = { response: { isError: true, statusCode: 404, - message: "Error retrieving solutions from repository: missing revision and file name" + message: "Error retrieving solutions from repository: missing revision and platform ID" } }, expected: { isError: true, statusCode: 404, - message: "Error retrieving solutions from repository: missing revision and file name" + message: "Error retrieving solutions from repository: missing revision and platform ID" } }; -fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevisionAndFileName", { +fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevisionAndPlatformId", { gradeNames: "fluid.test.testCaseHolder", modules: [{ - name: "Revision requester module tests - missing revision and file name", + name: "Revision requester module tests - missing revision and platform ID", expect: 1, tests: [{ - name: "Response: missing revision and file name", + name: "Response: missing revision and platform ID", sequence: [{ task: "{repositorySolutionsLoader}.getSolutions", args: [null, null], reject: "jqUnit.assertDeepEq", rejectArgs: [ - "Check missing both revision and file name", - gpii.tests.repositorySolutionsLoader.missingRevisionAndFileName.expected, + "Check missing both revision and platform ID", + gpii.tests.repositorySolutionsLoader.missingRevisionAndPlatformId.expected, "{arguments}.0" ] }] @@ -289,13 +285,13 @@ fluid.defaults("gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevis }] }); -fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingRevisionAndFileName", { +fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingRevisionAndPlatformId", { gradeNames: ["gpii.tests.repositorySolutionsLoaderTests", "gpii.test.testWithNock"], - testCaseHolderGrade: "gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevisionAndFileName", + testCaseHolderGrade: "gpii.tests.repositorySolutionsLoader.testCaseHolder.missingRevisionAndPlatformId", invokers: { setUpNock: { funcName: "gpii.tests.repositorySolutionsLoader.setUpNock", - args: gpii.tests.repositorySolutionsLoader.missingRevisionAndFileName.nockConfig + args: gpii.tests.repositorySolutionsLoader.missingRevisionAndPlatformId.nockConfig } } }); @@ -304,6 +300,6 @@ fluid.defaults("gpii.tests.repositorySolutionsLoaderTests.missingRevisionAndFile fluid.test.runTests([ "gpii.tests.repositorySolutionsLoaderTests.success", "gpii.tests.repositorySolutionsLoaderTests.missingRevision", - "gpii.tests.repositorySolutionsLoaderTests.missingFileName", - "gpii.tests.repositorySolutionsLoaderTests.missingRevisionAndFileName" + "gpii.tests.repositorySolutionsLoaderTests.missingPlatformId", + "gpii.tests.repositorySolutionsLoaderTests.missingRevisionAndPlatformId" ]); From 92233449bfe272db3b03b30d1e857209775dcc07 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 18 Mar 2020 12:21:08 -0400 Subject: [PATCH 46/68] GPII-4273: (GPII-4273iv) Modifications due to review comments Most important change: the local solutions registry data source's loadFromRepository() now returns a promise that resolves to the downloaded registry, or null if the download fails. --- .../flowManager/src/FlowManager.js | 5 +- .../src/SolutionsRegistryDataSource.js | 64 +++++---- .../test/SolutionsRegistryDataSourceTests.js | 123 ++++++++---------- .../test/shared/BrowserChannelTestDefs.js | 7 +- 4 files changed, 102 insertions(+), 97 deletions(-) diff --git a/gpii/node_modules/flowManager/src/FlowManager.js b/gpii/node_modules/flowManager/src/FlowManager.js index e749c5364..e57569dc4 100644 --- a/gpii/node_modules/flowManager/src/FlowManager.js +++ b/gpii/node_modules/flowManager/src/FlowManager.js @@ -43,7 +43,7 @@ fluid.defaults("gpii.flowManager", { gradeNames: ["kettle.app"], components: { solutionsRegistryDataSource: { - type: "gpii.flowManager.solutionsRegistry.dataSource.cloud", + type: "gpii.flowManager.solutionsRegistry.dataSource.cloudBased", options: { termMap: { "os": "%os", @@ -332,10 +332,13 @@ gpii.flowManager.local.resetAtStart = function (lifecycleManager, resetAtStart, defaultSettingsDataPromise.then(function (defaultSettingsData) { var defaultSnapshot = defaultSettingsData.defaultSnapshot; if (resetAtStart && defaultSnapshot) { + fluid.log("Resetting on system startup to default settings: ", defaultSnapshot); var resetPromise = lifecycleManager.restoreSnapshot(defaultSnapshot); resetPromise.then(function () { + fluid.log("Resetting on system startup completes successfully."); resetSuccessEvent.fire(); }, function (error) { + fluid.log("Resetting on system startup fails with the error: ", error); resetErrorEvent.fire(error); }); } else { diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index d80f18ce1..2a1c3aaf2 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -83,12 +83,12 @@ gpii.flowManager.solutionsRegistry.dataSource.loadFromLocalDisk = function (that }; // Solutions registry data source used by the Cloud Based Flow Manager -fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.cloud", { +fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.cloudBased", { gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource"], - readOnlyGrade: "gpii.flowManager.solutionsRegistry.dataSource.cloud", + readOnlyGrade: "gpii.flowManager.solutionsRegistry.dataSource.cloudBased", invokers: { getImpl: { - funcName: "gpii.flowManager.solutionsRegistry.dataSource.cloud.handle", + funcName: "gpii.flowManager.solutionsRegistry.dataSource.cloudBased.handle", args: ["{that}", "{arguments}.1", "{arguments}.2"] // options, directModel } @@ -107,17 +107,18 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.cloud", { /** * Handler for get requests to the solutions registry used by the Cloud Based - * Flow Manager. It will return either an object containing solutions registries - * for the given platform. + * Flow Manager. It will return an object containing the solutions registry for + * the given platform. * - * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource.cloud + * @param {Object} that - The gpii.flowManager.solutionsRegistry.dataSource.cloudBased + instance that is handling the GET request. * @param {Object} requestOptions - Currently the only request option supported * is "os". The returned solutions registry will be the solutions for * the OS version provided. * @return {Promise} A promise that will be resolved with results (see above) or * rejected on error. */ -gpii.flowManager.solutionsRegistry.dataSource.cloud.handle = function (that, requestOptions) { +gpii.flowManager.solutionsRegistry.dataSource.cloudBased.handle = function (that, requestOptions) { var promise = fluid.promise(); if (requestOptions.os && requestOptions.os in that.fullSolutionsRegistry) { promise.resolve(that.fullSolutionsRegistry[requestOptions.os]); @@ -131,8 +132,15 @@ gpii.flowManager.solutionsRegistry.dataSource.cloud.handle = function (that, req return promise; }; -// Solutions registry datasource used by the Local Flow Manager. It loads both -// solutions from the source code repository as well as the local file sysmtem. +// Solutions registry datasource used by the Local Flow Manager. On creation, +// it first loads all of the solution registries from the local file system for +// all of the platforms (win32, linux, darwin, android, etc). Then, the +// solutions for the current platform are downloaded from the source code +// repository. The current platform is the platform on which the Local Flow +// Manager is running. The solutions fetched from the source code repository +// overlay the set retrieved from the local file system at the first step. If +// the download from the source code repository fails, then the solutions loaded +// from the local file system are used. fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { gradeNames: ["gpii.flowManager.solutionsRegistry.dataSource"], components: { @@ -142,8 +150,7 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { repositorySolutionsLoader: { type: "gpii.flowManager.repositorySolutionsLoader" } - // The platformReporter subcomponent is distributed down from local - // flowManager +// The platformReporter is distributed down from the local flowManager // platformReporter: { // type: "gpii.platformReporter.native" // } @@ -186,8 +193,6 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { * If successful, sets the repositorySolutionsRegistry member to the fetched * solutions registry. * @param {Component} that - An instance of gpii.flowManager.solutionsRegistry.dataSource - * @param {Component} that.repositorySolutionsLoader - An instance of - * gpii.flowManager.repositorySolutionsLoader. * @param {Object} that.repositorySolutionsRegistry - Set to point to the * solutions registry retrieved from the respository, or null if * none were retrieved. @@ -197,20 +202,27 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { * @param {Component} platformReporter - used to get the name of the platform, * e.g., "win32". * @return {Promise} A promise whose resolved value is eiher the solutions - * registry, or, if there is an error, an object with an "isError: true" - * property. + * registry from the source code repository, or null, if there was an error. */ gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = function (that, revision, platformReporter) { var gpiiRevision = revision.sha256; var platformId = platformReporter.reportPlatform().id; - var fileName = platformId + ".json5"; - var togo = that.repositorySolutionsLoader.getSolutions(gpiiRevision, fileName, platformId); - togo.then(function () { - // Either the solutions registry has been successfully retrieved from the - // repository, or it hasn't (= null). Set that.repositorySolutionsRegistry - // to whatever the result. - that.repositorySolutionsRegistry = that.repositorySolutionsLoader.solutionsRegistry; - }); + var repoLoadPromise = that.repositorySolutionsLoader.getSolutions(gpiiRevision, platformId); + + // Either the solutions registry has been successfully retrieved from the + // repository, or it hasn't. Set that.repositorySolutionsRegistry to + // to either the result, or to null. + var togo = fluid.promise(); + repoLoadPromise.then( + function (repositorySolutions) { + that.repositorySolutionsRegistry = repositorySolutions; + togo.resolve(repositorySolutions); + }, + function () { + that.repositorySolutionsRegistry = null; + togo.resolve(null); + } + ); return togo; }; @@ -242,6 +254,12 @@ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, req statusCode: 404 }); } + } else { + promise.reject({ + isError: true, + message: "The requested OS (undefined) was not present in the solutions registry", + statusCode: 404 + }); } return promise; }; diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index be91cfeed..d1fdc1d47 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -28,6 +28,7 @@ gpii.tests.solutionsRegistry = { platformId: "darwin", repositoryDarwinSolutions: require("./data/darwin.json5"), requestOptions: { os: "darwin" }, + requestOptionsMissingOs: {foo: "bar"}, win32PlatformId: "win32" }; @@ -43,13 +44,19 @@ gpii.tests.solutionsRegistry.checkNamedRegistry = function (msg, equalityCheck, equalityCheck(msg, expectedSolutions, result); }; +// Check for failures. +gpii.tests.solutionsRegistry.checkRejection = function (msg, result) { + jqUnit.assertTrue(msg, result.isError); + jqUnit.assertEquals(msg, 404, result.statusCode); +}; + // ======== Testing the solutions registry data source used by the CBFM ======== fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { gradeNames: "fluid.test.testCaseHolder", components: { solutionsRegistryDataSource: { - type: "gpii.flowManager.solutionsRegistry.dataSource.cloud", + type: "gpii.flowManager.solutionsRegistry.dataSource.cloudBased", options: { path: gpii.tests.solutionsRegistry.path } @@ -62,27 +69,28 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { name: "Solutions registry used with CBFM", sequence: [ { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- START"] }, - - // For some reason, even though the solutionsRegistryReady event - // fires, this doesn't hear it. - // ... and doesn't appear to need to wait for it (?!) - /*{ - event: "{solutionsRegistryDataSource}.events.solutionsRegistryReady", - listener: "jqUnit.assert", - args: ["CBFM solutionsRegistryDataSource ready"] - },*/ { - funcName: "{solutionsRegistryDataSource}.get", - args: [gpii.tests.solutionsRegistry.requestOptions] - }, { - event: "{solutionsRegistryDataSource}.events.onRead", - listener: "gpii.tests.solutionsRegistry.checkOneRegistry", - args: [ + { + task: "{solutionsRegistryDataSource}.get", + args: [gpii.tests.solutionsRegistry.requestOptions], + resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", + resolveArgs: [ "Expecting one solutions registry", gpii.tests.solutionsRegistry.requestOptions.os, "{arguments}.0" ] }, - { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- END"] } + { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- END"] }, + { funcName: "fluid.log", args: ["Solutions Registry for CBFM, failure to provide platform -- START"] }, + { + task: "{solutionsRegistryDataSource}.get", + args: [gpii.tests.solutionsRegistry.requestOptionsMissingOs], + reject: "gpii.tests.solutionsRegistry.checkRejection", + rejectArgs: [ + "Check missing OS parameter", + "{arguments}.0" + ] + }, + { funcName: "fluid.log", args: ["Solutions Registry for CBFM, failure to provide platform -- END"] } ] }] }] @@ -114,14 +122,6 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.mockLoadFromReposi } }, listeners: { - "loadSolutions.loadFromLocalDisk": { - listener: "{that}.loadFromLocalDisk", - priority: "first" - }, - "loadSolutions.getRevision": { - listener: "{revisionRequester}.getRevision", - priority: "after:loadFromLocalDisk" - }, "loadSolutions.loadFromRepository": { listener: "gpii.tests.solutionsRegistry.dataSource.local.mockRepoLoad", args: [ @@ -130,10 +130,6 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.mockLoadFromReposi gpii.tests.solutionsRegistry.repositoryDarwinSolutions ], priority: "after:getRevision" - }, - "loadSolutions.solutionsLoaded": { - listener: "{that}.events.solutionsRegistryReady.fire", - priority: "after:loadFromRepository" } } }); @@ -142,7 +138,7 @@ gpii.tests.solutionsRegistry.dataSource.local.mockRepoLoad = function (that, pla var promise = fluid.promise(); var solutionsRegistry = {}; solutionsRegistry[platformId] = solutions; - that.repositorySolutionsRegistry = solutionsRegistry; + that.repositorySolutionsRegistry = fluid.freezeRecursive(solutionsRegistry); promise.resolve(that.repositorySolutionsRegistry); return promise; }; @@ -159,7 +155,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.mockRepository.testCaseHolder }, modules: [{ name: "Solutions registry used by LFM - repository + file system based solutions", - expect: 2, + expect: 3, tests: [{ name: "Solutions registry LFM - solutions loaded from repository and looking for named registry", sequence: [ @@ -169,12 +165,10 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.mockRepository.testCaseHolder listener: "jqUnit.assert", args: ["LFM solutionsRegistryMockRepoLoad ready"] }, { - funcName: "{solutionsRegistryMockRepoLoad}.get", - args: [gpii.tests.solutionsRegistry.requestOptions] - }, { - event: "{solutionsRegistryMockRepoLoad}.events.onRead", - listener: "gpii.tests.solutionsRegistry.checkNamedRegistry", - args: [ + task: "{solutionsRegistryMockRepoLoad}.get", + args: [gpii.tests.solutionsRegistry.requestOptions], + resolve: "gpii.tests.solutionsRegistry.checkNamedRegistry", + resolveArgs: [ "Expecting named solutions registry from repository", jqUnit.assertDeepEq, gpii.tests.solutionsRegistry.repositoryDarwinSolutions, @@ -184,18 +178,27 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.mockRepository.testCaseHolder { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named repository registry -- END"] }, { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named local registry -- START"] }, { - funcName: "{solutionsRegistryMockRepoLoad}.get", - args: [{os: gpii.tests.solutionsRegistry.win32PlatformId}] - }, { - event: "{solutionsRegistryMockRepoLoad}.events.onRead", - listener: "gpii.tests.solutionsRegistry.checkOneRegistry", - args: [ + task: "{solutionsRegistryMockRepoLoad}.get", + args: [{os: gpii.tests.solutionsRegistry.win32PlatformId}], + resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", + resolveArgs: [ "Expecting named solutions registries, but from the local file system", gpii.tests.solutionsRegistry.win32PlatformId, "{arguments}.0" ] }, - { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting all registries -- START"] } + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, getting named local registry -- END"] }, + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, failure to provide platform -- START"] }, + { + task: "{solutionsRegistryMockRepoLoad}.get", + args: [gpii.tests.solutionsRegistry.requestOptionsMissingOs], + reject: "gpii.tests.solutionsRegistry.checkRejection", + rejectArgs: [ + "Check missing OS parameter", + "{arguments}.0" + ] + }, + { funcName: "fluid.log", args: ["Solutions Registry Mock Repo Load, failure to provide platform -- END"] } ] }] }] @@ -226,22 +229,10 @@ fluid.defaults("gpii.tests.solutionsRegistry.dataSource.local.failLoadFromReposi } }, listeners: { - "loadSolutions.loadFromLocalDisk": { - listener: "{that}.loadFromLocalDisk", - priority: "first" - }, - "loadSolutions.getRevision": { - listener: "{revisionRequester}.getRevision", - priority: "after:loadFromLocalDisk" - }, "loadSolutions.loadFromRepository": { listener: "gpii.tests.solutionsRegistry.dataSource.local.nullRepoLoad", args: ["{that}"], priority: "after:getRevision" - }, - "loadSolutions.solutionsLoaded": { - listener: "{that}.events.solutionsRegistryReady.fire", - priority: "after:loadFromRepository" } } }); @@ -275,12 +266,10 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", listener: "jqUnit.assert", args: ["LFM solutionsRegistryNullRepoLoad ready"] }, { - funcName: "{solutionsRegistryNullRepoLoad}.get", - args: [gpii.tests.solutionsRegistry.requestOptions] - }, { - event: "{solutionsRegistryNullRepoLoad}.events.onRead", - listener: "gpii.tests.solutionsRegistry.checkNamedRegistry", - args: [ + task: "{solutionsRegistryNullRepoLoad}.get", + args: [gpii.tests.solutionsRegistry.requestOptions], + resolve: "gpii.tests.solutionsRegistry.checkNamedRegistry", + resolveArgs: [ "Expecting local solutions registry", jqUnit.assertDeepNeq, gpii.tests.solutionsRegistry.repositoryDarwinSolutions, @@ -290,12 +279,10 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named 'repository' registry -- END"] }, { funcName: "fluid.log", args: ["Solutions Registry No Repo Load, getting named local registry -- START"] }, { - funcName: "{solutionsRegistryNullRepoLoad}.get", - args: [{os: gpii.tests.solutionsRegistry.win32PlatformId}] - }, { - event: "{solutionsRegistryNullRepoLoad}.events.onRead", - listener: "gpii.tests.solutionsRegistry.checkOneRegistry", - args: [ + task: "{solutionsRegistryNullRepoLoad}.get", + args: [{os: gpii.tests.solutionsRegistry.win32PlatformId}], + resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", + resolveArgs: [ "Expecting local named solutions registry", gpii.tests.solutionsRegistry.win32PlatformId, "{arguments}.0" diff --git a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js index f390559bf..1c13872a4 100644 --- a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js +++ b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js @@ -55,11 +55,8 @@ gpii.tests.flowManager.browserChannel.reportPlatform = function () { // A no-op to gracefully fail fetching the solutions registry from the source // code repository in order to use the canned registry set up for these tests. -gpii.tests.flowManager.browserChannel.getRepositorySolutions = function (repositorySolutionsLoader) { - var togo = fluid.promise(); - repositorySolutionsLoader.solutionsRegistry = null; - togo.resolve(repositorySolutionsLoader.solutionsRegistry); - return togo; +gpii.tests.flowManager.browserChannel.getRepositorySolutions = function (/*repositorySolutionsLoader*/) { + return fluid.promise().resolve(null); }; gpii.tests.flowManager.browserChannel.checkConnectionRequest = function (data, request) { From 71614d3f483293aebe54e28b0e94cf3695845430 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 19 Mar 2020 09:43:00 -0400 Subject: [PATCH 47/68] GPII-4273: (GPII-4273iv) Improved error message --- .../node_modules/flowManager/src/SolutionsRegistryDataSource.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 2a1c3aaf2..4f7b3c119 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -257,7 +257,7 @@ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, req } else { promise.reject({ isError: true, - message: "The requested OS (undefined) was not present in the solutions registry", + message: "Missing OS (undefined) for accessing the solutions registry", statusCode: 404 }); } From c21ebf31fbca60276070ced305c8f9d08f58c79d Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 19 Mar 2020 16:26:13 -0400 Subject: [PATCH 48/68] GPII-4273: (GPII-4273iv) Added documentation for the SolutionsRegistryDataSource --- documentation/SolutionsRegistryDataSource.md | 94 ++++++++++++++++++++ 1 file changed, 94 insertions(+) create mode 100644 documentation/SolutionsRegistryDataSource.md diff --git a/documentation/SolutionsRegistryDataSource.md b/documentation/SolutionsRegistryDataSource.md new file mode 100644 index 000000000..5663149be --- /dev/null +++ b/documentation/SolutionsRegistryDataSource.md @@ -0,0 +1,94 @@ +# Solutions Registry Data Source + +The solutions registry data source provides a RESTful means of fetching +solutions registries via the [FlowManager](FlowManager.md) in order to determine +which solutions are available and appropriate for a user's preferences. A +solution is an application, such as the NVDA screen reader, or an operating +system feature, such as the Windows high contrast theme set using a system +control panel. Each solution supports a set of preferences and describes how +to configure the solution, launch it, reset it, and stop it. + +The solutions are listed in `JSON` files called "solutions registries". The +structure of a solutions registry is documented in +[SolutionsRegistryFormat](SolutionsRegistryFormat.md). Since solutions are +frequently specific to an operating system, or "platform", there are separate +solution registries for each platform. Examples of platforms are Windows, +GNOME-Linux, MacOS, and Android. + +The SolutionsRegistryDataSource is a component that loads and caches +solutions registries when the GPII starts up, and then serves solutions to the +rest of the system upon request. The flow manager coordinates retrieval of +solutions, user preferences, device information, and so on, passing these to the +[MatchMaker Framework](MatchMakerFramework.md) and [LifecycleManager](LifecycleManager.md). + +There are two initialization workflows with respect to solutions registries +depending on whether the flow manager is running in the cloud or locally on the +client device. This are described in the following two sections. + +## Cloud Based Flow Manager + +The solutions registries are included in the distribution of `gpii-universal` +along with the other components of the GPII -- the flow manager, lifecycle +manager and so on. The Cloud Base FlowManager is a central service for GPII +clients, and these clients run on a variety of platforms. As such, the +platform that the Cloud Based FlowManager is executing on is irrelevant in +terms of providing solutions for the client. When a request for a solutions +registry is made, the flow manager needs to have access to all platform +solutions in order to respond with the solutions relevant to a particular +client. + +The solutions registries are loaded from the local file system at system +startup. Here, "local" refers to the file system associated with machine that +the Cloud Base FlowManager is running on. The SolutionsRegistryDataSource is a +subcomponent of the flow manager, and there is a sequence of operations and +events that occurs during its instantiation: + +1. `loadSolutions.loadFromLocalDisk`, + * The solutions registry files are loaded from the local file system, +2. `loadSolutions.solutionsLoaded` + * Fires a `solutionsRegistryReady` event. + +The `solutionsRegistryReady` informs the flow manager that its +SolutionsRegistryDataSource is ready to provide solutions upon request. + +## Local Flow Manager + +As in the case of the Cloud Based FlowManager, the solutions registries are +included in the distribution of GPII for the client. However, they are not +updated as frequently as those in the cloud. In particular, the solutions +registry may be stale for the platform that the client is running on. However, +the registry associated with the latest version of the cloud based GPII is +available in `gpii-universal`'s source code repository (github), and can be +downloaded from there. In this regard, the Cloud Based FlowManager provides a +`/revision` end-point that responds with the full `SHA256` of the revision of +the source associated with the latest solutions registries. + +The SolutionsRegistryDataSource associated with the Local FlowManager uses the +initialized following sequence of events and operations at startup: + +1. `loadSolutions.loadFromLocalDisk`, + * The solutions registry files are loaded from the local file system, +2. `loadSolutions.getRevision`, + * Make an http request of the Cloud Based FlowManager for the revision of the + source code of the GPII used by the cloud, +3. `loadSolutions.loadFromRepository`, + * Make an http request of the source code respository, passing: + * the platform ID associated with the OS that the client is runing on, e.g. + "darwin", + * the revision fetched at the previous step, + * The solutions registry corresponding to the platform and revision provided is + downloaded from the source code repository and overlays the one fetched from + the local file system at the first step. +4. `loadSolutions.solutionsLoaded` + * Fires a `solutionsRegistryReady` event + +The above sequence is embeded within the Local FlowManager's `flowManagerReady` +startup interlock such that all initialition is completed before the GPII client +responds to user interactions. + +Note that both the `getRevision` and/or the `loadFromRepository` steps could +fail. In that case, the latest solutions registry for the client platform will +not be downloaded and cached within the client. When solutions for the client +platform are requested, the SolutionsRegistryDataSource uses a fallback where +the solutions loaded from the local file system during the first +`loadFromLocalDisk` step are provided. From 634fa2f36c9d80f3521a1296cefd12ddf763fe54 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 20 Mar 2020 12:04:06 -0400 Subject: [PATCH 49/68] GPII-4273: (GPII-4273iv) Improved check function in SolutionsRegistryDataSource tests --- .../test/SolutionsRegistryDataSourceTests.js | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index d1fdc1d47..e4e760545 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -32,10 +32,10 @@ gpii.tests.solutionsRegistry = { win32PlatformId: "win32" }; -// Check that the given platform id has been stripped out of the result. -gpii.tests.solutionsRegistry.checkOneRegistry = function (msg, platformId, result) { - jqUnit.assertValue(msg, result); - jqUnit.assertFalse(msg, platformId in result); +// Check that the local solutions for the given platformId matches the result. +gpii.tests.solutionsRegistry.checkLocalRegistry = function (msg, platformId, result) { + var solutions = fluid.require(gpii.tests.solutionsRegistry.path + "/" + platformId + ".json5"); + jqUnit.assertDeepEq(msg, solutions, result); }; // equalityCheck is either jqUnit.assertDeepEq() or jqUnit.assertDeepNeq(). @@ -72,7 +72,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { { task: "{solutionsRegistryDataSource}.get", args: [gpii.tests.solutionsRegistry.requestOptions], - resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", + resolve: "gpii.tests.solutionsRegistry.checkLocalRegistry", resolveArgs: [ "Expecting one solutions registry", gpii.tests.solutionsRegistry.requestOptions.os, @@ -180,7 +180,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.mockRepository.testCaseHolder { task: "{solutionsRegistryMockRepoLoad}.get", args: [{os: gpii.tests.solutionsRegistry.win32PlatformId}], - resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", + resolve: "gpii.tests.solutionsRegistry.checkLocalRegistry", resolveArgs: [ "Expecting named solutions registries, but from the local file system", gpii.tests.solutionsRegistry.win32PlatformId, @@ -281,7 +281,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.local.noRepository.testCaseHolder", { task: "{solutionsRegistryNullRepoLoad}.get", args: [{os: gpii.tests.solutionsRegistry.win32PlatformId}], - resolve: "gpii.tests.solutionsRegistry.checkOneRegistry", + resolve: "gpii.tests.solutionsRegistry.checkLocalRegistry", resolveArgs: [ "Expecting local named solutions registry", gpii.tests.solutionsRegistry.win32PlatformId, From a0b4abcb6d7bd556e31b31ea36255f83cadff383 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 20 Mar 2020 12:33:53 -0400 Subject: [PATCH 50/68] GPII-4273: (GPII-4273iv) Fixed lint errors, spelling, and grammar --- documentation/SolutionsRegistryDataSource.md | 74 ++++++++++++++------ 1 file changed, 51 insertions(+), 23 deletions(-) diff --git a/documentation/SolutionsRegistryDataSource.md b/documentation/SolutionsRegistryDataSource.md index 5663149be..de897d5f1 100644 --- a/documentation/SolutionsRegistryDataSource.md +++ b/documentation/SolutionsRegistryDataSource.md @@ -38,15 +38,23 @@ solutions in order to respond with the solutions relevant to a particular client. The solutions registries are loaded from the local file system at system -startup. Here, "local" refers to the file system associated with machine that +startup. Here, "local" refers to the file system associated with machine that the Cloud Base FlowManager is running on. The SolutionsRegistryDataSource is a subcomponent of the flow manager, and there is a sequence of operations and events that occurs during its instantiation: -1. `loadSolutions.loadFromLocalDisk`, - * The solutions registry files are loaded from the local file system, -2. `loadSolutions.solutionsLoaded` - * Fires a `solutionsRegistryReady` event. +
    +
  1. loadSolutions.loadFromLocalDisk, +
      +
    • The solutions registry files are loaded from the local file system,
    • +
    +
  2. +
  3. loadSolutions.solutionsLoaded +
      +
    • Fires a solutionsRegistryReady event.
    • +
    +
  4. +
The `solutionsRegistryReady` informs the flow manager that its SolutionsRegistryDataSource is ready to provide solutions upon request. @@ -57,33 +65,53 @@ As in the case of the Cloud Based FlowManager, the solutions registries are included in the distribution of GPII for the client. However, they are not updated as frequently as those in the cloud. In particular, the solutions registry may be stale for the platform that the client is running on. However, -the registry associated with the latest version of the cloud based GPII is +the registry associated with the latest version of the cloud based GPII is available in `gpii-universal`'s source code repository (github), and can be downloaded from there. In this regard, the Cloud Based FlowManager provides a `/revision` end-point that responds with the full `SHA256` of the revision of the source associated with the latest solutions registries. The SolutionsRegistryDataSource associated with the Local FlowManager uses the -initialized following sequence of events and operations at startup: +following sequence of events and operations at startup: -1. `loadSolutions.loadFromLocalDisk`, - * The solutions registry files are loaded from the local file system, -2. `loadSolutions.getRevision`, - * Make an http request of the Cloud Based FlowManager for the revision of the - source code of the GPII used by the cloud, -3. `loadSolutions.loadFromRepository`, - * Make an http request of the source code respository, passing: - * the platform ID associated with the OS that the client is runing on, e.g. - "darwin", - * the revision fetched at the previous step, - * The solutions registry corresponding to the platform and revision provided is - downloaded from the source code repository and overlays the one fetched from - the local file system at the first step. -4. `loadSolutions.solutionsLoaded` - * Fires a `solutionsRegistryReady` event +
    +
  1. loadSolutions.loadFromLocalDisk, +
      +
    • The solutions registry files are loaded from the local file system,
    • +
    +
  2. +
  3. loadSolutions.getRevision, +
      +
    • Make an http request of the Cloud Based FlowManager for the revision of + the source code of the GPII used by the cloud, +
    • +
    +
  4. +
  5. loadSolutions.loadFromRepository, +
      +
    • Make an http request of the source code respository, passing: +
        +
      • the platform ID associated with the OS that the client is runing on, + e.g. "darwin", +
      • +
      • the revision fetched at the previous step,
      • +
      +
    • +
    • The solutions registry corresponding to the platform and revision provided + is downloaded from the source code repository and overlays the one fetched + from the local file system at the first step. +
    • +
    +
  6. +
  7. loadSolutions.solutionsLoaded +
      +
    • Fires a solutionsRegistryReady event
    • +
    +
  8. +
The above sequence is embeded within the Local FlowManager's `flowManagerReady` -startup interlock such that all initialition is completed before the GPII client +startup interlock such that all initialization is completed before the GPII client responds to user interactions. Note that both the `getRevision` and/or the `loadFromRepository` steps could From d9428496ed57fcabcef8215af1a8ce77e68794df Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 27 Mar 2020 12:25:11 -0400 Subject: [PATCH 51/68] GPII-4273: (GPII-4273iv) Modified configurations to squelch irrelevant errors In some cases: Configured the URL for the "/revision" request to point to a server that has no "/revision" endpoint so that the usual "FATAL ..." error message will not be logged. --- .../shared/gpii.config.untrusted.development.local.json5 | 4 ++++ .../configs/gpii.flowManager.config.local.base.json5 | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/gpii/configs/shared/gpii.config.untrusted.development.local.json5 b/gpii/configs/shared/gpii.config.untrusted.development.local.json5 index e4bb8fdbd..8c1c46b2e 100644 --- a/gpii/configs/shared/gpii.config.untrusted.development.local.json5 +++ b/gpii/configs/shared/gpii.config.untrusted.development.local.json5 @@ -41,6 +41,10 @@ "record": "http://localhost:8084", "target": "{that cloudBasedConfig flowManager prefsServerDataSource}.options.prefsServerURL", "priority": "after:flowManager.prefsServerDataSource.default" + }, + "flowManager.local.revisionRequester": { + "record": "http://localhost", + "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" } } } diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index ff20a9188..fbee2c704 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -7,7 +7,7 @@ "target": "{that flowManager}.options.gradeNames" }, "flowManager.local.gpiiRevisionCloudURL": { - "record": "http://localhost:8081", + "record": "http://localhost", "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" }, "flowManager.local.solutionsRegistryRepositoryPrefix": { From 58afffabfb7851a08ee7e0a6ad4f12ff8f937edc Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 31 Mar 2020 12:38:52 -0400 Subject: [PATCH 52/68] GPII-4273: (GPII-4273iv) Another way to squelch irrelevant "FATAL" error messages Modified (1) configuration files so that only a production configuration fully supports the CBFM /revision endpoint; and, (2) modified GpiiRevisionRequester to assume a "null" url indicates a developemnt testing configuration. --- ...i.config.untrusted.development.local.json5 | 4 --- .../gpii.flowManager.config.local.base.json5 | 4 --- .../flowManager/src/GpiiRevisionRequester.js | 25 ++++++++++++++----- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/gpii/configs/shared/gpii.config.untrusted.development.local.json5 b/gpii/configs/shared/gpii.config.untrusted.development.local.json5 index 8c1c46b2e..e4bb8fdbd 100644 --- a/gpii/configs/shared/gpii.config.untrusted.development.local.json5 +++ b/gpii/configs/shared/gpii.config.untrusted.development.local.json5 @@ -41,10 +41,6 @@ "record": "http://localhost:8084", "target": "{that cloudBasedConfig flowManager prefsServerDataSource}.options.prefsServerURL", "priority": "after:flowManager.prefsServerDataSource.default" - }, - "flowManager.local.revisionRequester": { - "record": "http://localhost", - "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" } } } diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index fbee2c704..0020599bf 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -6,10 +6,6 @@ "record": ["gpii.flowManager.local"], "target": "{that flowManager}.options.gradeNames" }, - "flowManager.local.gpiiRevisionCloudURL": { - "record": "http://localhost", - "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" - }, "flowManager.local.solutionsRegistryRepositoryPrefix": { "record": "https://raw.githubusercontent.com/GPII/universal", "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.urlPrefix" diff --git a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js index da18f593a..288cd6ef0 100644 --- a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js +++ b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js @@ -23,6 +23,8 @@ fluid.defaults("gpii.flowmanager.revisionRequester", { gradeNames: ["fluid.component"], // Prepend CBFM host/port distributed down from, e.g., gpii.flowManager.config.untrusted + // For development tests where there is no valid /revision endpoint in the + // cloud, this is left as null. cloudURL: null, urlTemplate: "%cloudURL/revision", @@ -61,11 +63,22 @@ fluid.defaults("gpii.flowmanager.revisionRequester", { gpii.flowmanager.revisionRequester.getRevision = function (that) { var togo = fluid.promise(); - var revisionPromise = that.gpiiRevisionDataSource.get(); - revisionPromise.then(function (/*revision*/) { - fluid.promise.follow(revisionPromise, togo); - }, function (err) { - togo.resolve(err); - }); + if (that.options.cloudURL !== null) { + var revisionPromise = that.gpiiRevisionDataSource.get(); + revisionPromise.then(function (/*revision*/) { + fluid.promise.follow(revisionPromise, togo); + }, function (err) { + togo.resolve(err); + }); + } else { + // If the url to the CBFM is null, assume this is running in a + // development testing enviroment where there is no valid /revision + // endpoint. + togo.resolve({ + isError: true, + message: "No valid '/revision' endpoint, ignoring request", + statusCode: 404 + }); + } return togo; }; From f2f3904ff284964e736e70399f6ad0b78fec3e60 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 2 Apr 2020 16:31:25 -0400 Subject: [PATCH 53/68] GPII-4273: (GPII-4273iv) New configuration for revision requests - Added new configuration for production version of the LFM for its making revision requests of the CBFM, - Added documentation of this new configuration, - Modified the merging of this new configuration so it is not used for development testing but is used in production tests, - Fixed tests accordingly. --- documentation/Configs.md | 9 +++++++ ...roduction.local.flowManager.revision.json5 | 25 +++++++++++++++++++ ...ii.flowManager.config.untrusted.base.json5 | 9 ------- .../flowManager/test/CaptureTests.js | 18 ++++++++++--- .../test/SolutionsRegistryDataSourceTests.js | 11 +++++++- ...ii.tests.untrusted.production.config.json5 | 5 +++- 6 files changed, 62 insertions(+), 15 deletions(-) create mode 100644 gpii/configs/gpii.config.production.local.flowManager.revision.json5 diff --git a/documentation/Configs.md b/documentation/Configs.md index 0223ccf5b..9cc3b1376 100644 --- a/documentation/Configs.md +++ b/documentation/Configs.md @@ -84,3 +84,12 @@ for the reset API and how to use it. **Purpose**: This config fetches default settings from a remote URL. The default URL is set to `https://raw.githubusercontent.com/GPII/universal/master/testData/defaultSettings/defaultSettings.win32.json5` in this config. See [Reset Computer](ResetComputer.md) for what are default settings. + +### Handle Revision Endpoint in Production + +**Config file**: [`%universal/gpii/configs/gpii.config.production.local.flowManager.revision.json5`](../gpii/configs/gpii.config.production.local.flowManager.revision.json5) + +**Purpose**: This config is used in a production system where the cloud based +flowManager supports a valid `/revision` end point. For development +testing, the default is to assume there is no valid revision, and no request for +the revision is made (see [GpiiRevisionRequester.js](../gpii/node_modules/flowManager/src/GpiiRevisionRequester.js)). diff --git a/gpii/configs/gpii.config.production.local.flowManager.revision.json5 b/gpii/configs/gpii.config.production.local.flowManager.revision.json5 new file mode 100644 index 000000000..380ee0a8d --- /dev/null +++ b/gpii/configs/gpii.config.production.local.flowManager.revision.json5 @@ -0,0 +1,25 @@ +/** + * This configuration is for the production version of the system where the + * local flowManager provides its solutions registry dataSource with the url to + * the cloud based flowManager's /revision endpoint. + * + */ +{ + "type": "gpii.config.production.local.flowManager.revision", + "options": { + "distributeOptions": { + "flowManager.defaultRevisionCloudURL": { + "record": "http://localhost:8084", + "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" + }, + "flowManager.gpiiRevisionCloudURL": { + "record": "@expand:kettle.resolvers.env(GPII_CLOUD_URL)", + "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL", + "priority": "after:flowManager.defaultRevisionCloudURL" + } + } + }, + "mergeConfigs": [ + "%flowManager/configs/gpii.flowManager.config.untrusted.base.json5" + ] +} diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 index 4695f275b..5ae7cfa1b 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.untrusted.base.json5 @@ -19,15 +19,6 @@ "flowManager.clientCredentialFilePath": { "record": "%gpii-universal/testData/clientCredentials/pilot.json", "target": "{that flowManager settingsDataSource}.options.clientCredentialFilePath" - }, - "flowManager.defaultRevisionCloudURL": { - "record": "http://localhost:8084", - "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" - }, - "flowManager.gpiiRevisionCloudURL": { - "record": "@expand:kettle.resolvers.env(GPII_CLOUD_URL)", - "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL", - "priority": "after:flowManager.defaultRevisionCloudURL" } } }, diff --git a/gpii/node_modules/flowManager/test/CaptureTests.js b/gpii/node_modules/flowManager/test/CaptureTests.js index d1a7ddd75..9b8f76a49 100644 --- a/gpii/node_modules/flowManager/test/CaptureTests.js +++ b/gpii/node_modules/flowManager/test/CaptureTests.js @@ -71,6 +71,11 @@ gpii.tests.flowManager.capture.adjustSolutions = function (solutionsRegistryData return fluid.promise().resolve(solutionsRegistryDataSource.repositorySolutionsRegistry); }; +gpii.tests.flowManager.capture.solutionsRegistryIsReady = function (msg, solutionsRegistryDataSource) { + jqUnit.assertNotNull(msg, solutionsRegistryDataSource.fullSolutionsRegistry); + jqUnit.assertNotNull(msg, solutionsRegistryDataSource.repositorySolutionsRegistry); +}; + fluid.defaults("gpii.tests.flowManager.capture.tests", { gradeNames: ["fluid.test.testEnvironment", "fluid.test.testCaseHolder"], modules: [ @@ -78,11 +83,16 @@ fluid.defaults("gpii.tests.flowManager.capture.tests", { name: "Simple system capture", tests: [{ name: "Check for existing FakeMag Settings", - expect: 3, + expect: 4, sequence: [{ - event: "{config}.server.flowManager.solutionsRegistryDataSource.events.solutionsRegistryReady", - listener: "jqUnit.assert", - args: ["Solutions registry ready"] + // Would prefer to listen for the 'solutionsRegistryReady' + // event, but it was emitted long ago. Nonetheless, check + // that the SRDS is ready. + funcName: "gpii.tests.flowManager.capture.solutionsRegistryIsReady", + args: [ + "Solutions registry ready", + "{config}.server.flowManager.solutionsRegistryDataSource" + ] }, { task: "{config}.server.flowManager.capture.getSystemSettingsCapture", args: [], diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index e4e760545..f7566c825 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -70,6 +70,15 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { sequence: [ { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- START"] }, { + // Cannot listen for solutionsRegistryReady event since it + // is long gone by the time this executes. Double checking + // that it is actually ready. + funcName: "jqUnit.assertNotNull", + args: [ + "Cloud based solutionsRegistryDataSource is ready", + "{solutionsRegistryDataSource}.fullSolutionsRegistry" + ] + }, { task: "{solutionsRegistryDataSource}.get", args: [gpii.tests.solutionsRegistry.requestOptions], resolve: "gpii.tests.solutionsRegistry.checkLocalRegistry", @@ -96,7 +105,7 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { }] }); -// Test environment for CLFM solutions registry data source +// Test environment for CBFM solutions registry data source fluid.defaults("gpii.tests.solutionsRegistry.dataSource.cloud.env", { gradeNames: ["fluid.test.testEnvironment"], components: { diff --git a/tests/configs/gpii.tests.untrusted.production.config.json5 b/tests/configs/gpii.tests.untrusted.production.config.json5 index 14e009b58..f2599f1df 100644 --- a/tests/configs/gpii.tests.untrusted.production.config.json5 +++ b/tests/configs/gpii.tests.untrusted.production.config.json5 @@ -3,5 +3,8 @@ "options": { "mainServerPort": "@expand:kettle.resolvers.env(GPII_FLOWMANAGER_LISTEN_PORT)" }, - "mergeConfigs": "%gpii-universal/gpii/configs/shared/gpii.config.untrusted.development.json5" + "mergeConfigs": [ + "%gpii-universal/gpii/configs/gpii.config.production.local.flowManager.revision.json5", + "%gpii-universal/gpii/configs/shared/gpii.config.untrusted.development.json5" + ] } From 59bafa3ab645088c84a54bfb85b38883d83a8445 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Fri, 3 Apr 2020 09:54:32 -0400 Subject: [PATCH 54/68] GPII-4273: (GPII-4273iv) Removed extra line --- .../gpii.config.production.local.flowManager.revision.json5 | 1 - 1 file changed, 1 deletion(-) diff --git a/gpii/configs/gpii.config.production.local.flowManager.revision.json5 b/gpii/configs/gpii.config.production.local.flowManager.revision.json5 index 380ee0a8d..79fa99ca7 100644 --- a/gpii/configs/gpii.config.production.local.flowManager.revision.json5 +++ b/gpii/configs/gpii.config.production.local.flowManager.revision.json5 @@ -2,7 +2,6 @@ * This configuration is for the production version of the system where the * local flowManager provides its solutions registry dataSource with the url to * the cloud based flowManager's /revision endpoint. - * */ { "type": "gpii.config.production.local.flowManager.revision", From 65f4d866182e5c579ee0e00c9fd4d0cda61715a1 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 13 Apr 2020 12:11:47 -0400 Subject: [PATCH 55/68] GPII-4273: (GPII-4273iv) Address review comments --- documentation/Configs.md | 1 + documentation/SolutionsRegistryDataSource.md | 62 ++++++++++------- .../flowManager/src/GpiiRevisionRequester.js | 11 +--- .../src/RepositorySolutionsLoader.js | 2 +- .../src/SolutionsRegistryDataSource.js | 48 +++++++------- .../test/GpiiRevisionRequesterTests.js | 66 +++++++++++++++++-- .../test/SolutionsRegistryDataSourceTests.js | 26 ++++++-- 7 files changed, 147 insertions(+), 69 deletions(-) diff --git a/documentation/Configs.md b/documentation/Configs.md index 9cc3b1376..99c1330ac 100644 --- a/documentation/Configs.md +++ b/documentation/Configs.md @@ -93,3 +93,4 @@ in this config. See [Reset Computer](ResetComputer.md) for what are default sett flowManager supports a valid `/revision` end point. For development testing, the default is to assume there is no valid revision, and no request for the revision is made (see [GpiiRevisionRequester.js](../gpii/node_modules/flowManager/src/GpiiRevisionRequester.js)). +This is done by setting its `cloudURL` option to `null`. diff --git a/documentation/SolutionsRegistryDataSource.md b/documentation/SolutionsRegistryDataSource.md index de897d5f1..76b1beb44 100644 --- a/documentation/SolutionsRegistryDataSource.md +++ b/documentation/SolutionsRegistryDataSource.md @@ -4,9 +4,10 @@ The solutions registry data source provides a RESTful means of fetching solutions registries via the [FlowManager](FlowManager.md) in order to determine which solutions are available and appropriate for a user's preferences. A solution is an application, such as the NVDA screen reader, or an operating -system feature, such as the Windows high contrast theme set using a system -control panel. Each solution supports a set of preferences and describes how -to configure the solution, launch it, reset it, and stop it. +system feature set using a control panel, such as the Windows high contrast +theme. Each solution entry in the registry declares a set of preferences that +it supports and describes how to configure the solution, launch it, reset it, +and stop it. The solutions are listed in `JSON` files called "solutions registries". The structure of a solutions registry is documented in @@ -23,25 +24,29 @@ solutions, user preferences, device information, and so on, passing these to the There are two initialization workflows with respect to solutions registries depending on whether the flow manager is running in the cloud or locally on the -client device. This are described in the following two sections. - -## Cloud Based Flow Manager - -The solutions registries are included in the distribution of `gpii-universal` -along with the other components of the GPII -- the flow manager, lifecycle -manager and so on. The Cloud Base FlowManager is a central service for GPII -clients, and these clients run on a variety of platforms. As such, the -platform that the Cloud Based FlowManager is executing on is irrelevant in -terms of providing solutions for the client. When a request for a solutions -registry is made, the flow manager needs to have access to all platform -solutions in order to respond with the solutions relevant to a particular -client. - -The solutions registries are loaded from the local file system at system -startup. Here, "local" refers to the file system associated with machine that -the Cloud Base FlowManager is running on. The SolutionsRegistryDataSource is a -subcomponent of the flow manager, and there is a sequence of operations and -events that occurs during its instantiation: +client device. The Cloud Based Flow Manager uses a Solutions Registry Data +Source implemented to run in that context, whereas the Local Flow Manager uses a +Solutions Registry Data Source appropriate for running on client machines. +These two scenarios are described in the following two sections. + +## Cloud Based Flow Manager Solutions Registry Data Source + +With respect to the Cloud Based Flow Manager, the solutions registries are +included in the distribution of `gpii-universal` along with the other components +of the GPII -- the flow manager, lifecycle manager and so on. The Cloud Based +FlowManager is a central service for GPII clients, and these clients run on a +variety of platforms. As such, the platform that the Cloud Based FlowManager is +executing on is irrelevant in terms of providing solutions for the client. When +a request for a solutionsvregistry is made, the flow manager needs to have +access to all platform solutions in order to respond with the solutions relevant +to a particular client. + +Here, the SolutionsRegistryDataSource component loads the solutions +registries from the local file system at system startup. In this context, +"local" refers to the file system associated with machine that the Cloud Based +Flow Manager is running on. The SolutionsRegistryDataSource is a +subcomponent of the flow manager, and the sequence of operations and +events that occur during its instantiation are:
  1. loadSolutions.loadFromLocalDisk, @@ -59,7 +64,7 @@ events that occurs during its instantiation: The `solutionsRegistryReady` informs the flow manager that its SolutionsRegistryDataSource is ready to provide solutions upon request. -## Local Flow Manager +## Local Flow Manager Solutions Registry Data Source As in the case of the Cloud Based FlowManager, the solutions registries are included in the distribution of GPII for the client. However, they are not @@ -111,8 +116,8 @@ following sequence of events and operations at startup:
The above sequence is embeded within the Local FlowManager's `flowManagerReady` -startup interlock such that all initialization is completed before the GPII client -responds to user interactions. +startup interlock such that all initialization is completed before the GPII +client responds to user interactions. Note that both the `getRevision` and/or the `loadFromRepository` steps could fail. In that case, the latest solutions registry for the client platform will @@ -120,3 +125,10 @@ not be downloaded and cached within the client. When solutions for the client platform are requested, the SolutionsRegistryDataSource uses a fallback where the solutions loaded from the local file system during the first `loadFromLocalDisk` step are provided. + +Further note that the `getRevision` step feeds its result into the +`loadFromRepository` step. The revision is necessary to fetch the +correct solutions registry from the repository. If a developer wants to avoid +that, they can set the `cloudURL` of the `GpiiRevisionRequester` to `null`, +effectively stopping the entire sequence. No solutions registry will be +downloaded from the repository in that case. diff --git a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js index 288cd6ef0..846be9ff1 100644 --- a/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js +++ b/gpii/node_modules/flowManager/src/GpiiRevisionRequester.js @@ -62,7 +62,6 @@ fluid.defaults("gpii.flowmanager.revisionRequester", { */ gpii.flowmanager.revisionRequester.getRevision = function (that) { var togo = fluid.promise(); - if (that.options.cloudURL !== null) { var revisionPromise = that.gpiiRevisionDataSource.get(); revisionPromise.then(function (/*revision*/) { @@ -72,13 +71,9 @@ gpii.flowmanager.revisionRequester.getRevision = function (that) { }); } else { // If the url to the CBFM is null, assume this is running in a - // development testing enviroment where there is no valid /revision - // endpoint. - togo.resolve({ - isError: true, - message: "No valid '/revision' endpoint, ignoring request", - statusCode: 404 - }); + // development testing enviroment or, generally, a scenario where + // requests for the revision are to be suppressed. + togo.resolve(null); } return togo; }; diff --git a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js index b1b95598b..f6527a6c9 100644 --- a/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js +++ b/gpii/node_modules/flowManager/src/RepositorySolutionsLoader.js @@ -54,7 +54,7 @@ fluid.defaults("gpii.flowManager.repositorySolutionsLoader", { getSolutions: { funcName: "gpii.flowManager.repositorySolutionsLoader.getSolutions", args: ["{that}", "{arguments}.0", "{arguments}.1"] - // gpii revision, file name + // gpii revision, platform id } } }); diff --git a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js index 4f7b3c119..2408f583a 100644 --- a/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js +++ b/gpii/node_modules/flowManager/src/SolutionsRegistryDataSource.js @@ -125,8 +125,7 @@ gpii.flowManager.solutionsRegistry.dataSource.cloudBased.handle = function (that } else { promise.reject({ isError: true, - message: "The requested OS (" + requestOptions.os + ") was not present in the solutions registry", - statusCode: 404 + message: "The requested OS (" + requestOptions.os + ") was not present in the solutions registry" }); } return promise; @@ -205,24 +204,29 @@ fluid.defaults("gpii.flowManager.solutionsRegistry.dataSource.local", { * registry from the source code repository, or null, if there was an error. */ gpii.flowManager.solutionsRegistry.dataSource.local.loadFromRepository = function (that, revision, platformReporter) { - var gpiiRevision = revision.sha256; - var platformId = platformReporter.reportPlatform().id; - var repoLoadPromise = that.repositorySolutionsLoader.getSolutions(gpiiRevision, platformId); - - // Either the solutions registry has been successfully retrieved from the - // repository, or it hasn't. Set that.repositorySolutionsRegistry to - // to either the result, or to null. var togo = fluid.promise(); - repoLoadPromise.then( - function (repositorySolutions) { - that.repositorySolutionsRegistry = repositorySolutions; - togo.resolve(repositorySolutions); - }, - function () { - that.repositorySolutionsRegistry = null; - togo.resolve(null); - } - ); + if (revision) { + var gpiiRevision = revision.sha256; + var platformId = platformReporter.reportPlatform().id; + var repoLoadPromise = that.repositorySolutionsLoader.getSolutions(gpiiRevision, platformId); + + // Either the solutions registry has been successfully retrieved from the + // repository, or it hasn't. Set that.repositorySolutionsRegistry to + // to either the result, or to null. + repoLoadPromise.then( + function (repositorySolutions) { + that.repositorySolutionsRegistry = repositorySolutions; + togo.resolve(repositorySolutions); + }, + function () { + that.repositorySolutionsRegistry = null; + togo.resolve(null); + } + ); + } else { + that.repositorySolutionsRegistry = null; + togo.resolve(null); + } return togo; }; @@ -250,15 +254,13 @@ gpii.flowManager.solutionsRegistry.dataSource.local.handle = function (that, req } else { promise.reject({ isError: true, - message: "The requested OS (" + requestOptions.os + ") was not present in the solutions registry", - statusCode: 404 + message: "The requested OS (" + requestOptions.os + ") was not present in the solutions registry" }); } } else { promise.reject({ isError: true, - message: "Missing OS (undefined) for accessing the solutions registry", - statusCode: 404 + message: "Missing OS (undefined) for accessing the solutions registry" }); } return promise; diff --git a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js index 603b3d065..8706617dd 100644 --- a/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js +++ b/gpii/node_modules/flowManager/test/GpiiRevisionRequesterTests.js @@ -29,11 +29,11 @@ gpii.tests.revisionRequester.path = "/revision"; // Set up mock cloud request/response gpii.tests.revisionRequester.setUpNock = function (config) { - var cloudMock = nock(gpii.tests.revisionRequester.hostname); + var cloudMock = nock(config.hostname); cloudMock.log(console.log); // mock GET request - cloudMock.get(gpii.tests.revisionRequester.path) + cloudMock.get(config.path) .reply(config.status, config.response); }; @@ -66,7 +66,8 @@ fluid.defaults("gpii.tests.revisionRequesterTests", { // 1. Successful retrieval gpii.tests.revisionRequester.success = { nockConfig: { - url: gpii.tests.revisionRequester.hostname + gpii.tests.revisionRequester.path, + hostname: gpii.tests.revisionRequester.hostname, + path: gpii.tests.revisionRequester.path, type: "get", status: 200, response: {"sha256": "2602bdf868aec49993d8780feec42d4e9f995e21"} @@ -107,7 +108,8 @@ fluid.defaults("gpii.tests.revisionRequesterTests.success", { // 2. Retrieval of malformed or missing revision gpii.tests.revisionRequester.missingRevision = { nockConfig: { - url: gpii.tests.revisionRequester.hostname + gpii.tests.revisionRequester.path, + hostname: gpii.tests.revisionRequester.hostname, + path: gpii.tests.revisionRequester.path, type: "get", status: 404, response: { @@ -156,8 +158,62 @@ fluid.defaults("gpii.tests.revisionRequesterTests.missingRevision", { } }); +// 3. Null cloudURL for the revision request +gpii.tests.revisionRequester.nullCloudUrl = { + nockConfig: { + // The hostname should be null here, but nock can't handle it. Taken + // care of in the setup of the GpiiRevisionRquester used in the test: + // see the "components" block of + // "gpii.tests.revisionRequesterTests.nullCloudUrl" below. + hostname: gpii.tests.revisionRequester.hostname, + path: null, + type: "get" + }, + expected: null +}; + +fluid.defaults("gpii.tests.revisionRequester.testCaseHolder.nullCloudUrl", { + gradeNames: "fluid.test.testCaseHolder", + modules: [{ + name: "Revision requester module tests - null cloudURL", + expect: 1, + tests: [{ + name: "No revision request with a null result", + sequence: [{ + task: "{revisionRequester}.getRevision", + resolve: "jqUnit.assertNull", + resolveArgs: [ + "A null result is expected", + gpii.tests.revisionRequester.nullCloudUrl.expected, + "{arguments}.0" + ] + }] + }] + }] +}); + +fluid.defaults("gpii.tests.revisionRequesterTests.nullCloudUrl", { + gradeNames: ["gpii.tests.revisionRequesterTests", "gpii.test.testWithNock"], + testCaseHolderGrade: "gpii.tests.revisionRequester.testCaseHolder.nullCloudUrl", + invokers: { + setUpNock: { + funcName: "gpii.tests.revisionRequester.setUpNock", + args: gpii.tests.revisionRequester.nullCloudUrl.nockConfig + } + }, + components: { + revisionRequester: { + type: "gpii.tests.revisionRequester", + options: { + cloudURL: null + } + } + } +}); + // Run all tests fluid.test.runTests([ "gpii.tests.revisionRequesterTests.success", - "gpii.tests.revisionRequesterTests.missingRevision" + "gpii.tests.revisionRequesterTests.missingRevision", + "gpii.tests.revisionRequesterTests.nullCloudUrl" ]); diff --git a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js index f7566c825..d449b2838 100644 --- a/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js +++ b/gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js @@ -47,7 +47,10 @@ gpii.tests.solutionsRegistry.checkNamedRegistry = function (msg, equalityCheck, // Check for failures. gpii.tests.solutionsRegistry.checkRejection = function (msg, result) { jqUnit.assertTrue(msg, result.isError); - jqUnit.assertEquals(msg, 404, result.statusCode); +}; + +gpii.tests.solutionsRegistry.handleReadyEvent = function (that) { + that.isReady = true; }; // ======== Testing the solutions registry data source used by the CBFM ======== @@ -58,7 +61,16 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { solutionsRegistryDataSource: { type: "gpii.flowManager.solutionsRegistry.dataSource.cloudBased", options: { - path: gpii.tests.solutionsRegistry.path + path: gpii.tests.solutionsRegistry.path, + members: { + isReady: false + }, + listeners: { + "solutionsRegistryReady": { + listener: "gpii.tests.solutionsRegistry.handleReadyEvent", + args: ["{that}"] + } + } } } }, @@ -70,13 +82,13 @@ fluid.defaults("gpii.tests.solutionsRegistry.cloud.testCaseHolder", { sequence: [ { funcName: "fluid.log", args: ["Solutions Registry for CBFM, getting named registry -- START"] }, { - // Cannot listen for solutionsRegistryReady event since it - // is long gone by the time this executes. Double checking - // that it is actually ready. - funcName: "jqUnit.assertNotNull", + // Cannot listen for solutionsRegistryReady event directly + // since it is long gone by the time this executes. Check + // that the handleIsReady listener heard the event. + funcName: "jqUnit.assertTrue", args: [ "Cloud based solutionsRegistryDataSource is ready", - "{solutionsRegistryDataSource}.fullSolutionsRegistry" + "{solutionsRegistryDataSource}.isReady" ] }, { task: "{solutionsRegistryDataSource}.get", From 5507e83d18656559412ad28b1f7325b3b0dee31b Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 14 Apr 2020 10:45:52 -0400 Subject: [PATCH 56/68] GPII-4273: (GPII-4273iv) Addressed review comments Modified configurations such that the one that is used to request the code revision from the CBFM is now an add-on grade. --- .../configs/gpii.config.local.flowManager.revision.json5} | 7 ++----- .../configs/gpii.flowManager.config.local.base.json5 | 2 +- tests/configs/gpii.tests.untrusted.production.config.json5 | 2 +- 3 files changed, 4 insertions(+), 7 deletions(-) rename gpii/{configs/gpii.config.production.local.flowManager.revision.json5 => node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5} (82%) diff --git a/gpii/configs/gpii.config.production.local.flowManager.revision.json5 b/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5 similarity index 82% rename from gpii/configs/gpii.config.production.local.flowManager.revision.json5 rename to gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5 index 79fa99ca7..f12d5285e 100644 --- a/gpii/configs/gpii.config.production.local.flowManager.revision.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5 @@ -4,7 +4,7 @@ * the cloud based flowManager's /revision endpoint. */ { - "type": "gpii.config.production.local.flowManager.revision", + "type": "gpii.config.local.flowManager.revision", "options": { "distributeOptions": { "flowManager.defaultRevisionCloudURL": { @@ -17,8 +17,5 @@ "priority": "after:flowManager.defaultRevisionCloudURL" } } - }, - "mergeConfigs": [ - "%flowManager/configs/gpii.flowManager.config.untrusted.base.json5" - ] + } } diff --git a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 index 0020599bf..0e812a221 100644 --- a/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.flowManager.config.local.base.json5 @@ -11,7 +11,7 @@ "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.urlPrefix" }, "flowManager.local.solutionsRegistryRepositorySuffix": { - "record": "/testData/solutions", + "record": "testData/solutions", "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.urlSuffix" } } diff --git a/tests/configs/gpii.tests.untrusted.production.config.json5 b/tests/configs/gpii.tests.untrusted.production.config.json5 index f2599f1df..3ede375a4 100644 --- a/tests/configs/gpii.tests.untrusted.production.config.json5 +++ b/tests/configs/gpii.tests.untrusted.production.config.json5 @@ -4,7 +4,7 @@ "mainServerPort": "@expand:kettle.resolvers.env(GPII_FLOWMANAGER_LISTEN_PORT)" }, "mergeConfigs": [ - "%gpii-universal/gpii/configs/gpii.config.production.local.flowManager.revision.json5", + "%gpii-universal/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5", "%gpii-universal/gpii/configs/shared/gpii.config.untrusted.development.json5" ] } From 56114407d45aa1bb3fe920678f264f7d3ad8e6bf Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 15 Apr 2020 16:17:02 -0400 Subject: [PATCH 57/68] GPII-4273: (GPII-4273iv) More tweaking of configuration files --- ...fig.local.flowManager.loadSolutionsFromRepository.json5} | 6 +++--- .../gpii.flowManager.tests.browserChannel.config.json5 | 6 ------ .../flowManager/test/shared/BrowserChannelTestDefs.js | 6 ------ ...i.tests.acceptance.untrusted.browserChannel.config.json5 | 6 ------ tests/configs/gpii.tests.untrusted.production.config.json5 | 2 +- 5 files changed, 4 insertions(+), 22 deletions(-) rename gpii/node_modules/flowManager/configs/{gpii.config.local.flowManager.revision.json5 => gpii.config.local.flowManager.loadSolutionsFromRepository.json5} (66%) diff --git a/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5 b/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5 similarity index 66% rename from gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5 rename to gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5 index f12d5285e..680c905c8 100644 --- a/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5 +++ b/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5 @@ -4,16 +4,16 @@ * the cloud based flowManager's /revision endpoint. */ { - "type": "gpii.config.local.flowManager.revision", + "type": "gpii.config.local.flowManager.loadSolutionsFromRepository", "options": { "distributeOptions": { "flowManager.defaultRevisionCloudURL": { "record": "http://localhost:8084", - "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL" + "target": "{that gpii.flowManager.local solutionsRegistryDataSource revisionRequester}.options.cloudURL" }, "flowManager.gpiiRevisionCloudURL": { "record": "@expand:kettle.resolvers.env(GPII_CLOUD_URL)", - "target": "{that flowManager solutionsRegistryDataSource revisionRequester}.options.cloudURL", + "target": "{that gpii.flowManager.local solutionsRegistryDataSource revisionRequester}.options.cloudURL", "priority": "after:flowManager.defaultRevisionCloudURL" } } diff --git a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 index 98ad3dfe6..fee8f3f4c 100644 --- a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 +++ b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.browserChannel.config.json5 @@ -18,12 +18,6 @@ "funcName": "gpii.tests.flowManager.browserChannel.reportPlatform" }, "target": "{that deviceReporter platformReporter}.options.invokers.reportPlatform" - }, - "browserChannel.tests.repositorySolutionsLoader": { - "record": { - "funcName": "gpii.tests.flowManager.browserChannel.getRepositorySolutions" - }, - "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.invokers.getSolutions" } } }, diff --git a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js index 1c13872a4..398a79c9f 100644 --- a/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js +++ b/gpii/node_modules/flowManager/test/shared/BrowserChannelTestDefs.js @@ -53,12 +53,6 @@ gpii.tests.flowManager.browserChannel.reportPlatform = function () { }; }; -// A no-op to gracefully fail fetching the solutions registry from the source -// code repository in order to use the canned registry set up for these tests. -gpii.tests.flowManager.browserChannel.getRepositorySolutions = function (/*repositorySolutionsLoader*/) { - return fluid.promise().resolve(null); -}; - gpii.tests.flowManager.browserChannel.checkConnectionRequest = function (data, request) { request.events.onReceiveMessage.addListener(function (message, request) { fluid.log("BrowserChannel checkConnectionRequest got onReceiveMessage ", message); diff --git a/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 b/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 index 49961c0a1..eaf5edf3e 100644 --- a/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 +++ b/tests/configs/gpii.tests.acceptance.untrusted.browserChannel.config.json5 @@ -18,12 +18,6 @@ "funcName": "gpii.tests.flowManager.browserChannel.reportPlatform" }, "target": "{that localConfig deviceReporter platformReporter}.options.invokers.reportPlatform" - }, - "browserChannel.tests.repositorySolutionsLoader": { - "record": { - "funcName": "gpii.tests.flowManager.browserChannel.getRepositorySolutions" - }, - "target": "{that flowManager solutionsRegistryDataSource repositorySolutionsLoader}.options.invokers.getSolutions" } } }, diff --git a/tests/configs/gpii.tests.untrusted.production.config.json5 b/tests/configs/gpii.tests.untrusted.production.config.json5 index 3ede375a4..8229dc055 100644 --- a/tests/configs/gpii.tests.untrusted.production.config.json5 +++ b/tests/configs/gpii.tests.untrusted.production.config.json5 @@ -4,7 +4,7 @@ "mainServerPort": "@expand:kettle.resolvers.env(GPII_FLOWMANAGER_LISTEN_PORT)" }, "mergeConfigs": [ - "%gpii-universal/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.revision.json5", + "%gpii-universal/gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.loadSolutionsFromRepository", "%gpii-universal/gpii/configs/shared/gpii.config.untrusted.development.json5" ] } From ffa5b06486e294c0dfc651d092c8f4d313f77244 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 15 Apr 2020 16:56:15 -0400 Subject: [PATCH 58/68] GPII-4273: (GPII-4273iv) Better way to detect solutionsRegistryReady --- .../flowManager/test/CaptureTests.js | 16 ++++++++++------ ...owManager.tests.capture.fakeData.config.json5 | 9 +++++++++ 2 files changed, 19 insertions(+), 6 deletions(-) diff --git a/gpii/node_modules/flowManager/test/CaptureTests.js b/gpii/node_modules/flowManager/test/CaptureTests.js index 9b8f76a49..5817688d0 100644 --- a/gpii/node_modules/flowManager/test/CaptureTests.js +++ b/gpii/node_modules/flowManager/test/CaptureTests.js @@ -71,9 +71,12 @@ gpii.tests.flowManager.capture.adjustSolutions = function (solutionsRegistryData return fluid.promise().resolve(solutionsRegistryDataSource.repositorySolutionsRegistry); }; +gpii.tests.flowManager.capture.handleSolutionsReadyEvent = function (that) { + that.isReady = true; +}; + gpii.tests.flowManager.capture.solutionsRegistryIsReady = function (msg, solutionsRegistryDataSource) { - jqUnit.assertNotNull(msg, solutionsRegistryDataSource.fullSolutionsRegistry); - jqUnit.assertNotNull(msg, solutionsRegistryDataSource.repositorySolutionsRegistry); + jqUnit.assertTrue(msg, solutionsRegistryDataSource.isReady); }; fluid.defaults("gpii.tests.flowManager.capture.tests", { @@ -83,11 +86,12 @@ fluid.defaults("gpii.tests.flowManager.capture.tests", { name: "Simple system capture", tests: [{ name: "Check for existing FakeMag Settings", - expect: 4, + expect: 3, sequence: [{ - // Would prefer to listen for the 'solutionsRegistryReady' - // event, but it was emitted long ago. Nonetheless, check - // that the SRDS is ready. + // Cannot listen for solutionsRegistryReady event directly + // since it is long gone by the time this executes. Check + // that the handleSolutionsReadyEvent listener heard the + // event. funcName: "gpii.tests.flowManager.capture.solutionsRegistryIsReady", args: [ "Solutions registry ready", diff --git a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 index c606b2a62..7247320ff 100644 --- a/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 +++ b/gpii/node_modules/flowManager/test/configs/gpii.flowManager.tests.capture.fakeData.config.json5 @@ -23,6 +23,15 @@ "target": "{that flowManager solutionsRegistryDataSource}.options.listeners", "priority": "after:capture.solutionsRegistry" }, + "capture.noteSolutionsRegistryReady": { + "record":{ + "solutionsRegistryReady": { + "listener": "gpii.tests.flowManager.capture.handleSolutionsReadyEvent", + "args": ["{that}"] + } + }, + "target": "{that flowManager solutionsRegistryDataSource}.options.listeners" + }, "capture.deviceReporter": { "record": "%gpii-universal/gpii/node_modules/flowManager/test/data/capture_deviceReporter.json", "target": "{that deviceReporter installedSolutionsDataSource}.options.path", From 77a36c5cc2d404d5eb68487a068301bfddd7eb01 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 16 Apr 2020 14:44:02 -0400 Subject: [PATCH 59/68] GPII-4273: (GPII-4273iv) Fixed documentation --- documentation/FlowManager.md | 14 +++++++++++--- documentation/SolutionsRegistryDataSource.md | 2 +- 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/documentation/FlowManager.md b/documentation/FlowManager.md index 6b65e7bef..cdcbe4dea 100644 --- a/documentation/FlowManager.md +++ b/documentation/FlowManager.md @@ -115,11 +115,19 @@ payload structure to start a matchMaking process. cloud based components of the GPII. * **route:** `/revision` * **method:** `GET` -* **return:** A JSON document containing the revision: +* **return:** On success, an http status code of 200 and a payload containing the revision, e.g.: -```json +```json5 +{"sha256": "2602bdf868aec49993d8780feec42d4e9f995e21"} +``` + +Otherwise, returns status code 404 and an error payload: + +```json5 { - "sha256": "2602bdf868aec49993d8780feec42d4e9f995e21" + "isError": true, + "message": "Error retrieving full git revision: %reason", + "statusCode": 404 } ``` diff --git a/documentation/SolutionsRegistryDataSource.md b/documentation/SolutionsRegistryDataSource.md index 76b1beb44..179976134 100644 --- a/documentation/SolutionsRegistryDataSource.md +++ b/documentation/SolutionsRegistryDataSource.md @@ -96,7 +96,7 @@ following sequence of events and operations at startup:
  • Make an http request of the source code respository, passing:
      -
    • the platform ID associated with the OS that the client is runing on, +
    • the platform ID associated with the OS that the client is running on, e.g. "darwin",
    • the revision fetched at the previous step,
    • From b0c0a1be4b2c423a4f6ccdf320cf80f011dd2045 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 16 Apr 2020 15:23:08 -0400 Subject: [PATCH 60/68] GPII-4273: (GPII-4273iv) Fixed documentation of configuration file --- documentation/Configs.md | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/documentation/Configs.md b/documentation/Configs.md index 99c1330ac..fd05f458f 100644 --- a/documentation/Configs.md +++ b/documentation/Configs.md @@ -85,12 +85,17 @@ for the reset API and how to use it. `https://raw.githubusercontent.com/GPII/universal/master/testData/defaultSettings/defaultSettings.win32.json5` in this config. See [Reset Computer](ResetComputer.md) for what are default settings. -### Handle Revision Endpoint in Production +### Load Solutions from the Repository in Production Contexts -**Config file**: [`%universal/gpii/configs/gpii.config.production.local.flowManager.revision.json5`](../gpii/configs/gpii.config.production.local.flowManager.revision.json5) +**Config file**: [`%universal/gpii/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5`](../gpii/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5) -**Purpose**: This config is used in a production system where the cloud based -flowManager supports a valid `/revision` end point. For development -testing, the default is to assume there is no valid revision, and no request for -the revision is made (see [GpiiRevisionRequester.js](../gpii/node_modules/flowManager/src/GpiiRevisionRequester.js)). -This is done by setting its `cloudURL` option to `null`. +**Purpose**: This add-on config is for use in production where the cloud based +flow manager supports a valid `/revision` end point, and where the local +flow manager loads solutions registries from both its local hard drive and from +the source code repository. See [SolutionsRegistryDataSource](SolutionsRegistryDataSource.md#local-flow-manager-solutions-registry-data-source) +for more details. + +In addition, for development testing, the default is to assume there is no valid +revision, and no request for the revision is made (see [GpiiRevisionRequester.js](../gpii/node_modules/flowManager/src/GpiiRevisionRequester.js)). +This is done by setting the requester's `cloudURL` option to `null`. This +effectively stops the process of loading solutions from the repository. From fe8573949cb9da78b0afa65e5b8351144ff6b032 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Thu, 16 Apr 2020 15:34:03 -0400 Subject: [PATCH 61/68] GPII-4273: (GPII-4273iv) Fixed an url --- documentation/Configs.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/documentation/Configs.md b/documentation/Configs.md index fd05f458f..c4a4a12fe 100644 --- a/documentation/Configs.md +++ b/documentation/Configs.md @@ -87,7 +87,7 @@ in this config. See [Reset Computer](ResetComputer.md) for what are default sett ### Load Solutions from the Repository in Production Contexts -**Config file**: [`%universal/gpii/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5`](../gpii/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5) +**Config file**: [`%flowManager/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5`](../gpii/node_modules/flowManager/configs/gpii.config.local.flowManager.loadSolutionsFromRepository.json5) **Purpose**: This add-on config is for use in production where the cloud based flow manager supports a valid `/revision` end point, and where the local From 088c077aa1c8cc9e0e7f39a6bc297e15088c2e50 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 20 Apr 2020 10:05:54 -0400 Subject: [PATCH 62/68] GPII-4273: (GPII-4273iv) Adding production test of the SRDS loading sequence --- tests/all-tests.js | 2 +- .../production/LoginLogoutProductionTests.js | 34 ----- tests/production/ProductionTestsUtils.js | 34 +++++ .../SolutionsRegistryLoadSequenceTests.js | 129 ++++++++++++++++++ tests/production/all-tests.js | 1 + 5 files changed, 165 insertions(+), 35 deletions(-) create mode 100644 tests/production/SolutionsRegistryLoadSequenceTests.js diff --git a/tests/all-tests.js b/tests/all-tests.js index 99d5dbdad..c68521c6f 100644 --- a/tests/all-tests.js +++ b/tests/all-tests.js @@ -60,7 +60,7 @@ var testIncludes = [ "../gpii/node_modules/flowManager/test/BrowserChannelTests.js", "../gpii/node_modules/flowManager/test/CaptureTests.js", "../gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js", - "../gpii/node_modules/flowManager/test/DefaultSettingsLoaderTests.js", +// "../gpii/node_modules/flowManager/test/DefaultSettingsLoaderTests.js", "../gpii/node_modules/flowManager/test/PrefsServerDataSourceTests.js", "../gpii/node_modules/flowManager/test/PSPChannelTests.js", "../gpii/node_modules/flowManager/test/SettingsDataSourceTests.js", diff --git a/tests/production/LoginLogoutProductionTests.js b/tests/production/LoginLogoutProductionTests.js index 7c385b4df..568084cda 100644 --- a/tests/production/LoginLogoutProductionTests.js +++ b/tests/production/LoginLogoutProductionTests.js @@ -51,40 +51,6 @@ require("./ProductionTestsUtils.js"); * The keyin/keyout test sequence will wait until "onSystemReady" is fired. */ -// The customized testEnvironment component that adds and listens to the aggregate event "onSystemReady" -fluid.defaults("gpii.tests.productionConfigTesting.testEnvironment", { - gradeNames: ["gpii.test.serverEnvironment"], - distributeOptions: { - "resetAtStartSuccess.escalate": { - record: { - resetAtStartSuccess: "{testEnvironment}.events.resetAtStartSuccess" - }, - target: "{that gpii.flowManager.local}.options.events" - }, - "productionConfigTesting.startServerSequence": { - record: [ - { // This sequence point is required because of a QUnit bug - it defers the start of sequence by 13ms "to avoid any current callbacks" in its words - func: "{testEnvironment}.events.constructServer.fire" - }, - { - event: "{testEnvironment}.events.onSystemReady", - listener: "fluid.identity" - } - ], - target: "{that gpii.test.startServerSequence}.options.sequence" - } - }, - events: { - resetAtStartSuccess: null, - onSystemReady: { - events: { - resetAtStartSuccess: "resetAtStartSuccess", - onServerReady: "onServerReady" - } - } - } -}); - fluid.defaults("gpii.tests.productionConfigTesting.loginLogoutSequence", { gradeNames: ["gpii.test.standardServerSequenceGrade"], sequenceElements: { diff --git a/tests/production/ProductionTestsUtils.js b/tests/production/ProductionTestsUtils.js index 3d4d73bef..0411dd8d2 100644 --- a/tests/production/ProductionTestsUtils.js +++ b/tests/production/ProductionTestsUtils.js @@ -88,6 +88,40 @@ fluid.defaults("gpii.tests.cloud.oauth2.accessTokensDeleteRequests", { } }); +// The customized testEnvironment component that adds and listens to the aggregate event "onSystemReady" +fluid.defaults("gpii.tests.productionConfigTesting.testEnvironment", { + gradeNames: ["gpii.test.serverEnvironment"], + distributeOptions: { + "resetAtStartSuccess.escalate": { + record: { + resetAtStartSuccess: "{testEnvironment}.events.resetAtStartSuccess" + }, + target: "{that gpii.flowManager.local}.options.events" + }, + "productionConfigTesting.startServerSequence": { + record: [ + { // This sequence point is required because of a QUnit bug - it defers the start of sequence by 13ms "to avoid any current callbacks" in its words + func: "{testEnvironment}.events.constructServer.fire" + }, + { + event: "{testEnvironment}.events.onSystemReady", + listener: "fluid.identity" + } + ], + target: "{that gpii.test.startServerSequence}.options.sequence" + } + }, + events: { + resetAtStartSuccess: null, + onSystemReady: { + events: { + resetAtStartSuccess: "resetAtStartSuccess", + onServerReady: "onServerReady" + } + } + } +}); + // Sequence elements for cleaning up extra access tokens fluid.defaults("gpii.tests.productionConfigTesting.deleteAccessTokensSequence", { gradeNames: ["fluid.test.sequenceElement"], diff --git a/tests/production/SolutionsRegistryLoadSequenceTests.js b/tests/production/SolutionsRegistryLoadSequenceTests.js new file mode 100644 index 000000000..0fac6e639 --- /dev/null +++ b/tests/production/SolutionsRegistryLoadSequenceTests.js @@ -0,0 +1,129 @@ +/** +GPII Production Config tests - Loading Solutions Registries + +Requirements: +* an internet connection +* a cloud based flow manager +--- + +Copyright 2020 OCAD University + +Licensed under the New BSD license. You may not use this file except in +compliance with this License. + +The research leading to these results has received funding from the European Union's +Seventh Framework Programme (FP7/2007-2013) under grant agreement no. 289016. + +You may obtain a copy of the License at +https://github.com/GPII/universal/blob/master/LICENSE.txt + +WARNING: Do not run these tests directly. They are called from within the +"vagrantCloudBasedContainers.sh" after it has initialized the environment. +*/ + +"use strict"; + +var fluid = require("infusion"), + jqUnit = fluid.require("node-jqunit", require, "jqUnit"), + gpii = fluid.registerNamespace("gpii"); + +fluid.require("%gpii-universal"); + +gpii.loadTestingSupport(); + +fluid.registerNamespace("gpii.tests.productionConfigTesting"); + +require("./ProductionTestsUtils.js"); + +gpii.tests.productionConfigTesting.validGpiiRevision = require( + fluid.module.resolvePath( + "%gpii-universal/gpii-revision.json" + ) +); + +gpii.tests.productionConfigTesting.localSolutionsRegistries = + fluid.module.resolvePath("%gpii-universal/testData/solutions"); + +/** Local FlowManager tests of the solutions registry loading sequence: + * + * When the LFM starts, its SolutionsRegisryDataSource loads solutions + * registries from both the local file system, and from the source code + * repository. The tests need to start running *after* this loading process is + * complete, and are sensitive to the "onSystemReady" event, in that regard. See + * the component "gpii.tests.productionConfigTesting.testEnvironment" in the + * "ProductionTestUtils.js" file. + * + * "onSystemReady" is fired when: + * 1. The test server has been constructed; + * 2. The local flow manager initial actions have completed and is ready for + * requests + */ +fluid.defaults("gpii.tests.productionConfigTesting.loadingSolutionsTransform", { + gradeNames: ["gpii.test.standardServerSequenceGrade"], + sequenceElements: { + testLoadedSequence: { + gradeNames: "gpii.tests.productionConfigTesting.testLoadedSequence", + priority: "after:startServer" + } + } +}); + +fluid.defaults("gpii.tests.productionConfigTesting.testLoadedSequence", { + gradeNames: ["fluid.test.sequenceElement"], + sequence: [{ + funcName: "gpii.tests.productionConfigTesting.checkSolutionsRegistries" + }] +}); + +gpii.tests.productionConfigTesting.loadingSolutionsTransform.testDefs = [{ + name: "Flow Manager production tests -- solutions loading sequence", + config: gpii.tests.productionConfigTesting.config, + testEnvironmentGrade: "gpii.tests.productionConfigTesting.testEnvironment", + distributeOptions: { + // Override the default getRevision() to record the value it gets after + // requesting the revision. + "capture.revision": { + "record": { + "loadSolutions.getRevision": { + "listener": "gpii.tests.productionConfigTesting.loadingSolutionsTransform.getRevisionTest", + "args": ["{that}"] + } + }, + "target": "{that gpii.flowManager.local solutionsRegistryDataSource}.options.listeners" + } + }, + sequenceGrade: "gpii.tests.productionConfigTesting.loadingSolutionsTransform" +}]; + +// Call the default getRevision() and store the result is the SRDS +gpii.tests.productionConfigTesting.loadingSolutionsTransform.getRevisionTest = function (solutionRegistryDataSource) { + var revisionPromise = solutionRegistryDataSource.revisionRequester.getRevision(); + revisionPromise.then(function (revision) { + solutionRegistryDataSource.revision = revision; + }); + // For tests: keep a reference to this solutions registry data source. + gpii.tests.productionConfigTesting.loadingSolutionsTransform.solutionsRegistryDataSource = solutionRegistryDataSource; + + return revisionPromise; +}; + +// Check that the solutions were loaded from local file system and repository +// and that the revision used matches. +gpii.tests.productionConfigTesting.checkSolutionsRegistries = function () { + var solutionRegistryDataSource = gpii.tests.productionConfigTesting.loadingSolutionsTransform.solutionsRegistryDataSource; + jqUnit.assertNotNull( + "Check loading of solutions registries from local file system", + solutionRegistryDataSource.fullSolutionsRegistry + ); + jqUnit.assertDeepEq( + "Check revision", + gpii.tests.productionConfigTesting.validGpiiRevision, + solutionRegistryDataSource.revision + ); + jqUnit.assertNotNull( + "Check loading from soruce code respository", + solutionRegistryDataSource.repositorySolutionsRegistry + ); +}; + +gpii.test.runServerTestDefs(gpii.tests.productionConfigTesting.loadingSolutionsTransform.testDefs); diff --git a/tests/production/all-tests.js b/tests/production/all-tests.js index a2eafcd50..972866a72 100644 --- a/tests/production/all-tests.js +++ b/tests/production/all-tests.js @@ -26,6 +26,7 @@ fluid.require("%gpii-universal", require); var testIncludes = [ "./CloudStatusProductionTests.js", + "./SolutionsRegistryLoadSequenceTests.js", "./LoginLogoutProductionTests.js", "./SettingsGetProductionTests.js", "./SettingsPutProductionTests.js" From 2ea71a86d300cc8f2ecefb3baec9e1c4297e662e Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 20 Apr 2020 17:28:43 -0400 Subject: [PATCH 63/68] GPII-4273: (GPII-4273iv) Re-ordering the production tests. Put the testing of the loading of solutions registries at the end such that the data base cleanup occurs before they run, in case of failure. --- package.json | 2 +- tests/production/all-tests.js | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index ee2f67c66..524d0496e 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "test:vagrantBrowser": "vagrant ssh -c 'cd /home/vagrant/sync/universal; DISPLAY=:0; npm run test:browser'", "test:vagrantNode": "vagrant ssh -c 'cd /home/vagrant/sync/universal; npm run test:node'", "test:vagrantProduction": "vagrant ssh -c 'cd /home/vagrant/sync/universal; DISPLAY=:0; ./scripts/vagrantCloudBasedContainers.sh'", - "test:productionConfig": "node tests/production/AddUserSettingsToCouchTests.js && node tests/production/all-tests.js && node tests/production/DeleteUserSettingsFromCouchTests.js", + "test:productionConfig": "node tests/production/AddUserSettingsToCouchTests.js && node tests/production/all-tests.js && node tests/production/DeleteUserSettingsFromCouchTests.js && node tests/production/SolutionsRegistryLoadSequenceTests.js", "test:vagrant": "vagrant ssh -c 'cd /home/vagrant/sync/universal; DISPLAY=:0; npm test'", "posttest": "node node_modules/nyc/bin/nyc.js report -r text-summary -r html --report-dir reports --temp-directory coverage", "start": "node gpii.js", diff --git a/tests/production/all-tests.js b/tests/production/all-tests.js index 972866a72..a2eafcd50 100644 --- a/tests/production/all-tests.js +++ b/tests/production/all-tests.js @@ -26,7 +26,6 @@ fluid.require("%gpii-universal", require); var testIncludes = [ "./CloudStatusProductionTests.js", - "./SolutionsRegistryLoadSequenceTests.js", "./LoginLogoutProductionTests.js", "./SettingsGetProductionTests.js", "./SettingsPutProductionTests.js" From a98a54396a7ef7422cf0a9bbbb056a65e4be57ac Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 21 Apr 2020 14:08:54 -0400 Subject: [PATCH 64/68] GPII-4273: (GPII-4273iv) Moved load sequence tests back into all-tests.js Reworked the tests to provide a more graceful way of storing computed sequence value for later testing. --- package.json | 2 +- .../SolutionsRegistryLoadSequenceTests.js | 43 +++++++++++++------ tests/production/all-tests.js | 1 + 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index 524d0496e..ee2f67c66 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "test:vagrantBrowser": "vagrant ssh -c 'cd /home/vagrant/sync/universal; DISPLAY=:0; npm run test:browser'", "test:vagrantNode": "vagrant ssh -c 'cd /home/vagrant/sync/universal; npm run test:node'", "test:vagrantProduction": "vagrant ssh -c 'cd /home/vagrant/sync/universal; DISPLAY=:0; ./scripts/vagrantCloudBasedContainers.sh'", - "test:productionConfig": "node tests/production/AddUserSettingsToCouchTests.js && node tests/production/all-tests.js && node tests/production/DeleteUserSettingsFromCouchTests.js && node tests/production/SolutionsRegistryLoadSequenceTests.js", + "test:productionConfig": "node tests/production/AddUserSettingsToCouchTests.js && node tests/production/all-tests.js && node tests/production/DeleteUserSettingsFromCouchTests.js", "test:vagrant": "vagrant ssh -c 'cd /home/vagrant/sync/universal; DISPLAY=:0; npm test'", "posttest": "node node_modules/nyc/bin/nyc.js report -r text-summary -r html --report-dir reports --temp-directory coverage", "start": "node gpii.js", diff --git a/tests/production/SolutionsRegistryLoadSequenceTests.js b/tests/production/SolutionsRegistryLoadSequenceTests.js index 0fac6e639..11cde4167 100644 --- a/tests/production/SolutionsRegistryLoadSequenceTests.js +++ b/tests/production/SolutionsRegistryLoadSequenceTests.js @@ -80,9 +80,9 @@ gpii.tests.productionConfigTesting.loadingSolutionsTransform.testDefs = [{ config: gpii.tests.productionConfigTesting.config, testEnvironmentGrade: "gpii.tests.productionConfigTesting.testEnvironment", distributeOptions: { - // Override the default getRevision() to record the value it gets after + // Override the default getRevision() to record the value it resolves after // requesting the revision. - "capture.revision": { + "store.revision": { "record": { "loadSolutions.getRevision": { "listener": "gpii.tests.productionConfigTesting.loadingSolutionsTransform.getRevisionTest", @@ -90,6 +90,15 @@ gpii.tests.productionConfigTesting.loadingSolutionsTransform.testDefs = [{ } }, "target": "{that gpii.flowManager.local solutionsRegistryDataSource}.options.listeners" + }, + "store.registries": { + "record":{ + "solutionsRegistryReady": { + "listener": "gpii.tests.productionConfigTesting.loadingSolutionsTransform.storeRegistries", + "args": ["{that}"] + } + }, + "target": "{that flowManager solutionsRegistryDataSource}.options.listeners" } }, sequenceGrade: "gpii.tests.productionConfigTesting.loadingSolutionsTransform" @@ -99,30 +108,36 @@ gpii.tests.productionConfigTesting.loadingSolutionsTransform.testDefs = [{ gpii.tests.productionConfigTesting.loadingSolutionsTransform.getRevisionTest = function (solutionRegistryDataSource) { var revisionPromise = solutionRegistryDataSource.revisionRequester.getRevision(); revisionPromise.then(function (revision) { - solutionRegistryDataSource.revision = revision; + gpii.tests.productionConfigTesting.loadingSolutionsTransform.revision = revision; }); - // For tests: keep a reference to this solutions registry data source. - gpii.tests.productionConfigTesting.loadingSolutionsTransform.solutionsRegistryDataSource = solutionRegistryDataSource; - return revisionPromise; }; -// Check that the solutions were loaded from local file system and repository +// After the SRDS has finished loading the registries, keep a copy of them for +// testing. +gpii.tests.productionConfigTesting.loadingSolutionsTransform.storeRegistries = function (solutionRegistryDataSource) { + gpii.tests.productionConfigTesting.loadingSolutionsTransform.fullSolutionsRegistry = + solutionRegistryDataSource.fullSolutionsRegistry; + + gpii.tests.productionConfigTesting.loadingSolutionsTransform.repositorySolutionsRegistry = + solutionRegistryDataSource.repositorySolutionsRegistry; +}; + +// Check that the solutions were loaded from local file system and repository, // and that the revision used matches. gpii.tests.productionConfigTesting.checkSolutionsRegistries = function () { - var solutionRegistryDataSource = gpii.tests.productionConfigTesting.loadingSolutionsTransform.solutionsRegistryDataSource; - jqUnit.assertNotNull( - "Check loading of solutions registries from local file system", - solutionRegistryDataSource.fullSolutionsRegistry - ); jqUnit.assertDeepEq( "Check revision", gpii.tests.productionConfigTesting.validGpiiRevision, - solutionRegistryDataSource.revision + gpii.tests.productionConfigTesting.loadingSolutionsTransform.revision + ); + jqUnit.assertNotNull( + "Check loading of solutions registries from local file system", + gpii.tests.productionConfigTesting.loadingSolutionsTransform.fullSolutionsRegistry ); jqUnit.assertNotNull( "Check loading from soruce code respository", - solutionRegistryDataSource.repositorySolutionsRegistry + gpii.tests.productionConfigTesting.loadingSolutionsTransform.repositorySolutionsRegistry ); }; diff --git a/tests/production/all-tests.js b/tests/production/all-tests.js index a2eafcd50..972866a72 100644 --- a/tests/production/all-tests.js +++ b/tests/production/all-tests.js @@ -26,6 +26,7 @@ fluid.require("%gpii-universal", require); var testIncludes = [ "./CloudStatusProductionTests.js", + "./SolutionsRegistryLoadSequenceTests.js", "./LoginLogoutProductionTests.js", "./SettingsGetProductionTests.js", "./SettingsPutProductionTests.js" From 008c4bd33a9b750618e15daa80cec59a6e3076ed Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Tue, 21 Apr 2020 17:43:19 -0400 Subject: [PATCH 65/68] GPII-4273: (GPII-4273i) Modified technique for getting a revision For production tests run locally within a VM, the script now uses an upstream github revision to guarantee it is on github's server. --- scripts/vagrantCloudBasedContainers.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/scripts/vagrantCloudBasedContainers.sh b/scripts/vagrantCloudBasedContainers.sh index 43a558945..9872164a3 100755 --- a/scripts/vagrantCloudBasedContainers.sh +++ b/scripts/vagrantCloudBasedContainers.sh @@ -27,10 +27,12 @@ fi UNIVERSAL_IMAGE=vagrant-universal -# The following SHA256 is not the actual latest revision that is used in -# in production. This is here for the tests, and written to the file -# gpii-revision.json at the root universal folder. See the Dockerfile. -GITFULLREV="$(git rev-parse HEAD)" +# The following SHA256 is guaranteed to be a revison on github, and recent. It +# is not guaranteed to be the latest revision that is used in production; it +# could be an even later revision. It is sufficient for the tests. It is +# written to the file "gpii-revision.json" at the root universal folder. +# See the Dockerfile. +GITFULLREV="$(git rev-parse @{upstream})" COUCHDB_IMAGE=couchdb:2.3.1 COUCHDB_PORT=5984 From a5d316abc281f0991825203002115d7f2e395535 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 22 Apr 2020 10:14:21 -0400 Subject: [PATCH 66/68] GPII-4273: (GPII-4273i) Fixed bug in getting revision --- scripts/vagrantCloudBasedContainers.sh | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/scripts/vagrantCloudBasedContainers.sh b/scripts/vagrantCloudBasedContainers.sh index 9872164a3..21b9d1fc0 100755 --- a/scripts/vagrantCloudBasedContainers.sh +++ b/scripts/vagrantCloudBasedContainers.sh @@ -28,11 +28,20 @@ fi UNIVERSAL_IMAGE=vagrant-universal # The following SHA256 is guaranteed to be a revison on github, and recent. It -# is not guaranteed to be the latest revision that is used in production; it -# could be an even later revision. It is sufficient for the tests. It is -# written to the file "gpii-revision.json" at the root universal folder. -# See the Dockerfile. +# is not necessarily the latest revision that is used in production -- it +# could be a later revision -- but it is sufficient for the tests. For local +# development, @{upsteram} is used in case the local changes have not been +# pushed. CI has no upstream, and uses HEAD instead. The result is written to +# the file "gpii-revision.json" at the root universal folder. See the +# Dockerfile. GITFULLREV="$(git rev-parse @{upstream})" +if [ $? != 0 ] +then + echo "No upstream, using HEAD for revision.json" + GITFULLREV="$(git rev-parse HEAD)" +else + echo "Using upstream for revision.json" +fi COUCHDB_IMAGE=couchdb:2.3.1 COUCHDB_PORT=5984 From 5418f50c0c2d37ff5ec086f3d705e71294d026fc Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Wed, 22 Apr 2020 10:27:56 -0400 Subject: [PATCH 67/68] GPII-4273: Fixed spelling --- scripts/vagrantCloudBasedContainers.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/vagrantCloudBasedContainers.sh b/scripts/vagrantCloudBasedContainers.sh index 21b9d1fc0..a47e4669f 100755 --- a/scripts/vagrantCloudBasedContainers.sh +++ b/scripts/vagrantCloudBasedContainers.sh @@ -30,7 +30,7 @@ UNIVERSAL_IMAGE=vagrant-universal # The following SHA256 is guaranteed to be a revison on github, and recent. It # is not necessarily the latest revision that is used in production -- it # could be a later revision -- but it is sufficient for the tests. For local -# development, @{upsteram} is used in case the local changes have not been +# development, @{upstream} is used in case the local changes have not been # pushed. CI has no upstream, and uses HEAD instead. The result is written to # the file "gpii-revision.json" at the root universal folder. See the # Dockerfile. From a4c8a02a43b3eb460634a98793d9f2cd4648afc3 Mon Sep 17 00:00:00 2001 From: Joseph Scheuhammer Date: Mon, 27 Apr 2020 16:56:40 -0400 Subject: [PATCH 68/68] GPII-4273: (GPII-4273iii) Removed accidentally commented out line --- tests/all-tests.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/all-tests.js b/tests/all-tests.js index c68521c6f..99d5dbdad 100644 --- a/tests/all-tests.js +++ b/tests/all-tests.js @@ -60,7 +60,7 @@ var testIncludes = [ "../gpii/node_modules/flowManager/test/BrowserChannelTests.js", "../gpii/node_modules/flowManager/test/CaptureTests.js", "../gpii/node_modules/flowManager/test/SolutionsRegistryDataSourceTests.js", -// "../gpii/node_modules/flowManager/test/DefaultSettingsLoaderTests.js", + "../gpii/node_modules/flowManager/test/DefaultSettingsLoaderTests.js", "../gpii/node_modules/flowManager/test/PrefsServerDataSourceTests.js", "../gpii/node_modules/flowManager/test/PSPChannelTests.js", "../gpii/node_modules/flowManager/test/SettingsDataSourceTests.js",