Name

sn_cmdb_int_util.AtfTestCoverageUtil

Description

Utility functions to get coverage of ATF tests

Script

var AtfTestCoverageUtil = Class.create();
AtfTestCoverageUtil.prototype = {
  initialize: function() {
      this.RECORD_QUERY = "Record Query";
      this.SOFTWARE_QUERY = "Software Query";
      this.CONDITIONS_VARIABLE = "915990ab531000109e02ddeeff7b12f8";
      this.IGNORED_TABLES = ["em_event", "em_alert"];
      this.IGNORED_FIELDS = ["EQ", "discovery_source", "source_native_key", "source_recency_timestamp", "sys_class_name", "assigned_to"];
      this.SOFTWARE_CLASSES = ["cmdb_sam_sw_install", "cmdb_software_instance", "cmdb_ci_spkg"];
      this.CMDB_REL_CI = "cmdb_rel_ci";
      this.CMDBIntegrationValidationTestUtils = new sn_cmdb_int_util.CMDBIntegrationValidationTestUtils();
  },

  getTargetedClassesAndFields: function(applicationSysId) {
      var jsonResult = {};
      var entityMappingGr = new GlideRecord("sys_rte_eb_entity_mapping");
      entityMappingGr.addQuery("sys_scope", applicationSysId);
      entityMappingGr.addQuery("source_sys_rte_eb_entity", "DOES NOT CONTAIN", "import");
      entityMappingGr.orderBy("target_sys_rte_eb_entity");
      entityMappingGr.query();
      while (entityMappingGr.next()) {
          var table = entityMappingGr.target_sys_rte_eb_entity.table;
          if (gs.nil(table) || this.IGNORED_TABLES.indexOf(table) > -1) {
              continue;
          }
          var fieldMappingGr = new GlideRecord("sys_rte_eb_field_mapping");
          fieldMappingGr.addQuery("sys_scope", applicationSysId);
          fieldMappingGr.addQuery("sys_rte_eb_entity_mapping", entityMappingGr.getUniqueValue());
          fieldMappingGr.query();
          if (this.CMDB_REL_CI == table) {
              var relationship = {};
              relationship.type = entityMappingGr.target_sys_rte_eb_entity.relationship_type.name.toString();
              while (fieldMappingGr.next()) {
                  if ("parent" == fieldMappingGr.target_sys_rte_eb_field.field.toString()) {
                      relationship.parent = fieldMappingGr.referenced_sys_rte_eb_entity.table.toString();
                  } else if ("child" == fieldMappingGr.target_sys_rte_eb_field.field.toString()) {
                      relationship.child = fieldMappingGr.referenced_sys_rte_eb_entity.table.toString();
                  }
              }
              var relationships = [];
              if (jsonResult[table]) {
                  relationships = jsonResult[table];
              } else {
                  jsonResult[table] = relationships;
              }
              if (!gs.nil(relationship.parent) && !gs.nil(relationship.child) && this.relationshipArrayContainsRelationship(jsonResult[table], relationship) < 0) {
                  jsonResult[table].push(relationship);
              }
          } else {
              var fields = [];
              if (jsonResult[table]) {
                  fields = jsonResult[table];
              } else {
                  jsonResult[table] = fields;
              }
              while (fieldMappingGr.next()) {
                  var field = fieldMappingGr.target_sys_rte_eb_field.field.toString();
                  if (gs.nil(field) || this.IGNORED_FIELDS.indexOf(field) > -1) {
                      continue;
                  }
                  if (fields.indexOf(field) === -1) {
                      fields.push(field);
                  }
              }
          }
          //
      }
      return jsonResult;
  },

  getCoveredClassesAndFields: function(applicationSysId) {
      var jsonResult = {};
      var stepGr = new GlideRecord("sys_atf_step");
      stepGr.addQuery("display_name", this.RECORD_QUERY);
      stepGr.addQuery("sys_scope", applicationSysId);
      stepGr.addQuery("active", "true");
      stepGr.orderBy("table");
      stepGr.query();
      while (stepGr.next()) {
          var testSuiteGr = new GlideRecord("sys_atf_test_suite_test");
          testSuiteGr.addQuery("test", stepGr.test.toString());
          testSuiteGr.query();
          if (testSuiteGr.next()) {
              jsonResult.testSuite = testSuiteGr.test_suite.toString();
          }
          var table = stepGr.table.toString();
          var originalTable = stepGr.table.toString();
          if (gs.nil(table) || this.IGNORED_TABLES.indexOf(table) > -1) {
              continue;
          }
          if (this.CMDB_REL_CI == table) {
              var relationship = {};
              var variableValueGr = new GlideRecord("sys_variable_value");
              variableValueGr.addQuery("document", "sys_atf_step");
              variableValueGr.addQuery("document_key", stepGr.getUniqueValue());
              variableValueGr.addQuery("variable", this.CONDITIONS_VARIABLE);
              variableValueGr.query();
              while (variableValueGr.next()) {
                  var parentStep;
                  var childStep;
                  var type;

                  var value = variableValueGr.value;
                  var splitFields = value.split("^");
                  for (var i = 0; i < splitFields.length; i++) {
                      var field = splitFields[i].substring(0, splitFields[i].indexOf("="));
                      if (gs.nil(field) || this.IGNORED_FIELDS.indexOf(field) > -1) {
                          continue;
                      }
                      if ("parent" == field) {
                          parentStep = splitFields[i].substring(splitFields[i].indexOf("=") + 9, splitFields[i].length - 17); //parent={{step['ef72675e77261110a52b1bfaae5a991a'].first_record}}
                      } else if ("child" == field) {
                          childStep = splitFields[i].substring(splitFields[i].indexOf("=") + 9, splitFields[i].length - 17); //child={{step['e772275e77261110a52b1bfaae5a99e2'].first_record}}
                      } else if ("type" == field) {
                          type = splitFields[i].substring(splitFields[i].indexOf("=") + 1); //type=5f985e0ec0a8010e00a9714f2a172815
                      }
                  }

                  var relationshipTypeGr = new GlideRecord("cmdb_rel_type");
                  relationshipTypeGr.get(type);
                  relationship.type = relationshipTypeGr.name.toString();
                  var stepGr2 = new GlideRecord("sys_atf_step");
                  stepGr2.get(parentStep);
                  relationship.parent = stepGr2.table.toString();
                  stepGr2 = new GlideRecord("sys_atf_step");
                  stepGr2.get(childStep);
                  relationship.child = stepGr2.table.toString();
              }
              var relationships = [];
              if (jsonResult[table]) {
                  relationships = jsonResult[table];
              } else {
                  jsonResult[table] = relationships;
              }
              if (this.relationshipArrayContainsRelationship(jsonResult[table], relationship) < 0) {
                  jsonResult[table].push(relationship);
              }
          } else {
              // check to see if the table is targeted or a child class
              var entityGr = new GlideRecord("cmdb_inst_entity");
              entityGr.addQuery("sys_scope", applicationSysId);
              entityGr.addQuery("table", table);
              entityGr.query();
              while (!entityGr.hasNext() && !gs.nil(table)) {
                  table = this.CMDBIntegrationValidationTestUtils._getParentClass(table);
                  entityGr = new GlideRecord("cmdb_inst_entity");
                  entityGr.addQuery("sys_scope", applicationSysId);
                  entityGr.addQuery("table", table);
                  entityGr.query();
              }
              if (gs.nil(table)) {
                  table = originalTable;
              }

              var fields = [];
              if (jsonResult[table]) {
                  fields = jsonResult[table];
              } else {
                  jsonResult[table] = fields;
              }
              variableValueGr = new GlideRecord("sys_variable_value");
              variableValueGr.addQuery("document", "sys_atf_step");
              variableValueGr.addQuery("document_key", stepGr.getUniqueValue());
              variableValueGr.addQuery("variable", this.CONDITIONS_VARIABLE);
              variableValueGr.query();
              while (variableValueGr.next()) {
                  value = variableValueGr.value;
                  splitFields = value.split("^");
                  for (i = 0; i < splitFields.length; i++) {
                      field = splitFields[i].substring(0, splitFields[i].indexOf("="));
                      if (gs.nil(field) || this.IGNORED_FIELDS.indexOf(field) > -1) {
                          continue;
                      }
                      if (fields.indexOf(field) === -1) {
                          fields.push(field);
                      }
                  }
              }
          }
      }
      return jsonResult;
  },

  getMappingCoverage: function(applicationSysId) {
      var jsonResult = {};
      jsonResult.targetFields = this.getTargetedClassesAndFields(applicationSysId);
      jsonResult.coveredFields = this.getCoveredClassesAndFields(applicationSysId);
      jsonResult.testSuite = jsonResult.coveredFields.testSuite + "";
      delete jsonResult.coveredFields.testSuite;
      jsonResult.missingFields = {};
      var missingClasses = [];
      for (var className in jsonResult.targetFields) {
          if (this.SOFTWARE_CLASSES.indexOf(className) > -1) {
              // Software requires it's own specific test step
              var stepGr = new GlideRecord("sys_atf_step");
              stepGr.addQuery("display_name", this.SOFTWARE_QUERY);
              stepGr.addQuery("sys_scope", applicationSysId);
              stepGr.addQuery("active", "true");
              stepGr.query();
              if (!stepGr.hasNext()) {
                  jsonResult.missingFields[className] = jsonResult.targetFields[className];
                  missingClasses.push(className);
              }
          } else if (this.CMDB_REL_CI == className) {
              for (var i = 0; i < jsonResult.targetFields[className].length; i++) {
                  var targetedRelationship = jsonResult.targetFields[className][i];
                  if (this.relationshipArrayContainsRelationship(jsonResult.coveredFields[className], targetedRelationship) < 0) {
                      var parent = this.CMDBIntegrationValidationTestUtils._getParentClass(targetedRelationship.parent).toString();
                      var child = targetedRelationship.child;
                      var found = false;
                      while (!gs.nil(parent)) {
                          var tempTargetedRelationship = {};
                          tempTargetedRelationship.parent = parent;
                          tempTargetedRelationship.child = targetedRelationship.child;
                          tempTargetedRelationship.type = targetedRelationship.type.toString();
                          if (this.relationshipArrayContainsRelationship(jsonResult.coveredFields[className], tempTargetedRelationship) > -1) {
                              found = true;
                              break;
                          }
                          parent = this.CMDBIntegrationValidationTestUtils._getParentClass(parent).toString();
                      }
                      child = this.CMDBIntegrationValidationTestUtils._getParentClass(targetedRelationship.child).toString();
                      while (found == false && !gs.nil(child)) {
                          tempTargetedRelationship = {};
                          tempTargetedRelationship.parent = targetedRelationship.parent;
                          tempTargetedRelationship.child = child;
                          tempTargetedRelationship.type = targetedRelationship.type.toString();
                          if (this.relationshipArrayContainsRelationship(jsonResult.coveredFields[className], tempTargetedRelationship) > -1) {
                              found = true;
                              break;
                          }
                          child = this.CMDBIntegrationValidationTestUtils._getParentClass(child).toString();
                      }
                      if (found == false) {
                          if (!jsonResult.missingFields[className]) {
                              jsonResult.missingFields[className] = [];
                          }
                          jsonResult.missingFields[className].push(targetedRelationship);
                      }
                  }
              }
          } else if (jsonResult.coveredFields[className]) {
              for (i = 0; i < jsonResult.targetFields[className].length; i++) {
                  var targetedField = jsonResult.targetFields[className][i];
                  if (jsonResult.coveredFields[className].indexOf(targetedField) < 0) {
                      if (!jsonResult.missingFields[className]) {
                          jsonResult.missingFields[className] = [];
                      }
                      jsonResult.missingFields[className].push(targetedField);
                  }
              }
          } else if (jsonResult.targetFields[className].length > 0) {
              jsonResult.missingFields[className] = jsonResult.targetFields[className];
              missingClasses.push(className);
          }
      }
      // make a pass through the covered fields to see if there are any targeting child classes of the target fields
      for (className in jsonResult.coveredFields) {
          if (this.CMDB_REL_CI == className.toString()) {
              for (i = 0; i < jsonResult.coveredFields[className].length; i++) {
                  var coveredRelationship = jsonResult.coveredFields[className][i];
                  if (this.relationshipArrayContainsRelationship(jsonResult.targetFields[className], coveredRelationship) < 0) {
                      parent = this.CMDBIntegrationValidationTestUtils._getParentClass(coveredRelationship.parent).toString();
                      child = coveredRelationship.child;
                      found = false;
                      while (!gs.nil(parent)) {
                          var tempCoveredRelationship = {}; //tempTargetedRelationship
                          tempCoveredRelationship.parent = parent;
                          tempCoveredRelationship.child = coveredRelationship.child;
                          tempCoveredRelationship.type = coveredRelationship.type.toString();
                          if (this.relationshipArrayContainsRelationship(jsonResult.targetFields[className], tempCoveredRelationship) > -1) {
                              found = true;
                              var indexInMissing = this.relationshipArrayContainsRelationship(jsonResult.missingFields[className], tempCoveredRelationship);
                              if (indexInMissing > -1) {
                                  jsonResult.missingFields[className].splice(indexInMissing, 1);
                              }
                              break;
                          }
                          parent = this.CMDBIntegrationValidationTestUtils._getParentClass(parent).toString();
                      }
                      child = this.CMDBIntegrationValidationTestUtils._getParentClass(coveredRelationship.child).toString();
                      while (found == false && !gs.nil(child)) {
                          tempCoveredRelationship = {};
                          tempCoveredRelationship.parent = coveredRelationship.parent;
                          tempCoveredRelationship.child = child;
                          tempCoveredRelationship.type = coveredRelationship.type.toString();
                          if (this.relationshipArrayContainsRelationship(jsonResult.targetFields[className], tempCoveredRelationship) > -1) {
                              found = true;
                              indexInMissing = this.relationshipArrayContainsRelationship(jsonResult.missingFields[className], tempCoveredRelationship);
                              if (indexInMissing > -1) {
                                  jsonResult.missingFields[className].splice(indexInMissing, 1);
                              }
                              break;
                          }
                          child = this.CMDBIntegrationValidationTestUtils._getParentClass(child).toString();
                      }
                  }
              }
          } else {
              var coveredOriginalClassName = className.toString();
              className = this.CMDBIntegrationValidationTestUtils._getParentClass(className).toString();
              while (!gs.nil(className) && !jsonResult.missingFields[className]) {
                  className = this.CMDBIntegrationValidationTestUtils._getParentClass(className).toString();
              }
              if (jsonResult.missingFields[className]) {
                  for (i = jsonResult.missingFields[className].length; i >= 0; i--) {
                      var missingField = jsonResult.missingFields[className][i];
                      if (jsonResult.coveredFields[coveredOriginalClassName] && jsonResult.coveredFields[coveredOriginalClassName].indexOf(missingField) > -1) {
                          jsonResult.missingFields[className].splice(i, 1);
                      }
                  }
                  if (jsonResult.missingFields[className].length <= 0) {
                      delete jsonResult.missingFields[className];
                  }
              }
          }
      }
      var missingRelationships = "";
      for (className in jsonResult.missingFields) {
          if (this.CMDB_REL_CI == className.toString()) {
              missingRelationships = jsonResult.missingFields[className];
              delete jsonResult.missingFields[className];
              break;
          }
      }
      jsonResult.totalClassCount = parseInt(Object.keys(jsonResult.targetFields).length);
      jsonResult.missingClassCount = parseInt(missingClasses.length);
      jsonResult.totalFieldCount = parseInt(this.getTotalField(jsonResult.targetFields));
      jsonResult.missingFieldCount = parseInt(this.getTotalField(jsonResult.missingFields));
      var totalRelationshipCount = 0;
      if (!gs.nil(jsonResult.targetFields.cmdb_rel_ci)) {
          totalRelationshipCount = jsonResult.targetFields.cmdb_rel_ci.length;
      }
      jsonResult.totalRelationshipCount = totalRelationshipCount;
      jsonResult.missingRelationshipCount = gs.nil(missingRelationships) ? 0 : missingRelationships.length;
      jsonResult.missingClasses = !gs.nil(missingClasses) && missingClasses.length > 0 ? missingClasses : "";
      jsonResult.missingRelationships = !gs.nil(missingRelationships) && missingRelationships.length > 0 ? missingRelationships : "";
      return jsonResult;
  },

  getTotalField: function(classFieldObject) {
      var total = 0;
      for (var className in classFieldObject) {
          total = parseInt(total) + parseInt(classFieldObject[className].length);
      }
      return total;
  },

  relationshipArrayContainsRelationship: function(array, relationship) {
      if (gs.nil(array)) {
          return -1;
      }
      var found = false;
      for (var i = 0; i < array.length; i++) {
          if (array[i].parent == relationship.parent && array[i].child == relationship.child && array[i].type == relationship.type) {
              found = true;
              return i;
          }
      }
      return -1;
  },

  type: 'AtfTestCoverageUtil'
};

Sys ID

3454bfbc77af5110a52b1bfaae5a9961

Offical Documentation

Official Docs: