def test_get_class_objects(stc):
    ctor = CScriptableCreator()
    stc_sys = CStcSystem.Instance()
    project = stc_sys.GetObject("Project")
    port = ctor.Create("Port", project)
    rx_port = ctor.Create("Port", project)
    stream_block = ctor.Create("StreamBlock", port)
    stream_block.AddObject(rx_port, RelationType("ExpectedRx"))
    tag_utils.add_tag_to_object(stream_block, "ttStreamBlock")
    proto_mix = ctor.Create("StmProtocolMix", project)
    template_config = ctor.Create("StmTemplateConfig", proto_mix)
    template_config.AddObject(port, RelationType("GeneratedObject"))
    tag_utils.add_tag_to_object(template_config, "ttTemplateConfig")
    em_device = ctor.Create("EmulatedDevice", project)
    bgp_router_config = ctor.Create("BgpRouterConfig", em_device)

    # No target object for class type
    target_objs = dm_utils.get_class_objects([], [], ["StreamBlock"])
    assert len(target_objs) == 0

    # Handle passed in is of class type
    target_objs = dm_utils.get_class_objects([stream_block.GetObjectHandle()], [], ["StreamBlock"])
    assert len(target_objs) == 1
    assert target_objs[0].IsTypeOf("StreamBlock")

    # Handle passed in has child of class type
    target_objs = dm_utils.get_class_objects([proto_mix.GetObjectHandle()], [], ["StreamBlock"])
    assert len(target_objs) == 1
    assert target_objs[0].IsTypeOf("StreamBlock")

    # ProtocolMix
    target_objs = dm_utils.get_class_objects([proto_mix.GetObjectHandle()], [], ["StreamBlock"])
    assert len(target_objs) == 1
    assert target_objs[0].IsTypeOf("StreamBlock")

    # TemplateConfig
    target_objs = dm_utils.get_class_objects([], ["ttTemplateConfig"], ["StreamBlock"])
    assert len(target_objs) == 1
    assert target_objs[0].IsTypeOf("StreamBlock")

    # Verify that only one streamblock is returned and there aren't duplicates
    target_objs = dm_utils.get_class_objects([proto_mix.GetObjectHandle()], ["ttTemplateConfig"], ["StreamBlock"])
    assert len(target_objs) == 1
    assert target_objs[0].IsTypeOf("StreamBlock")

    # Multiple class types
    target_objs = dm_utils.get_class_objects([], ["ttTemplateConfig"], ["StreamBlock", "Port"])
    assert len(target_objs) == 2
    for obj in target_objs:
        assert obj.IsTypeOf("StreamBlock") or obj.IsTypeOf("Port")

    # Handle passed in is of class type
    target_objs = dm_utils.get_class_objects([bgp_router_config.GetObjectHandle()], [], ["RouterConfig"])
    assert len(target_objs) == 1
    assert target_objs[0].IsTypeOf("BgpRouterConfig")
def get_valid_handles(handle_list, tag_name_list):
    hnd_reg = CHandleRegistry.Instance()
    l2_obj_list = []
    l3_obj_list = []
    l2_handle_list = []
    l3_handle_list = []

    # Add object handles from the tag list to the handle list
    if len(tag_name_list) > 0:
        for obj in tag_utils.get_tagged_objects_from_string_names(tag_name_list):
            handle_list.append(obj.GetObjectHandle())

    # The L2 learning command only allows handles of type Port and StreamBlock
    # The L3 learning command only allows handles of type Port, StreamBlock, Host,
    # Router, and EmulatedDevice
    for hnd in handle_list:
        obj = hnd_reg.Find(hnd)
        if obj.IsTypeOf("Port") or obj.IsTypeOf("StreamBlock") or obj.IsTypeOf("Project"):
            l2_obj_list.append(obj)
            l3_obj_list.append(obj)
        elif obj.IsTypeOf("EmulatedDevice") or obj.IsTypeOf("Host") or obj.IsTypeOf("Router"):
            l3_obj_list.append(obj)
        elif obj.IsTypeOf("StmTemplateMix") or obj.IsTypeOf("StmTemplateConfig"):
                l2_obj_list.extend(dm_utils.get_class_objects([hnd], [],
                                                              ["Port",
                                                               "StreamBlock",
                                                               "Project"]))
                l3_obj_list.extend(dm_utils.get_class_objects([hnd], [],
                                                              ["Port",
                                                               "StreamBlock",
                                                               "Project",
                                                               "EmulatedDevice",
                                                               "Host",
                                                               "Router"]))

    for obj in dm_utils.sort_obj_list_by_handle(l2_obj_list):
        l2_handle_list.append(obj.GetObjectHandle())
    for obj in dm_utils.sort_obj_list_by_handle(l3_obj_list):
        l3_handle_list.append(obj.GetObjectHandle())
    return l2_handle_list, l3_handle_list
def get_routers(TargetObjectList, TargetObjectTagList):
    plLogger = PLLogger.GetLogger("methodology")
    routers_dict = defaultdict(list)
    this_cmd = get_this_cmd()

    rtr_list = []
    rtr_list = dm_utils.get_class_objects(TargetObjectList, TargetObjectTagList, ["RouterConfig"])

    if len(rtr_list) == 0:
        err = "No routers found in TargetObjectList or TargetObjectTagList"
        plLogger.LogError(err)
        this_cmd.Set('Status', err)
        return {}

    # Build the output dictionary based on router type
    for rtr in rtr_list:
        # Use the CMeta to get the correct form of the class name
        meta_dict = CMeta.GetClassMeta(rtr)
        routers_dict[meta_dict["name"]].append(rtr)
    return routers_dict