def test_parse_prop_val_data(stc):
    input_string = '''{
        "ParentTagName": "ttIpv4If",
        "ClassName": "Ipv4If",
        "PropertyValueDict": {
            "PrefixLength": ["22", "11"],
            "IfCountPerLowerIf": ["2", "1"]
        }
    }'''

    expected_prop_val1 = {}
    expected_prop_val1["className"] = "Ipv4If"
    expected_prop_val1["tagName"] = "ttIpv4If"
    expected_prop_val1["propertyValueList"] = {}
    expected_prop_val1["propertyValueList"]["PrefixLength"] = "22"
    expected_prop_val1["propertyValueList"]["IfCountPerLowerIf"] = "2"

    expected_prop_val2 = {}
    expected_prop_val2["className"] = "Ipv4If"
    expected_prop_val2["tagName"] = "ttIpv4If"
    expected_prop_val2["propertyValueList"] = {}
    expected_prop_val2["propertyValueList"]["PrefixLength"] = "11"
    expected_prop_val2["propertyValueList"]["IfCountPerLowerIf"] = "1"

    err_str, input_table_data = json_utils.load_json(input_string)
    assert err_str == ""
    # Call parse on the first row
    res1 = process_util.parse_prop_val_data(input_table_data, 0)
    # Call parse on the second row
    res2 = process_util.parse_prop_val_data(input_table_data, 1)

    assert len(res1["propertyValueList"]) == 1
    assert cmp(res1["propertyValueList"][0], expected_prop_val1) == 0
    assert cmp(res2["propertyValueList"][0], expected_prop_val2) == 0
def config_protocol_table_data(input_dict):
    plLogger = PLLogger.GetLogger('methodology')
    plLogger.LogDebug('begin.txml_processing_functions.config_protocol_table_data')

    output_dict = {}
    err_msg = ""
    json_data_list = {}

    plLogger.LogDebug('input_dict: ' + str(input_dict))

    # Validate the input_dict
    res = validate_input_dict(input_dict)
    if res != "":
        return output_dict, res

    devCnt = input_dict["input"]["customDict"]["DeviceCount"]
    json_data_list["deviceCount"] = int(devCnt)

    # Loop through each row in the txml table
    weight_list = make_list(input_dict["input"]["customDict"]["Weight"])

    component_list = []
    for row_idx, weight in enumerate(weight_list):
        comp_dict = {}
        comp_dict["weight"] = str(weight)
        if "TagPrefix" in input_dict["input"]["customDict"]:
            comp_dict["tagPrefix"] = input_dict["input"]["customDict"]["TagPrefix"]

        dev_per_block = make_list(input_dict["input"]["customDict"]["DevPerBlock"])[row_idx]
        comp_dict["devicesPerBlock"] = int(dev_per_block)

        enable_vlan = make_list(input_dict["input"]["customDict"]["EnableVlan"])[row_idx]
        ip_stack = "Dual"
        if "IpStack" in input_dict["input"]["customDict"]:
            ip_stack = make_list(input_dict["input"]["customDict"]["IpStack"])[row_idx]
        plLogger.LogInfo("using " + str(ip_stack) + " as the IP stack")
        if ast.literal_eval(enable_vlan):
            comp_dict["baseTemplateFile"] = str(ip_stack) + "_Vlan.xml"
        else:
            comp_dict["baseTemplateFile"] = str(ip_stack) + "_NoVlan.xml"

        enable_bfd = False
        bfd_protocol = {}
        modify_list = []
        mergeList = []
        propertyValueList = []
        stmPropertyModifierList = []

        # Loop through the interfaceDict in the input_dict and add to
        # stmPropertyModifierList & propertyValueList in output_dict
        for interface in input_dict["input"]["interfaceDict"]:

            # Don't add the VlanIf if EnableVlan is False
            if interface["ClassName"] == "VlanIf" and \
               ast.literal_eval(enable_vlan) is False:
                continue

            # Don't process IPv4 if we're using an IPv6 stack
            if interface["ClassName"] == "Ipv4If" and str(ip_stack) == "IPV6":
                continue

            # Don't process IPv6 if we're using an IPv4 stack
            if interface["ClassName"] == "Ipv6If" and str(ip_stack) == "IPV4":
                continue

            if "PropertyValueDict" in interface:
                prop_val_dict = process_util.parse_prop_val_data(interface, row_idx)
                propertyValueList.extend(prop_val_dict["propertyValueList"])

            if "StmPropertyModifierDict" in interface:
                prop_mod_dict = process_util.parse_prop_mod_data(interface, row_idx)
                stmPropertyModifierList.extend(prop_mod_dict["stmPropertyModifierList"])

        # Loop through the protocolDict in the input_dict and add to
        # mergeList in the output_dict
        for protocol in input_dict["input"]["protocolDict"]:
            protocol["MergeSourceTag"] = protocol["ParentTagName"]
            protocol["MergeSourceTemplateFile"] = "AllRouters.xml"
            protocol["MergeTargetTag"] = "ttEmulatedDevice"
            # Add the protocol to the protocolList if it is enabled
            if "EnableProperty" in protocol.keys():
                if ast.literal_eval(make_list(protocol["EnableProperty"])[row_idx]):
                    if "EnableBfd" in protocol["PropertyValueDict"].keys():
                        enable_bfd |= ast.literal_eval(
                            make_list(protocol["PropertyValueDict"]["EnableBfd"])[row_idx])
                        mergeList.append(process_util.parse_merge_list_data(protocol, row_idx))

            # BfdRouterConfig will be handled after all other protocols are parsed
            if protocol["ClassName"] == "BfdRouterConfig":
                bfd_protocol = protocol

        # Bfd is added to the protocolList if bfd is enabled in at least one protocol and
        # the BfdRouterConfig information is defined in input_dict
        if enable_bfd is True and len(bfd_protocol) != 0:
            mergeList.append(process_util.parse_merge_list_data(bfd_protocol, row_idx))

        modify_list.append({"mergeList": mergeList})
        modify_list.append({"propertyValueList": propertyValueList})
        modify_list.append({"stmPropertyModifierList": stmPropertyModifierList})
        comp_dict["modifyList"] = modify_list
        component_list.append(comp_dict)

    json_data_list["components"] = component_list

    # f = open('out.txt', 'w')
    # f.write(json.dumps(json_data_list))

    output_dict["TableData"] = json.dumps(json_data_list)
    plLogger.LogDebug('output_dict: ' + str(output_dict))
    plLogger.LogDebug('end.txml_processing_functions.config_table_data')
    return output_dict, err_msg