def test_get_valid_handles(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")
    em_device = ctor.Create("EmulatedDevice", project)
    em_device.AddObject(port, RelationType("AffiliationPort"))
    tag_utils.add_tag_to_object(em_device, "ttEmulatedDevice")
    proto_mix = ctor.Create("StmProtocolMix", project)
    template_config = ctor.Create("StmTemplateConfig", proto_mix)
    template_config.AddObject(stream_block, RelationType("GeneratedObject"))
    tag_utils.add_tag_to_object(template_config, "ttTemplateConfig")

    bgp_config = ctor.Create("BgpRouterConfig", em_device)
    tag_utils.add_tag_to_object(bgp_config, "ttBgpRouterConfig")

    # Empty handle list
    handle_list = []
    l2_handles, l3_handles = learningCmd.get_valid_handles(handle_list, [])
    assert l2_handles == []
    assert l3_handles == []

    # Port valid for L2 and L3
    handle_list = [port.GetObjectHandle()]
    l2_handles, l3_handles = learningCmd.get_valid_handles(handle_list, [])
    assert l2_handles == handle_list
    assert l3_handles == handle_list

    # EmulatedDevice valid for L3 only
    handle_list = [em_device.GetObjectHandle()]
    l2_handles, l3_handles = learningCmd.get_valid_handles(handle_list, [])
    assert l2_handles == []
    assert l3_handles == handle_list

    # BgpRouterConfig not valid for L2 or L3
    handle_list = [bgp_config.GetObjectHandle()]
    l2_handles, l3_handles = learningCmd.get_valid_handles(handle_list, [])
    assert l2_handles == []
    assert l3_handles == []

    # Valid L2L3 tagged object
    tag_name_list = ['ttStreamBlock']
    l2_handles, l3_handles = learningCmd.get_valid_handles([], tag_name_list)
    assert l2_handles == [stream_block.GetObjectHandle()]
    assert l3_handles == [stream_block.GetObjectHandle()]

    # Valid L2L3 tagged object and empty tag
    tag_name_list = ['ttStreamBlock', 'ttBlah']
    l2_handles, l3_handles = learningCmd.get_valid_handles([], tag_name_list)
    assert l2_handles == [stream_block.GetObjectHandle()]
    assert l3_handles == [stream_block.GetObjectHandle()]

    # Valid L3 tagged object
    tag_name_list = ['ttEmulatedDevice']
    l2_handles, l3_handles = learningCmd.get_valid_handles([], tag_name_list)
    assert l2_handles == []
    assert l3_handles == [em_device.GetObjectHandle()]

    # Valid L3 tagged object and valid L2L3 tagged object
    tag_name_list = ['ttStreamBlock', 'ttEmulatedDevice']
    l2_handles, l3_handles = learningCmd.get_valid_handles([], tag_name_list)
    assert l2_handles == [stream_block.GetObjectHandle()]
    assert l3_handles == [stream_block.GetObjectHandle(), em_device.GetObjectHandle()]

    # Shouldn't ever happen because of validate_handle_types being called
    # but testing anyway
    tag_name_list = ['ttBgpRouterConfig']
    l2_handles, l3_handles = learningCmd.get_valid_handles([], tag_name_list)
    assert l2_handles == []
    assert l3_handles == []

    # Valid template config tagged object
    tag_name_list = ['ttTemplateConfig']
    l2_handles, l3_handles = learningCmd.get_valid_handles([], tag_name_list)
    assert len(l2_handles) == 1
    assert l2_handles == [stream_block.GetObjectHandle()]
    assert len(l3_handles) == 1
    assert l3_handles == [stream_block.GetObjectHandle()]

    # Valid protocolmix object
    tag_name_list = ['ttTemplateConfig']
    l2_handles, l3_handles = learningCmd.get_valid_handles([proto_mix.GetObjectHandle()], [])
    assert len(l2_handles) == 1
    assert l2_handles == [stream_block.GetObjectHandle()]
    assert len(l3_handles) == 1
    assert l3_handles == [stream_block.GetObjectHandle()]

    return