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
Esempio n. 2
0
    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')))
Esempio n. 3
0
    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))
Esempio n. 4
0
    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)))
Esempio n. 5
0
    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))
Esempio n. 6
0
    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
Esempio n. 7
0
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]))
Esempio n. 8
0
    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))
Esempio n. 9
0
    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])))
Esempio n. 10
0
    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
Esempio n. 12
0
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))
Esempio n. 13
0
    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))
Esempio n. 14
0
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))
Esempio n. 15
0
    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)
Esempio n. 16
0
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))
Esempio n. 17
0
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
Esempio n. 18
0
    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)
Esempio n. 19
0
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))
Esempio n. 20
0
 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))
Esempio n. 21
0
 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)
Esempio n. 22
0
    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)
Esempio n. 23
0
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
Esempio n. 24
0
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
Esempio n. 25
0
 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))
Esempio n. 26
0
 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)))
Esempio n. 27
0
    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)
Esempio n. 28
0
 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))
Esempio n. 29
0
    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))
Esempio n. 30
0
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))