def test_run_applied_value_static_only(stc):
    ctor = CScriptableCreator()
    stc_sys = CStcSystem.Instance()
    sequencer = stc_sys.GetObject("Sequencer")
    project = stc_sys.GetObject("Project")

    tags = project.GetObject("Tags")
    assert tags
    tag = ctor.Create("Tag", tags)
    tag.Set("Name", "UnitTestTag")

    # Create the StmTemplateMix
    mix_obj = ctor.Create("StmTemplateMix", project)

    # Create the StmTemplateConfigs
    tmpl1 = ctor.Create("StmTemplateConfig", mix_obj)
    tmpl2 = ctor.Create("StmTemplateConfig", mix_obj)
    tmpl3 = ctor.Create("StmTemplateConfig", mix_obj)
    assert tmpl1
    assert tmpl2
    assert tmpl3

    cmd = ctor.Create(PKG + ".AllocateRouteMixCountCommand", sequencer)

    gtc_p = patch(PKG + ".AllocateRouteMixCountCommand.get_this_cmd",
                  new=MagicMock(return_value=cmd))
    gtc_p.start()

    # Function signature
    # run(RouteMixList, RouteMixTagList, RouteCount)

    # Build the MixInfo
    comp_dict1 = {}
    comp_dict1["baseTemplateFile"] = "AllRouters.xml"
    comp_dict1["weight"] = "20"
    comp_dict2 = {}
    comp_dict2["baseTemplateFile"] = "AllRouters.xml"
    comp_dict2["weight"] = "50"
    comp_dict3 = {}
    comp_dict3["baseTemplateFile"] = "AllRouters.xml"
    comp_dict3["weight"] = "30"

    mix_info = {}
    mix_info["routeCount"] = 1
    mix_info["components"] = [comp_dict1, comp_dict2, comp_dict3]

    mix_obj.Set("MixInfo", json.dumps(mix_info))
    ret = AllocCmd.run([mix_obj.GetObjectHandle()], "", 1000)
    assert ret

    # Check the appliedValue
    mix_info = json.loads(mix_obj.Get("MixInfo"))
    comp_list = mix_info["components"]
    assert len(comp_list) == 3

    assert comp_list[0].get("appliedValue", 0) == 20
    assert comp_list[1].get("appliedValue", 0) == 50
    assert comp_list[2].get("appliedValue", 0) == 30

    gtc_p.stop()
def test_run_fail_validate_mix_object(stc):
    ctor = CScriptableCreator()
    stc_sys = CStcSystem.Instance()
    sequencer = stc_sys.GetObject("Sequencer")
    project = stc_sys.GetObject("Project")

    tags = project.GetObject("Tags")
    assert tags
    tag = ctor.Create("Tag", tags)
    tag.Set("Name", "UnitTestTag")

    cmd = ctor.Create(PKG + ".AllocateRouteMixCountCommand", sequencer)

    gtc_p = patch(PKG + ".AllocateRouteMixCountCommand.get_this_cmd",
                  new=MagicMock(return_value=cmd))
    gtc_p.start()

    # Function signature
    # run(RouteMixList, RouteMixTagList, RouteCount)

    # No mix objects specified
    ret = AllocCmd.run(None, "", 100)
    assert not ret
    assert "Neither RouteMixList nor RouteMixTagList specified a" \
        in cmd.Get("Status")

    # Invalid tag name (no Tag object)
    ret = AllocCmd.run(None, "InvalidTagName", 100)
    assert not ret
    assert "Neither RouteMixList nor RouteMixTagList specified a" \
        in cmd.Get("Status")

    # Empty tag (valid tag that doesn't tag anything)
    ret = AllocCmd.run(None, "UnitTestTag", 100)
    assert not ret
    assert "Neither RouteMixList nor RouteMixTagList specified a" \
        in cmd.Get("Status")

    gtc_p.stop()
