def testAnalyzeFindsDuplicates(self): yaml = {'literals': ['field1', 'field2', 'field3', 'field4', 'field5']} field_universe = field_lib.FieldUniverse([_GetFieldFolder(yaml)]) yaml = { 'parent': { 'description': 'parent', 'uses': ['field1', 'field2', 'field3'] }, 'child1': { 'description': 'child1', 'implements': ['parent'], 'uses': ['field4'] }, 'child2': { 'description': 'child2', 'uses': ['field1', 'field2', 'field3', 'field4'] }, } type_folder = _GetEntityTypeFolder(field_universe, yaml) universe = _GetEntityTypeUniverse([type_folder]) manager = entity_type_manager.EntityTypeManager(universe) manager.Analyze() child1 = universe.GetEntityType('', 'child1') child2 = universe.GetEntityType('', 'child2') parent = universe.GetEntityType('', 'parent') self.assertTrue( child2.HasFindingTypes( [findings_lib.DuplicateExpandedFieldSetsWarning])) self.assertTrue( child1.HasFindingTypes( [findings_lib.DuplicateExpandedFieldSetsWarning])) self.assertFalse( parent.HasFindingTypes( [findings_lib.DuplicateExpandedFieldSetsWarning]))
def testAnalyzeIgnoresAutogeneratedTypes(self): yaml = {'literals': ['field1', 'field2', 'field3', 'field4']} field_universe = field_lib.FieldUniverse([_GetFieldFolder(yaml)]) yaml = { 'parent': { 'description': 'parent', 'uses': ['field1', 'field2', 'field3'] }, 'AUTOGENERATED_NETWORK_DEVICE': { 'description': 'AUTOGENERATED_NETWORK_DEVICE', }, 'child2': { 'implements': ['AUTOGENERATED_NETWORK_DEVICE'], 'description': 'child2', 'uses': ['field1', 'field2', 'field3', 'field4'] }, } type_folder = _GetEntityTypeFolder(field_universe, yaml) universe = _GetEntityTypeUniverse([type_folder]) manager = entity_type_manager.EntityTypeManager(universe) findings = manager.Analyze() self.assertEmpty(findings)
def _ValidateConfigInner(unmodified, modified_base, modified_client, interactive=False): """Runs config validation and finding filtration. Args: unmodified: unchanged file paths to include in validation modified_base: paths to original versions of changed files in validation modified_client: paths to changed files in validation interactive: Set true for timing log messages. Returns: A tuple with a list of findings from validation and the universe """ # Separate different kinds of config files # Concatenate paths such that the changed files go last. This is important # because we always want conflicts between new and old files to show as # being caused by new changes and files are processed in order. start_time = time.time() cl_paths = unmodified + modified_client cl_config = SeparateConfigFiles(cl_paths) new_universe = BuildUniverse(cl_config) end_time = time.time() if interactive: print('New universe build: {0} seconds.\n'.format( str(end_time - start_time))) start_time = end_time if not new_universe.IsValid(): findings = [ f for f in new_universe.GetFindings() if isinstance(f, findings_lib.ValidationError) ] return findings, new_universe # Validate across the type namespaces. Short-circuit if validation fails and # return any breaking findings. cl_validator = namespace_validator.NamespaceValidator( new_universe.GetEntityTypeNamespaces()) if not cl_validator.IsValid(): universe_errors = [] universe_errors = [ f for f in new_universe.GetFindings() if isinstance(f, findings_lib.ValidationError) ] # Technically there should never be universe errors if we get here. Better # to be safe than sorry though. return cl_validator.GetFindings() + universe_errors, new_universe if interactive: end_time = time.time() print('New ns check: {0} seconds.\n'.format(str(end_time - start_time))) start_time = end_time base_paths = unmodified + modified_base base_config = SeparateConfigFiles(base_paths) old_universe = BuildUniverse(base_config) if interactive: end_time = time.time() print('Old uverse build: {0} seconds.\n'.format(str(end_time - start_time))) start_time = end_time # Run validation on base universe to expand types. namespace_validator.NamespaceValidator(old_universe.GetEntityTypeNamespaces()) if interactive: end_time = time.time() print('Old ns check: {0} seconds.\n'.format(str(end_time - start_time))) start_time = end_time mgr = entity_type_manager.EntityTypeManager(new_universe.entity_type_universe) mgr.Analyze() del mgr if interactive: end_time = time.time() print('Type analysis: {0} seconds.\n'.format(str(end_time - start_time))) start_time = end_time CheckBackwardsCompatibility(new_universe.entity_type_universe, old_universe.entity_type_universe) if interactive: end_time = time.time() print('Backwards compat: {0} seconds.\n'.format(str(end_time - start_time))) start_time = end_time # TODO(berkoben) pass this to methods below when fixing b/116850383? # cl_path_set = set(cl_paths) if new_universe.entity_type_universe: _SetTypeFolderChanges( list(new_universe.entity_type_universe.namespace_folder_map.values())) _SetFieldChanges(new_universe.field_universe, old_universe.field_universe) _SetSubfieldChanges(new_universe.subfield_universe, old_universe.subfield_universe) _SetStateChanges(new_universe.state_universe, old_universe.state_universe) _SetUnitChanges(new_universe.unit_universe, old_universe.unit_universe) filtered_findings = new_universe.GetFindings(True) all_findings = new_universe.GetFindings(False) diff = len(all_findings) - len(filtered_findings) if diff > 0: filtered_findings.append(findings_lib.SuppressedFindingsWarning(diff)) return filtered_findings, new_universe
def testAnalyzeFindsFlexibleParents(self): yaml = {'literals': ['field1', 'field2', 'field3', 'field4']} field_universe = field_lib.FieldUniverse( [_GetFieldFolder(yaml)]) yaml = { 'VAV_parent': { 'description': 'parent', 'is_canonical': True, 'uses': ['field1', 'field4'], 'opt_uses': ['field2', 'field3'] }, 'VAV_child1': { 'description': 'child1', 'uses': ['field1', 'field4'], 'opt_uses': ['field2'] }, 'VAV_child2': { 'description': 'child2', 'uses': ['field1', 'field3', 'field4'] }, 'different_equip_type': { 'description': 'different', 'uses': ['field1', 'field3', 'field4'] }, 'VAV_nomatch': { 'description': 'nomatch', 'uses': ['field1', 'field2', 'field3'] }, } type_folder = _GetEntityTypeFolder(field_universe, yaml) universe = _GetEntityTypeUniverse([type_folder]) manager = entity_type_manager.EntityTypeManager(universe) manager.Analyze() child1 = universe.GetEntityType('', 'VAV_child1') child2 = universe.GetEntityType('', 'VAV_child2') child2_nm = universe.GetEntityType('', 'different_equip_type') parent = universe.GetEntityType('', 'VAV_parent') nomatch = universe.GetEntityType('', 'VAV_nomatch') self.assertTrue(parent.HasFindingTypes( [findings_lib.OverlappingFlexTypeParentWarning])) self.assertFalse(parent.HasFindingTypes( [findings_lib.OverlappingFlexTypeChildWarning])) self.assertTrue(child1.HasFindingTypes( [findings_lib.OverlappingFlexTypeChildWarning])) self.assertFalse(child1.HasFindingTypes( [findings_lib.OverlappingFlexTypeParentWarning])) self.assertTrue(child2.HasFindingTypes( [findings_lib.OverlappingFlexTypeChildWarning])) self.assertFalse(child2.HasFindingTypes( [findings_lib.OverlappingFlexTypeParentWarning])) self.assertFalse(child2_nm.HasFindingTypes( [findings_lib.OverlappingFlexTypeChildWarning, findings_lib.OverlappingFlexTypeParentWarning])) self.assertFalse(nomatch.HasFindingTypes( [findings_lib.OverlappingFlexTypeChildWarning, findings_lib.OverlappingFlexTypeParentWarning]))