UNPKG

@haystacks/async

Version:

A framework to build any number or any kind of native application or automation solution.

801 lines (751 loc) 50.2 kB
/** * @file integrationTests.js * @module integrationTests * @description Contains all of the commands to test various components of the system. * @requires module:commandBroker * @requires module:ruleBroker * @requires module:workflowBroker * @requires module:colorizer * @requires module:configurator * @requires module:loggers * @requires module:data * @requires module:queue * @requires module:stack * @requires {@link https://www.npmjs.com/package/@haystacks/constants|@haystacks/constants} * @requires {@link https://www.npmjs.com/package/path|path} * @author Seth Hollingsead * @date 2022/03/25 * @copyright Copyright © 2022-… by Seth Hollingsead. All rights reserved */ // Internal imports import commandBroker from '../../brokers/commandBroker.js'; import ruleBroker from '../../brokers/ruleBroker.js'; import workflowBroker from '../../brokers/workflowBroker.js'; import colorizer from '../../executrix/colorizer.js'; import configurator from '../../executrix/configurator.js'; import loggers from '../../executrix/loggers.js'; import D from '../../structures/data.js'; import queue from '../../structures/queue.js'; import stack from '../../structures/stack.js'; // External imports import hayConst from '@haystacks/constants'; import path from 'path'; const {bas, biz, clr, cmd, cfg, msg, num, sys, wrd} = hayConst; const baseFileName = path.basename(import.meta.url, path.extname(import.meta.url)); // framework.commandsBlob.commands.integrationTests. const namespacePrefix = wrd.cframework + bas.cDot + sys.ccommandsBlob + bas.cDot + wrd.ccommands + bas.cDot + baseFileName + bas.cDot; /** * @function validateConstants * @description Validates all constants with a 2-phase verification process. * @param {array<string>} inputData An array that could possibly include the name of this command, * and a list of top-level constants validation data structures to be validated. * That way we can parameterize and optimize the validation of the constants specific to the testing needs. * Rather than always running the full set of constants validation, as that could take a very long time, * and only needs to be done exhaustively when releasing a new instance of the entire Haystacks platform. * inputData[1] = validateConstants - This command name * inputData[2] = Could be a coma-separated string list of constants validation data to validate. * inputData[n] = Could be additional list of constants validation data to validate if the user entered a space-separated list. * Options are: Framework,Platform,Application,App,Plugins,Plugin * @param {string} inputMetaData Not used for this command. * @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to * indicate if the application should exit or not exit, followed by the command output. * @author Seth Hollingsead * @date 2022/03/25 */ async function validateConstants(inputData, inputMetaData) { let functionName = validateConstants.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData); let returnData = [true, false]; if (await configurator.getConfigurationSetting(wrd.csystem, cfg.cenableConstantsValidation) === true) { let pluginNamespace = ''; let processingPluginResults = false; let validationTypesInputArray = []; // Use this to process any inputs the user may have entered. let validationTypesConfirmedArray = []; // Use this once we've confirmed valid user entry for inputs given the types of validation that are available. let validationTypesConfirmedList = ''; let validUserEntry = false; // Get the array of keys and values for all the constants that need to be validated. let validationArray = []; // D[sys.cConstantsValidationData][sys.cConstantsFilePaths]; // This will return an object with all of the key-value pair attributes we need. let validationFrameworkArray = D[sys.cConstantsValidationData][wrd.cFramework][sys.cConstantsFilePaths]; // Framework constants paths let validationApplicationArray = D[sys.cConstantsValidationData][wrd.cApplication][sys.cConstantsFilePaths]; // Application constants paths let validationPluginsMetaArray = D[sys.cConstantsValidationData][wrd.cPlugins]; // Will need to iterate through each of the plugins and capture the plugin constants path for each plugin! let phase1FinalResult = true; let phase2FinalResult = true; let phase1Results = {}; let phase2Results = {}; let validConstantsValidationTypes = [wrd.cFramework, wrd.cApplication, wrd.cPlugins]; let validConstantsValidationUserTypes = [wrd.cFramework, wrd.cPlatform, wrd.cApplication, wrd.cApp, wrd.cPlugins, wrd.cPlugin] // validationFrameworkArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationFrameworkArrayIs + JSON.stringify(validationFrameworkArray)); // validationApplicationArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationApplicationArrayIs + JSON.stringify(validationApplicationArray)); // validationPluginsMetaArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationPluginsMetaArrayIs + JSON.stringify(validationPluginsMetaArray)); // Check first to see what, if any options, the user may have entered into this command, // that will determine to what extent we do validation. if (Array.isArray(inputData) && inputData.length === 2) { // User either entered a single data structure to validate, or a coma-separated list. // inputData.length is: await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataLengthIs + inputData.length); if (inputData[1].includes(bas.cComa)) { validationTypesInputArray = inputData[1].split(bas.cComa); } else if (inputData[1].includes(bas.cSemiColon)) { validationTypesInputArray = inputData[1].split(bas.cSemiColon); } else if (inputData[1].includes(bas.cForwardSlash)) { validationTypesInputArray = inputData[1].split(bas.cForwardSlash); } else if (inputData[1].includes(bas.cBackSlash)) { validationTypesInputArray = inputData[1].split(bas.cBackSlash); } else { // shift the data1! await loggers.consoleLog(namespacePrefix + functionName, msg.cshiftData1); inputData.shift(); validationTypesInputArray = inputData; } } else if (Array.isArray(inputData) && inputData.length > 2) { // shift the data2! await loggers.consoleLog(namespacePrefix + functionName, msg.cshiftData2); inputData.shift(); validationTypesInputArray = inputData; } // validationTypesInputArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesInputArrayIs + JSON.stringify(validationTypesInputArray)); // This is where we need to process the array of inputs to normalize them to the validation types available by the system. // Available types are: Framework,Platform,Application,App,Plugins,Plugin if (validationTypesInputArray.length > 0) { for (let validationTypesKey in validationTypesInputArray) { let userEnteredValidationType = validationTypesInputArray[validationTypesKey]; if (userEnteredValidationType.toUpperCase().trim() === wrd.cFRAMEWORK || userEnteredValidationType.toUpperCase().trim() === wrd.cPLATFORM) { validationTypesConfirmedArray.push(wrd.cFramework); } else if (userEnteredValidationType.toUpperCase().trim() === wrd.cAPPLICATION || userEnteredValidationType.toUpperCase().trim() === wrd.cAPP) { validationTypesConfirmedArray.push(wrd.cApplication); } else if (userEnteredValidationType.toUpperCase().trim() === wrd.cPLUGINS || userEnteredValidationType.toUpperCase().trim() === wrd.cPLUGIN) { validationTypesConfirmedArray.push(wrd.cPlugins); } else if (userEnteredValidationType === '') { // Just ignore it! } else { // WARNING: The specified validation type is not available, please enter a valid type and try again. Type not recognized: // Constants validation types are: console.log(msg.cWarningUserEnteredConstantsValidationDataTypeMessage01 + userEnteredValidationType); console.log(msg.cWarningUserEnteredConstantsValidationDataTypeMessage02 + validConstantsValidationUserTypes.join(bas.cComa + bas.cSpace)); } } // End-for (let validationTypesKey in validationTypesInputArray) // validationTypesConfirmedArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesConfirmedArrayIs + JSON.stringify(validationTypesConfirmedArray)); if (validationTypesConfirmedArray.length > 0) { validationTypesConfirmedList = validationTypesConfirmedArray.join(bas.cComa); validUserEntry = true; } else { // WARNING: No valid constants validation types were entered. console.log(msg.cWarningUserEnteredConstantsValidationDataTypeMessage03); // Constants validation types are: console.log(msg.cWarningUserEnteredConstantsValidationDataTypeMessage02 + validConstantsValidationUserTypes.join(bas.cComa + bas.cSpace)); } } else { // User didn't enter any parameters at all....just run it all! validationTypesConfirmedList = validConstantsValidationTypes.join(bas.cComa); validUserEntry = true; } // validationTypesConfirmedList is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesConfirmedListIs + validationTypesConfirmedList); if (validUserEntry) { if (validationTypesConfirmedList.includes(wrd.cFramework)) { validationArray = validationFrameworkArray; } if (validationTypesConfirmedList.includes(wrd.cApplication)) { validationArray = Object.assign(validationArray, validationApplicationArray); } // validationArray before plugin constants validation data merge is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationArrayBeforePluginConstantsValidationDataMergeIs + JSON.stringify(validationArray)); if (await configurator.getConfigurationSetting(wrd.csystem, cfg.cenablePluginLoader)) { if (validationTypesConfirmedList.includes(wrd.cPlugins)) { for (let plugin in validationPluginsMetaArray) { // plugin is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginIs + plugin); let pluginValidationPathData = validationPluginsMetaArray[plugin][sys.cConstantsFilePaths]; for (let constantsFilePathName in pluginValidationPathData) { // constantsFilePathName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cconstantsFilePathNamesIs + constantsFilePathName); let constantsFilePathValue = pluginValidationPathData[constantsFilePathName]; // constantsFilePathValue is: await loggers.consoleLog(namespacePrefix + functionName, msg.cconstantsFilePathValueIs + constantsFilePathValue); let newPluginConstantValidationName = plugin + bas.cColon + constantsFilePathName; // newPluginConstantValidationName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cnewPluginConstantValidationNameIs + newPluginConstantValidationName); let newPluginConstantValidationPathObject = {[newPluginConstantValidationName]: constantsFilePathValue}; validationArray = Object.assign(validationArray, newPluginConstantValidationPathObject); // validationArray after plugin constants validation data merge is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationArrayAfterPluginConstantsValidationDataMergeIs + JSON.stringify(validationArray)); } // End-for (let constantsFilePathNames in pluginValidationPathData) } // End-for (let plugin in validationPluginsMetaArray) } // End-if (validationTypesConfirmedList.includes(wrd.cPlugins)) } // End-if (await configurator.getConfigurationSetting(wrd.csystem, cfg.cenablePluginLoader)) // validationArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationArrayIs + JSON.stringify(validationArray)); // Phase1 Constants Validation // BEGIN Phase 1 Constants Validation await loggers.consoleLog(namespacePrefix + functionName, msg.cBeginPhase1ConstantsValidation); console.log(msg.cBeginPhase1ConstantsValidation); // First scan through each file and validate that the constants defined in the constants code file are also contained in the validation file. for (let key1 in validationArray) { let constantsPath = validationArray[key1]; phase1Results[key1] = await ruleBroker.processRules([constantsPath, key1], [biz.cvalidateConstantsDataValidation]); } // End-for (let key1 in validationArray) // END Phase 1 Constants Validation await loggers.consoleLog(namespacePrefix + functionName, msg.cEndPhase1ConstantsValidation); // phase1Results is: await loggers.consoleLog(namespacePrefix + functionName, msg.cphase1ResultsIs + JSON.stringify(phase1Results)); // Phase 2 Constants Validation // BEGIN Phase 2 Constants Validation await loggers.consoleLog(namespacePrefix + functionName, msg.cBeginPhase2ConstantsValidation); console.log(msg.cBeginPhase2ConstantsValidation); // Now verify that the values of the constants are what they are expected to be by using the constants validation data to validate. for (let key2 in validationArray) { phase2Results[key2] = await ruleBroker.processRules([key2, ''], [biz.cvalidateConstantsDataValues]); } // End-for (let key2 in validationArray) // END Phase 2 Constants Validation await loggers.consoleLog(namespacePrefix + functionName, msg.cEndPhase2ConstantsValidation); // phase2Results is: await loggers.consoleLog(namespacePrefix + functionName, msg.cphase2ResultsIs + JSON.stringify(phase2Results)); for (let key3 in phase1Results) { let constantsPhase1ValidationNamespaceParentObject = await ruleBroker.processRules([key3, ''], [biz.cgetConstantsValidationNamespaceParentObject]); if (key3.includes(bas.cColon) && key3.toUpperCase().includes(wrd.cPLUGIN)) { let pluginPhase1NamespaceArray = key3.split(bas.cColon); pluginNamespace = pluginPhase1NamespaceArray[1]; processingPluginResults = true; } if (processingPluginResults === false) { await loggers.constantsValidationSummaryLog(constantsPhase1ValidationNamespaceParentObject[sys.cConstantsPhase1ValidationMessages][key3], phase1Results[key3]); } else if (processingPluginResults === true) { await loggers.constantsValidationSummaryLog(constantsPhase1ValidationNamespaceParentObject[sys.cConstantsPhase1ValidationMessages][pluginNamespace], phase1Results[key3]); } processingPluginResults = false; pluginNamespace = ''; if (phase1Results[key3] === false) { phase1FinalResult = false; } } // End-for (let key3 in phase1ResultsArray) for (let key4 in phase2Results) { let constantsPhase2ValidationNamespaceParentObject = await ruleBroker.processRules([key4, ''], [biz.cgetConstantsValidationNamespaceParentObject]); if (key4.includes(bas.cColon) && key4.toUpperCase().includes(wrd.cPLUGIN)) { let pluginPhase2NamespaceArray = key4.split(bas.cColon); pluginNamespace = pluginPhase2NamespaceArray[1]; processingPluginResults = true; } if (processingPluginResults === false) { await loggers.constantsValidationSummaryLog(constantsPhase2ValidationNamespaceParentObject[sys.cConstantsPhase2ValidationMessages][key4], phase2Results[key4]); } else if (processingPluginResults === true) { await loggers.constantsValidationSummaryLog(constantsPhase2ValidationNamespaceParentObject[sys.cConstantsPhase2ValidationMessages][pluginNamespace], phase2Results[key4]); } processingPluginResults = false pluginNamespace = ''; if (phase2Results[key4] === false) { phase2FinalResult = false; } } // End-for (let key4 in phase2Results) if (phase1FinalResult === true && phase2FinalResult === true) { await configurator.setConfigurationSetting(wrd.csystem, cfg.cpassAllConstantsValidation, true); returnData[1] = true; } else { await configurator.setConfigurationSetting(wrd.csystem, cfg.cpassAllConstantsValidation, false); returnData[1] = false; } } else { await configurator.setConfigurationSetting(wrd.csystem, cfg.cpassAllConstantsValidation, false); returnData[1] = false; } // End-if (validUserEntry) } else { // The enableConstantsValidation flag is disabled. Enable this flag in the configuration settings to activate this command. console.log(msg.ccconstantsGeneratorMessage3 + msg.cconstantsGeneratorMessage4); await configurator.setConfigurationSetting(wrd.csystem, cfg.cpassAllConstantsValidation, false); returnData[1] = false; } await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function validateCommandAliases * @description Validates all command aliases have no duplicates within a command, but also between commands. * @param {array<string>} inputData An array that could possibly include the name of this command, * and a list of top-level command aliases data structures to be validated. * That way we can parameterize and optimize the validation of the command aliases specific to the testing needs. * Rather than always running the full set of command aliases, as that could take a very long time, * and only needs to be done exhaustively when releasing a new instance of the entire Haystacks platform. * inputData[1] = validateCommandAliases * inputData[2] = Could be a coma-separated string list of command alias data types to validate. * inputData[n] = Could be additional list of command alias list data to validate if the user entered a space-separated list. * Options are: Framework,Platform,Application,App,Plugins,Plugin * @param {string} inputMetaData Not used for this command. * @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to * indicate if the application should exit or not exit, followed by the command output. * @author Seth Hollingsead * @date 2022/03/30 */ async function validateCommandAliases(inputData, inputMetaData) { let functionName = validateCommandAliases.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData); let returnData = [true, false]; let validationTypesInputArray = []; // Use this to process any inputs the user may have entered. let validationTypesConfirmedArray = []; // Use this once we've confirmed valid user entry for inputs given the types of validation that are available. let validationTypesConfirmedList = ''; let validUserEntry = false; let allCommandAliasesToValidate = [] let passedAllCommandAliasesDuplicateCheck = true; let duplicateAliasCount = 0 let blackColorArray = await colorizer.getNamedColorData(clr.cBlack, [0,0,0]); let redColorArray = await colorizer.getNamedColorData(clr.cRed, [255,0,0]); let validCommandAliasesValidationTypes = [wrd.cFramework, wrd.cApplication, wrd.cPlugins]; let validCommandAliasesValidationUserTypes = [wrd.cFramework, wrd.cPlatform, wrd.cApplication, wrd.cApp, wrd.cPlugins, wrd.cPlugin]; // Process user input(s). // Check first to see what, if any options, the user may have entered into this command, // that will determine to what extent we do validation. if (Array.isArray(inputData) && inputData.length === 2) { // User either entered a single data structure to validate, or a coma-separated list. // inputData.length is: await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataLengthIs + inputData.length); if (inputData[1].includes(bas.cComa)) { validationTypesInputArray = inputData[1].split(bas.cComa); } else if (inputData[1].includes(bas.cSemiColon)) { validationTypesInputArray = inputData[1].split(bas.cSemiColon); } else if (inputData[1].includes(bas.cForwardSlash)) { validationTypesInputArray = inputData[1].split(bas.cForwardSlash); } else if (inputData[1].includes(bas.cBackSlash)) { validationTypesInputArray = inputData[1].split(bas.cBackSlash); } else { // shift the data1! await loggers.consoleLog(namespacePrefix + functionName, msg.cshiftData1); inputData.shift(); validationTypesInputArray = inputData; } } else if (Array.isArray(inputData) && inputData.length > 2) { // shift the data2! await loggers.consoleLog(namespacePrefix + functionName, msg.cshiftData2); inputData.shift(); validationTypesInputArray = inputData; } // validationTypesInputArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesInputArrayIs + JSON.stringify(validationTypesInputArray)); // This is where we need to process the array of inputs to normalize them to the validation types available by the system. // Available types are: Framework,Platform,Application,App,Plugins,Plugin if (validationTypesInputArray.length > 0) { for (let validationTypesKey in validationTypesInputArray) { let userEnteredValidationType = validationTypesInputArray[validationTypesKey]; if (userEnteredValidationType.toUpperCase().trim() === wrd.cFRAMEWORK || userEnteredValidationType.toUpperCase().trim() === wrd.cPLATFORM) { validationTypesConfirmedArray.push(wrd.cFramework); } else if (userEnteredValidationType.toUpperCase().trim() === wrd.cAPPLICATION || userEnteredValidationType.toUpperCase().trim() === wrd.cAPP) { validationTypesConfirmedArray.push(wrd.cApplication); } else if (userEnteredValidationType.toUpperCase().trim() === wrd.cPLUGINS || userEnteredValidationType.toUpperCase().trim() === wrd.cPLUGIN) { validationTypesConfirmedArray.push(wrd.cPlugins); } else if (userEnteredValidationType === '') { // Just ignore it! } else { // WARNING: The specified validation type is not available, please enter a valid type and try again. Type not recognized: console.log(msg.cWarningUserEnteredConstantsValidationDataTypeMessage01 + userEnteredValidationType); // Command Aliases validation types are: console.log(msg.cWarningUserEnteredCommandAliasesValidationDataTypeMessage02 + validCommandAliasesValidationUserTypes.join(bas.cComa + bas.cSpace)); } } // End-for (let validationTypesKey in validationTypesInputArray) // validationTypesConfirmedArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesConfirmedArrayIs + JSON.stringify(validationTypesConfirmedArray)); if (validationTypesConfirmedArray.length > 0) { validationTypesConfirmedList = validationTypesConfirmedArray.join(bas.cComa); validUserEntry = true; } else { // WARNING: No valid command aliases validation types were entered. console.log(msg.cWarningUserEnteredCommandAliasesValidationDataTypeMessage03); // Command Aliases validation types are: console.log(msg.cWarningUserEnteredCommandAliasesValidationDataTypeMessage02 + validCommandAliasesValidationUserTypes.join(bas.cComa + bas.cSpace)); } } else { // User didn't enter any parameters at all....just run it all! validationTypesConfirmedList = validCommandAliasesValidationTypes.join(bas.cComa); validUserEntry = true; } // validationTypesConfirmedList is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesConfirmedListIs + validationTypesConfirmedList); if (validUserEntry === true) { if (validationTypesConfirmedList.includes(wrd.cFramework)) { let frameworkCommandAliases = await commandBroker.getAllCommandAliasData(D[sys.cCommandsAliases][wrd.cFramework]); // frameworkCommandAliases is: await loggers.consoleLog(namespacePrefix + functionName, msg.cframeworkCommandAliasesIs + JSON.stringify(frameworkCommandAliases)); if (frameworkCommandAliases) { allCommandAliasesToValidate = await ruleBroker.processRules([allCommandAliasesToValidate, frameworkCommandAliases], [biz.cobjectDeepMerge]); } } if (validationTypesConfirmedList.includes(wrd.cApplication)) { let applicationCommandAliases = await commandBroker.getAllCommandAliasData(D[sys.cCommandsAliases][wrd.cApplication]); // applicationCommandAliases is: await loggers.consoleLog(namespacePrefix + functionName, msg.capplicationCommandAliasesIs + JSON.stringify(applicationCommandAliases)); if (applicationCommandAliases) { if (Object.keys(allCommandAliasesToValidate).length != 0) { allCommandAliasesToValidate = await ruleBroker.processRules([allCommandAliasesToValidate, applicationCommandAliases], [biz.cobjectDeepMerge]); } else { allCommandAliasesToValidate = applicationCommandAliases; } } } // If the system is either loading plugins or plugin data has been loaded by the build-release-deployment system for // the purpose of releasing a plugin and running plugin validations as part of the plugin release process. if (await configurator.getConfigurationSetting(wrd.csystem, cfg.cenablePluginLoader) || await configurator.getConfigurationSetting(wrd.csystem, sys.cPluginName)) { if (validationTypesConfirmedList.includes(wrd.cPlugins)) { let pluginCommandAliases = await commandBroker.getAllCommandAliasData(D[sys.cCommandsAliases][wrd.cPlugins]); // pluginCommandAliases is: await loggers.consoleLog(namespacePrefix + functionName, msg.cpluginCommandAliasesIs + JSON.stringify(pluginCommandAliases)); if (pluginCommandAliases) { if (Object.keys(allCommandAliasesToValidate).length != 0) { allCommandAliasesToValidate = await ruleBroker.processRules([allCommandAliasesToValidate, pluginCommandAliases], [biz.cobjectDeepMerge]); } else { allCommandAliasesToValidate = pluginCommandAliases; } } } } // Old method of getting all the command aliases data: // allCommandAliasesToValidate = await commandBroker.getAllCommandAliasData(D[sys.cCommandsAliases]); // allCommandAliasesToValidate is: await loggers.consoleLog(namespacePrefix + functionName, msg.callCommandAliasesToValidateIs + JSON.stringify(allCommandAliasesToValidate)); // Now do the validation from the flattened array of command aliases data. // Begin command aliases validation console.log(msg.cBeginCommandAliasesValidationMessage); for (let key1 in allCommandAliasesToValidate[0]) { // key1 is: await loggers.consoleLog(namespacePrefix + functionName, msg.ckey1Is + key1); let currentCommand = allCommandAliasesToValidate[0][key1]; // currentCommand is: await loggers.consoleLog(namespacePrefix + functionName, msg.ccurrentCommandIs + JSON.stringify(currentCommand)); console.log(msg.ccurrentCommandIs + currentCommand[wrd.cName]); let aliasList = currentCommand[wrd.cAliases]; // aliasList is: await loggers.consoleLog(namespacePrefix + functionName, msg.caliasListIs + aliasList); let arrayOfAliases = aliasList.split(bas.cComa); for (let j = 0; j < arrayOfAliases.length; j++) { // BEGIN j-th loop: await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_jthLoop + j); let currentAlias = arrayOfAliases[j]; // currentAlias is: await loggers.consoleLog(namespacePrefix + functionName, msg.ccurrentAliasIs + currentAlias); duplicateAliasCount = await commandBroker.countMatchingCommandAlias(D[sys.cCommandsAliases], currentAlias); if (duplicateAliasCount > 1) { // duplicateAliasCount is: let duplicateAliasCountMessage = msg.cduplicateAliasCountIs + duplicateAliasCount; duplicateAliasCountMessage = await colorizer.colorizeMessageSimple(duplicateAliasCountMessage, blackColorArray, true); duplicateAliasCountMessage = await colorizer.colorizeMessageSimple(duplicateAliasCountMessage, redColorArray, false); console.log(duplicateAliasCountMessage); // duplicate command alias is: let duplicateAliasCommandMessage = msg.cduplicateCommandAliasIs + currentAlias; duplicateAliasCommandMessage = await colorizer.colorizeMessageSimple(duplicateAliasCommandMessage, blackColorArray, true); duplicateAliasCommandMessage = await colorizer.colorizeMessageSimple(duplicateAliasCommandMessage, redColorArray, false); console.log(duplicateAliasCommandMessage); passedAllCommandAliasesDuplicateCheck = false; returnData[1] = false; // DO NOT break out of any loops here, the command should scan all command aliases! } // END j-th loop: await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_jthLoop + j); } // End-for (let j = 0; j < arrayOfAliases.length; j++) } // End-for (let key1 in allCommandAliasesToValidate[0]) if (passedAllCommandAliasesDuplicateCheck === true) { // PASSED: All duplicate command aliases validation tests! console.log(msg.cvalidateCommandAliasesMessage1); returnData[1] = true; } // End-if (passedAllCommandAliasesDuplicateCheck === true) } else { // No validation was run, YOU SHALL NOT PASS!!!! passedAllCommandAliasesDuplicateCheck = false; returnData[1] = false; } // End-if (validUserEntry === true) await configurator.setConfigurationSetting(wrd.csystem, cfg.cpassedAllCommandAliasesDuplicateChecks, passedAllCommandAliasesDuplicateCheck); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function validateWorkflows * @description Validates all the workflows have no duplicates. * @param {array<string>} inputData An array that could possibly include the name of this command, * and a list of top-level workflows data structures to be validated. * That way we can parameterize and optimize the validation of the workflows specific to the testing needs. * Rather than always running the full set of workflows, as that could take longer, * and only needs to be done exhaustively when releasing a new instance of the entire Haystacks platform. * inputData[1] = validateWorkflows * inputData[2] = Could be a coma-separated string list of workflow data types to validate. * inputData[n] = Could be additional list of workflow data types list to validate if the user entered a space-separated list. * Options are: Framework,Platform,Application,App,Plugins,Plugin * @param {string} inputMetaData Not used for this command. * @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to * indicate if the application should exit or not exit, followed by the command output. * @author Seth Hollingsead * @date 2022/06/08 */ async function validateWorkflows(inputData, inputMetaData) { let functionName = validateWorkflows.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData); let returnData = [true, false]; let validationTypesInputArray = []; // Use this to process any inputs the user may have entered. let validationTypesConfirmedArray = []; // Use this once we've confirmed valid user entry for inputs given the types of validation that are available. let validationTypesConfirmedList = ''; let validUserEntry = false; let allWorkflowsToValidate = []; let numberOfDuplicatesFound = 0; let passedAllWorkflowDuplicateCheck = true; let blackColorArray = await colorizer.getNamedColorData(clr.cBlack, [0,0,0]); let redColorArray = await colorizer.getNamedColorData(clr.cRed, [255,0,0]); let validWorkflowsValidationTypes = [wrd.cFramework, wrd.cApplication, wrd.cPlugins]; let validWorkflowsValidationUserTypes = [wrd.cFramework, wrd.cPlatform, wrd.cApplication, wrd.cApp, wrd.cPlugins, wrd.cPlugin]; // Process user input(s). // Check first to see what, if any options, the user may have entered into this command, // that will determine to what extent we do validation. if (Array.isArray(inputData) && inputData.length === 2) { // User either entered a single data structure to validate, or a coma-separated list. // inputData.length is: await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataLengthIs + inputData.length); if (inputData[1].includes(bas.cComa)) { validationTypesInputArray = inputData[1].split(bas.cComa); } else if (inputData[1].includes(bas.cSemiColon)) { validationTypesInputArray = inputData[1].split(bas.cSemiColon); } else if (inputData[1].includes(bas.cForwardSlash)) { validationTypesInputArray = inputData[1].split(bas.cForwardSlash); } else if (inputData[1].includes(bas.cBackSlash)) { validationTypesInputArray = inputData[1].split(bas.cBackSlash); } else { // shift the data1! await loggers.consoleLog(namespacePrefix + functionName, msg.cshiftData1); inputData.shift(); validationTypesInputArray = inputData; } } else if (Array.isArray(inputData) && inputData.length > 2) { // shift the data2! await loggers.consoleLog(namespacePrefix + functionName, msg.cshiftData2); inputData.shift(); validationTypesInputArray = inputData; } // validationTypesInputArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesInputArrayIs + JSON.stringify(validationTypesInputArray)); // This is where we need to process the array of inputs to normalize them to the validation types available by the system. // Available types are: Framework,Platform,Application,App,Plugins,Plugin if (validationTypesInputArray.length > 0) { for (let validationTypesKey in validationTypesInputArray) { let userEnteredValidationType = validationTypesInputArray[validationTypesKey]; if (userEnteredValidationType.toUpperCase().trim() === wrd.cFRAMEWORK || userEnteredValidationType.toUpperCase().trim() === wrd.cPLATFORM) { validationTypesConfirmedArray.push(wrd.cFramework); } else if (userEnteredValidationType.toUpperCase().trim() === wrd.cAPPLICATION || userEnteredValidationType.toUpperCase().trim() === wrd.cAPP) { validationTypesConfirmedArray.push(wrd.cApplication); } else if (userEnteredValidationType.toUpperCase().trim() === wrd.cPLUGINS || userEnteredValidationType.toUpperCase().trim() === wrd.cPLUGIN) { validationTypesConfirmedArray.push(wrd.cPlugins); } else if (userEnteredValidationType === '') { // Just ignore it! } else { // WARNING: The specified validation type is not available, please enter a valid type and try again. Type not recognized: console.log(msg.cWarningUserEnteredConstantsValidationDataTypeMessage01 + userEnteredValidationType); // Workflows validation types are: console.log(msg.cWarningUserEnteredWorkflowsValidationDataTypeMessage02 + validWorkflowsValidationUserTypes.join(bas.cComa + bas.cSpace)); } } // End-for (let validationTypesKey in validationTypesInputArray) // validationTypesConfirmedArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesConfirmedArrayIs + JSON.stringify(validationTypesConfirmedArray)); if (validationTypesConfirmedArray.length > 0) { validationTypesConfirmedList = validationTypesConfirmedArray.join(bas.cComa); validUserEntry = true; } else { // WARNING: No valid workflow validation types were entered. console.log(msg.cWarningUserEnteredWorkflowsValidationDataTypeMessage03); // Workflows validation types are: console.log(msg.cWarningUserEnteredWorkflowsValidationDataTypeMessage02 + validWorkflowsValidationUserTypes.join(bas.cComa + bas.cSpace)); } } else { // User didn't enter any parameters at all....just run it all! validationTypesConfirmedList = validWorkflowsValidationTypes.join(bas.cComa); validUserEntry = true; } // validationTypesConfirmedList is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesConfirmedListIs + validationTypesConfirmedList); if (validUserEntry === true) { if (validationTypesConfirmedList.includes(wrd.cFramework)) { allWorkflowsToValidate = await workflowBroker.getAllWorkflows(D[sys.cCommandWorkflows][wrd.cFramework]); } // allWorkflowsToValidate is: 1 await loggers.consoleLog(namespacePrefix + functionName, msg.callWorkflowsToValidate + num.c1 + bas.cSpace + JSON.stringify(allWorkflowsToValidate)); if (validationTypesConfirmedList.includes(wrd.cApplication)) { allWorkflowsToValidate.push(...await workflowBroker.getAllWorkflows(D[sys.cCommandWorkflows][wrd.cApplication])); } // If the system is either loading plugins or plugin data has been loaded by the build-release-deployment system for // the purpose of releasing a plugin and running plugin validations as part of the plugin release process. if (await configurator.getConfigurationSetting(wrd.csystem, cfg.cenablePluginLoader) || await configurator.getConfigurationSetting(wrd.csystem, sys.cPluginName)) { // NOTE: If the plugin system is enabled, but no plugins are loaded, then the following will be undefined if we don't check to see if it is also undefined. // The result would be the call to getAllWorkflows will return the contents of all workflows and they would get duplicate added to the allWorkflowsToValidate array. // This will generate many duplicate entries that are not actual duplicates, causing false positive failures. if (validationTypesConfirmedList.includes(wrd.cPlugins) && D[sys.cCommandWorkflows][wrd.cPlugins] !== undefined) { allWorkflowsToValidate.push(...await workflowBroker.getAllWorkflows(D[sys.cCommandWorkflows][wrd.cPlugins])); } } // Old method of getting all the command aliases data: // allWorkflowsToValidate = await workflowBroker.getAllWorkflows(D[sys.cCommandWorkflows]); // allWorkflowsToValidate is: 2 await loggers.consoleLog(namespacePrefix + functionName, msg.callWorkflowsToValidate + num.c2 + bas.cSpace + JSON.stringify(allWorkflowsToValidate)); // Begin workflows validation console.log(msg.cBeginWorkflowsValidationMessage); for (let workflowKey in allWorkflowsToValidate) { numberOfDuplicatesFound = 0; let workflowName = allWorkflowsToValidate[workflowKey]; // workflowName is: await loggers.consoleLog(namespacePrefix + functionName, msg.cworkflowNameIs + workflowName); console.log(msg.cworkflowNameIs + workflowName); for (const element of allWorkflowsToValidate) { let secondTierWorkflowName = element; // secondTierWorkflowName is: await loggers.consoleLog(namespacePrefix + functionName, msg.csecondTierWorkflowNameIs + secondTierWorkflowName); if (workflowName === secondTierWorkflowName) { numberOfDuplicatesFound = numberOfDuplicatesFound + 1; } } // End-for (const element of allWorkflowsToValidate) if (numberOfDuplicatesFound > 1) { // Duplicate workflow count is: let duplicateWorkflowCountMessage = msg.cDuplicateWorkflowCountIs + numberOfDuplicatesFound; duplicateWorkflowCountMessage = await colorizer.colorizeMessageSimple(duplicateWorkflowCountMessage, blackColorArray, true); duplicateWorkflowCountMessage = await colorizer.colorizeMessageSimple(duplicateWorkflowCountMessage, redColorArray, false); console.log(duplicateWorkflowCountMessage); // Duplicate workflow name is: let duplicateWorkflowMessage = msg.cDuplicateWorkflowNameIs + workflowName; duplicateWorkflowMessage = await colorizer.colorizeMessageSimple(duplicateWorkflowMessage, blackColorArray, true); duplicateWorkflowMessage = await colorizer.colorizeMessageSimple(duplicateWorkflowMessage, redColorArray, false); console.log(duplicateWorkflowMessage); passedAllWorkflowDuplicateCheck = false; returnData[1] = false; } // End-if (numberOfDuplicatesFound > 1) } // End-for (let workflowName in allWorkflowsToValidate) } else { // No validation was run, YOU SHALL NOT PASS!!!! passedAllWorkflowDuplicateCheck = false; returnData[1] = false; } // End-if (validUserEntry === true) if (passedAllWorkflowDuplicateCheck === true) { // PASSED: All duplicate workflow validation tests! console.log(msg.cvalidateWorkflowsMessage01); returnData[1] = true; } // End-if (passedAllWorkflowDuplicateCheck === true) await configurator.setConfigurationSetting(wrd.csystem, cfg.cpassedAllWorkflowDuplicateChecks, passedAllWorkflowDuplicateCheck); await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JSON.stringify(returnData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cEND_Function); return returnData; } /** * @function runAllValidations * @description Runs all validations together, constants validation, command alias validation and workflow validation. * @param {string} inputData An array that could possibly include the name of this command, * and a list of top-level data structures that all validations should be run against. * Rather than always running the full set of validations against everything, as that could take longer, * and only needs to be done exhaustively when releasing a new instance of the entire Haystacks platform. * inputData[1] = runAllValidations * inputData[2] = Could be a coma-separated string list of data types to run all validation with. * inputData[n] = Could be additional list of workflow data types list to validate if the user entered a space-separated list. * Options are: Framework,Platform,Application,App,Plugins,Plugin * @param {string} inputMetaData Not used for this command. * @return {array<boolean,string|integer|boolean|object|array>} An array with a boolean True or False value to * indicate if the application should exit or not exit, followed by the command output. * @author Seth Hollingsead * @date 2023/02/20 */ async function runAllValidations(inputData, inputMetaData) { let functionName = runAllValidations.name; await loggers.consoleLog(namespacePrefix + functionName, msg.cBEGIN_Function); await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataIs + JSON.stringify(inputData)); await loggers.consoleLog(namespacePrefix + functionName, msg.cinputMetaDataIs + inputMetaData); let returnData = [true, false]; let validationTypesInputArray = []; // Use this to process any inputs the user may have entered. let validationTypesConfirmedArray = []; // Use this once we've confirmed valid user entry for inputs given the types of validation that are available. let validationTypesConfirmedList = ''; let validUserEntry = false; let validValidationTypes = [wrd.cFramework, wrd.cApplication, wrd.cPlugins]; let validValidationUserTypes = [wrd.cFramework, wrd.cPlatform, wrd.cApplication, wrd.cApp, wrd.cPlugins, wrd.cPlugin]; // Process user input(s). // Check first to see what, if any options, the user may have entered nto this command, // that will determine to what extent we do validation. if (Array.isArray(inputData) && inputData.length === 2) { // User either entered a single data structure to validate, or a coma-separated list. // inputData.length is: await loggers.consoleLog(namespacePrefix + functionName, msg.cinputDataLengthIs + inputData.length); if (inputData[1].includes(bas.cComa)) { validationTypesInputArray = inputData[1].split(bas.cComa); } else if (inputData[1].includes(bas.cSemiColon)) { validationTypesInputArray = inputData[1].split(bas.cSemiColon); } else if (inputData[1].includes(bas.cForwardSlash)) { validationTypesInputArray = inputData[1].split(bas.cForwardSlash); } else if (inputData[1].includes(bas.cBackSlash)) { validationTypesInputArray = inputData[1].split(bas.cForwardSlash); } else { // shift the data1! await loggers.consoleLog(namespacePrefix + functionName, msg.cshiftData1); inputData.shift(); validationTypesInputArray = inputData; } } else if (Array.isArray(inputData) && inputData.length > 2) { // shift the data2! await loggers.consoleLog(namespacePrefix + functionName, msg.cshiftData2); inputData.shift(); validationTypesInputArray = inputData; } // validationTypesInputArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesInputArrayIs + JSON.stringify(validationTypesInputArray)); // This is where we need to process the array of inputs to normalize them to the validation types available by the system. // Available types are: Framework,Platform,Application,App,Plugins,Plugin if (validationTypesInputArray.length > 0) { for (let validationTypesKey in validationTypesInputArray) { let userEnteredValidationType = validationTypesInputArray[validationTypesKey]; if (userEnteredValidationType.toUpperCase().trim() === wrd.cFRAMEWORK || userEnteredValidationType.toUpperCase().trim() === wrd.cPLATFORM) { validationTypesConfirmedArray.push(wrd.cFramework); } else if (userEnteredValidationType.toUpperCase().trim() === wrd.cAPPLICATION || userEnteredValidationType.toUpperCase().trim() === wrd.cAPP) { validationTypesConfirmedArray.push(wrd.cApplication); } else if (userEnteredValidationType.toUpperCase().trim() === wrd.cPLUGINS || userEnteredValidationType.toUpperCase().trim() === wrd.cPLUGIN) { validationTypesConfirmedArray.push(wrd.cPlugins); } else if (userEnteredValidationType === '') { // Just ignore it } else { // WARNING: The specified validation type is not available, please enter a valid type and try again. Type not recognized: console.log(msg.cWarningUserEnteredConstantsValidationDataTypeMessage01 + userEnteredValidationType); // Validation types are: console.log(msg.cWarningUserEnteredValidationDateTypeMessage02 + validValidationUserTypes.join(bas.cComa + bas.cSpace)); } } // End-for (let validationTypesKey in validationTypesInputArray) // validationTypesConfirmedArray is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesConfirmedArrayIs + JSON.stringify(validationTypesConfirmedArray)); if (validationTypesConfirmedArray.length > 0) { validationTypesConfirmedList = validationTypesConfirmedArray.join(bas.cComa); validUserEntry = true; } else { // WARNING: No valid validation types were entered. console.log(msg.cWarningUserEnteredValidationDataTypeMessage03); // All validation types are: console.log(msg.cWarningUserEnteredValidationDataTypeMessage02 + validValidationUserTypes.join(bas.cComa + bas.cSpace)); } } else { // User didn't enter any parameters at all....just run it all! validationTypesConfirmedList = validValidationTypes.join(bas.cComa); validationTypesConfirmedArray = validValidationTypes validUserEntry = true; } // vaidationTypesConfirmedList is: await loggers.consoleLog(namespacePrefix + functionName, msg.cvalidationTypesConfirmedListIs + validationTypesConfirmedList); if (validUserEntry === true) { let constantsValidationCommandToQueue = cmd.cvalidateConstants + bas.cSpace + validationTypesConfirmedList; let commandAliasesValidationCommandToQueue = cmd.cvalidateCommandAliases + bas.cSpace + validationTypesConfirmedList; let workflowsValidationCommandToQueue = cmd.cvalidateWorkflows + bas.cSpace + validationTypesConfirmedList; if (await configurator.getConfigurationSetting(wrd.csystem, cfg.clogAllCommands) === true) { await stack.push(sys.cSystemCommandLog, constantsValidationCommandToQueue); await stack.push(sys.cSystemCommandLog, commandAliasesValidationCommandToQueue); await stack.push(sys.cSystemCommandLog, workflowsValidationCommandToQueue); } // Now add them to the front of the command queue in reverse order, so they will get executed next. // Running all validations console.log(msg.cRunningAllValidationsMessage); await queue.enqueueFront(sys.cCommandQueue, workflowsValidationCommandToQueue); await queue.enqueueFront(sys.cCommandQueue, commandAliasesValidationCommandToQueue); await queue.enqueueFront(sys.cCommandQueue, constantsValidationCommandToQueue); } await loggers.consoleLog(namespacePrefix + functionName, msg.creturnDataIs + JS