def test_run_fail_validate_json_weights_and_counts(stc):
    ctor = CScriptableCreator()
    stc_sys = CStcSystem.Instance()
    sequencer = stc_sys.GetObject("Sequencer")
    project = stc_sys.GetObject("Project")

    tags = project.GetObject("Tags")
    assert tags
    tag = ctor.Create("Tag", tags)
    tag.Set("Name", "UnitTestTag")

    # Create the StmTemplateMix
    mix_obj = ctor.Create("StmTemplateMix", project)

    # Add the StmTemplateConfigs
    tmpl1 = ctor.Create("StmTemplateConfig", mix_obj)
    tmpl2 = ctor.Create("StmTemplateConfig", mix_obj)
    assert tmpl1
    assert tmpl2

    cmd = ctor.Create(PKG + ".AllocateRouteMixCountCommand", sequencer)

    gtc_p = patch(PKG + ".AllocateRouteMixCountCommand.get_this_cmd",
                  new=MagicMock(return_value=cmd))
    gtc_p.start()

    # Function signature
    # run(RouteMixList, RouteMixTagList, RouteCount)

    # Invalid RouteCount
    ret = AllocCmd.run([mix_obj.GetObjectHandle()], "", 0)
    assert not ret
    assert cmd.Get("Status") == "RouteCount must be at least 1."

    # Invalid number of components
    mix_info = {}
    mix_info["routeCuont"] = 1
    mix_info["components"] = []
    mix_obj.Set("MixInfo", json.dumps(mix_info))
    ret = AllocCmd.run([mix_obj.GetObjectHandle()], "", 100)
    assert not ret
    assert "but 0 components in the MixInfo.  These MUST match." \
        in cmd.Get("Status")

    # Invalid MixInfo JSON
    # mix_obj.Set("MixInfo", json.dumps({"invalid_json": "value"}))
    # ret = AllocCmd.run([mix_obj.GetObjectHandle()], "", 100)
    # assert not ret
    # assert cmd.Get("Status") == "Something...fill in when known")

    # Build the MixInfo
    comp_dict1 = {}
    comp_dict1["baseTemplateFile"] = "AllRouters.xml"
    comp_dict1["weight"] = "5"

    comp_dict2 = {}
    comp_dict2["baseTemplateFile"] = "AllRouters.xml"
    comp_dict2["weight"] = "5"

    mix_info = {}
    mix_info["routeCount"] = 100
    mix_info["components"] = [comp_dict1, comp_dict2]

    # Check error when total static count > total route count
    comp_dict1["weight"] = "500"
    comp_dict2["weight"] = "501"
    mix_obj.Set("MixInfo", json.dumps(mix_info))
    ret = AllocCmd.run([mix_obj.GetObjectHandle()], "", 1000)
    assert not ret
    assert "Sum total of the static counts (1001) exceeds the total" \
        in cmd.Get("Status")

    # Check error when total percent > 100%
    comp_dict1["weight"] = "50%"
    comp_dict2["weight"] = "51%"
    mix_obj.Set("MixInfo", json.dumps(mix_info))
    ret = AllocCmd.run([mix_obj.GetObjectHandle()], "", 1000)
    assert not ret
    assert "Sum total of the weights defined as percentages (101.0%) exceeds" \
        in cmd.Get("Status")

    # Check error when static count uses up all of the RouteCount
    # and there still are components that are defined by percent
    comp_dict1["weight"] = "23"
    comp_dict2["weight"] = "1%"
    mix_obj.Set("MixInfo", json.dumps(mix_info))
    ret = AllocCmd.run([mix_obj.GetObjectHandle()], "", 23)
    assert not ret
    assert "Not enough total RouteCount to distribute routes to all " \
        in cmd.Get("Status")
    assert "The required total static route count will use up all of the " \
        in cmd.Get("Status")

    # Check error when not enough routes for each component using
    # percent-based weighting to receive at least one route
    comp_dict1["weight"] = "50%"
    comp_dict1["weight"] = "50%"
    mix_obj.Set("MixInfo", json.dumps(mix_info))
    ret = AllocCmd.run([mix_obj.GetObjectHandle()], "", 1)
    assert not ret
    assert "Not enough total RouteCount to distribute routes to all " \
        in cmd.Get("Status")
    assert "there aren't enough routes left (1) such that each " + \
        "percent-based mix component will get at least one route." \
        in cmd.Get("Status")

    gtc_p.stop()