def test_validate_obj_prop_val():
    # Positive
    res = dm_utils.validate_obj_prop_val("EmulatedDevice", "DeviceCount", "100")
    assert res == ""
    # Invalid Object
    res = dm_utils.validate_obj_prop_val("InvalidObject", "DeviceCount", "100")
    assert "Object with name: InvalidObject does not exist" in res
    # Invalid Property
    res = dm_utils.validate_obj_prop_val("EmulatedDevice", "InvalidProperty", "100")
    assert "Property: InvalidProperty does not exist" in res
    # Invalid Value
    res = dm_utils.validate_obj_prop_val("EmulatedDevice", "DeviceCount", "InvalidValue")
    assert "Invalid value: InvalidValue specified" in res
def run(
    StmTemplateConfig,
    TagName,
    TargetObjectTagName,
    ObjectName,
    PropertyName,
    ModifierType,
    StartList,
    StepList,
    RepeatList,
    RecycleList,
    TargetObjectStepList,
    ResetOnNewTargetObject,
):
    plLogger = PLLogger.GetLogger("methodology")
    plLogger.LogDebug("ConfigTemplateStmPropertyModifierCommand.start")
    hnd_reg = CHandleRegistry.Instance()
    ctor = CScriptableCreator()
    this_cmd = get_this_cmd()

    template = hnd_reg.Find(StmTemplateConfig)
    if template is None:
        err_str = "Invalid or missing StmTemplateConfig"
        plLogger.LogError(err_str)
        this_cmd.Set("Status", err_str)
        return False
    if not template.IsTypeOf("StmTemplateConfig"):
        err_str = "Input StmTemplateConfig is not an StmTemplateConfig"
        plLogger.LogError(err_str)
        this_cmd.Set("Status", err_str)
        return False

    # Check the ModifierType
    if ModifierType != "RANGE":
        err_str = "Unspported ModifierType: " + ModifierType
        this_cmd.Set("Status", err_str)
        return False

    # Validate the ObjectName and PropertyName
    # Note that neither are required if an existing modifier can
    # be modified.  However, both are required if a new modifier
    # is being added.
    err_str, obj_name, prop_name = check_obj_and_prop_names(ObjectName, PropertyName)

    plLogger.LogDebug("checked ObjectName: " + str(obj_name))
    plLogger.LogDebug("checked PropertyName: " + str(prop_name))

    # Find the Tag with TagName in the StmTemplateConfig
    mod_ele_list = []
    if TagName != "":
        root = etree.fromstring(template.Get("TemplateXml"))
        tagged_ele_list = xml_utils.find_tagged_elements_by_tag_name(root, [TagName], ignore_tags_element=True)

        if len(tagged_ele_list):
            err_str, res_list = find_matching_modifiers(tagged_ele_list, obj_name, prop_name)
            if err_str != "":
                this_cmd.Set("Status", err_str)
                return False
            if len(res_list):
                mod_ele_list = res_list

    # If an existing StmPropertyModifier is being modified,
    # nothing is required.  Whatever exists will be updated; whatever
    # doesn't exist will be added.
    # If there is no existing StmPropertyModifier, PropertyName,
    # ObjectName, start, and step are required.
    start_list = []
    step_list = []
    repeat_list = []
    recycle_list = []
    target_step_list = []
    if len(mod_ele_list) == 0:
        plLogger.LogInfo("Add a new StmPropertyModifier on " + ObjectName + "'s " + PropertyName + ".")
        if obj_name == "":
            err_str = "ObjectName is required to add a new " + "StmPropertyModifier with tag name " + TagName + "."
            this_cmd.Set("Status", err_str)
            return False
        if prop_name == "":
            err_str = (
                "PropertyName is required to add a new "
                + "StmPropertyModifier on "
                + ObjectName
                + " with tag name "
                + TagName
                + "."
            )
            this_cmd.Set("Status", err_str)

        # StartList
        if StartList is None or StartList == "" or StartList == []:
            err_str = (
                "StartList is required to add a new "
                + "StmPropertyModifier on "
                + ObjectName
                + " property "
                + PropertyName
                + " with tag name "
                + TagName
                + "."
            )
            this_cmd.Set("Status", err_str)
        else:
            # Check start_list values for validity
            for value in StartList:
                res = dm_utils.validate_obj_prop_val(obj_name, prop_name, value)
                if res != "":
                    this_cmd.Set("Status", res)
                    return False
            start_list = StartList

        # StepList
        if StepList is None or StepList == "" or StepList == []:
            err_str = (
                "StepList is required to add a new "
                + "StmPropertyModifier on "
                + ObjectName
                + " property "
                + PropertyName
                + " with tag name "
                + TagName
                + "."
            )
            this_cmd.Set("Status", err_str)
        else:
            # Check step_list values for validity
            for value in step_list:
                res = dm_utils.validate_obj_prop_val(obj_name, prop_name, value)
                if res != "":
                    this_cmd.Set("Status", res)
                    return False
            step_list = StepList

        # RepeatList
        if RepeatList is None or RepeatList == "" or RepeatList == []:
            repeat_list = None
        else:
            repeat_list = RepeatList

        # RecycleList
        if RecycleList is None or RecycleList == "" or RecycleList == []:
            recycle_list = None
        else:
            recycle_list = RecycleList

        # TargetObjectStepList
        if TargetObjectStepList is None or TargetObjectStepList == "" or TargetObjectStepList == []:
            target_step_list = None
        else:
            # Check target_step_list values for validity
            for value in target_step_list:
                res = dm_utils.validate_obj_prop_val(obj_name, prop_name, value)
                if res != "":
                    this_cmd.Set("Status", res)
                    return False
            target_step_list = TargetObjectStepList

        # Build the new modifier info
        mod_info = gen_range_modifier_json(
            obj_name,
            prop_name,
            start_list,
            step_list,
            repeat=repeat_list,
            recycle=recycle_list,
            target_step=target_step_list,
            reset=ResetOnNewTargetObject,
        )

        # Create a new StmPropertyModifier under the elements tagged by
        # TargetObjectTagName
        # Call AddTemplateObjectCommand
        add_cmd = ctor.CreateCommand(PKG + ".AddTemplateObjectCommand")
        add_cmd.Set("StmTemplateConfig", template.GetObjectHandle())
        add_cmd.Set("ParentTagName", TargetObjectTagName)
        add_cmd.Set("TagName", TagName)
        add_cmd.Set("ClassName", "StmPropertyModifier")
        add_cmd.SetCollection("PropertyList", ["ModifierInfo", "TagName"])
        add_cmd.SetCollection("ValueList", [mod_info, TargetObjectTagName])
        add_cmd.Execute()
        add_cmd.MarkDelete()
    else:
        # Get the ObjectName/PropertyName from the existing info
        for mod_ele in mod_ele_list:
            mod_info = mod_ele.get("ModifierInfo")
            err_str, mod_dict = json_utils.load_json(mod_info)
            if err_str != "":
                t_err_str = (
                    "Failed to read ModifierInfo out of the " + "StmTemplateModifier that is being modified: " + err_str
                )
                this_cmd.Set("Status", t_err_str)
                return False

            plLogger.LogDebug("ModifierInfo json: " + json.dumps(mod_dict))
            if prop_name == "":
                prop_name = mod_dict["propertyName"]
            if obj_name == "":
                obj_name = mod_dict["objectName"]
            plLogger.LogInfo(
                "Found an StmPropertyModifier tagged with "
                + TagName
                + " that is modifying "
                + str(obj_name)
                + "'s "
                + str(prop_name)
                + " to modify."
            )
            pv_dict = mod_dict["propertyValueDict"]

            # StartList
            if StartList is not None and StartList != "" and StartList != []:
                start_list = StartList
                for value in start_list:
                    res = dm_utils.validate_obj_prop_val(obj_name, prop_name, value)
                    if res != "":
                        this_cmd.Set("Status", res)
                        return False
                pv_dict["start"] = start_list

            # StepList
            if StepList is not None and StepList != "" and StepList != []:
                step_list = StepList
                for value in step_list:
                    res = dm_utils.validate_obj_prop_val(obj_name, prop_name, value)
                    if res != "":
                        this_cmd.Set("Status", res)
                        return False
                pv_dict["step"] = step_list

            # RepeatList
            if RepeatList is not None and RepeatList != "" and RepeatList != []:
                pv_dict["repeat"] = RepeatList

            # RecycleList
            if RecycleList is not None and RecycleList != "" and RecycleList != []:
                pv_dict["recycle"] = RecycleList

            # TargetObjectStepList
            if TargetObjectStepList is not None and TargetObjectStepList != "" and TargetObjectStepList != []:
                target_step_list = TargetObjectStepList
                for value in target_step_list:
                    res = dm_utils.validate_obj_prop_val(obj_name, prop_name, value)
                    if res != "":
                        this_cmd.Set("Status", res)
                        return False
                pv_dict["targetObjectStepList"] = target_step_list

            # Call ModifyTemplatePropertyCommand
            plLogger.LogInfo("call the modify template property command")
            mod_cmd = ctor.CreateCommand(PKG + ".ModifyTemplatePropertyCommand")
            mod_cmd.Set("StmTemplateConfig", template.GetObjectHandle())
            mod_cmd.SetCollection("TagNameList", [TagName])
            mod_cmd.SetCollection("PropertyList", ["StmPropertyModifier.ModifierInfo"])
            mod_cmd.SetCollection("ValueList", [json.dumps(mod_dict)])
            mod_cmd.Execute()
            mod_cmd.MarkDelete()

    plLogger.LogDebug("ConfigTemplateStmPropertyModifierCommand.end")
    return True