def make_instances(cls, number, value_profile): """ Construct and return a number of CIMInstance objects with path, with random values for the instance properties. """ insts = [] for _ in range(0, number): inst = CIMInstance(cls.classname) # TODO: Make namespace flexible inst.path = CIMInstanceName(cls.classname, namespace='root/cimv2') for pname, cls_prop in cls.properties.items(): ptype = cls_prop.type _, pvalue = random_type_value(value_profile, type=ptype) inst_prop = CIMProperty(pname, type=ptype, value=pvalue) inst.properties[pname] = inst_prop if cls_prop.qualifiers.get('Key', False): inst.path.keybindings[pname] = pvalue insts.append(inst) return insts
def inst_from_class(klass, namespace=None, property_values=None, include_null_properties=True, include_path=True, strict=False, include_class_origin=False): """ Build a new CIMInstance from the input CIMClass using the property_values dictionary to complete properties and the other parameters to filter properties, validate the properties, and optionally set the path component of the CIMInstance. If any of the properties in the class have default values, those values are passed to the instance unless overridden by the property_values dictionary. No CIMProperty qualifiers are included in the created instance and the `class_origin` attribute is transfered from the class only if the `include_class_origin` parameter is True Parameters: klass (:class:`pywbem:CIMClass`) CIMClass from which the instance will be constructed. This class must include qualifiers and should include properties from any superclasses to be sure it includes all properties that are to be built into the instance. Properties may be excluded from the instance by not including them in the `klass` parameter. namespace (:term:`string`): Namespace in the WBEMConnection used to retrieve the class or `None` if the default_namespace is to be used. property_values (dictionary): Dictionary containing name/value pairs where the names are the names of properties in the class and the properties are the property values to be set into the instance. If a property is in the property_values dictionary but not in the class an ValueError exception is raised. include_null_properties (:class:`py:bool`): Determines if properties with Null values are included in the instance. If `True` they are included in the instance returned. If `False` they are not included in the instance returned inclued_class_origin (:class:`py:bool`): Determines if ClassOrigin information is included in the returned instance. If None or False, class origin information is not included. If True, class origin information is included. include_path (:class:`py:bool`:): If `True` the CIMInstanceName path is build and inserted into the new instance. If `strict` all key properties must be in the instance. strict (:class:`py:bool`:): If `True` and `include_path` is set, all key properties must be in the instance so that If not `True` The path component is created even if not all key properties are in the created instance. Returns: Returns an instance with the defined properties and optionally the path set. No qualifiers are included in the returned instance and the existence of ClassOrigin depends on the `include_class_origin` parameter. The value of each property is either the value from the `property_values` dictionary, the default_value from the class or Null(unless `include_null_properties` is False). All other attributes of each property are the same as the corresponding class property. Raises: ValueError if there are conflicts between the class and property_values dictionary or strict is set and the class is not complete. """ class_name = klass.classname inst = CIMInstance(class_name) for p in property_values: if p not in klass.properties: raise ValueError('Property Name %s in property_values but ' 'not in class %s' % (p, class_name)) for cp in klass.properties: ip = klass.properties[cp].copy() ip.qualifiers = NocaseDict() if not include_class_origin: ip.class_origin = None if ip.name in property_values: ip.value = property_values[ip.name] if include_null_properties: inst[ip.name] = ip else: if ip.value: inst[ip.name] = ip if include_path: inst.path = CIMInstanceName.from_instance(klass, inst, namespace, strict=strict) return inst
def test_objectstore(testcase, init_args, cls_kwargs, inst_kwargs, qual_kwargs): # pylint: disable=unused-argument """ Simple test inserts one inst of defined type and tests retrievail methods. """ namespace = "root/cimv2" # Setup the ObjectStore xxx_repo = InMemoryObjectStore(*init_args) if cls_kwargs: cls = CIMClass(**cls_kwargs) if inst_kwargs: inst = CIMInstance(**inst_kwargs) inst.path = CIMInstanceName.from_instance( cls, inst, namespace=namespace, host='me', strict=True) if qual_kwargs: qual = CIMQualifierDeclaration(**qual_kwargs) # Is this instance or class test if inst_kwargs: name = inst.path obj = inst elif qual_kwargs: name = qual.name obj = qual else: name = cls.classname obj = cls # The code to be tested. The test include adding , getting, and deleting # with the various inspection methods and testing for # correct returns # Create the object in the object store xxx_repo.create(name, obj) # confirm that exists works assert xxx_repo.object_exists(name) # Test repository object count; len() assert xxx_repo.len() == 1 # Test get the object and test for same object rtn_obj = xxx_repo.get(name) # Test that the properties have changed indicating the deepcopy # Uses only class and instance because we they have properties if isinstance(obj, (CIMClass, CIMInstance)): for prop in obj.properties: assert rtn_obj.properties[prop] is not \ obj.properties[prop] # Test same object return on two gets rtn_obj2 = xxx_repo.get(name) assert rtn_obj2 == rtn_obj # Test that return with copy gets same object. rtn_obj3 = xxx_repo.get(name, copy=True) assert rtn_obj3 == obj # Test that with copy=True the property ids have changed between the # two gets indicating that the deepcopy was executed. if isinstance(obj, (CIMClass, CIMInstance)): for prop in obj.properties: assert rtn_obj.properties[prop] is not \ rtn_obj3.properties[prop] names = list(xxx_repo.iter_names()) assert len(names) == 1 assert names[0] == name objs = list(xxx_repo.iter_values()) assert len(objs) == 1 assert objs[0] == obj objs = list(xxx_repo.iter_values(copy=True)) assert len(objs) == 1 assert objs[0] == obj if isinstance(obj, (CIMClass, CIMInstance)): for prop in obj.properties: assert objs[0].properties[prop] is not \ obj.properties[prop] # Test update # Test update; should work. Note that this test does not modify the # object before creating the copy. obj2 = obj.copy() xxx_repo.update(name, obj2) assert xxx_repo.get(name) == obj2 # Test valid delete of object xxx_repo.delete(name) assert not xxx_repo.object_exists(name) assert xxx_repo.len() == 0 # Test errors # Test update with unknown object; should fail try: xxx_repo.update(name, obj) except KeyError: pass # Test delete nonexistent entity; should fail try: xxx_repo.delete(name) assert False except KeyError: pass # Test get non existent entity; should fail try: xxx_repo.get(name) assert False except KeyError: pass # Test exists; entity should not exist assert not xxx_repo.object_exists(name) # Test create with existing object xxx_repo.create(name, obj) # Test duplicate create; should fail try: xxx_repo.create(name, obj) assert False except ValueError: pass
def test_objectstore(testcase, init_args, cls_kwargs, inst_kwargs, qual_kwargs): # pylint: disable=unused-argument """ Simple test inserts one inst of defined type and tests retrievail methods. """ namespace = "root/cimv2" # Setup the ObjectStore xxx_repo = InMemoryObjectStore(*init_args) if cls_kwargs: cls = CIMClass(**cls_kwargs) if inst_kwargs: inst = CIMInstance(**inst_kwargs) inst.path = CIMInstanceName.from_instance( cls, inst, namespace=namespace, host='me', strict=True) if qual_kwargs: qual = CIMQualifierDeclaration(**qual_kwargs) # is this instance or class test if inst_kwargs: name = inst.path obj = inst elif qual_kwargs: name = qual.name obj = qual else: name = cls.classname obj = cls # The code to be tested. The test include adding and testing the # various inspection methods for correct returns # Create the object in the object store xxx_repo.create(name, obj) # confirm that exists works assert xxx_repo.exists(name) # Test len() assert xxx_repo.len() == 1 # Test get the object and test for same object rtn_obj = xxx_repo.get(name) assert rtn_obj == obj names = [n for n in xxx_repo.iter_names()] assert len(names) == 1 assert names[0] == name objs = [x for x in xxx_repo.iter_values()] assert len(objs) == 1 assert objs[0] == obj # Test update # Test update; should work obj2 = obj.copy() xxx_repo.update(name, obj2) assert xxx_repo.get(name) == obj2 # Test valid delete of object xxx_repo.delete(name) assert not xxx_repo.exists(name) assert xxx_repo.len() == 0 # Test errors # Test update with unknown object; should fail try: xxx_repo.update(name, obj) except KeyError: pass # Test delete nonexistent entity; should fail try: xxx_repo.delete(name) assert False except KeyError: pass # Test get non existent entity; should fail try: xxx_repo.get(name) assert False except KeyError: pass # Test exists; entity should not exist assert not xxx_repo.exists(name) # Test create with existing object xxx_repo.create(name, obj) # Test duplicate create; should fail try: xxx_repo.create(name, obj) assert False except ValueError: pass