summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMichal Minar <miminar@redhat.com>2013-03-04 15:15:36 +0100
committerMichal Minar <miminar@redhat.com>2013-03-04 15:15:36 +0100
commit19ab3372fe708be3e937df5d1ed6945ac813b51c (patch)
tree7e2cc6c06c2234498d1ac37633333a4c2eb13ff3 /src
parent282aa360c1ab3c58622d9e284bb0b3600e8997b4 (diff)
downloadopenlmi-providers-19ab3372fe708be3e937df5d1ed6945ac813b51c.tar.gz
openlmi-providers-19ab3372fe708be3e937df5d1ed6945ac813b51c.tar.xz
openlmi-providers-19ab3372fe708be3e937df5d1ed6945ac813b51c.zip
added association providers for SoftwareIdentityResource
simplified writing references() method of any association provider
Diffstat (limited to 'src')
-rw-r--r--src/software/openlmi/software/LMI_HostedSoftwareIdentityResource.py281
-rw-r--r--src/software/openlmi/software/LMI_InstalledSoftwareIdentity.py75
-rw-r--r--src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py97
-rw-r--r--src/software/openlmi/software/cimom_entry.py19
-rw-r--r--src/software/openlmi/software/core/__init__.py58
-rwxr-xr-xsrc/software/test/test_hosted_software_identity_resource.py165
-rwxr-xr-xsrc/software/test/test_resource_for_software_identity.py176
7 files changed, 781 insertions, 90 deletions
diff --git a/src/software/openlmi/software/LMI_HostedSoftwareIdentityResource.py b/src/software/openlmi/software/LMI_HostedSoftwareIdentityResource.py
new file mode 100644
index 0000000..09ab5d3
--- /dev/null
+++ b/src/software/openlmi/software/LMI_HostedSoftwareIdentityResource.py
@@ -0,0 +1,281 @@
+# Software Management Providers
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+#
+
+"""Python Provider for LMI_HostedSoftwareIdentityResource
+
+Instruments the CIM class LMI_HostedSoftwareIdentityResource
+
+"""
+
+import pywbem
+from pywbem.cim_provider2 import CIMProvider2
+
+from openlmi.common import cmpi_logging
+from openlmi.software.core import generate_references
+from openlmi.software.core import ComputerSystem
+from openlmi.software.core import SoftwareIdentityResource
+from openlmi.software.yumdb import YumDB
+
+@cmpi_logging.trace_function
+def generate_system_referents(env, object_name, model, _keys_only):
+ """
+ Handler for referents enumeration request.
+ """
+ ComputerSystem.check_path(env, object_name, "Antecedent")
+ repomodel = pywbem.CIMInstanceName(
+ classname='LMI_SoftwareIdentityResource',
+ namespace='root/cimv2',
+ host=model.path.host)
+ model["Antecedent"] = ComputerSystem.get_path()
+ for repo in YumDB.get_instance().get_repository_list('all'):
+ model["Dependent"] = SoftwareIdentityResource.repo2model(
+ repo, model=repomodel)
+ yield model
+
+@cmpi_logging.trace_function
+def generate_repository_referents(env, object_name, model, _keys_only):
+ """
+ Handler for referents enumeration request.
+ """
+ repo = SoftwareIdentityResource.object_path2repo(
+ env, object_name, kind='all')
+ model["Antecedent"] = ComputerSystem.get_path()
+ model["Dependent"] = SoftwareIdentityResource.repo2model(repo)
+ yield model
+
+class LMI_HostedSoftwareIdentityResource(CIMProvider2):
+ """Instrument the CIM class LMI_HostedSoftwareIdentityResource
+
+ CIM_HostedAccessPoint is an association between a Service AccessPoint
+ and the System on which it is provided. The cardinality of this
+ association is one-to-many and is weak with respect to the System.
+ Each System can host many ServiceAccessPoints. Heuristic: If the
+ implementation of the ServiceAccessPoint is modeled, it must be
+ implemented by a Device or SoftwareFeature that is part of the System
+ that is hosting the ServiceAccessPoint.
+
+ """
+
+ def __init__ (self, _env):
+ cmpi_logging.logger.debug('Initializing provider %s from %s' \
+ % (self.__class__.__name__, __file__))
+
+ @cmpi_logging.trace_method
+ def get_instance(self, env, model):
+ """Return an instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ model -- A template of the pywbem.CIMInstance to be returned. The
+ key properties are set on this instance to correspond to the
+ instanceName that was requested. The properties of the model
+ are already filtered according to the PropertyList from the
+ request. Only properties present in the model need to be
+ given values. If you prefer, you can set all of the
+ values, and the instance will be filtered for you.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ Instance does not exist in the specified namespace)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ ComputerSystem.check_path_property(env, model, "Antecedent")
+ if not "Name" in model['Dependent']:
+ raise pywbem.CIMError(pywbem.CIM_ERR_INVALID_PARAMETER,
+ 'Missing key property "Name" in Dependent!')
+
+ with YumDB.get_instance() as ydb:
+ repoid = model["Dependent"]["Name"]
+ repos = ydb.filter_repositories('all', repoid=repoid)
+ if len(repos) < 1:
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_FOUND,
+ 'Unknown repository "%s".' % repoid)
+ model["Antecedent"] = ComputerSystem.get_path()
+ model["Dependent"] = SoftwareIdentityResource.repo2model(repos[0])
+
+ return model
+
+ @cmpi_logging.trace_method
+ def enum_instances(self, env, model, keys_only):
+ """Enumerate instances.
+
+ The WBEM operations EnumerateInstances and EnumerateInstanceNames
+ are both mapped to this method.
+ This method is a python generator
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ model -- A template of the pywbem.CIMInstances to be generated.
+ The properties of the model are already filtered according to
+ the PropertyList from the request. Only properties present in
+ the model need to be given values. If you prefer, you can
+ always set all of the values, and the instance will be filtered
+ for you.
+ keys_only -- A boolean. True if only the key properties should be
+ set on the generated instances.
+
+ Possible Errors:
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+
+ # Prime model.path with knowledge of the keys, so key values on
+ # the CIMInstanceName (model.path) will automatically be set when
+ # we set property values on the model.
+ model.path.update({'Dependent': None, 'Antecedent': None})
+
+ repolist = YumDB.get_instance().get_repository_list('all')
+ model["Antecedent"] = ComputerSystem.get_path()
+ repomodel = pywbem.CIMInstanceName(
+ classname='LMI_SoftwareIdentityResource',
+ namespace='root/cimv2')
+ for repo in repolist:
+ model["Dependent"] = SoftwareIdentityResource.repo2model(
+ repo, model=repomodel)
+ yield model
+
+ @cmpi_logging.trace_method
+ def set_instance(self, env, instance, modify_existing):
+ """Return a newly created or modified instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ instance -- The new pywbem.CIMInstance. If modifying an existing
+ instance, the properties on this instance have been filtered by
+ the PropertyList from the request.
+ modify_existing -- True if ModifyInstance, False if CreateInstance
+
+ Return the new instance. The keys must be set on the new instance.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_ALREADY_EXISTS (the CIM Instance already exists -- only
+ valid if modify_existing is False, indicating that the operation
+ was CreateInstance)
+ CIM_ERR_NOT_FOUND (the CIM Instance does not exist -- only valid
+ if modify_existing is True, indicating that the operation
+ was ModifyInstance)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+ @cmpi_logging.trace_method
+ def delete_instance(self, env, instance_name):
+ """Delete an instance.
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ instance_name -- A pywbem.CIMInstanceName specifying the instance
+ to delete.
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_NAMESPACE
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_INVALID_CLASS (the CIM Class does not exist in the specified
+ namespace)
+ CIM_ERR_NOT_FOUND (the CIM Class does exist, but the requested CIM
+ Instance does not exist in the specified namespace)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+ raise pywbem.CIMError(pywbem.CIM_ERR_NOT_SUPPORTED)
+
+ @cmpi_logging.trace_method
+ def references(self, env, object_name, model, result_class_name, role,
+ result_role, keys_only):
+ """Instrument Associations.
+
+ All four association-related operations (Associators, AssociatorNames,
+ References, ReferenceNames) are mapped to this method.
+ This method is a python generator
+
+ Keyword arguments:
+ env -- Provider Environment (pycimmb.ProviderEnvironment)
+ object_name -- A pywbem.CIMInstanceName that defines the source
+ CIM Object whose associated Objects are to be returned.
+ model -- A template pywbem.CIMInstance to serve as a model
+ of the objects to be returned. Only properties present on this
+ model need to be set.
+ result_class_name -- If not empty, this string acts as a filter on
+ the returned set of Instances by mandating that each returned
+ Instances MUST represent an association between object_name
+ and an Instance of a Class whose name matches this parameter
+ or a subclass.
+ role -- If not empty, MUST be a valid Property name. It acts as a
+ filter on the returned set of Instances by mandating that each
+ returned Instance MUST refer to object_name via a Property
+ whose name matches the value of this parameter.
+ result_role -- If not empty, MUST be a valid Property name. It acts
+ as a filter on the returned set of Instances by mandating that
+ each returned Instance MUST represent associations of
+ object_name to other Instances, where the other Instances play
+ the specified result_role in the association (i.e. the
+ name of the Property in the Association Class that refers to
+ the Object related to object_name MUST match the value of this
+ parameter).
+ keys_only -- A boolean. True if only the key properties should be
+ set on the generated instances.
+
+ The following diagram may be helpful in understanding the role,
+ result_role, and result_class_name parameters.
+ +------------------------+ +-------------------+
+ | object_name.classname | | result_class_name |
+ | ~~~~~~~~~~~~~~~~~~~~~ | | ~~~~~~~~~~~~~~~~~ |
+ +------------------------+ +-------------------+
+ | +-----------------------------------+ |
+ | | [Association] model.classname | |
+ | object_name | ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ | |
+ +--------------+ object_name.classname REF role | |
+ (CIMInstanceName) | result_class_name REF result_role +------+
+ | |(CIMInstanceName)
+ +-----------------------------------+
+
+ Possible Errors:
+ CIM_ERR_ACCESS_DENIED
+ CIM_ERR_NOT_SUPPORTED
+ CIM_ERR_INVALID_NAMESPACE
+ CIM_ERR_INVALID_PARAMETER (including missing, duplicate, unrecognized
+ or otherwise incorrect parameters)
+ CIM_ERR_FAILED (some other unspecified error occurred)
+
+ """
+
+ handlers = [
+ ("Antecedent", "CIM_ComputerSystem" , generate_system_referents),
+ ("Dependent", "LMI_SoftwareIdentityResource",
+ generate_repository_referents)
+ ]
+ for ref in generate_references(env, object_name, model,
+ result_class_name, role, result_role, keys_only, handlers):
+ yield ref
+
diff --git a/src/software/openlmi/software/LMI_InstalledSoftwareIdentity.py b/src/software/openlmi/software/LMI_InstalledSoftwareIdentity.py
index 08dc674..b4c1b6f 100644
--- a/src/software/openlmi/software/LMI_InstalledSoftwareIdentity.py
+++ b/src/software/openlmi/software/LMI_InstalledSoftwareIdentity.py
@@ -29,10 +29,39 @@ import pywbem
from pywbem.cim_provider2 import CIMProvider2
from openlmi.common import cmpi_logging
+from openlmi.software.core import generate_references
from openlmi.software.core import ComputerSystem
from openlmi.software.core import SoftwareIdentity
from openlmi.software.yumdb import YumDB
+@cmpi_logging.trace_function
+def generate_system_referents(env, object_name, model, _keys_only):
+ """
+ Handler for referents enumeration request.
+ """
+ ComputerSystem.check_path(env, object_name, "object_name")
+
+ pkg_model = pywbem.CIMInstanceName(
+ classname='LMI_SoftwareIdentity',
+ namespace="root/cimv2",
+ host=model.path.host)
+ model["System"] = ComputerSystem.get_path()
+ with YumDB.get_instance() as ydb:
+ for pkg_info in ydb.get_package_list('installed', sort=True):
+ model["InstalledSoftware"] = SoftwareIdentity.pkg2model(
+ pkg_info, model=pkg_model)
+ yield model
+
+@cmpi_logging.trace_function
+def generate_package_referents(_env, object_name, model, _keys_only):
+ """
+ Handler for referents enumeration request.
+ """
+ pkg_info = SoftwareIdentity.object_path2pkg(object_name, kind="installed")
+ model['InstalledSoftware'] = SoftwareIdentity.pkg2model(pkg_info)
+ model["System"] = ComputerSystem.get_path()
+ yield model
+
class LMI_InstalledSoftwareIdentity(CIMProvider2):
"""Instrument the CIM class LMI_InstalledSoftwareIdentity
@@ -268,41 +297,13 @@ class LMI_InstalledSoftwareIdentity(CIMProvider2):
CIM_ERR_FAILED (some other unspecified error occurred)
"""
- cimhandle = env.get_cimom_handle()
-
- model.path.update({'InstalledSoftware': None, 'System': None})
-
- with YumDB.get_instance() as ydb:
- try:
- if ( (not role or role.lower() == 'system')
- and cimhandle.is_subclass(object_name.namespace,
- sub=object_name.classname,
- super='CIM_ComputerSystem')):
- ComputerSystem.check_path(env, object_name, "object_name")
-
- pkg_model = pywbem.CIMInstanceName(
- classname='LMI_SoftwareIdentity',
- namespace="root/cimv2",
- host=model.path.host)
- model["System"] = ComputerSystem.get_path()
- for pkg_info in ydb.get_package_list('installed',
- sort=True):
- model["InstalledSoftware"] = SoftwareIdentity.pkg2model(
- pkg_info, model=pkg_model)
- yield model
-
- if ( (not role or role.lower() == 'installedsoftware')
- and cimhandle.is_subclass(object_name.namespace,
- sub=object_name.classname,
- super='LMI_SoftwareIdentity')):
- pkg_info = SoftwareIdentity.object_path2pkg(
- object_name, kind="installed")
- model['InstalledSoftware'] = SoftwareIdentity.pkg2model(
- pkg_info)
- model["System"] = ComputerSystem.get_path()
- yield model
-
- except pywbem.CIMError as exc:
- if exc.args[0] != pywbem.CIM_ERR_NOT_FOUND:
- raise
+ handlers = [
+ ("System", "CIM_ComputerSystem", generate_system_referents),
+ ("InstalledSoftware", "LMI_SoftwareIdentity",
+ generate_package_referents)
+ ]
+
+ for ref in generate_references(env, object_name, model,
+ result_class_name, role, result_role, keys_only, handlers):
+ yield ref
diff --git a/src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py b/src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py
index 6fa6ea4..e9f73b5 100644
--- a/src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py
+++ b/src/software/openlmi/software/LMI_MemberOfSoftwareCollection.py
@@ -25,10 +25,51 @@ import pywbem
from pywbem.cim_provider2 import CIMProvider2
from openlmi.common import cmpi_logging
+from openlmi.software.core import generate_references
from openlmi.software.core import SystemSoftwareCollection
from openlmi.software.core import SoftwareIdentity
from openlmi.software.yumdb import YumDB
+@cmpi_logging.trace_function
+def generate_collection_referents(env, object_name, model, _keys_only):
+ """
+ Handler for referents enumeration request.
+ """
+ SystemSoftwareCollection.check_path(env, object_name, "collection")
+ pkg_model = pywbem.CIMInstanceName(
+ classname='LMI_SoftwareIdentity',
+ namespace="root/cimv2",
+ host=model.path.host)
+ model["Collection"] = SystemSoftwareCollection.get_path()
+ with YumDB.get_instance() as ydb:
+ for pkg_info in ydb.get_package_list('available',
+ allow_duplicates=True, sort=True):
+ model["Member"] = SoftwareIdentity.pkg2model(
+ pkg_info, model=pkg_model)
+ yield model
+
+@cmpi_logging.trace_function
+def generate_member_referents(_env, object_name, model, _keys_only):
+ """
+ Handler for referents enumeration request.
+ """
+ try:
+ pkg_info = SoftwareIdentity.object_path2pkg(
+ object_name, kind="available")
+ model['Member'] = SoftwareIdentity.pkg2model(pkg_info)
+ model["Collection"] = SystemSoftwareCollection.get_path()
+ except pywbem.CIMError as exc:
+ if exc.args[0] == pywbem.CIM_ERR_NOT_FOUND:
+ msg = "Could not find requested package%s."
+ if "InstanceID" in object_name:
+ msg = msg % (' with InstanceID="%s"' %object_name["InstanceID"])
+ else:
+ msg = msg % ""
+ raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, msg)
+ else:
+ raise
+ yield model
+
class LMI_MemberOfSoftwareCollection(CIMProvider2):
"""Instrument the CIM class LMI_MemberOfSoftwareCollection
@@ -232,51 +273,13 @@ class LMI_MemberOfSoftwareCollection(CIMProvider2):
CIM_ERR_FAILED (some other unspecified error occurred)
"""
- cimhandle = env.get_cimom_handle()
-
- model.path.update({'Collection': None, 'Member': None})
-
- with YumDB.get_instance() as ydb:
- if ( (not role or role.lower() == 'collection')
- and cimhandle.is_subclass(object_name.namespace,
- sub=object_name.classname,
- super='LMI_SystemSoftwareCollection')):
- try:
- SystemSoftwareCollection.check_path(env, object_name,
- "collection")
- pkg_model = pywbem.CIMInstanceName(
- classname='LMI_SoftwareIdentity',
- namespace="root/cimv2",
- host=model.path.host)
- model["Collection"] = SystemSoftwareCollection.get_path()
- for pkg_info in ydb.get_package_list('available',
- allow_duplicates=True, sort=True):
- model["Member"] = SoftwareIdentity.pkg2model(
- pkg_info, model=pkg_model)
- yield model
- except pywbem.CIMError as exc:
- if exc.args[0] != pywbem.CIM_ERR_NOT_FOUND:
- raise
-
- if ( (not role or role.lower() == 'member')
- and cimhandle.is_subclass(object_name.namespace,
- sub=object_name.classname,
- super='LMI_SoftwareIdentity')):
- try:
- pkg_info = SoftwareIdentity.object_path2pkg(
- object_name, kind="available")
- model['Member'] = SoftwareIdentity.pkg2model(pkg_info)
- model["Collection"] = SystemSoftwareCollection.get_path()
- except pywbem.CIMError as exc:
- if exc.args[0] == pywbem.CIM_ERR_NOT_FOUND:
- msg = "Could not find requested package%s."
- if "InstanceID" in object_name:
- msg = msg % (' with InstanceID="%s"' % \
- object_name["InstanceID"])
- else:
- msg = msg % ""
- raise pywbem.CIMError(pywbem.CIM_ERR_FAILED, msg)
- else:
- raise
- yield model
+ handlers = [
+ ("Collection", "LMI_SystemSoftwareCollection",
+ generate_collection_referents),
+ ("Member", "LMI_SoftwareIdentity", generate_member_referents)
+ ]
+
+ for ref in generate_references(env, object_name, model,
+ result_class_name, role, result_role, keys_only, handlers):
+ yield ref
diff --git a/src/software/openlmi/software/cimom_entry.py b/src/software/openlmi/software/cimom_entry.py
index a259ff0..a598fb1 100644
--- a/src/software/openlmi/software/cimom_entry.py
+++ b/src/software/openlmi/software/cimom_entry.py
@@ -36,6 +36,10 @@ from openlmi.software.LMI_InstalledSoftwareIdentity import \
LMI_InstalledSoftwareIdentity
from openlmi.software.LMI_SoftwareIdentityResource import \
LMI_SoftwareIdentityResource
+from openlmi.software.LMI_ResourceForSoftwareIdentity import \
+ LMI_ResourceForSoftwareIdentity
+from openlmi.software.LMI_HostedSoftwareIdentityResource import \
+ LMI_HostedSoftwareIdentityResource
from openlmi.software.yumdb import YumDB
def get_providers(env):
@@ -45,12 +49,15 @@ def get_providers(env):
cmpi_logging.LogManager(env)
providers = {
- "LMI_SoftwareIdentity" : LMI_SoftwareIdentity(env),
- "LMI_SystemSoftwareCollection" : LMI_SystemSoftwareCollection(env),
- "LMI_HostedSoftwareCollection" : LMI_HostedSoftwareCollection(env),
- "LMI_MemberOfSoftwareCollection" : LMI_MemberOfSoftwareCollection(env),
- "LMI_InstalledSoftwareIdentity" : LMI_InstalledSoftwareIdentity(env),
- "LMI_SoftwareIdentityResource" : LMI_SoftwareIdentityResource(env)
+ "LMI_SoftwareIdentity" : LMI_SoftwareIdentity(env),
+ "LMI_SystemSoftwareCollection" : LMI_SystemSoftwareCollection(env),
+ "LMI_HostedSoftwareCollection" : LMI_HostedSoftwareCollection(env),
+ "LMI_MemberOfSoftwareCollection" : LMI_MemberOfSoftwareCollection(env),
+ "LMI_InstalledSoftwareIdentity" : LMI_InstalledSoftwareIdentity(env),
+ "LMI_SoftwareIdentityResource" : LMI_SoftwareIdentityResource(env),
+ "LMI_ResourceForSoftwareIdentity" : LMI_ResourceForSoftwareIdentity(env),
+ "LMI_HostedSoftwareIdentityResource" :
+ LMI_HostedSoftwareIdentityResource(env)
}
return providers
diff --git a/src/software/openlmi/software/core/__init__.py b/src/software/openlmi/software/core/__init__.py
index 61158e1..a684897 100644
--- a/src/software/openlmi/software/core/__init__.py
+++ b/src/software/openlmi/software/core/__init__.py
@@ -24,3 +24,61 @@ Core functionality of particular providers.
Each provider having functionality useful to others has a submodule
in this subpackage with the same name except for LMI_ prefix.
"""
+
+import pywbem
+from openlmi.common import cmpi_logging
+
+@cmpi_logging.trace_function
+def generate_references(
+ env,
+ object_name,
+ model,
+ filter_result_class_name,
+ filter_role,
+ filter_result_role,
+ keys_only,
+ handlers):
+ """
+ Function for generating references to object_name. It's supposed
+ to be used directly from references method of provider classes.
+ @param handlers is a list of tuples:
+ [ (role, class_name, handler), ... ]
+ where handler is a function, that will be called for matching
+ parameters, yielding instance(s/names). It accepts arguments:
+ env, object_name, model, keys_only.
+ """
+ if not isinstance(object_name, pywbem.CIMInstanceName):
+ raise TypeError("object_name must be a CIMInstanceName")
+ if not isinstance(model, pywbem.CIMInstance):
+ raise TypeError("model must be a CIMInstance")
+
+ ch = env.get_cimom_handle()
+ model.path.update(dict((t[0], None) for t in handlers))
+
+ try:
+ for i, (role, clsname, handler) in enumerate(handlers):
+ if ( ( filter_role
+ and filter_role.lower() != role.lower())
+ or not ch.is_subclass(object_name.namespace,
+ sub=object_name.classname,
+ super=clsname)):
+ continue
+ other_results = list((htuple[0], htuple[1]) for htuple in (
+ handlers[:i] + handlers[i+1:]))
+ for res_role, res_clsname in other_results:
+ if ( ( not filter_result_role
+ or filter_result_role.lower() == res_role.lower())
+ and (not filter_result_class_name or ch.is_subclass(
+ object_name.namespace,
+ sub=filter_result_class_name,
+ super=res_clsname))):
+ break
+ else:
+ continue
+ # matches filters
+ for obj in handler(env, object_name, model, keys_only):
+ yield obj
+ except pywbem.CIMError as exc:
+ if exc.args[0] != pywbem.CIM_ERR_NOT_FOUND:
+ raise
+
diff --git a/src/software/test/test_hosted_software_identity_resource.py b/src/software/test/test_hosted_software_identity_resource.py
new file mode 100755
index 0000000..af7b491
--- /dev/null
+++ b/src/software/test/test_hosted_software_identity_resource.py
@@ -0,0 +1,165 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+#
+"""
+Unit tests for LMI_HostedSoftwareIdentityResource provider.
+"""
+
+import pywbem
+import socket
+import unittest
+
+import base
+
+class TestHostedSoftwareIdentityResource(base.SoftwareBaseTestCase):
+ """
+ Basic cim operations test.
+ """
+
+ CLASS_NAME = "LMI_HostedSoftwareIdentityResource"
+ KEYS = ("Antecedent", "Dependent")
+
+ @classmethod
+ def needs_pkgdb(cls):
+ return False
+
+ @classmethod
+ def needs_repodb(cls):
+ return True
+
+ def make_op(self, repo):
+ """
+ @return object path of HostedSoftwareIdentityResource association
+ """
+ objpath = self.objpath.copy()
+ objpath["Antecedent"] = pywbem.CIMInstanceName(
+ classname="Linux_ComputerSystem",
+ namespace="root/cimv2",
+ keybindings=pywbem.NocaseDict({
+ "CreationClassName" : "Linux_ComputerSystem",
+ "Name" : socket.gethostname()
+ }))
+ objpath["Dependent"] = pywbem.CIMInstanceName(
+ classname="LMI_SoftwareIdentityResource",
+ namespace="root/cimv2",
+ keybindings=pywbem.NocaseDict({
+ "CreationClassName" : "LMI_SoftwareIdentityResource",
+ "SystemCreationClassName" : "Linux_ComputerSystem",
+ "SystemName" : socket.gethostname(),
+ "Name" : repo.repoid
+ }))
+ return objpath
+
+ def test_get_instance(self):
+ """
+ Tests GetInstance call on repositories from our rpm cache.
+ """
+ for repo in self.repodb:
+ objpath = self.make_op(repo)
+ inst = self.conn.GetInstance(InstanceName=objpath)
+ self.assertEqual(objpath, inst.path,
+ "Object paths should match for repo %s" % repo.repoid)
+ for key in self.KEYS:
+ self.assertTrue(inst.properties.has_key(key),
+ 'OP is missing \"%s\" key for repo "%s".' % (key, repo.repoid))
+ self.assertEqual(inst[key], inst.path[key],
+ 'Key property "%s" does not match for repo "%s"!' %
+ (key, repo.repoid))
+
+ def test_enum_instance_names(self):
+ """
+ Tests EnumInstanceNames call on repositories from our cache.
+ """
+ inames = self.conn.EnumerateInstanceNames(ClassName=self.CLASS_NAME)
+ repos = { r.repoid: r for r in self.repodb }
+ self.assertEqual(len(repos), len(inames))
+ for iname in inames:
+ self.assertIn('Dependent', iname)
+ self.assertIn('Name', iname['Dependent'])
+ self.assertIn(iname['Dependent']['Name'], repos)
+ objpath = self.make_op(repos[iname['Dependent']['Name']])
+ self.assertEqual(objpath, iname)
+
+ def test_enum_instances(self):
+ """
+ Tests EnumInstanceNames call on repositories from our cache.
+ """
+ inames = self.conn.EnumerateInstances(ClassName=self.CLASS_NAME)
+ repos = { r.repoid: r for r in self.repodb }
+ self.assertEqual(len(repos), len(inames))
+ for inst in inames:
+ self.assertIn('Dependent', inst)
+ self.assertIn('Name', inst['Dependent'])
+ repoid = inst['Dependent']['Name']
+ self.assertIn(repoid, repos)
+ objpath = self.make_op(repos[repoid])
+ self.assertEqual(objpath, inst.path)
+ for key in self.KEYS:
+ self.assertTrue(inst.properties.has_key(key),
+ 'OP is missing \"%s\" key for repo "%s".' % (key, repoid))
+ self.assertEqual(inst[key], inst.path[key],
+ 'Key property "%s" does not match for repo "%s"!' %
+ (key, repoid))
+
+ def test_get_antecedent_referents(self):
+ """
+ Test ReferenceNames for ComputerSystem.
+ """
+ if not self.repodb:
+ return
+ repo = self.repodb[0]
+ objpath = self.make_op(repo)
+ refs = self.conn.AssociatorNames(
+ Role="Antecedent",
+ ObjectName=objpath["Antecedent"],
+ ResultRole="Dependent",
+ ResultClass="LMI_SoftwareIdentityResource")
+ repos = {r.repoid: r for r in self.repodb}
+ for ref in refs:
+ self.assertIsInstance(ref, pywbem.CIMInstanceName)
+ self.assertEqual(ref.namespace, 'root/cimv2')
+ self.assertEqual(ref.classname, "LMI_SoftwareIdentityResource")
+ self.assertIn("Name", ref.keys())
+ objpath = self.make_op(repos[ref["Name"]])
+ self.assertEqual(objpath["Dependent"], ref)
+ del repos[ref["Name"]]
+ self.assertEqual(0, len(repos))
+
+ def test_get_dependent_referents(self):
+ """
+ Test ReferenceNames for repository.
+ """
+ for repo in self.repodb:
+ objpath = self.make_op(repo=repo)
+ refs = self.conn.AssociatorNames(
+ Role="Dependent",
+ ObjectName=objpath["Dependent"],
+ ResultRole="Antecedent",
+ ResultClass="Linux_ComputerSystem")
+ self.assertEqual(len(refs), 1)
+ self.assertEqual(objpath["Antecedent"], refs[0])
+
+def suite():
+ """For unittest loaders."""
+ return unittest.TestLoader().loadTestsFromTestCase(
+ TestHostedSoftwareIdentityResource)
+
+if __name__ == '__main__':
+ unittest.main()
diff --git a/src/software/test/test_resource_for_software_identity.py b/src/software/test/test_resource_for_software_identity.py
new file mode 100755
index 0000000..15fc047
--- /dev/null
+++ b/src/software/test/test_resource_for_software_identity.py
@@ -0,0 +1,176 @@
+#!/usr/bin/env python
+#
+# Copyright (C) 2012 Red Hat, Inc. All rights reserved.
+#
+# This library is free software; you can redistribute it and/or
+# modify it under the terms of the GNU Lesser General Public
+# License as published by the Free Software Foundation; either
+# version 2.1 of the License, or (at your option) any later version.
+#
+# This library is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+# Lesser General Public License for more details.
+#
+# You should have received a copy of the GNU Lesser General Public
+# License along with this library; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+#
+# Authors: Michal Minar <miminar@redhat.com>
+#
+"""
+Unit tests for LMI_ResourceForSoftwareIdentity provider.
+"""
+
+import pywbem
+import socket
+import unittest
+
+import base
+
+class TestResourceForSoftwareIdentity(base.SoftwareBaseTestCase):
+ """
+ Basic cim operations test.
+ """
+
+ CLASS_NAME = "LMI_ResourceForSoftwareIdentity"
+ KEYS = ("ManagedElement", "AvailableSAP")
+
+ @classmethod
+ def needs_repodb(cls):
+ return True
+
+ def make_op(self, pkg=None, newer=True, repo=None):
+ """
+ @return object path of ResourceForSoftwareIdentity association
+ """
+ objpath = self.objpath.copy()
+ objpath["AvailableSAP"] = pywbem.CIMInstanceName(
+ classname="LMI_SoftwareIdentityResource",
+ namespace="root/cimv2",
+ keybindings=pywbem.NocaseDict({
+ "CreationClassName" : "LMI_SoftwareIdentityResource",
+ "SystemCreationClassName" : "Linux_ComputerSystem",
+ "SystemName" : socket.gethostname()
+ }))
+ if repo is not None:
+ objpath["AvailableSAP"]["Name"] = repo.repoid
+ elif pkg is not None:
+ objpath["AvailableSAP"]["Name"] = getattr(pkg,
+ 'up_repo' if newer else 'repo')
+ objpath["ManagedElement"] = pywbem.CIMInstanceName(
+ classname="LMI_SoftwareIdentity",
+ namespace="root/cimv2")
+ if pkg is not None:
+ objpath["ManagedElement"]["InstanceID"] = \
+ 'LMI:PKG:' + pkg.get_nevra(newer=newer, with_epoch="ALWAYS")
+ return objpath
+
+ def test_get_instance(self):
+ """
+ Tests GetInstance call on packages from our rpm cache.
+ """
+ for pkg in self.dangerous_pkgs:
+ objpath = self.make_op(pkg)
+ inst = self.conn.GetInstance(InstanceName=objpath)
+ self.assertEqual(objpath, inst.path,
+ "Object paths should match for package %s"%pkg)
+ for key in self.KEYS:
+ self.assertTrue(inst.properties.has_key(key),
+ 'OP is missing \"%s\" key for package "%s".' % (key, pkg))
+ self.assertEqual(inst[key], inst.path[key],
+ 'Key property "%s" does not match for package "%s"!' %
+ (key, pkg))
+
+ @base.mark_tedious
+ def test_get_resource_referents(self):
+ """
+ Test ReferenceNames for AvailableSAP.
+ """
+ for repo in self.repodb:
+ objpath = self.make_op(repo=repo)
+ if not repo.pkg_count or repo.pkg_count > 10000:
+ # do not test too big repositories
+ continue
+ refs = self.conn.AssociatorNames(
+ Role="AvailableSAP",
+ ObjectName=objpath["AvailableSAP"],
+ ResultRole="ManagedElement",
+ ResultClass="LMI_SoftwareIdentity")
+ # there may be empty repositories
+ #self.assertGreater(len(refs), 0)
+ for ref in refs:
+ self.assertIsInstance(ref, pywbem.CIMInstanceName)
+ self.assertEqual(ref.namespace, 'root/cimv2')
+ self.assertEqual(ref.classname, "LMI_SoftwareIdentity")
+ self.assertEqual(sorted(ref.keys()), ["InstanceID"])
+ self.assertTrue(ref["InstanceID"].startswith("LMI:PKG:"))
+
+ nevra_set = set(i["InstanceID"] for i in refs)
+ # NOTE: installed packages might not be available
+ for pkg, up in ((pkg, up) for pkg in self.dangerous_pkgs
+ for up in (True, False)):
+ nevra = 'LMI:PKG:'+pkg.get_nevra(
+ newer=up, with_epoch="ALWAYS")
+ reponame = getattr(pkg, 'up_repo' if up else 'repo')
+ if reponame == repo.repoid:
+ self.assertTrue(nevra in nevra_set,
+ 'Missing nevra "%s" for repo "%s".' % (nevra,
+ reponame))
+
+ @base.mark_tedious
+ def test_get_resource_referents_for_disabled_repo(self):
+ """
+ Test ReferenceNames for AvailableSAP, which is disabled.
+ """
+ for repo in self.repodb:
+ if repo.status:
+ continue # test only disabled repositories
+ objpath = self.make_op(repo=repo)
+ refs = self.conn.AssociatorNames(
+ Role="AvailableSAP",
+ ObjectName=objpath["AvailableSAP"],
+ ResultRole="ManagedElement",
+ ResultClass="LMI_SoftwareIdentity")
+ self.assertGreater(len(refs), 0)
+ for ref in refs:
+ self.assertIsInstance(ref, pywbem.CIMInstanceName)
+ self.assertEqual(ref.namespace, 'root/cimv2')
+ self.assertEqual(ref.classname, "LMI_SoftwareIdentity")
+ self.assertEqual(sorted(ref.keys()), ["InstanceID"])
+ self.assertTrue(ref["InstanceID"].startswith("LMI:PKG:"))
+
+ def test_get_managed_element_referents(self):
+ """
+ Test ReferenceNames for SoftwareIdentity.
+ """
+ for pkg, up in ((pkg, up) for pkg in self.dangerous_pkgs
+ for up in (True, False)):
+ objpath = self.make_op(pkg, newer=up)
+ refs = self.conn.AssociatorNames(
+ ObjectName=objpath["ManagedElement"],
+ Role="ManagedElement",
+ ResultRole="AvailableSAP",
+ ResultClass="LMI_SoftwareIdentityResource")
+ self.assertEqual(1, len(refs),
+ 'No repo found for pkg "%s".' % pkg.get_nevra(newer=up,
+ with_epoch="ALWAYS"))
+ ref = refs[0]
+ self.assertIsInstance(ref, pywbem.CIMInstanceName)
+ self.assertEqual(ref.namespace, 'root/cimv2')
+ self.assertEqual(ref.classname, "LMI_SoftwareIdentityResource")
+ self.assertEqual(sorted(ref.keys()),
+ sorted(["SystemCreationClassName", "SystemName",
+ "Name", "CreationClassName"]))
+ self.assertEqual(
+ getattr(pkg, 'up_repo' if up else 'repo'),
+ ref["Name"], 'Repository name does not match for pkg "%s"'%
+ pkg.get_nevra(newer=up, with_epoch="ALWAYS"))
+
+def suite():
+ """For unittest loaders."""
+ return unittest.TestLoader().loadTestsFromTestCase(
+ TestResourceForSoftwareIdentity)
+
+if __name__ == '__main__':
+ unittest.main()