@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
JavaScript
/**
* @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