def testEntityTypeUniverseHandlesNamespaceMovesWithIds(self): filepath = _GOOD_PATH + '/file.yaml' folder = entity_type_lib.EntityTypeFolder(_GOOD_PATH) namespace = folder.local_namespace filepath2 = _GOOD_PATH_2 + '/file.yaml' folder2 = entity_type_lib.EntityTypeFolder(_GOOD_PATH_2) namespace2 = folder2.local_namespace entity_type1 = entity_type_lib.EntityType(typename='one', filepath=filepath, description='hi', uid='1') namespace.InsertType(entity_type1) entity_type1a = entity_type_lib.EntityType(typename='oneA', filepath=filepath2, description='hi', uid='1') namespace2.InsertType(entity_type1a) types_universe = entity_type_lib.EntityTypeUniverse([folder, folder2]) findings = types_universe.GetFindings() self.assertLen(findings, 2) self.assertTrue( types_universe.HasFindingTypes([findings_lib.DuplicateIdsError])) self.assertTrue( entity_type1.HasFindingTypes([findings_lib.DuplicateIdsError])) self.assertTrue( entity_type1a.HasFindingTypes([findings_lib.DuplicateIdsError]))
def testBackwardsCompatibilityRemovedType(self): # Two types. One is abstract. ns1_path = '{0}/entity_types/anyfolder'.format('namespace_one') folder1 = entity_type_lib.EntityTypeFolder(ns1_path) ns1 = folder1.local_namespace type1 = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type1', inherited_fields_expanded=True) ns1.InsertType(type1) type2 = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type2', inherited_fields_expanded=True, is_abstract=True) ns1.InsertType(type2) old_uv = entity_type_lib.EntityTypeUniverse([folder1]) # No Types. folder1a = entity_type_lib.EntityTypeFolder(ns1_path) new_uv = entity_type_lib.EntityTypeUniverse([folder1a]) findings = presubmit_validate_types_lib.CheckBackwardsCompatibility( new_uv, old_uv) self.assertLen(findings, 1) self.assertIsInstance(findings[0], findings_lib.RemovedTypeWarning) self.assertIn('type1', str(findings[0]))
def testBackwardsCompatibilityAcrossNamespaces(self): # Two types. One is abstract. ns1_path = '{0}/entity_types/anyfolder'.format('namespace_one') ns2_path = '{0}/entity_types/anyfolder'.format('namespace_two') folder1 = entity_type_lib.EntityTypeFolder(ns1_path) ns1 = folder1.local_namespace type1 = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type1', inherited_fields_expanded=True, uid='1') ns1.InsertType(type1) old_uv = entity_type_lib.EntityTypeUniverse([folder1]) folder1a = entity_type_lib.EntityTypeFolder(ns1_path) folder2 = entity_type_lib.EntityTypeFolder(ns2_path) ns2 = folder1a.local_namespace type1a = entity_type_lib.EntityType(filepath=ns2_path + '/file.yaml', typename='type1a', inherited_fields_expanded=True, uid='1') ns2.InsertType(type1a) new_uv = entity_type_lib.EntityTypeUniverse([folder1a, folder2]) findings = presubmit_validate_types_lib.CheckBackwardsCompatibility( new_uv, old_uv) self.assertEmpty(findings)
def testAddTypeWithNamespacedField(self): fields_universe = field_lib.FieldUniverse([]) fields_universe._namespace_map = { '': [field_lib.Field('animal')], 'ANIMAL': [field_lib.Field('meow')], 'ATTACK': [field_lib.Field('claws')] } folderpath = 'ANIMAL/entity_types' type_folder = entity_type_lib.EntityTypeFolder(folderpath, fields_universe) self.assertFalse(type_folder.GetFindings()) rel_typepath = os.path.join(folderpath, 'mammal') # field 'claws' is undefined. entity_type = entity_type_lib.EntityType( filepath=rel_typepath, typename='cat', description='feline animal', local_field_tuples=_FS(['ANIMAL/meow', 'ATTACK/claws', '/animal'])) type_folder._AddType(entity_type) self.assertFalse(type_folder.local_namespace.GetFindings()) self.assertLen(type_folder.local_namespace.valid_types_map, 1) self.assertIn(entity_type.typename, type_folder.local_namespace.valid_types_map) self.assertEqual( type_folder.local_namespace.valid_types_map.get( entity_type.typename), entity_type)
def testAddDuplicateTypes(self): fields_universe = field_lib.FieldUniverse([]) fields_universe._namespace_map = {'': ('animal'), 'ANIMAL': ('meow')} folderpath = 'ANIMAL/entity_types' type_folder = entity_type_lib.EntityTypeFolder(folderpath, fields_universe) self.assertFalse(type_folder.GetFindings()) rel_typepath = os.path.join(folderpath, 'mammal') # entity type entity_type = entity_type_lib.EntityType( filepath=rel_typepath, typename='kitty', description='feline animal', local_field_tuples=_FS(['ANIMAL/meow', '/animal'])) # duplicate type dup_type = entity_type_lib.EntityType(filepath=rel_typepath, typename='kitty', description='feline animal', local_field_tuples=_FS( ['ANIMAL/meow', '/animal'])) type_folder._AddType(entity_type) type_folder._AddType(dup_type) self.assertTrue( type_folder.local_namespace.HasFindingTypes( [findings_lib.DuplicateTypesError])) self.assertLen(type_folder.local_namespace.valid_types_map, 1) self.assertIn(entity_type.typename, type_folder.local_namespace.valid_types_map) self.assertEqual( type_folder.local_namespace.valid_types_map.get( entity_type.typename), entity_type)
def testEntityTypeUniverseFindsDupIds(self): filepath = _GOOD_PATH + '/file.yaml' folder = entity_type_lib.EntityTypeFolder(_GOOD_PATH) namespace = folder.local_namespace entity_type1 = entity_type_lib.EntityType(typename='one', filepath=filepath, description='hi', uid='1') namespace.InsertType(entity_type1) entity_type1a = entity_type_lib.EntityType(typename='oneA', filepath=filepath, description='hi', uid='1') namespace.InsertType(entity_type1a) entity_type2 = entity_type_lib.EntityType(typename='two', filepath=filepath, description='hi', uid='2') namespace.InsertType(entity_type2) types_universe = entity_type_lib.EntityTypeUniverse([folder]) findings = types_universe.GetFindings() self.assertLen(findings, 2) self.assertTrue( types_universe.HasFindingTypes([findings_lib.DuplicateIdsError])) self.assertTrue( entity_type1.HasFindingTypes([findings_lib.DuplicateIdsError])) self.assertTrue( entity_type1a.HasFindingTypes([findings_lib.DuplicateIdsError])) self.assertFalse(entity_type2.GetFindings())
def testAddMultipleTypes(self): fields_universe = field_lib.FieldUniverse([]) fields_universe._namespace_map = { '': [field_lib.Field('animal')], 'ANIMAL': [field_lib.Field('meow')] } folderpath = 'ANIMAL/entity_types' type_folder = entity_type_lib.EntityTypeFolder(folderpath, fields_universe) self.assertFalse(type_folder.GetFindings()) rel_typepath = os.path.join(folderpath, 'mammal') # bad entity type, field 'claws' is undefined. bad_type = entity_type_lib.EntityType( filepath=rel_typepath, typename='cat', description='feline animal', local_field_tuples=_FS(['ANIMAL/meow', 'ANIMAL/claws', '/animal'])) # good entity type good_type = entity_type_lib.EntityType( filepath=rel_typepath, typename='kitty', description='feline animal', local_field_tuples=_FS(['ANIMAL/meow', '/animal'])) type_folder._AddType(good_type) type_folder._AddType(bad_type) self.assertTrue( type_folder.local_namespace.HasFindingTypes( [findings_lib.UndefinedFieldError])) self.assertLen(type_folder.local_namespace.valid_types_map, 1) self.assertIn(good_type.typename, type_folder.local_namespace.valid_types_map) self.assertEqual( type_folder.local_namespace.valid_types_map.get(good_type.typename), good_type)
def testEntityTypeUniverseGetFindings(self): filepath = _GOOD_PATH + '/file.yaml' context = findings_lib.FileContext(filepath) folder = entity_type_lib.EntityTypeFolder(_GOOD_PATH) folder.AddFinding( findings_lib.InconsistentFileLocationError('', context)) namespace = folder.local_namespace namespace.AddFinding(findings_lib.IllegalCharacterError( 'two', context)) # This will generate a MissingDescriptionWarning on itself entity_type = entity_type_lib.EntityType(typename='one', filepath=filepath) namespace.InsertType(entity_type) types_universe = entity_type_lib.EntityTypeUniverse([folder]) findings = types_universe.GetFindings() self.assertLen(findings, 3) self.assertTrue( types_universe.HasFindingTypes([ findings_lib.InconsistentFileLocationError, findings_lib.IllegalCharacterError, findings_lib.MissingDescriptionWarning ])) self.assertFalse(types_universe.IsValid())
def testAddFromConfig(self): folderpath = 'ANIMAL/entity_types' # don't supply a fields_universe type_folder = entity_type_lib.EntityTypeFolder(folderpath) self.assertFalse(type_folder.GetFindings()) good_filepath = os.path.join(folderpath, 'mammal.yaml') # Build test proto yaml_doc = { 'cat': { 'description': 'feline animal', 'uses': ['meow', 'claws'], 'opt_uses': ['cuddle'], 'implements': ['fuzzy'] } } type_folder.AddFromConfig([yaml_doc], good_filepath) self.assertFalse(type_folder.GetFindings()) self.assertFalse(type_folder.local_namespace.GetFindings()) self.assertLen(type_folder.local_namespace.valid_types_map, 1) new_type = type_folder.local_namespace.valid_types_map['cat'] self.assertCountEqual(['/meow', '/claws', '/cuddle'], new_type.local_field_names) self.assertCountEqual(['fuzzy'], new_type.unqualified_parent_names) self.assertEqual('feline animal', new_type.description) self.assertEqual(good_filepath, new_type.file_context.filepath)
def testBackwardsCompatibilityOptionalAddedFieldsOk(self): # Two types. One is abstract. ns1_path = '{0}/entity_types/anyfolder'.format('namespace_one') folder1 = entity_type_lib.EntityTypeFolder(ns1_path) ns1 = folder1.local_namespace type1 = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type1', local_field_tuples=_F(['local1']), inherited_fields_expanded=True) ns1.InsertType(type1) type2 = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type2', local_field_tuples=_F(['local1']), inherited_fields_expanded=True) ns1.InsertType(type2) old_uv = entity_type_lib.EntityTypeUniverse([folder1]) # Same Types with added fields folder1a = entity_type_lib.EntityTypeFolder(ns1_path) ns1a = folder1a.local_namespace type1a = entity_type_lib.EntityType( filepath=ns1_path + '/file.yaml', typename='type1', local_field_tuples=[_F1('local1', False), _F1('local2', False)], inherited_fields_expanded=True) ns1a.InsertType(type1a) type2a = entity_type_lib.EntityType( filepath=ns1_path + '/file.yaml', typename='type2', local_field_tuples=[_F1('local1', False), _F1('local2', True)], inherited_fields_expanded=True) ns1a.InsertType(type2a) new_uv = entity_type_lib.EntityTypeUniverse([folder1a]) findings = presubmit_validate_types_lib.CheckBackwardsCompatibility( new_uv, old_uv) self.assertLen(findings, 1) self.assertTrue( type1a.HasFindingTypes([findings_lib.AddedFieldWarning])) self.assertFalse( type2a.HasFindingTypes([findings_lib.AddedFieldWarning]))
def testAddFromConfigBadLocation(self): folderpath = 'ANIMAL/entity_types' type_folder = entity_type_lib.EntityTypeFolder(folderpath) self.assertFalse(type_folder.GetFindings()) bad_typepath = os.path.join('something', 'INSECT/entity_types/ant') type_folder.AddFromConfig([], bad_typepath) self.assertTrue( type_folder.HasFindingTypes( [findings_lib.InconsistentFileLocationError]))
def testAddFromConfigExtraKeys(self): folderpath = 'ANIMAL/entity_types' # don't supply a fields_universe type_folder = entity_type_lib.EntityTypeFolder(folderpath) self.assertFalse(type_folder.GetFindings()) good_filepath = os.path.join(folderpath, 'mammal.yaml') # Build test proto yaml_doc = { 'cat': { 'description': 'feline animal', 'uses': ['meow', 'claws'], 'implements': ['fuzzy'], 'notakey': 'stuff' } } type_folder.AddFromConfig([yaml_doc], good_filepath) self.assertTrue( type_folder.HasFindingTypes([findings_lib.UnrecognizedKeyError]))
def testAddTypeUndefinedFields(self): fields_universe = field_lib.FieldUniverse([]) fields_universe._namespace_map = {'': ('animal'), 'ANIMAL': ('meow')} folderpath = 'ANIMAL/entity_types' type_folder = entity_type_lib.EntityTypeFolder(folderpath, fields_universe) self.assertFalse(type_folder.GetFindings()) rel_typepath = os.path.join(folderpath, 'mammal') # field 'claws' is undefined. entity_type = entity_type_lib.EntityType( filepath=rel_typepath, typename='cat', description='feline animal', local_field_tuples=_FS(['ANIMAL/meow', 'ANIMAL/claws', '/animal'])) type_folder._AddType(entity_type) self.assertTrue( type_folder.local_namespace.HasFindingTypes( [findings_lib.UndefinedFieldError])) self.assertFalse(type_folder.local_namespace.valid_types_map)
def testBackwardsCompatibilityRemovedFields(self): # Two types. One is abstract. ns1_path = '{0}/entity_types/anyfolder'.format('namespace_one') folder1 = entity_type_lib.EntityTypeFolder(ns1_path) ns1 = folder1.local_namespace type1 = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type1', local_field_tuples=_F( ['local1', 'local2']), inherited_fields_expanded=True) type1.inherited_field_names = { '/inherited1': _F1('/inherited1', False), '/inherited2': _F1('/inherited2', False) } ns1.InsertType(type1) type2 = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type2', local_field_tuples=_F( ['abstract1', 'abstract2']), inherited_fields_expanded=True, is_abstract=True) type2.inherited_field_names = { '/abstract1a': _F1('/abstract1a', False), '/abstract2a': _F1('/abstract2a', False) } ns1.InsertType(type2) old_uv = entity_type_lib.EntityTypeUniverse([folder1]) # Same Types with removed fields folder1a = entity_type_lib.EntityTypeFolder(ns1_path) ns1a = folder1a.local_namespace type1a = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type1', local_field_tuples=_F(['local1']), inherited_fields_expanded=True) type1a.inherited_field_names = { '/inherited1': _F1('/inherited1', False) } ns1a.InsertType(type1a) type2a = entity_type_lib.EntityType(filepath=ns1_path + '/file.yaml', typename='type2', local_field_tuples=_F( ['abstract1']), inherited_fields_expanded=True, is_abstract=True) type2a.inherited_field_names = { '/abstract1a': _F1('/abstract1a', False) } ns1a.InsertType(type2a) new_uv = entity_type_lib.EntityTypeUniverse([folder1a]) findings = presubmit_validate_types_lib.CheckBackwardsCompatibility( new_uv, old_uv) self.assertLen(findings, 2) field1 = 'local2' field2 = 'inherited2' if field1 not in str(findings[0]): field1 = 'inherited2' field2 = 'local2' self.assertIsInstance(findings[0], findings_lib.RemovedFieldWarning) self.assertIn(field1, str(findings[0])) self.assertIsInstance(findings[1], findings_lib.RemovedFieldWarning) self.assertIn(field2, str(findings[1]))
def create_simplified_universe( ) -> presubmit_validate_types_lib.ConfigUniverse: """Creates a simplified test universe with minimal configuration for testing. Returns: config_universe a partially defined ConfigUniverse """ # constant universes state_universe = states.STATE_UNIVERSE connection_universe = connections.CONNECTION_UNIVERSE subfield_universe = subfields.SUBFIELD_UNIVERSE # update unit folder with subfield_universe unit_folder = unit_lib.UnitFolder(folderpath='units') unit_folder.local_namespace.subfields = subfield_universe.GetSubfieldsMap( unit_folder.local_namespace.namespace) unit_folder.AddFromConfig(config_filename='units/units.yaml', documents=[units.UNIT_DOCUMENT]) unit_universe = unit_lib.UnitUniverse(folders=[unit_folder]) # subfield universe has to validate unit universe subfield_universe.ValidateUnits(unit_universe) # field universe depends on subfield and state universes field_folder = field_lib.FieldFolder(folderpath='fields') field_folder.local_namespace.subfields = subfield_universe.GetSubfieldsMap( field_folder.local_namespace.namespace) field_folder.local_namespace.states = state_universe.GetStatesMap( field_folder.local_namespace.namespace) field_folder.AddFromConfig(config_filename='fields/telemetry_fields.yaml', documents=[fields.TELEMETRY_FIELDS_DOCUMENT]) field_folder.AddFromConfig(config_filename='fields/metadata_fields.yaml', documents=[fields.METADATA_FIELDS_DOCUMENT]) field_universe = field_lib.FieldUniverse(folders=[field_folder]) # entity type universe depends on field universe global_type_folder = entity_type_lib.EntityTypeFolder( folderpath='entity_types', field_universe=field_universe) facilities_type_folder = entity_type_lib.EntityTypeFolder( folderpath='FACILITIES/entity_types', field_universe=field_universe) hvac_type_folder = entity_type_lib.EntityTypeFolder( folderpath='HVAC/entity_types', field_universe=field_universe) global_type_folder.AddFromConfig( config_filename='entity_types/global.yaml', documents=[types.GLOBAL_TYPES_DOCUMENT]) facilities_type_folder.AddFromConfig( config_filename='FACILITIES/entity_types/Facilities.yaml', documents=[types.FACILITIES_TYPES_DOCUMENT]) hvac_type_folder.AddFromConfig( config_filename='HVAC/entity_types/ANALYSIS.yaml', documents=[types.HVAC_ANALYSIS_TYPES_DOCUMENT]) hvac_type_folder.AddFromConfig( config_filename='HVAC/entity_types/ABSTRACT.yaml', documents=[types.HVAC_ABSTRACT_TYPES_DOCUMENT]) hvac_type_folder.AddFromConfig( config_filename='HVAC/entity_types/CHWS.yaml', documents=[types.HVAC_CHWS_TYPES_DOCUMENT]) hvac_type_folder.AddFromConfig( config_filename='HVAC/entity_types/GENERALTYPES.yaml', documents=[types.HVAC_GENERAL_TYPES_DOCUMENT]) hvac_type_folder.AddFromConfig( config_filename='HVAC/entity_types/SDC.yaml', documents=[types.HVAC_SDC_TYPES_DOCUMENT]) hvac_type_folder.AddFromConfig( config_filename='HVAC/entity_types/DMP.yaml', documents=[types.HVAC_DMP_TYPES_DOCUMENT]) entity_type_universe = entity_type_lib.EntityTypeUniverse( entity_type_folders=[ global_type_folder, facilities_type_folder, hvac_type_folder ]) config_universe = presubmit_validate_types_lib.ConfigUniverse( entity_type_universe=entity_type_universe, field_universe=field_universe, subfield_universe=subfield_universe, state_universe=state_universe, connection_universe=connection_universe, unit_universe=unit_universe) # call this to expand inherited fields namespace_validator.NamespaceValidator( config_universe.GetEntityTypeNamespaces()) return config_universe
def CreateEntityTypeFolder(folderpath, parent_namespace): del parent_namespace # Unused by EntityTypeFolder. return entity_type_lib.EntityTypeFolder(folderpath, fields_universe)
def _GetEntityTypeFolder(field_universe, yaml, namespace=''): folderpath = os.path.join(namespace, 'entity_types') type_folder = entity_type_lib.EntityTypeFolder(folderpath, field_universe) good_filepath = os.path.join(folderpath, 'f.yaml') type_folder.AddFromConfig([yaml], good_filepath) return type_folder
def testCreateTypeFolderSuccessWithSubfolder(self): folderpath = 'NS/entity_types/subfolder' type_folder = entity_type_lib.EntityTypeFolder(folderpath) self.assertFalse(type_folder.GetFindings())
def testCreateTypeFolderFailure(self): bad_folderpath = 'NS/bad' with self.assertRaises(RuntimeError): entity_type_lib.EntityTypeFolder(bad_folderpath)