def ModifyInstance(self, *args, **kwargs): """This method is used by the MOF compiler only in the course of handling CIM_ERR_ALREADY_EXISTS after trying to create an instance. NOTE: It does NOT support the propertylist attribute that is part of the CIM/XML defintion of ModifyInstance and it requires that each created instance include the instance path which means that the MOF must include the instance alias on each created instance. """ mod_inst = args[0] if args else kwargs['ModifiedInstance'] if self.default_namespace not in self.instances: raise CIMError( CIM_ERR_INVALID_NAMESPACE, _format( 'ModifyInstance failed. No instance repo exists. ' 'Use compiler instance alias to set path on ' 'instance declaration. inst: {0!A}', mod_inst)) if mod_inst.path not in self.instances[self.default_namespace]: raise CIMError( CIM_ERR_NOT_FOUND, _format( 'ModifyInstance failed. No instance exists. ' 'Use compiler instance alias to set path on ' 'instance declaration. inst: {0!A}', mod_inst)) orig_instance = self.instances[self.default_namespace][mod_inst.path] orig_instance.update(mod_inst.properties) self.instances[self.default_namespace][mod_inst.path] = orig_instance
def print_repository(self, dest=None): """ Print the CIM repository to a destination. This displays information on the items in the data base and is only a diagnostic tool. Parameters: dest (:term:`string`): File path of an output file. If `None`, the output is written to stdout. """ def objstore_info(objstore_name): """ Display the data for the object store """ for ns in self._repository: if objstore_name == 'class': store = self.get_class_store(ns) elif objstore_name == 'qualifier': store = self.get_qualifier_store(ns) else: assert objstore_name == 'instance' store = self.get_instance_store(ns) rtn_str = u'Namespace: {} Repo: {} len:{}\n'.format( ns, objstore_name, store.len()) for val in store.iter_values(): rtn_str += (u'{}\n'.format(val)) return rtn_str namespaces = ",".join(self._repository.keys()) _uprint(dest, _format(u'NAMESPACES: {0}', namespaces)) _uprint(dest, _format(u'QUALIFIERS: {0}', objstore_info('qualifier'))) _uprint(dest, _format(u'CLASSES: {0}', objstore_info('class'))) _uprint(dest, _format(u'INSTANCES: {0}', objstore_info('instance')))
def _validate_qualifiers(qualifier_list, qual_repo, new_class, scope): """ Validate a list of qualifiers against the Qualifier decl in the repository. 1. Whether it is declared (can be obtained from the declContext). 2. Whether it has the same type as the declaration. 3. Whether the qualifier is valid for the given scope. 4. Whether the qualifier can be overridden. 5. Whether the qualifier should be propagated to the subclass. """ for qname, qvalue in qualifier_list.items(): if qname not in qual_repo: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Qualifier {0!A} in new_class {1!A} in " "CreateClass not in repository.", qname, new_class.classname)) q_decl = qual_repo[qname] if qvalue.type != q_decl.type: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Qualifier {0!A} in new_class {1!A} override type " "mismatch {2!A} with qualifier declaration {3!A}.", qname, new_class.classname, qvalue.type, q_decl.type)) if scope not in q_decl.scopes: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Qualifier {0!A} in new class {1!A} scope {2!A} " "invalid. Not in qualifier decl scopes {3}", qname, new_class.classname, scope, q_decl.scopes))
def test_Namespace(self, assert_association_func, wbem_connection): # noqa: F811 # pylint: disable=redefined-outer-name """ Test the associated CIM_Namespace instances. """ skip_if_unsupported_capability(wbem_connection, 'snia-server') self.init_profile(wbem_connection) self.init_central_instances() central_inst_path = self.central_inst_paths[0] far_insts, _ = assert_association_func( conn=wbem_connection, profile_id=self.profile_id, source_path=central_inst_path, source_role='Antecedent', assoc_class='CIM_NamespaceInManager', far_role='Dependent', far_class='CIM_Namespace') far_insts_msg = _format( "CIM_Namespace instances associated via " "CIM_NamespaceInManager to " "central instance of profile {0} {1!A} (version {2})", self.profile_definition['registered_org'], self.profile_definition['registered_name'], self.profile_definition['registered_version'] or 'any') for inst in far_insts: assert_mandatory_properties(wbem_connection, inst, [ 'SystemCreationClassName', 'SystemName', 'ObjectManagerCreationClassName', 'ObjectManagerName', 'CreationClassName', 'Name', 'ClassType' ]) # Check that they are the namespaces determined by WBEMServer. # Because the Interop namespace is added if missing, we need to also # do that here. inst_names = [inst['Name'].lower() for inst in far_insts] interop_ns_lower = server_prop_asserted(self.server, 'interop_ns').lower() if interop_ns_lower not in inst_names: inst_names.append(interop_ns_lower) # pylint: disable=not-an-iterable determined_names = [ ns.lower() for ns in server_prop_asserted(self.server, 'namespaces') ] if set(inst_names) != set(determined_names): raise AssertionError( _format( "Server {0} at {1}: The namespaces ({2}) of the {3} " "do not match the namespaces ({4}) determined by the " "WBEMServer class", wbem_connection.es_server.nickname, wbem_connection.url, set(inst_names), far_insts_msg, set(determined_names)))
def remove_namespace(self, namespace, verbose=False): """ Remove a CIM namespace from the CIM repository. The namespace must exist in the CIM repository and must be empty. The Interop namespace cannot be removed from the CIM repository. Parameters: namespace (:term:`string`): The name of the CIM namespace in the CIM repository (case insensitive). Must not be `None`. Leading or trailing slash characters are ignored. verbose (:class:`py:bool`): Verbose mode: Print a message about the namespace deletion. Raises: ValueError: Namespace argument must not be None. :exc:`~pywbem.CIMError`: CIM_ERR_NOT_FOUND if the namespace does not exist in the CIM repository. :exc:`~pywbem.CIMError`: CIM_ERR_INVALID_NAMESPACE if the Interop namespace was specified. :exc:`~pywbem.CIMError`: CIM_ERR_NAMESPACE_NOT_EMPTY if the namespace icontains objects. :exc:`~pywbem.CIMError`: CIM_ERR_NAMESPACE_NOT_EMPTY if attempting to delete the default connection namespace. This namespace cannot be deleted from the CIM repository """ if namespace is None: raise ValueError("Namespace argument must not be None") namespace = namespace.strip('/') if namespace not in self.cimrepository.namespaces: raise CIMError( CIM_ERR_NOT_FOUND, _format( "Namespace {0!A} does not exist in the CIM repository ", namespace)) if self.is_interop_namespace(namespace): raise CIMError( CIM_ERR_INVALID_NAMESPACE, _format( "The Interop namespace {0!A} cannot be removed from " "the CIM repository.", namespace)) if verbose: print("Deleting namespace {} (in mock support)".format(namespace)) try: self.cimrepository.remove_namespace(namespace) # KeyError cannot happen because existence was already verified except ValueError: raise CIMError( CIM_ERR_NAMESPACE_NOT_EMPTY, _format("Namespace {0!A} contains objects.", namespace))
def CreateInstance(self, *args, **kwargs): """ Create a CIM instance in the local repository of this class. This method is derived from the the same method in the pywbem mof compiler but modified to: 1. Use a dictionary as the container for instances where the key is the path. This means that all instances must have a path component to be inserted into the repository. Normally the path component is built within the compiler by using the instance alias. 2. Fail with a CIMError exception if the instance already exists in the repository. For a description of the parameters, see :meth:`pywbem.WBEMConnection.CreateInstance`. """ namespace = self.default_namespace inst = args[0] if args else kwargs['NewInstance'] # Get list of properties in class defined for this instance cln = inst.classname cls = self.GetClass(cln, IncludeQualifiers=True, LocalOnly=False) cls_key_properties = [ p for p, v in cls.properties.items() if 'key' in v.qualifiers ] # Validate all key properties are in instance for pname in cls_key_properties: if pname not in inst.properties: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( 'CreateInstance failed. Key property {0!A} in ' 'class {1!A} but not in new_instance: {2!A}', pname, cln, str(inst))) # Build path from instance and class if inst.path is None or not inst.path.keybindings: inst.path = CIMInstanceName.from_instance( cls, inst, namespace=self.default_namespace) # Exception if duplicate. NOTE: compiler overrides this with # modify instance. instance_store = self.repo.get_instance_store(namespace) if instance_store.exists(inst.path): raise CIMError( CIM_ERR_ALREADY_EXISTS, _format( 'CreateInstance failed. Instance with path {0!A} ' 'already exists in mock repository', inst.path)) try: # TODO: This should go through self.conn.CreateInstance instance_store.create(inst.path, inst) except KeyError: raise return inst.path
def assert_instance_consistency(conn, instance, path): """ Assert that an instance and an instance path are consistent: - They must have the same classname. - The instance must have the key properties matching the keybindings of the instance path. The 'path' attribute of the instance is ignored for this purpose. Of course, this function can be used to verify consistency of an instance and its 'path' attribute by passing it as the 'path' parameter. Parameters: conn (WBEMConnection with 'server_definition' attribute) instance (CIMInstance): The CIM instance to be verified. path (CIMInstanceName): The CIM instance path to be verified. """ # Check parameters assert isinstance(instance, CIMInstance) assert isinstance(path, CIMInstanceName) if instance.classname.lower() != path.classname.lower(): raise AssertionError( _format( "Server {0} at {1}: Inconsistent instance and instance " "path: Instance classname {2!A} does not match classname " "of instance path {3!A}", conn.server_definition.nickname, conn.url, instance.classname, path.to_wbem_uri())) for key_name in path.keybindings: if key_name not in instance.properties: raise AssertionError( _format( "Server {0} at {1}: Inconsistent instance and " "instance path: Instance does not have key property " "{2!A} of instance path {3!A}", conn.server_definition.nickname, conn.url, key_name, path.to_wbem_uri())) if instance.properties[key_name].value != \ path.keybindings[key_name]: raise AssertionError( _format( "Server {0} at {1}: Inconsistent instance and " "instance path: For key {2!A}, instance property " "value {3!A} does not match instance path keybinding " "value {4!A}", conn.server_definition.nickname, conn.url, key_name, instance.properties[key_name], path.keybindings[key_name]))
def add_namespace(self, namespace, verbose=False): """ Add a CIM namespace to the CIM repository. The namespace must not yet exist in the CIM repository and the repository can contain only one Interop namespace. An Interop namespace can be added with this method, if an Interop namespace does not yet exist in the CIM repository. Parameters: namespace (:term:`string`): The name of the CIM namespace in the CIM repository. Must not be `None`. Any leading or trailing slash characters are removed before the string is used to define the namespace name. verbose (:class:`py:bool`): Verbose mode: Print a message about the namespace creation. Raises: ValueError: Namespace argument must not be None. :exc:`~pywbem.CIMError`: CIM_ERR_ALREADY_EXISTS if the namespace already exists in the CIM repository. :exc:`~pywbem.CIMError`: CIM_ERR_ALREADY_EXISTS if the namespace is one of the possible Interop namespace names and an interop namespace already exists in the CIM repository. """ if namespace is None: raise ValueError("Namespace argument must not be None") namespace = namespace.strip('/') # Just for appearance in exc messages # Cannot add more than one of the possible Interop namespace names if self.is_interop_namespace(namespace): if self.find_interop_namespace(): raise CIMError( CIM_ERR_ALREADY_EXISTS, _format( "An Interop namespace {0!A} already exists in the " "CIM repository. {1!A} cannot be added. ", self.find_interop_namespace(), namespace)) if verbose: print("Creating namespace {} (in mock support)".format(namespace)) try: self.cimrepository.add_namespace(namespace) except ValueError: raise CIMError( CIM_ERR_ALREADY_EXISTS, _format( "Namespace {0!A} already exists in the CIM repository ", namespace))
def _validate_qualifiers(qualifiers, qualifier_store, new_class, scope): """ Validate a list of qualifiers against the Qualifier decl in the repository. 1. Whether it is declared (can be obtained from the declContext). 2. Whether it has the same type as the declaration. 3. Whether the qualifier is valid for the given scope. 4. Whether the qualifier can be overridden. 5. Whether the qualifier should be propagated to the subclass. Parameters: qualifiers: (:class:`py:dict` or `NocaseDict`_): Qualifiers to validate qualifier_store (): new_class (:class:`~pywbem.CIMClass`): The class being validated scope (:term:`string`): The scope defined for the object containing the qualifiers. May be 'CLASS', 'PROPERTY', 'METHOD', 'PARAMETER' """ for qname, qual in qualifiers.items(): if not qualifier_store.object_exists(qname): raise CIMError( CIM_ERR_INVALID_PARAMETER, _format("Qualifier {0!A} used in new class {1!A} " "has no qualifier declaration in repository.", qname, new_class.classname)) q_decl = qualifier_store.get(qname) if qual.type != q_decl.type: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format("Qualifier {0!A} used in new class {1!A} has " "invalid type {2!A} (Qualifier declaration type: " "{3!A}).", qname, new_class.classname, qual.type, q_decl.type)) # Test for valid scope for this object type ot qualdecl ANY if not q_decl.scopes[scope] and not q_decl.scopes['ANY']: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format("Qualifier {0!A} in new class {1!A} is used in " "invalid scope: {2!A}. (QualifierDeclaration " "scopes: ({3})", qname, new_class.classname, scope, ", ".join( [s for s, v in q_decl.scopes.items() if v])))
def DeleteInstance(self, InstanceName): # pylint: disable=invalid-name """ Dispatcher for the DeleteInstance provider method. This method performs validations and if successful, routes the provider method call either to a registered provider, or to the default provider. """ # Verify the input parameter types (type errors have already been # raised during checks in the WBEMConnection operation). assert isinstance(InstanceName, CIMInstanceName) # Verify that the namespace exists in the CIM repository. namespace = InstanceName.namespace self.validate_namespace(namespace) class_store = self.cimrepository.get_class_store(namespace) instance_store = self.cimrepository.get_instance_store(namespace) # Verify that the creation class of the instance to be deleted exists # in the CIM repository. if not class_store.object_exists(InstanceName.classname): raise CIMError( CIM_ERR_INVALID_CLASS, _format( "Creation class {0!A} of instance to be deleted does " "not exist in namespace {1!A} of the CIM repository.", InstanceName.classname, namespace)) # Verify that the instance to be deleted exists in the CIM repository. if not instance_store.object_exists(InstanceName): raise CIMError( CIM_ERR_NOT_FOUND, _format( "Instance to be deleted does not exist in the CIM " "repository: {0!A}", InstanceName)) # Determine the provider to be used. Note that a registered provider # always has all provider methods for the provider type, either # implemented or inherited. provider = self.provider_registry.get_registered_provider( namespace, 'instance-write', InstanceName.classname) if not provider: provider = self.default_instance_write_provider # Call the provider method. result = provider.DeleteInstance(InstanceName) # Verify provider method result. assert result is None
def CreateInstance(self, *args, **kwargs): """ Create a CIM instance in the local repository of this class. This method is derived from the the same method in the pywbem mof compiler but modified to: 1. Use a dictionary as the container for instances where the key is the path. This means that all instances must have a path component to be inserted into the repository. Normally the path component is built within the compiler by using the instance alias. 2. Fail with a CIMError exception if the instance already exists in the repository. TODO: Determine if the logic should be to fail or replace. See pywbem issue #1890 For a description of the parameters, see :meth:`pywbem.WBEMConnection.CreateInstance`. """ inst = args[0] if args else kwargs['NewInstance'] # TODO build path if does not exist. For now simply abort # NOTE: compiler does not build path unless the instance alias is # defined for the instance if inst.path is None or not inst.path.keybindings: raise CIMError( CIM_ERR_FAILED, _format( 'CreateInstance failed. No path in new_instance or ' 'keybindings in path. ', 'Use compiler instance alias to set path on ' 'instance declaration. inst: {0!A}', inst)) if self.default_namespace not in self.instances: self.instances[self.default_namespace] = {} if inst.path in self.instances[self.default_namespace]: raise CIMError( CIM_ERR_ALREADY_EXISTS, _format( 'CreateInstance failed. Instance with path {0!A} ' 'already exists in mock repository', inst.path)) try: self.instances[self.default_namespace][inst.path] = inst except KeyError: self.instances[self.default_namespace] = {} self.instances[self.default_namespace][inst.path] = inst return inst.path
def assert_property_one_of(conn, instance, prop_name, value_list): """ Assert that a simple (= non-array) CIM property of an instance has a value that is one of a set of allowable values. Parameters: conn (WBEMConnection with 'server_definition' attribute) instance (CIMInstance): The CIM instance that has the property to be verified. prop_name (string): Name of the CIM property to be verified. value_list (iterable of values): The set of allowable values for the property. """ # Check parameters assert isinstance(instance, CIMInstance) assert isinstance(prop_name, six.string_types) prop = instance.properties[prop_name] assert not prop.is_array prop_value = prop.value if prop_value not in value_list: raise AssertionError( _format("Server {0} at {1}: Property value issue: The value of " "simple property {2!A} in an instance of class {3!A} is " "not in the allowable set of values {4!A}, but is {5!A}", conn.server_definition.nickname, conn.url, prop_name, instance.classname, value_list, prop_value))
def validate_namespace(self, namespace): """ Validates that a namespace is defined in the CIM repository. Returns only if namespace is valid. Otherwise it generates an exception. Parameters: namespace (:term:`string`): The name of the CIM namespace in the CIM repository (case insensitive). Must not be `None`. Any leading or trailing slash characters are ignored. Raises: :exc:`~pywbem.CIMError`: (CIM_ERR_INVALID_NAMESPACE) Namespace does not exist. """ try: self.cimrepository.validate_namespace(namespace) except KeyError: raise CIMError( CIM_ERR_INVALID_NAMESPACE, _format("Namespace does not exist in CIM repository: {0!A}", namespace))
def assert_path_in(conn, path, path_msg, path_list, path_list_msg): """ Assert that an instance path is in a list of instance paths or instances, with special treatment of their host component as described in assert_path_equal(). Parameters: conn (WBEMConnection with 'server_definition' attribute) path (CIMInstanceName): Instance path to be tested for being contained in list. path_msg (string): Short definition what path is. path_list (iterable of CIMInstanceName): List of instance paths tested for containing path. path_list_msg (string): Short definition what path_list is. """ # Check parameters # Note: path and path_list are checked in path_in() assert isinstance(path_msg, six.string_types) assert isinstance(path_list_msg, six.string_types) if not path_in(path, path_list): raise AssertionError( _format("Server {0} at {1}: Instance path issue: Instance path " "{2!A} ({3}) is not in expected set of instance paths " "({4})", conn.server_definition.nickname, conn.url, path.to_wbem_uri(), path_msg, path_list_msg))
def validate_no_subscription(self, instance_name): """ Validate that no subscriptions exist containing reference to this instance. Parameters: instance_name (:class:`~pywbem.CIMInstanceName`) Instance name of the target instance. The class must be either the filter class or the listener destination class Returns: Returns if there are no corresponding subscriptions. """ # If a subscription exists containing this ListenerDestination, # reject delete if self.conn.ReferenceNames(instance_name, ResultClass=SUBSCRIPTION_CLASSNAME): # DSP1054 1.2 defines CIM error is raised by the server # in that case; we simulate it. raise CIMError(CIM_ERR_FAILED, _format( "The instance {0} is referenced by " "subscriptions.", instance_name), conn_id=self.conn.conn_id)
def assert_property_contains(conn, instance, prop_name, value): """ Assert that a CIM array property (of an instance) contains a particular value. Parameters: conn (WBEMConnection with 'server_definition' attribute) instance (CIMInstance): The CIM instance that has the property to be verified. prop_name (string): Name of the CIM property to be verified. value (value): The value. """ # Check parameters assert isinstance(instance, CIMInstance) assert isinstance(prop_name, six.string_types) prop = instance.properties[prop_name] assert prop.is_array prop_values = prop.value if value not in prop_values: raise AssertionError( _format("Server {0} at {1}: Property value issue: The value of " "array property {2!A} in an instance of class {3!A} does " "not contain value {4!A}, but is {5!A}", conn.server_definition.nickname, conn.url, prop_name, instance.classname, value, prop_values))
def test_format_random(unicode_cp): # pylint: disable=redefined-outer-name """ Test _format() with a random set of Unicode code points. """ unicode_char = unichr2(unicode_cp) if unicode_char is None: pytest.skip("Random Unicode code point U+%06X is a surrogate" % unicode_cp) cat = unicodedata.category(unicode_char) if cat in ('Cn', 'Cc', 'Cs'): pytest.skip("Random Unicode code point U+%06X has category: %s" % (unicode_cp, cat)) # The code to be tested act_result = _format("{0!A}", unicode_char) # Construct the expected formatting result. Note that the result is # ASCII-only in all cases. if unicode_cp < 0x7F: if unicode_char == "'": exp_result = '"\'"' else: exp_result = "'{0}'".format(unicode_char) elif unicode_cp < 0x10000: exp_result = "'\\u{0:04x}'".format(unicode_cp) else: exp_result = "'\\U{0:08x}'".format(unicode_cp) # pylint: disable=unidiomatic-typecheck assert type(act_result) is type(exp_result) assert act_result == exp_result
def test_get_central_instances(self, wbem_connection): # noqa: F811 # pylint: disable=redefined-outer-name """ Test WBEMServer.get_central_instances() for this profile. """ self.init_profile(wbem_connection) central_inst_paths = server_func_asserted( self.server, 'get_central_instances', profile_path=self.profile_inst.path, central_class=self.profile_definition['central_class'], scoping_class=self.profile_definition['scoping_class'], scoping_path=self.profile_definition['scoping_path'], reference_direction=self.profile_definition['reference_direction']) central_insts_msg = _format( "central instances of profile {0} {1!A} (version: {2})", self.profile_definition['registered_org'], self.profile_definition['registered_name'], self.profile_definition['registered_version'] or 'any') # Check that there is just one central instance for this profile assert_number_of_instances_equal(wbem_connection, central_inst_paths, central_insts_msg, 1)
def assert_instance_of(conn, obj_list, classname): """ Assert that a set of CIM instances and/or CIM instance paths are of a particular CIM class (including subclasses). Because there are WBEM servers without support for class operations, this is implemented without relying on class operations. The function performs an EnumerateInstanceNames operation on the desired class in the namespace of the instance in question, and verifies that the instance in question is in the result. Parameters: conn (WBEMConnection with 'server_definition' attribute) obj_list (CIMInstanceName or CIMInstance or tuple/list thereof): The CIM instances and CIM instance paths to be evaluated. classname (string): The CIM class name. """ # TODO 2018-12 AM: Improve performance by avoiding EI on each path if not isinstance(obj_list, (tuple, list)): obj_list = [obj_list] for obj in obj_list: if isinstance(obj, CIMInstance): path = obj.path assert isinstance(path, CIMInstanceName) # Ensured by CIMInstance assert path.namespace is not None # Ensured by WBEMConnection ops if path.classname != obj.classname: raise AssertionError( _format( "Server {0} at {1}: Inconsistent class name in " "CIMInstance object: obj.classname={2!A}, " "obj.path.classname={3!A}, obj.path={4!A}", conn.server_definition.nickname, conn.url, obj.classname, path.classname, path.to_wbem_uri())) else: path = obj assert isinstance(path, CIMInstanceName) if not instance_of(conn, path, classname): raise AssertionError( _format( "Server {0} at {1}: Instance at {2!A} is not of " "class {3!A}", conn.server_definition.nickname, conn.url, path.to_wbem_uri(), classname))
def ModifyInstance(self, modified_instance, IncludeQualifiers=None): """ Modification of CIM_Namespace instance not allowed """ raise CIMError( CIM_ERR_NOT_SUPPORTED, _format("Modification of {0} instances is not allowed: " "{1!A}", NAMESPACE_CLASSNAME, modified_instance.path))
def __repr__(self): return _format( "{s.__class__.__name__}(" "provider_type={s.provider_type!A}, " "provider_classnames={s.provider_classnames!A}, " "_interop_namespace_names={s._interop_namespace_names!A}, " "cimrepository=...)", s=self)
def build_schema_mof(self, schema_classes): """ Build a string that includes the ``#include pragma`` statements for the DMTF schema CIM classes defined in `schema_classes` using the DMTF CIM schema defined by this object. The class names in this list can be just leaf classes. The pywbem MOF compiler will search for dependent classes. It builds a compilable MOF string in the form:: #pragma locale ("en_US") #pragma include ("System/CIM_ComputerSystem.mof") with a ``#pragma include`` for each classname in the `schema_classes` list Parameters: schema_classes (:term:`py:list` of :term:`string` or :term:`string`): These must be class names of classes in the DMTF CIM schema represented by this :class:`~pywbem_mock.DMTFCIMSchema` object. This parameter can be a string if there is only a single class name to be included. If the returned string is compiled, the MOF compiler will search the directory defined by `schema_mof_dir` for dependent classes. Returns: :term:`string`: Valid MOF containing pragma statements for all of the classes in `schema_classes`. Raises: ValueError: If any of the classnames in `schema_classes` are not in the DMTF CIM schema installed """ if isinstance(schema_classes, six.string_types): schema_classes = [schema_classes] schema_lines = [] with open(self.schema_mof_file, 'r') as f: schema_lines = f.readlines() output_lines = ['#pragma locale ("en_US")\n'] for cln in schema_classes: test_cln = '/{0}.mof'.format(cln) # May contain Unicode found = False for line in schema_lines: if line.find(test_cln) != -1: output_lines.append(line) found = True break if not found: raise ValueError( _format("Class {0!A} not in DMTF CIM schema {1!A}", cln, self.schema_mof_file)) return ''.join(output_lines)
def test_WBEMListener_str(obj): """ Test function for WBEMListener.__str__() / str() """ # The code to be tested result = str(obj) assert re.match(r'^WBEMListener\(', result) exp_host_str = _format('_host={0!A}', obj.host) assert exp_host_str in result exp_http_port_str = _format('_http_port={0!A}', obj.http_port) assert exp_http_port_str in result exp_https_port_str = _format('_https_port={0!A}', obj.https_port) assert exp_https_port_str in result
def test_WBEMListener_repr(obj): """ Test function for WBEMListener.__repr__() / repr() """ # The code to be tested result = repr(obj) assert re.match(r'^WBEMListener\(', result) exp_host_str = _format('_host={0!A}', obj.host) assert exp_host_str in result exp_http_port_str = _format('_http_port={0!A}', obj.http_port) assert exp_http_port_str in result exp_https_port_str = _format('_https_port={0!A}', obj.https_port) assert exp_https_port_str in result exp_certfile_str = _format('_certfile={0!A}', obj.certfile) assert exp_certfile_str in result exp_keyfile_str = _format('_keyfile={0!A}', obj.keyfile) assert exp_keyfile_str in result exp_logger_str = _format('_logger={0!A}', obj.logger) assert exp_logger_str in result
def _test_qualifier_decl(qualifier, qualifier_store, namespace): """ Test that qualifier is in repo and valid. """ if qualifier_store is None: return if not qualifier_store.exists(qualifier.name): raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Qualifier declaration {0!A} required by CreateClass " "not found in namespace {1!A}.", qualifier.name, namespace))
def parameter_is_interop(self, ns, classname): # pylint: disable=no-self-use """ Test if the parameter provided in ns is the interop namespace """ if not self.is_interop_namespace(ns): raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Cannot create instance of class {0!A} in namespace {1!A}: " "The namespace is not an Interop namespace. " "Valid Interop namespaces are: {2!A}", classname, ns, ", ".join(self.interop_namespace_names)))
def DeleteInstance(self, InstanceName): """ Delete an instance of the CIM_Namespace class in an Interop namespace of the CIM repository, and in addition delete the namespace represented by it in the CIM repository. See `~pywbem_mock.InstanceWriteProvider.CreateInstance` for documentation of validation and description of input parameters, noting extra conditions for this provider as described below: The namespace to be deleted must be empty and must not be the Interop namespace. Parameters: InstanceName: (:class:`~pywbem.CIMInstanceName`): The keybinding `Name` must exist; it defines the namespace to be deleted. Raises: :exc:`~pywbem.CIMError`: (CIM_ERR_INVALID_PARAMETER) :exc:`~pywbem.CIMError`: (CIM_ERR_NAMESPACE_NOT_EMPTY) """ # The provider dispatcher ensures that provider methods are only called # for the registered classes. # And this provider sets only a single class, not a list. assert InstanceName.classname.lower() == \ CIMNamespaceProvider.provider_classnames.lower() remove_namespace = InstanceName.keybindings['Name'] if self.is_interop_namespace(remove_namespace): raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Cannot delete instance {0!A} from the CIM repository: " "This instance represents the Interop namespace {1!A} " "which must not be deleted.", InstanceName, remove_namespace)) # Delete the namespace from the CIM repository. # This call verifies that the namespace is empty and raises # CIMError(CIM_ERR_NAMESPACE_NOT_EMPTY) if not empty. self.remove_namespace(remove_namespace) # Delete the instance from the CIM repository instance_store = self.cimrepository.get_instance_store( InstanceName.namespace) instance_store.delete(InstanceName)
def _test_qualifier_decl(qualifier, qualifier_repo, namespace): """ Test that qualifier is in repo and valid. For for conn_lite, ignore this test """ if qualifier_repo is None: return if qualifier.name not in qualifier_repo: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Qualifier declaration {0!A} required by CreateClass " "not found in namespace {1!A}.", qualifier.name, namespace))
def _validate_qualifiers(qualifier_list, qualifier_store, new_class, scope): """ Validate a list of qualifiers against the Qualifier decl in the repository. 1. Whether it is declared (can be obtained from the declContext). 2. Whether it has the same type as the declaration. 3. Whether the qualifier is valid for the given scope. 4. Whether the qualifier can be overridden. 5. Whether the qualifier should be propagated to the subclass. """ for qname, qvalue in qualifier_list.items(): if not qualifier_store.exists(qname): raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Qualifier {0!A} used in new class {1!A} " "has no qualifier declaration in repository.", qname, new_class.classname)) q_decl = qualifier_store.get(qname) if qvalue.type != q_decl.type: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Qualifier {0!A} used in new class {1!A} has " "invalid type {2!A} (Qualifier declaration type: " "{3!A}).", qname, new_class.classname, qvalue.type, q_decl.type)) if scope not in q_decl.scopes and 'ANY' not in q_decl.scopes: raise CIMError( CIM_ERR_INVALID_PARAMETER, _format( "Qualifier {0!A} in new class {1!A} is used in " "invalid scope {2!A} (Qualifier declaration " "scopes: {3})", qname, new_class.classname, scope, q_decl.scopes))
def assert_mandatory_properties(conn, instance, property_list): """ Assert that an instance has non-null values for a set of properties. Parameters: conn (WBEMConnection with 'server_definition' attribute) instance (CIMInstance): The CIM instance to be verified. property_list (iterable of string): The property names. """ # Check parameters assert isinstance(instance, CIMInstance) instance_prop_names = instance.properties.keys() for prop_name in property_list: assert isinstance(prop_name, six.string_types) if prop_name not in instance_prop_names: raise AssertionError( _format( "Server {0} at {1}: Mandatory properties issue: " "Instance of class {2!A} does not have mandatory " "property {3!A}", conn.server_definition.nickname, conn.url, instance.classname, prop_name)) prop_value = instance.properties[prop_name] if prop_value is None: raise AssertionError( _format( "Server {0} at {1}: Mandatory properties issue: " "Instance of class {2!A} has mandatory property " "{3!A} but with a value of NULL", conn.server_definition.nickname, conn.url, instance.classname, prop_name))