示例#1
0
def test(q, bus, conn):
    cm = bus.get_object(cs.CM + '.ring',
        tp_path_prefix + '/ConnectionManager/ring')
    cm_iface = dbus.Interface(cm, cs.CM)
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['tel']), set(protocols.keys()))

    protocol_names = unwrap(cm_iface.ListProtocols())
    assertEquals(set(['tel']), set(protocol_names))

    cm_params = cm_iface.GetParameters('tel')
    local_props = protocols['tel']
    local_params = local_props[cs.PROTOCOL + '.Parameters']
    assertEquals(cm_params, local_params)

    proto = bus.get_object(cm.bus_name, cm.object_path + '/tel')
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in ['Parameters', 'Interfaces', 'ConnectionInterfaces',
      'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon']:
        a = local_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('tel', proto_props['VCardField'])
    assertEquals('Mobile Telephony', proto_props['EnglishName'])
    assertEquals('im-tel', proto_props['Icon'])

    assertContains(cs.CONN_IFACE_REQUESTS, proto_props['ConnectionInterfaces'])
def test(q, bus, conn, stream):
    event = q.expect('stream-iq', to=None, query_ns=ns.ROSTER,
            query_name='query')

    result = make_result_iq(stream, event.stanza)
    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'

    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'

    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'
    stream.send(result)

    stream.send(make_presence('*****@*****.**', 'SHA1SUM-FOR-AMY'))
    stream.send(make_presence('*****@*****.**', 'SHA1SUM-FOR-BOB'))
    stream.send(make_presence('*****@*****.**', None))

    q.expect('dbus-signal', signal='AvatarUpdated')
    handles = conn.RequestHandles(1, [
        '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**' ])

    tokens = unwrap(conn.Avatars.GetAvatarTokens(handles))
    assert tokens == ['SHA1SUM-FOR-AMY', 'SHA1SUM-FOR-BOB', '', '']

    tokens = unwrap(conn.Avatars.GetKnownAvatarTokens(handles))
    tokens = sorted(tokens.items())
    assert tokens == [(2, 'SHA1SUM-FOR-AMY'), (3, 'SHA1SUM-FOR-BOB'), (4, u'')]
示例#3
0
def test(q, bus, conn):
    cm = bus.get_object(cs.CM + '.ring',
                        tp_path_prefix + '/ConnectionManager/ring')
    cm_iface = dbus.Interface(cm, cs.CM)
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['tel']), set(protocols.keys()))

    protocol_names = unwrap(cm_iface.ListProtocols())
    assertEquals(set(['tel']), set(protocol_names))

    cm_params = cm_iface.GetParameters('tel')
    local_props = protocols['tel']
    local_params = local_props[cs.PROTOCOL + '.Parameters']
    assertEquals(cm_params, local_params)

    proto = bus.get_object(cm.bus_name, cm.object_path + '/tel')
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in [
            'Parameters', 'Interfaces', 'ConnectionInterfaces',
            'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon'
    ]:
        a = local_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('tel', proto_props['VCardField'])
    assertEquals('Mobile Telephony', proto_props['EnglishName'])
    assertEquals('im-tel', proto_props['Icon'])

    assertContains(cs.CONN_IFACE_REQUESTS, proto_props['ConnectionInterfaces'])
def check_tube_in_tubes(tube, tubes):
    """
    Check that 'tube' is in 'tubes', which should be the return value of
    ListTubes(). tube[0] may be None to check that a new-style tube is
    represented on the old interface (because you don't know what its id is in
    those cases)
    """

    utube = unwrap(tube)

    if tube[0] is None:
        for t in tubes:
            if tube[1:] == t[1:]:
                return
    else:
        for t in tubes:
            if tube[0] != t[0]:
                continue

            pair = "\n    %s,\n    %s" % (utube, unwrap(t))

            assert tube[1] == t[1], "self handles don't match: %s" % pair
            assert tube[2] == t[2], "tube types don't match: %s" % pair
            assert tube[3] == t[3], "services don't match: %s " % pair
            assert tube[4] == t[4], "parameters don't match: %s" % pair
            assert tube[5] == t[5], "states don't match: %s" % pair

            return

    assert False, "tube %s not in %s" % (unwrap (tube), unwrap (tubes))
def check_tube_in_tubes(tube, tubes):
    """
    Check that 'tube' is in 'tubes', which should be the return value of
    ListTubes(). tube[0] may be None to check that a new-style tube is
    represented on the old interface (because you don't know what its id is in
    those cases)
    """

    utube = unwrap(tube)

    if tube[0] is None:
        for t in tubes:
            if tube[1:] == t[1:]:
                return
    else:
        for t in tubes:
            if tube[0] != t[0]:
                continue

            pair = "\n    %s,\n    %s" % (utube, unwrap(t))

            assert tube[1] == t[1], "self handles don't match: %s" % pair
            assert tube[2] == t[2], "tube types don't match: %s" % pair
            assert tube[3] == t[3], "services don't match: %s " % pair
            assert tube[4] == t[4], "parameters don't match: %s" % pair
            assert tube[5] == t[5], "states don't match: %s" % pair

            return

    assert False, "tube %s not in %s" % (unwrap (tube), unwrap (tubes))
示例#6
0
def test(q, bus, conn, server):
    cm = bus.get_object(cs.CM + '.idle',
                        tp_path_prefix + '/ConnectionManager/idle')
    cm_iface = dbus.Interface(cm, cs.CM)
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['irc']), set(protocols.keys()))

    protocol_names = unwrap(cm_iface.ListProtocols())
    assertEquals(set(['irc']), set(protocol_names))

    cm_params = cm_iface.GetParameters('irc')
    local_props = protocols['irc']
    local_params = local_props[cs.PROTOCOL + '.Parameters']
    assertEquals(cm_params, local_params)

    proto = bus.get_object(cm.bus_name, cm.object_path + '/irc')
    proto_iface = dbus.Interface(proto, cs.PROTOCOL)
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in [
            'Parameters', 'Interfaces', 'ConnectionInterfaces',
            'RequestableChannelClasses', 'VCardField', 'EnglishName', 'Icon'
    ]:
        a = local_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('x-irc', proto_props['VCardField'])
    assertEquals('IRC', proto_props['EnglishName'])
    assertEquals('im-irc', proto_props['Icon'])

    assertContains(cs.CONN_IFACE_ALIASING, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_REQUESTS, proto_props['ConnectionInterfaces'])

    assertEquals('robot101', unwrap(proto_iface.NormalizeContact('Robot101')))

    call_async(q, proto_iface, 'IdentifyAccount', {'account': 'Robot101'})
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)

    test_params = {'account': 'Robot101', 'server': 'irc.oftc.net'}
    acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
    assertEquals('*****@*****.**', acc_name)

    # Test validating 'username'
    test_params = {
        'account': 'Robot101',
        'server': 'irc.oftc.net',
        'username': '******',
    }
    call_async(q, proto_iface, 'IdentifyAccount', test_params)
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)
def test(q, bus, conn, server):
    cm = bus.get_object(cs.CM + '.idle',
        tp_path_prefix + '/ConnectionManager/idle')
    cm_iface = dbus.Interface(cm, cs.CM)
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['irc']), set(protocols.keys()))

    protocol_names = unwrap(cm_iface.ListProtocols())
    assertEquals(set(['irc']), set(protocol_names))

    cm_params = cm_iface.GetParameters('irc')
    local_props = protocols['irc']
    local_params = local_props[cs.PROTOCOL + '.Parameters']
    assertEquals(cm_params, local_params)

    proto = bus.get_object(cm.bus_name, cm.object_path + '/irc')
    proto_iface = dbus.Interface(proto, cs.PROTOCOL)
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in ['Parameters', 'Interfaces', 'ConnectionInterfaces',
      'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon']:
        a = local_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('x-irc', proto_props['VCardField'])
    assertEquals('IRC', proto_props['EnglishName'])
    assertEquals('im-irc', proto_props['Icon'])

    assertContains(cs.CONN_IFACE_ALIASING, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_REQUESTS, proto_props['ConnectionInterfaces'])

    assertEquals('robot101', unwrap(proto_iface.NormalizeContact('Robot101')))

    call_async(q, proto_iface, 'IdentifyAccount', {'account': 'Robot101'})
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)

    test_params = {'account': 'Robot101', 'server': 'irc.oftc.net' }
    acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
    assertEquals('*****@*****.**', acc_name)

    # Test validating 'username'
    test_params = {
        'account': 'Robot101',
        'server': 'irc.oftc.net',
        'username': '******',
    }
    call_async(q, proto_iface, 'IdentifyAccount', test_params)
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)
示例#8
0
 def signal_receiver(*args, **kw):
     queue.append(
         Event('dbus-signal',
               path=unwrap(kw['path']),
               signal=kw['member'],
               args=map(unwrap, args),
               interface=kw['interface']))
def test(q, bus, conn, stream):
    event = q.expect('stream-iq', to=None, query_ns=ns.ROSTER,
            query_name='query')

    result = make_result_iq(stream, event.stanza)
    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'

    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'

    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'
    stream.send(result)

    stream.send(make_presence('*****@*****.**', 'SHA1SUM-FOR-AMY'))
    stream.send(make_presence('*****@*****.**', 'SHA1SUM-FOR-BOB'))
    stream.send(make_presence('*****@*****.**', None))

    q.expect('dbus-signal', signal='AvatarUpdated')
    handles = conn.get_contact_handles_sync([
        '*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**' ])

    h2asv = conn.Contacts.GetContactAttributes(handles, [cs.CONN_IFACE_AVATARS], False)
    assertEquals('SHA1SUM-FOR-AMY', h2asv[handles[0]][cs.ATTR_AVATAR_TOKEN])
    assertEquals('SHA1SUM-FOR-BOB', h2asv[handles[1]][cs.ATTR_AVATAR_TOKEN])
    assertEquals('', h2asv[handles[2]][cs.ATTR_AVATAR_TOKEN])
    assertEquals(None, h2asv[handles[3]].get(cs.ATTR_AVATAR_TOKEN))

    tokens = unwrap(conn.Avatars.GetKnownAvatarTokens(handles))
    tokens = sorted(tokens.items())
    assert tokens == [(2, 'SHA1SUM-FOR-AMY'), (3, 'SHA1SUM-FOR-BOB'), (4, u'')]
示例#10
0
 def signal_receiver(*args, **kw):
     if kw['path'] == '/org/freedesktop/DBus' and \
             kw['member'] == 'NameOwnerChanged':
         bus_name, old_name, new_name = args
         if new_name == '':
             for i, conn in enumerate(conns):
                 stream = streams[i]
                 jid = jids[i]
                 if conn._requested_bus_name == bus_name:
                     factory.lost_presence(stream, jid)
                     break
     queue.append(
         Event('dbus-signal',
               path=unwrap(kw['path']),
               signal=kw['member'],
               args=[unwrap(arg) for arg in args],
               interface=kw['interface']))
示例#11
0
def exec_test_deferred (funs, params, protocol=None, timeout=None):
    colourer = None

    if sys.stdout.isatty():
        colourer = install_colourer()

    queue = servicetest.IteratingEventQueue(timeout)
    queue.verbose = (
        os.environ.get('CHECK_TWISTED_VERBOSE', '') != ''
        or '-v' in sys.argv)

    bus = dbus.SessionBus()

    sim = Simulator()

    bus.add_signal_receiver(
        lambda *args, **kw:
            queue.append(
                Event('dbus-signal',
                    path=unwrap(kw['path']),
                    signal=kw['member'], args=map(unwrap, args),
                    interface=kw['interface'])),
        None,       # signal name
        None,       # interface
        None,
        path_keyword='path',
        member_keyword='member',
        interface_keyword='interface',
        byte_arrays=True
        )

    try:
        for f in funs:
            conn = make_connection(bus, queue.append, params)
            f(queue, bus, conn)
    except Exception:
        import traceback
        traceback.print_exc()

    try:
        if colourer:
          sys.stdout = colourer.fh
        reactor.crash()

        # force Disconnect in case the test crashed and didn't disconnect
        # properly.  We need to call this async because the BaseIRCServer
        # class must do something in response to the Disconnect call and if we
        # call it synchronously, we're blocking ourself from responding to the
        # quit method.
        servicetest.call_async(queue, conn, 'Disconnect')

        if 'RING_TEST_REFDBG' in os.environ:
            # we have to wait for the timeout so the process is properly
            # exited and refdbg can generate its report
            time.sleep(5.5)

    except dbus.DBusException:
        pass
示例#12
0
def exec_test_deferred(funs, params, protocol=None, timeout=None):
    colourer = None

    if sys.stdout.isatty():
        colourer = install_colourer()

    queue = servicetest.IteratingEventQueue(timeout)
    queue.verbose = (os.environ.get('CHECK_TWISTED_VERBOSE', '') != ''
                     or '-v' in sys.argv)

    bus = dbus.SessionBus()

    sim = Simulator()

    bus.add_signal_receiver(
        lambda *args, **kw: queue.append(
            Event('dbus-signal',
                  path=unwrap(kw['path']),
                  signal=kw['member'],
                  args=map(unwrap, args),
                  interface=kw['interface'])),
        None,  # signal name
        None,  # interface
        None,
        path_keyword='path',
        member_keyword='member',
        interface_keyword='interface',
        byte_arrays=True)

    try:
        for f in funs:
            conn = make_connection(bus, queue.append, params)
            f(queue, bus, conn)
    except Exception:
        import traceback
        traceback.print_exc()

    try:
        if colourer:
            sys.stdout = colourer.fh
        reactor.crash()

        # force Disconnect in case the test crashed and didn't disconnect
        # properly.  We need to call this async because the BaseIRCServer
        # class must do something in response to the Disconnect call and if we
        # call it synchronously, we're blocking ourself from responding to the
        # quit method.
        servicetest.call_async(queue, conn, 'Disconnect')

        if 'RING_TEST_REFDBG' in os.environ:
            # we have to wait for the timeout so the process is properly
            # exited and refdbg can generate its report
            time.sleep(5.5)

    except dbus.DBusException:
        pass
示例#13
0
def test(q, bus, conn, stream):
    cm = bus.get_object(cs.CM + '.gabble',
        tp_path_prefix + '/ConnectionManager/gabble')
    cm_iface = dbus.Interface(cm, cs.CM)
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['jabber']), set(protocols.keys()))

    protocol_names = unwrap(cm_iface.ListProtocols())
    assertEquals(set(['jabber']), set(protocol_names))

    cm_params = cm_iface.GetParameters('jabber')
    jabber_props = protocols['jabber']
    jabber_params = jabber_props[cs.PROTOCOL + '.Parameters']
    assertEquals(cm_params, jabber_params)

    proto = bus.get_object(cm.bus_name, cm.object_path + '/jabber')
    proto_iface = dbus.Interface(proto, cs.PROTOCOL)
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in ['Parameters', 'Interfaces', 'ConnectionInterfaces',
      'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon']:
        a = jabber_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('*****@*****.**',
        unwrap(proto_iface.NormalizeContact('[email protected]/Telepathy')))

    # org.freedesktop.Telepathy.Protocol.Interface.Presence
    expected_status = {'available': (cs.PRESENCE_AVAILABLE,     True,  True),
                       'dnd'      : (cs.PRESENCE_BUSY,          True,  True),
                       'unknown'  : (cs.PRESENCE_UNKNOWN,       False, False),
                       'away'     : (cs.PRESENCE_AWAY,          True,  True),
                       'xa'       : (cs.PRESENCE_EXTENDED_AWAY, True,  True),
                       'chat'     : (cs.PRESENCE_AVAILABLE,     True,  True),
                       'error'    : (cs.PRESENCE_ERROR,         False, False),
                       'offline'  : (cs.PRESENCE_OFFLINE,       False, False),
                       'testaway' : (cs.PRESENCE_AWAY,          False, False),
                       'testbusy' : (cs.PRESENCE_BUSY,          True,  False),
                       'hidden'   : (cs.PRESENCE_HIDDEN,        True,  True)}

    presences = proto_prop_iface.Get(cs.PROTOCOL_IFACE_PRESENCES, 'Statuses');
    assertEquals(expected_status, unwrap(presences))

    # (Only) 'account' is mandatory for IdentifyAccount()
    call_async(q, proto_iface, 'IdentifyAccount', {})
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)

    test_params = { 'account': 'test@localhost' }
    acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
    assertEquals(test_params['account'], acc_name)

    conn.Connect()
    q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED])
    q.expect('stream-authenticated')
    q.expect('dbus-signal', signal='PresencesChanged',
        args=[{1L: (cs.PRESENCE_AVAILABLE, 'available', '')}])
示例#14
0
def test(q, bus, conn, sip):
    cm = bus.get_object(cs.CM + '.sofiasip',
        tp_path_prefix + '/ConnectionManager/sofiasip')
    cm_iface = dbus.Interface(cm, cs.CM)
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['sip']), set(protocols.keys()))

    local_props = protocols['sip']

    proto = bus.get_object(cm.bus_name, cm.object_path + '/sip')
    proto_iface = dbus.Interface(proto, cs.PROTOCOL)
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in ['Parameters', 'Interfaces', 'ConnectionInterfaces',
      'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon']:
        a = local_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('x-sip', proto_props['VCardField'])
    assertEquals('SIP', proto_props['EnglishName'])
    assertEquals('im-sip', proto_props['Icon'])

    assertContains(cs.CONN_IFACE_ALIASING, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_CONTACTS, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_REQUESTS, proto_props['ConnectionInterfaces'])

    assertEquals('sip:[email protected]',
        unwrap(proto_iface.NormalizeContact('*****@*****.**')))

    # Only account is mandatory
    call_async(q, proto_iface, 'IdentifyAccount', {})
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)
    test_params = {'account': '*****@*****.**'}
    acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
    assertEquals('*****@*****.**', acc_name)
def do_one_search(q, bus, conn, stream, fields, expected_search_keys,
                  terms, results):

    call_create(q, conn, server)

    ret, nc_sig = answer_extended_field_query(q, stream, server, fields)

    path, props = ret.value
    props = unwrap(props)

    assert props[cs.CONTACT_SEARCH_SERVER] == server, pformat(props)
    assert sorted(props[cs.CONTACT_SEARCH_ASK]) == expected_search_keys, \
        sorted(props[cs.CONTACT_SEARCH_ASK])
    assert cs.CONTACT_SEARCH_STATE not in props, pformat(props)

    c = make_channel_proxy(conn, path, 'Channel')
    c_props = dbus.Interface(c, cs.PROPERTIES_IFACE)
    c_search = dbus.Interface(c, cs.CHANNEL_TYPE_CONTACT_SEARCH)

    state = c_props.Get(cs.CHANNEL_TYPE_CONTACT_SEARCH, 'SearchState')
    assert state == cs.SEARCH_NOT_STARTED, state

    # We make a search.
    iq = make_search(q, c_search, c_props, server, terms)
    query = iq.firstChildElement()
    fields_sent = xpath.queryForNodes(
        '/iq/query[@xmlns="%s"]/x[@xmlns="%s"][@type="submit"]/field'
        % (ns.SEARCH, ns.X_DATA), iq)
    assert fields_sent is not None

    # check FORM_TYPE
    f = fields_sent[0]
    assert f['type'] == 'hidden'
    assert f['var'] == 'FORM_TYPE'
    value = f.firstChildElement()
    assert value.name == 'value'
    assert value.children[0] == ns.SEARCH

    # extract search fields
    search_fields = []
    for f in fields_sent[1:]:
        value = f.firstChildElement()
        assert value.name == 'value'
        search_fields.append((f['var'], value.children[0]))

    # Server sends the results of the search.
    send_results_extended(stream, iq, results, fields)

    return search_fields, c, c_search, c_props
示例#16
0
 def signal_receiver(*args, **kw):
     if kw['path'] == '/org/freedesktop/DBus' and \
             kw['member'] == 'NameOwnerChanged':
         bus_name, old_name, new_name = args
         if new_name == '':
             for i, conn in enumerate(conns):
                 stream = streams[i]
                 jid = jids[i]
                 if conn._requested_bus_name == bus_name:
                     factory.lost_presence(stream, jid)
                     break
     queue.append(Event('dbus-signal',
                        path=unwrap(kw['path']),
                        signal=kw['member'], args=map(unwrap, args),
                        interface=kw['interface']))
示例#17
0
def prepare_test(event_func, register_cb, params=None):
    actual_params = {
        'account': '[email protected]',
        'password': '******',
        'proxy-host': '127.0.0.1',
        'port': dbus.UInt16(random.randint(9090, 9999)),
        'local-ip-address': '127.0.0.1',
        'transport': 'udp'
    }

    if params is not None:
        for k, v in params.items():
            if v is None:
                actual_params.pop(k, None)
            else:
                actual_params[k] = v

    bus = dbus.SessionBus()
    conn = servicetest.make_connection(bus, event_func,
        'sofiasip', 'sip', actual_params)

    bus.add_signal_receiver(
        lambda *args, **kw:
            event_func(
                Event('dbus-signal',
                    path=unwrap(kw['path']),
                    signal=kw['member'], args=map(unwrap, args),
                    interface=kw['interface'])),
        None,       # signal name
        None,       # interface
        None,
        path_keyword='path',
        member_keyword='member',
        interface_keyword='interface',
        byte_arrays=True
        )

    port = int(actual_params['port'])
    sip = SipProxy(host=actual_params['proxy-host'], port=port)
    sip.event_func = event_func
    sip.registrar_handler = register_cb
    reactor.listenUDP(port, sip)
    return bus, conn, sip
def complete_search2(q, bus, conn, stream):
    # uses other, dataform specific, fields
    fields = [('given', 'text-single', 'Name', []),
        ('family', 'text-single', 'Family Name', []),
        ('nickname', 'text-single', 'Nickname', [])]

    expected_search_keys = ['nickname', 'x-n-family', 'x-n-given']

    terms = { 'x-n-family': 'Threepwood' }

    g_results = { 'jid': g_jid, 'given': 'Guybrush', 'family': 'Threepwood',
        'nickname': 'Fancy Pants', 'email': g_jid }
    f_results = { 'jid': f_jid, 'given': 'Frederick', 'family': 'Threepwood',
        'nickname': 'Freddie', 'email': f_jid }

    results = { g_jid: g_results, f_jid: f_results }

    search_fields, chan, c_search, c_props = do_one_search (q, bus, conn, stream,
        fields, expected_search_keys, terms, results.values())

    assert len(search_fields) == 1
    assert ('family', 'Threepwood') in search_fields, search_fields

    e = q.expect('dbus-signal', signal='SearchResultReceived')
    infos = e.args[0]

    assertSameSets(results.keys(), infos.keys())

    for id in results.keys():
        i = infos[id]
        r = results[id]
        i_ = pformat(unwrap(i))
        assert ("n", [], [r['family'], r['given'], "", "", ""])    in i, i_
        assert ("nickname", [], [r['nickname']]) in i, i_
        assert ("email", [], [r['email']]) in i, i_
        assert ("x-n-family", [], [r['family']]) in i, i_
        assert ("x-n-given", [], [r['given']]) in i, i_

        assert len(i) == 5, i_

    search_done(q, chan, c_search, c_props)
示例#19
0
def exec_test_deferred (funs, params, protocol=None, timeout=None):
    colourer = None

    if sys.stdout.isatty():
        colourer = install_colourer()

    queue = servicetest.IteratingEventQueue(timeout)
    queue.verbose = (
        os.environ.get('CHECK_TWISTED_VERBOSE', '') != ''
        or '-v' in sys.argv)

    bus = dbus.SessionBus()
    # conn = make_connection(bus, queue.append, params)
    (server, port) = start_server(queue.append, protocol=protocol)

    bus.add_signal_receiver(
        lambda *args, **kw:
            queue.append(
                Event('dbus-signal',
                    path=unwrap(kw['path']),
                    signal=kw['member'], args=map(unwrap, args),
                    interface=kw['interface'])),
        None,       # signal name
        None,       # interface
        None,
        path_keyword='path',
        member_keyword='member',
        interface_keyword='interface',
        byte_arrays=True
        )

    error = None

    try:
        for f in funs:
            conn = make_connection(bus, queue.append, params)
            f(queue, bus, conn, server)
    except Exception, e:
        import traceback
        traceback.print_exc()
        error = e
def test(q, bus, conn, stream):
    event = q.expect('stream-iq',
                     to=None,
                     query_ns=ns.ROSTER,
                     query_name='query')

    result = make_result_iq(stream, event.stanza)
    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'

    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'

    item = result.addElement('item')
    item['jid'] = '*****@*****.**'
    item['subscription'] = 'both'
    stream.send(result)

    stream.send(make_presence('*****@*****.**', 'SHA1SUM-FOR-AMY'))
    stream.send(make_presence('*****@*****.**', 'SHA1SUM-FOR-BOB'))
    stream.send(make_presence('*****@*****.**', None))

    q.expect('dbus-signal', signal='AvatarUpdated')
    handles = conn.get_contact_handles_sync(
        ['*****@*****.**', '*****@*****.**', '*****@*****.**', '*****@*****.**'])

    h2asv = conn.Contacts.GetContactAttributes(handles,
                                               [cs.CONN_IFACE_AVATARS], False)
    assertEquals('SHA1SUM-FOR-AMY', h2asv[handles[0]][cs.ATTR_AVATAR_TOKEN])
    assertEquals('SHA1SUM-FOR-BOB', h2asv[handles[1]][cs.ATTR_AVATAR_TOKEN])
    assertEquals('', h2asv[handles[2]][cs.ATTR_AVATAR_TOKEN])
    assertEquals(None, h2asv[handles[3]].get(cs.ATTR_AVATAR_TOKEN))

    tokens = unwrap(conn.Avatars.GetKnownAvatarTokens(handles))
    tokens = sorted(tokens.items())
    assert tokens == [(2, 'SHA1SUM-FOR-AMY'), (3, 'SHA1SUM-FOR-BOB'), (4, u'')]
def openfire_search(q, bus, conn, stream):
    # Openfire only supports one text field and a bunch of checkboxes
    fields = [('search', 'text-single', 'Search', []),
        ('Username', 'boolean', 'Username', []),
        ('Name', 'boolean', 'Name', []),
        ('Email', 'boolean', 'Email', [])]

    expected_search_keys = ['']

    terms = { '': '*badger*' }

    jid = '*****@*****.**'
    results = {jid : { 'jid': jid, 'Name': 'Badger Badger', 'Email': jid, 'Username': '******'}}

    search_fields, chan, c_search, c_props = do_one_search (q, bus, conn, stream,
        fields, expected_search_keys, terms, results.values())

    assert len(search_fields) == 4
    assert ('search', '*badger*') in search_fields, search_fields
    assert ('Username', '1') in search_fields, search_fields
    assert ('Name', '1') in search_fields, search_fields
    assert ('Email', '1') in search_fields, search_fields

    r = q.expect('dbus-signal', signal='SearchResultReceived')
    infos = r.args[0]

    assertSameSets(results.keys(), infos.keys())

    for id in results.keys():
        i = infos[id]
        r = results[id]
        i_ = pformat(unwrap(i))
        assert ("fn", [], [r['Name']]) in i, i_
        assert ("email", [], [r['Email']]) in i, i_

        assert len(i) == 2
示例#22
0
def test(q, bus, conn, stream):
    conn.Connect()
    q.expect('dbus-signal', signal='StatusChanged',
            args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])

    self_handle = conn.GetSelfHandle()

    requests = dbus.Interface(conn, CONN_IFACE_REQUESTS)

    room_jid = '*****@*****.**'
    room_handle = request_muc_handle(q, conn, stream, room_jid)

    call_async(q, requests, 'CreateChannel',
        dbus.Dictionary({ CHANNEL_TYPE: CHANNEL_TYPE_TEXT,
                          TARGET_HANDLE_TYPE: HT_ROOM,
                          TARGET_HANDLE: room_handle,
                        }, signature='sv'))

    expected_jid = '%s/%s' % (room_jid, 'test')

    q.expect('stream-presence', to=expected_jid)

    # Send presence for another member of the MUC
    stream.send(make_muc_presence('owner', 'moderator', room_jid, 'liz'))

    # This is a themed discussion, so the MUC server forces you to have an
    # appropriate name.
    self_presence = make_muc_presence('none', 'participant', room_jid, 'toofer')
    x = [elt for elt in self_presence.elements() if elt.name == 'x'][0]
    status = x.addElement('status')
    status['code'] = '110' # "This is you"
    status = x.addElement('status')
    status['code'] = '210' # "I renamed you. Muahaha."
    stream.send(self_presence)

    # Gabble should figure out from 110 that it's in the room, and from 210
    # that we've been renamed.
    event = q.expect('dbus-return', method='CreateChannel')
    path, props = event.value
    text_chan = bus.get_object(conn.bus_name, path)
    group_props = unwrap(text_chan.GetAll(CHANNEL_IFACE_GROUP,
        dbus_interface=dbus.PROPERTIES_IFACE))

    liz, toofer, expected_handle = conn.RequestHandles(HT_CONTACT,
        ["%s/%s" % (room_jid, m) for m in ['liz', 'toofer', 'test']])

    # Check that Gabble think our nickname in the room is toofer not test
    muc_self_handle = group_props['SelfHandle']
    assert muc_self_handle == toofer, (muc_self_handle, toofer, expected_handle)

    members = group_props['Members']

    # Check there are exactly two members (liz and toofer)
    expected_members = [liz, toofer]
    assert sorted(members) == sorted(expected_members), \
        (members, expected_members)

    # There should be no pending members.
    assert len(group_props['LocalPendingMembers']) == 0, group_props
    assert len(group_props['RemotePendingMembers']) == 0, group_props

    # Check that toofer's handle owner is us, and that liz has
    # no owner.
    handle_owners = group_props['HandleOwners']
    assert handle_owners[toofer] == self_handle, \
        (handle_owners, toofer, handle_owners[toofer], self_handle)
    assert handle_owners[liz] == 0, (handle_owners, liz)
示例#23
0
def test_join(q, bus, conn, stream, room_jid, transient_conflict):
    """
    Tells Gabble to join a MUC, but make the first nick it tries conflict with
    an existing member of the MUC.  If transient_conflict is True, then when
    Gabble successfully joins with a different nick the originally conflicting
    user turns out not actually to be in the room (they left while we were
    retrying).
    """
    # Implementation detail: Gabble uses the first part of your jid (if you
    # don't have an alias) as your room nickname, and appends an underscore a
    # few times before giving up.
    member, member_ = [room_jid + '/' + x for x in ['test', 'test_']]

    call_async(q, conn.Requests, 'CreateChannel',
        dbus.Dictionary({ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
                          cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
                          cs.TARGET_ID: room_jid,
                        }, signature='sv'))

    # Gabble first tries to join as test
    q.expect('stream-presence', to=member)

    # MUC says no: there's already someone called test in room_jid
    presence = elem('presence', from_=member, type='error')(
        elem(ns.MUC, 'x'),
        elem('error', type='cancel')(
          elem(ns.STANZA, 'conflict'),
        ))
    stream.send(presence)

    # Gabble tries again as test_
    q.expect('stream-presence', to=member_)

    # MUC says yes!

    if not transient_conflict:
        # Send the other member of the room's presence. This is the nick we
        # originally wanted.
        stream.send(make_muc_presence('owner', 'moderator', room_jid, 'test'))

    # If gabble erroneously thinks the other user's presence is our own, it'll
    # think that it's got the whole userlist now. If so, syncing here will make
    # CreateChannel incorrectly return here.
    sync_stream(q, stream)
    sync_dbus(bus, q, conn)

    # Send presence for own membership of room.
    stream.send(make_muc_presence('none', 'participant', room_jid, 'test_'))

    # Only now should we have finished joining the room.
    event = q.expect('dbus-return', method='CreateChannel')
    path, props = event.value
    text_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
    group_props = unwrap(text_chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP))

    t, t_ = conn.RequestHandles(cs.HT_CONTACT, [member, member_])

    # Check that Gabble think our nickname in the room is test_, not test
    muc_self_handle = group_props['SelfHandle']
    assert muc_self_handle == t_, (muc_self_handle, t_, t)

    members = group_props['Members']

    if transient_conflict:
        # The user we originally conflicted with isn't actually here; check
        # there's exactly one member (test_).
        assert members == [t_], (members, t_, t)
    else:
        # Check there are exactly two members (test and test_)
        assertSameSets([t, t_], members)

    # In either case, there should be no pending members.
    assert len(group_props['LocalPendingMembers']) == 0, group_props
    assert len(group_props['RemotePendingMembers']) == 0, group_props

    # Check that test_'s handle owner is us, and that test (if it's there) has
    # no owner.
    handle_owners = group_props['HandleOwners']
    assertEquals (conn.GetSelfHandle(), handle_owners[t_])
    if not transient_conflict:
        assertEquals (0, handle_owners[t])

    # test that closing the channel results in an unavailable message to the
    # right jid
    text_chan.Close()

    event = q.expect('stream-presence', to=member_)
    assertEquals('unavailable', event.stanza['type'])
def test_join(q, bus, conn, stream, room_jid, transient_conflict):
    """
    Tells Gabble to join a MUC, but make the first nick it tries conflict with
    an existing member of the MUC.  If transient_conflict is True, then when
    Gabble successfully joins with a different nick the originally conflicting
    user turns out not actually to be in the room (they left while we were
    retrying).
    """
    # Implementation detail: Gabble uses the first part of your jid (if you
    # don't have an alias) as your room nickname, and appends an underscore a
    # few times before giving up.
    member, member_ = [room_jid + '/' + x for x in ['test', 'test_']]

    call_async(
        q, conn.Requests, 'CreateChannel',
        dbus.Dictionary(
            {
                cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
                cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
                cs.TARGET_ID: room_jid,
            },
            signature='sv'))

    # Gabble first tries to join as test
    q.expect('stream-presence', to=member)

    # MUC says no: there's already someone called test in room_jid
    presence = elem('presence', from_=member,
                    type='error')(elem(ns.MUC, 'x'),
                                  elem('error', type='cancel')(elem(
                                      ns.STANZA, 'conflict'), ))
    stream.send(presence)

    # Gabble tries again as test_
    q.expect('stream-presence', to=member_)

    # MUC says yes!

    if not transient_conflict:
        # Send the other member of the room's presence. This is the nick we
        # originally wanted.
        stream.send(make_muc_presence('owner', 'moderator', room_jid, 'test'))

    # If gabble erroneously thinks the other user's presence is our own, it'll
    # think that it's got the whole userlist now. If so, syncing here will make
    # CreateChannel incorrectly return here.
    sync_stream(q, stream)
    sync_dbus(bus, q, conn)

    # Send presence for own membership of room.
    stream.send(make_muc_presence('none', 'participant', room_jid, 'test_'))

    # Only now should we have finished joining the room.
    event = q.expect('dbus-return', method='CreateChannel')
    path, props = event.value
    text_chan = wrap_channel(bus.get_object(conn.bus_name, path), 'Text')
    group_props = unwrap(text_chan.Properties.GetAll(cs.CHANNEL_IFACE_GROUP))

    t, t_ = conn.get_contact_handles_sync([member, member_])

    # Check that Gabble think our nickname in the room is test_, not test
    muc_self_handle = group_props['SelfHandle']
    assert muc_self_handle == t_, (muc_self_handle, t_, t)

    members = group_props['Members']

    if transient_conflict:
        # The user we originally conflicted with isn't actually here; check
        # there's exactly one member (test_).
        assert members == [t_], (members, t_, t)
    else:
        # Check there are exactly two members (test and test_)
        assertSameSets([t, t_], members)

    # In either case, there should be no pending members.
    assert len(group_props['LocalPendingMembers']) == 0, group_props
    assert len(group_props['RemotePendingMembers']) == 0, group_props

    # Check that test_'s handle owner is us, and that test (if it's there) has
    # no owner.
    handle_owners = group_props['HandleOwners']
    assertEquals(conn.Properties.Get(cs.CONN, "SelfHandle"), handle_owners[t_])
    if not transient_conflict:
        assertEquals(0, handle_owners[t])

    # test that closing the channel results in an unavailable message to the
    # right jid
    text_chan.Close()

    event = q.expect('stream-presence', to=member_)
    assertEquals('unavailable', event.stanza['type'])
def test(q, bus, conn, stream):
    self_handle = conn.Properties.Get(cs.CONN, "SelfHandle")

    requests = dbus.Interface(conn, CONN_IFACE_REQUESTS)

    room_jid = '*****@*****.**'

    call_async(
        q, requests, 'CreateChannel',
        dbus.Dictionary(
            {
                CHANNEL_TYPE: CHANNEL_TYPE_TEXT,
                TARGET_HANDLE_TYPE: HT_ROOM,
                TARGET_ID: room_jid,
            },
            signature='sv'))

    expected_jid = '%s/%s' % (room_jid, 'test')

    q.expect('stream-presence', to=expected_jid)

    # Send presence for another member of the MUC
    stream.send(make_muc_presence('owner', 'moderator', room_jid, 'liz'))

    # This is a themed discussion, so the MUC server forces you to have an
    # appropriate name.
    self_presence = make_muc_presence('none', 'participant', room_jid,
                                      'toofer')
    x = [elt for elt in self_presence.elements() if elt.name == 'x'][0]
    status = x.addElement('status')
    status['code'] = '110'  # "This is you"
    status = x.addElement('status')
    status['code'] = '210'  # "I renamed you. Muahaha."
    stream.send(self_presence)

    # Gabble should figure out from 110 that it's in the room, and from 210
    # that we've been renamed.
    event = q.expect('dbus-return', method='CreateChannel')
    path, props = event.value
    text_chan = bus.get_object(conn.bus_name, path)
    group_props = unwrap(
        text_chan.GetAll(CHANNEL_IFACE_GROUP,
                         dbus_interface=dbus.PROPERTIES_IFACE))

    liz, toofer, expected_handle = conn.get_contact_handles_sync(
        ["%s/%s" % (room_jid, m) for m in ['liz', 'toofer', 'test']])

    # Check that Gabble think our nickname in the room is toofer not test
    muc_self_handle = group_props['SelfHandle']
    assert muc_self_handle == toofer, (muc_self_handle, toofer,
                                       expected_handle)

    members = group_props['Members']

    # Check there are exactly two members (liz and toofer)
    expected_members = [liz, toofer]
    assert sorted(members) == sorted(expected_members), \
        (members, expected_members)

    # There should be no pending members.
    assert len(group_props['LocalPendingMembers']) == 0, group_props
    assert len(group_props['RemotePendingMembers']) == 0, group_props

    # Check that toofer's handle owner is us, and that liz has
    # no owner.
    handle_owners = group_props['HandleOwners']
    assert handle_owners[toofer] == self_handle, \
        (handle_owners, toofer, handle_owners[toofer], self_handle)
    assert handle_owners[liz] == 0, (handle_owners, liz)
def test(q, bus, conn, stream, bytestream_cls,
        address_type, access_control, access_control_param):
    if bytestream_cls in [BytestreamS5BRelay, BytestreamS5BRelayBugged]:
        # disable SOCKS5 relay tests because proxy can't be used with muc
        # contacts atm
        return

    iq_event, disco_event = q.expect_many(
        EventPattern('stream-iq', to=None, query_ns='vcard-temp',
            query_name='vCard'),
        EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS))

    acknowledge_iq(stream, iq_event.stanza)

    announce_socks5_proxy(q, stream, disco_event.stanza)

    call_async(q, conn, 'RequestHandles', 2,
        ['*****@*****.**'])

    event = q.expect('dbus-return', method='RequestHandles')
    handles = event.value[0]
    room_handle = handles[0]

    # join the muc
    call_async(q, conn, 'RequestChannel', cs.CHANNEL_TYPE_TEXT, cs.HT_ROOM,
        room_handle, True)

    _, stream_event = q.expect_many(
        EventPattern('dbus-signal', signal='MembersChanged',
            args=[u'', [], [], [], [2], 0, 0]),
        EventPattern('stream-presence', to='[email protected]/test'))

    # Send presence for other member of room.
    stream.send(make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob'))

    # Send presence for own membership of room.
    stream.send(make_muc_presence('none', 'participant', '*****@*****.**', 'test'))

    q.expect('dbus-signal', signal='MembersChanged',
            args=[u'', [2, 3], [], [], [], 0, 0])

    assert conn.InspectHandles(1, [2]) == ['[email protected]/test']
    assert conn.InspectHandles(1, [3]) == ['[email protected]/bob']
    bob_handle = 3

    event = q.expect('dbus-return', method='RequestChannel')

    # Bob offers a stream tube
    stream_tube_id = 666
    presence = make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob')
    tubes = presence.addElement((ns.TUBES, 'tubes'))
    tube = tubes.addElement((None, 'tube'))
    tube['type'] = 'stream'
    tube['service'] = 'echo'
    tube['id'] = str(stream_tube_id)
    parameters = tube.addElement((None, 'parameters'))
    parameter = parameters.addElement((None, 'parameter'))
    parameter['name'] = 's'
    parameter['type'] = 'str'
    parameter.addContent('hello')
    parameter = parameters.addElement((None, 'parameter'))
    parameter['name'] = 'ay'
    parameter['type'] = 'bytes'
    parameter.addContent('aGVsbG8=')
    parameter = parameters.addElement((None, 'parameter'))
    parameter['name'] = 'u'
    parameter['type'] = 'uint'
    parameter.addContent('123')
    parameter = parameters.addElement((None, 'parameter'))
    parameter['name'] = 'i'
    parameter['type'] = 'int'
    parameter.addContent('-123')

    stream.send(presence)

    # text channel
    event, new_event = q.expect_many(
        EventPattern('dbus-signal', signal='NewChannel'),
        EventPattern('dbus-signal', signal='NewChannels'))

    assert event.args[1] == cs.CHANNEL_TYPE_TEXT, event.args

    channels = new_event.args[0]
    assert len(channels) == 1
    path, props = channels[0]
    assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT

    # tubes channel is automatically created
    event, new_event = q.expect_many(
        EventPattern('dbus-signal', signal='NewChannel'),
        EventPattern('dbus-signal', signal='NewChannels'))

    assert event.args[1] == cs.CHANNEL_TYPE_TUBES, event.args
    assert event.args[2] == cs.HT_ROOM
    assert event.args[3] == room_handle

    tubes_chan = bus.get_object(conn.bus_name, event.args[0])
    tubes_iface = dbus.Interface(tubes_chan, event.args[1])

    channel_props = tubes_chan.GetAll(cs.CHANNEL, dbus_interface=cs.PROPERTIES_IFACE)
    assert channel_props['TargetID'] == '*****@*****.**', channel_props
    assert channel_props['Requested'] == False
    assert channel_props['InitiatorID'] == ''
    assert channel_props['InitiatorHandle'] == 0

    channels = new_event.args[0]
    assert len(channels) == 1
    path, props = channels[0]
    assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TUBES

    tubes_self_handle = tubes_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP)

    q.expect('dbus-signal', signal='NewTube',
        args=[stream_tube_id, bob_handle, 1, 'echo', sample_parameters, 0])

    expected_tube = (stream_tube_id, bob_handle, cs.TUBE_TYPE_STREAM, 'echo',
        sample_parameters, cs.TUBE_STATE_LOCAL_PENDING)
    tubes = tubes_iface.ListTubes(byte_arrays=True)
    assert tubes == [(
        stream_tube_id,
        bob_handle,
        1,      # Stream
        'echo',
        sample_parameters,
        cs.TUBE_CHANNEL_STATE_LOCAL_PENDING
        )]

    assert len(tubes) == 1, unwrap(tubes)
    t.check_tube_in_tubes(expected_tube, tubes)

    # tube channel is also announced (new API)
    new_event = q.expect('dbus-signal', signal='NewChannels')

    channels = new_event.args[0]
    assert len(channels) == 1
    path, props = channels[0]
    assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE
    assert props[cs.INITIATOR_HANDLE] == bob_handle
    assert props[cs.INITIATOR_ID] == '[email protected]/bob'
    assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE]
    assert props[cs.REQUESTED] == False
    assert props[cs.TARGET_HANDLE] == room_handle
    assert props[cs.TARGET_ID] == '*****@*****.**'
    assert props[cs.STREAM_TUBE_SERVICE] == 'echo'
    assert props[cs.TUBE_PARAMETERS] == {'s': 'hello', 'ay': 'hello', 'u': 123, 'i': -123}
    assert access_control in \
            props[cs.STREAM_TUBE_SUPPORTED_SOCKET_TYPES][address_type]

    tube_chan = bus.get_object(conn.bus_name, path)
    tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE,
        byte_arrays=True)
    assert tube_props['Parameters'] == sample_parameters
    assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_LOCAL_PENDING

    # Accept the tube
    call_async(q, tubes_iface, 'AcceptStreamTube', stream_tube_id,
        address_type, access_control, access_control_param, byte_arrays=True)

    accept_return_event, _ = q.expect_many(
        EventPattern('dbus-return', method='AcceptStreamTube'),
        EventPattern('dbus-signal', signal='TubeStateChanged',
            args=[stream_tube_id, 2]))

    address = accept_return_event.value[0]

    socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob',
        address_type, address, access_control, access_control_param)

    protocol = socket_event.protocol
    protocol.sendData("hello initiator")

    def accept_tube_si_connection():
        bytestream, profile = create_from_si_offer(stream, q, bytestream_cls, si_event.stanza,
                '[email protected]/test')

        assert profile == ns.TUBES

        muc_stream_node = xpath.queryForNodes('/iq/si/muc-stream[@xmlns="%s"]' %
            ns.TUBES, si_event.stanza)[0]
        assert muc_stream_node is not None
        assert muc_stream_node['tube'] == str(stream_tube_id)

        # set the real jid of the target as 'to' because the XMPP server changes
        # it when delivering the IQ
        result, si = bytestream.create_si_reply(si_event.stanza, 'test@localhost/Resource')
        si.addElement((ns.TUBES, 'tube'))
        stream.send(result)

        bytestream.wait_bytestream_open()
        return bytestream

    bytestream = accept_tube_si_connection()

    binary = bytestream.get_data()
    assert binary == 'hello initiator'

    # reply on the socket
    bytestream.send_data('hi joiner!')

    q.expect('socket-data', protocol=protocol, data="hi joiner!")

    # peer closes the bytestream
    bytestream.close()
    e = q.expect('dbus-signal', signal='ConnectionClosed')
    assertEquals(conn_id, e.args[0])
    assertEquals(cs.CONNECTION_LOST, e.args[1])

    # establish another tube connection
    socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob',
        address_type, address, access_control, access_control_param)

    # bytestream is refused
    send_error_reply(stream, si_event.stanza)
    e, _ = q.expect_many(
        EventPattern('dbus-signal', signal='ConnectionClosed'),
        EventPattern('socket-disconnected'))
    assertEquals(conn_id, e.args[0])
    assertEquals(cs.CONNECTION_REFUSED, e.args[1])

    # establish another tube connection
    socket_event, si_event, conn_id = t.connect_to_cm_socket(q, '[email protected]/bob',
        address_type, address, access_control, access_control_param)

    protocol = socket_event.protocol
    bytestream = accept_tube_si_connection()

    # disconnect local socket
    protocol.transport.loseConnection()
    e, _ = q.expect_many(
        EventPattern('dbus-signal', signal='ConnectionClosed'),
        EventPattern('socket-disconnected'))
    assertEquals(conn_id, e.args[0])
    assertEquals(cs.CANCELLED, e.args[1])

    # OK, we're done
    disconnect_conn(q, conn, stream,
        [EventPattern('dbus-signal', signal='TubeClosed', args=[stream_tube_id])])
def _start_audio_session(jp, q, bus, conn, stream, incoming):
    jt = JingleTest2(jp, conn, q, stream, 'test@localhost', '[email protected]/Foo')
    jt.prepare()

    self_handle = conn.GetSelfHandle()
    remote_handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]

    if incoming:
        jt.incoming_call()
    else:
        ret = conn.Requests.CreateChannel(
            { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
              cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
              cs.TARGET_HANDLE: remote_handle,
              cs.INITIAL_AUDIO: True
              })

    nc, e = q.expect_many(
        EventPattern('dbus-signal', signal='NewChannel',
            predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
        EventPattern('dbus-signal', signal='NewSessionHandler'))

    path = nc.args[0]

    media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
    media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')

    # S-E was notified about new session handler, and calls Ready on it
    session_handler = make_channel_proxy(conn, e.args[0],
                                         'Media.SessionHandler')
    session_handler.Ready()

    nsh_event = q.expect('dbus-signal', signal='NewStreamHandler')

    # S-E gets notified about a newly-created stream
    stream_handler = make_channel_proxy(conn, nsh_event.args[0],
        'Media.StreamHandler')

    group_props = media_chan.GetAll(
        cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE)

    if incoming:
        assertEquals([remote_handle], group_props['Members'])
        assertEquals(unwrap(group_props['LocalPendingMembers']),
                     [(self_handle, remote_handle, cs.GC_REASON_INVITED, '')])
    else:
        assertEquals([self_handle], group_props['Members'])

    streams = media_chan.ListStreams(
            dbus_interface=cs.CHANNEL_TYPE_STREAMED_MEDIA)

    stream_id = streams[0][0]

    stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
    stream_handler.Ready(jt.dbusify_codecs([("FOO", 5, 8000, {})]))

    msg = u"None of the codecs are good for us, damn!"

    expected_events = []

    if incoming:
        stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
        stream_handler.SupportedCodecs(jt.get_audio_codecs_dbus())

        e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
        assertEquals(jt.peer, e.query['initiator'])
        content = xpath.queryForNodes('/iq/jingle/content', e.stanza)[0]
        assertEquals('initiator', content['creator'])

        stream.send(make_result_iq(stream, e.stanza))

        media_chan.AddMembers([self_handle], 'accepted')

        memb, acc, _, _, _ = q.expect_many(
            EventPattern('dbus-signal', signal='MembersChanged',
                         args=[u'', [self_handle], [], [], [], self_handle,
                               cs.GC_REASON_NONE]),
            EventPattern('stream-iq',
                         predicate=jp.action_predicate('session-accept')),
            EventPattern('dbus-signal', signal='SetStreamSending',
                         args=[True]),
            EventPattern('dbus-signal', signal='SetStreamPlaying',
                         args=[True]),
            EventPattern('dbus-signal', signal='StreamDirectionChanged',
                         args=[stream_id,
                               cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0]))

        stream.send(make_result_iq(stream, acc.stanza))

        active_event = jp.rtp_info_event("active")
        if active_event is not None:
            q.expect_many(active_event)

        members = media_chan.GetMembers()
        assert set(members) == set([self_handle, remote_handle]), members
    else:
        stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
        session_initiate = q.expect(
            'stream-iq',
            predicate=jp.action_predicate('session-initiate'))

        q.expect('dbus-signal', signal='MembersChanged', path=path,
                 args=['', [], [], [], [remote_handle], self_handle,
                       cs.GC_REASON_INVITED])

        jt.parse_session_initiate(session_initiate.query)
        stream.send(jp.xml(jp.ResultIq('test@localhost',
                                       session_initiate.stanza, [])))

        jt.accept()

        q.expect_many(
            EventPattern('stream-iq', iq_type='result'),
            # Call accepted
            EventPattern('dbus-signal', signal='MembersChanged',
                         args=['', [remote_handle], [], [], [], remote_handle,
                               cs.GC_REASON_NONE]),
            )
    return jt, media_iface
示例#28
0
def test(q, bus, conn, stream):
    cm = bus.get_object(cs.CM + '.gabble',
                        tp_path_prefix + '/ConnectionManager/gabble')
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['jabber']), set(protocols.keys()))

    jabber_props = protocols['jabber']

    proto = bus.get_object(cm.bus_name, cm.object_path + '/jabber')
    proto_iface = dbus.Interface(proto, cs.PROTOCOL)
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in [
            'Parameters', 'Interfaces', 'ConnectionInterfaces',
            'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon'
    ]:
        a = jabber_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('*****@*****.**',
                 unwrap(proto_iface.NormalizeContact('[email protected]/Telepathy')))

    # Protocol.Interface.Presence
    expected_status = {
        'available': (cs.PRESENCE_AVAILABLE, True, True),
        'dnd': (cs.PRESENCE_BUSY, True, True),
        'unknown': (cs.PRESENCE_UNKNOWN, False, False),
        'away': (cs.PRESENCE_AWAY, True, True),
        'xa': (cs.PRESENCE_EXTENDED_AWAY, True, True),
        'chat': (cs.PRESENCE_AVAILABLE, True, True),
        'error': (cs.PRESENCE_ERROR, False, False),
        'offline': (cs.PRESENCE_OFFLINE, False, False),
        'testaway': (cs.PRESENCE_AWAY, False, False),
        'testbusy': (cs.PRESENCE_BUSY, True, False),
        'hidden': (cs.PRESENCE_HIDDEN, True, True)
    }

    presences = proto_prop_iface.Get(cs.PROTOCOL_IFACE_PRESENCES, 'Statuses')
    # Plugins could add additional statuses, so we check if expected_status is
    # included in presences rather than equality.
    for k, v in expected_status.items():
        assertEquals(expected_status[k], unwrap(presences[k]))

    # (Only) 'account' is mandatory for IdentifyAccount()
    call_async(q, proto_iface, 'IdentifyAccount', {})
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)

    test_params = {'account': 'test@localhost'}
    acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
    assertEquals(test_params['account'], acc_name)

    assertContains(cs.PROTOCOL_IFACE_AVATARS, proto_props['Interfaces'])
    avatar_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL_IFACE_AVATARS))
    assertEquals(8192, avatar_props['MaximumAvatarBytes'])
    assertEquals(96, avatar_props['MaximumAvatarHeight'])
    assertEquals(96, avatar_props['MaximumAvatarWidth'])
    assertEquals(32, avatar_props['MinimumAvatarHeight'])
    assertEquals(32, avatar_props['MinimumAvatarWidth'])
    assertEquals(64, avatar_props['RecommendedAvatarHeight'])
    assertEquals(64, avatar_props['RecommendedAvatarWidth'])
    assertEquals(['image/png', 'image/jpeg', 'image/gif'],
                 avatar_props['SupportedAvatarMIMETypes'])

    conn.Connect()
    q.expect('dbus-signal',
             signal='StatusChanged',
             args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED])
    q.expect('stream-authenticated')
    q.expect('dbus-signal',
             signal='PresencesChanged',
             args=[{
                 1: (cs.PRESENCE_AVAILABLE, 'available', '')
             }])
    q.expect('dbus-signal',
             signal='StatusChanged',
             args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED])
    return
示例#29
0
def get_schemes(props):
    return unwrap (props.Get (cs.ACCOUNT_IFACE_ADDRESSING, 'URISchemes'))
示例#30
0
def complete_search(q, bus, conn, stream, server):
    call_create(q, conn, server)

    # the channel is not yet in conn.Requests.Channels as it's not ready yet
    channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels',
        dbus_interface=cs.PROPERTIES_IFACE)
    for path, props in channels:
        assert props[cs.CHANNEL_TYPE] != cs.CHANNEL_TYPE_CONTACT_SEARCH

    ret, nc_sig = answer_field_query(q, stream, server)

    path, props = ret.value
    props = unwrap(props)

    expected_search_keys = ['email', 'nickname', 'x-n-family', 'x-n-given']

    assert props[cs.CONTACT_SEARCH_SERVER] == server, pformat(props)
    assert sorted(props[cs.CONTACT_SEARCH_ASK]) == expected_search_keys, \
        pformat(props)
    assert cs.CONTACT_SEARCH_STATE not in props, pformat(props)

    # check that channel is listed in conn.Requests.Channels
    channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels',
        dbus_interface=cs.PROPERTIES_IFACE)
    assert (path, props) in channels

    c = make_channel_proxy(conn, path, 'Channel')
    c_props = dbus.Interface(c, cs.PROPERTIES_IFACE)
    c_search = dbus.Interface(c, cs.CHANNEL_TYPE_CONTACT_SEARCH)

    state = c_props.Get(cs.CHANNEL_TYPE_CONTACT_SEARCH, 'SearchState')
    assert state == cs.SEARCH_NOT_STARTED, state

    # We make a search.
    iq = make_search(q, c_search, c_props, server, { 'x-n-family': 'Threepwood' })
    query = iq.firstChildElement()
    i = 0
    for field in query.elements():
        assert field.name == 'last', field.toXml()
        assert field.children[0] == u'Threepwood', field.children[0]
        i += 1
    assert i == 1, query

    # Server sends the results of the search.
    send_results(stream, iq, results.values())

    r = q.expect('dbus-signal', signal='SearchResultReceived')
    infos = r.args[0]

    assertSameSets(results.keys(), infos.keys())

    for id in results.keys():
        i = infos[id]
        r = results[id]
        i_ = pformat(unwrap(i))
        assert ("n", [], [r[2], r[1], "", "", ""])    in i, i_
        assert ("nickname", [], [r[3]])               in i, i_
        assert ("email", [], [r[0]])                  in i, i_
        assert ("x-n-family", [], [r[2]]) in i, i_
        assert ("x-n-given", [], [r[1]]) in i, i_

        assert len(i) == 5, i_

    ssc = q.expect('dbus-signal', signal='SearchStateChanged')
    assert ssc.args[0] == cs.SEARCH_COMPLETED, ssc.args

    # We call Stop after the search has completed; it should succeed, but leave
    # the channel in state Completed rather than changing it to Failed for
    # reason Cancelled.
    call_async(q, c_search, 'Stop')
    event = q.expect('dbus-return', method='Stop')
    state = c_props.Get(cs.CHANNEL_TYPE_CONTACT_SEARCH, 'SearchState')
    assert state == cs.SEARCH_COMPLETED, (state, cs.SEARCH_COMPLETED)

    c.Close()

    q.expect_many(
        EventPattern('dbus-signal', signal='Closed'),
        EventPattern('dbus-signal', signal='ChannelClosed'),
        )
def test(q, bus, conn):
    cm = bus.get_object(cs.CM + '.salut',
        tp_path_prefix + '/ConnectionManager/salut')
    cm_iface = dbus.Interface(cm, cs.CM)
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['local-xmpp']), set(protocols.keys()))

    local_props = protocols['local-xmpp']
    local_params = local_props[cs.PROTOCOL + '.Parameters']

    proto = bus.get_object(cm.bus_name, cm.object_path + '/local_xmpp')
    proto_iface = dbus.Interface(proto, cs.PROTOCOL)
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in ['Parameters', 'Interfaces', 'ConnectionInterfaces',
      'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon']:
        a = local_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('', proto_props['VCardField'])
    assertEquals('Link-local XMPP', proto_props['EnglishName'])
    assertEquals('im-local-xmpp', proto_props['Icon'])

    assertContains(cs.CONN_IFACE_ALIASING, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_AVATARS, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_CONTACTS, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_SIMPLE_PRESENCE,
            proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_REQUESTS, proto_props['ConnectionInterfaces'])

    # local-xmpp has case-sensitive literals as identifiers
    assertEquals('SMcV@Reptile',
        unwrap(proto_iface.NormalizeContact('SMcV@Reptile')))

    # (Only) 'first-name' and 'last-name' are mandatory for IdentifyAccount()
    call_async(q, proto_iface, 'IdentifyAccount', {'first-name': 'Simon'})
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)

    # Identifying an account doesn't do much, anyway
    test_params = {'first-name': 'Simon', 'last-name': 'McVittie'}
    acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
    assertEquals('', acc_name)

    assertContains(cs.PROTOCOL_IFACE_AVATARS, proto_props['Interfaces'])
    avatar_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL_IFACE_AVATARS))
    assertEquals(65535, avatar_props['MaximumAvatarBytes'])
    assertEquals(0, avatar_props['MaximumAvatarHeight'])
    assertEquals(0, avatar_props['MaximumAvatarWidth'])
    assertEquals(0, avatar_props['MinimumAvatarHeight'])
    assertEquals(0, avatar_props['MinimumAvatarWidth'])
    assertEquals(64, avatar_props['RecommendedAvatarHeight'])
    assertEquals(64, avatar_props['RecommendedAvatarWidth'])
    assertEquals(['image/png', 'image/jpeg'], avatar_props['SupportedAvatarMIMETypes'])

    assertContains(cs.PROTOCOL_IFACE_PRESENCES, proto_props['Interfaces'])

    expected_status = {'available': (cs.PRESENCE_AVAILABLE,     True,  True),
                       'dnd'      : (cs.PRESENCE_BUSY,          True,  True),
                       'away'     : (cs.PRESENCE_AWAY,          True,  True),
                       'offline'  : (cs.PRESENCE_OFFLINE,       False, False)}

    presences = proto_prop_iface.Get(cs.PROTOCOL_IFACE_PRESENCES, 'Statuses');
    assertEquals(expected_status, presences)
示例#32
0
        'resource': 'Resource',
        'server': 'localhost',
        'port': dbus.UInt32(4343),
    }
    conn2, jid2 = make_connection(bus, queue.append, params)
    authenticator = XmppAuthenticator('test2', 'pass')
    stream2 = make_stream(queue.append, authenticator, protocol=XmppXmlStream)

    factory = twisted.internet.protocol.Factory()
    factory.protocol = lambda: stream2
    port1 = reactor.listenTCP(4343, factory, interface='localhost')

    bus.add_signal_receiver(
        lambda *args, **kw: queue.append(
            Event('dbus-signal',
                  path=unwrap(kw['path']),
                  signal=kw['member'],
                  args=[unwrap(a) for a in args],
                  interface=kw['interface'])),
        None,  # signal name
        None,  # interface
        None,
        path_keyword='path',
        member_keyword='member',
        interface_keyword='interface',
        byte_arrays=True)

    try:
        test(queue, bus, conn1, conn2, stream1, stream2)
    finally:
        try:
        'server': 'localhost',
        'port': dbus.UInt32(4343),
        }
    conn2, jid2 = make_connection(bus, queue.append, params)
    authenticator = XmppAuthenticator('test2', 'pass')
    stream2 = make_stream(queue.append, authenticator, protocol=XmppXmlStream)

    factory = twisted.internet.protocol.Factory()
    factory.protocol = lambda:stream2
    port1 = reactor.listenTCP(4343, factory, interface='localhost')


    bus.add_signal_receiver(
        lambda *args, **kw:
            queue.append(Event('dbus-signal',
                               path=unwrap(kw['path']),
                               signal=kw['member'], args=map(unwrap, args),
                               interface=kw['interface'])),
        None,       # signal name
        None,       # interface
        None,
        path_keyword='path',
        member_keyword='member',
        interface_keyword='interface',
        byte_arrays=True
        )

    try:
        test(queue, bus, conn1, conn2, stream1, stream2)
    finally:
        try:
def test(q, bus, conn, stream, send_early_description_info=False):
    jp = JingleProtocol031()
    jt2 = JingleTest2(jp, conn, q, stream, 'test@localhost', '[email protected]/Foo')
    jt2.prepare()

    self_handle = conn.GetSelfHandle()
    remote_handle = conn.RequestHandles(cs.HT_CONTACT, ["[email protected]/Foo"])[0]

    # Remote end calls us
    jt2.incoming_call()

    # FIXME: these signals are not observable by real clients, since they
    #        happen before NewChannels.
    # The caller is in members
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [remote_handle], [], [], [], 0, 0])

    # We're pending because of remote_handle
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [], [], [self_handle], [], remote_handle,
                   cs.GC_REASON_INVITED])

    chan = wrap_channel(bus.get_object(conn.bus_name,  e.path),
        'StreamedMedia')

    # S-E gets notified about new session handler, and calls Ready on it
    e = q.expect('dbus-signal', signal='NewSessionHandler')
    assert e.args[1] == 'rtp'

    if send_early_description_info:
        """
        Regression test for a bug where Gabble would crash if you sent it
        description-info before calling Ready() on the relevant StreamHandler,
        and then for a bug where Gabble would never accept the call if a
        description-info was received before all StreamHandlers were Ready().
        """
        node = jp.SetIq(jt2.peer, jt2.jid, [
            jp.Jingle(jt2.sid, jt2.peer, 'description-info', [
                jp.Content('stream1', 'initiator', 'both',
                    jp.Description('audio', [ ])) ]) ])
        stream.send(jp.xml(node))

        sync_stream(q, stream)

    session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
    session_handler.Ready()

    chan.Group.AddMembers([self_handle], 'accepted')

    # S-E gets notified about a newly-created stream
    e = q.expect('dbus-signal', signal='NewStreamHandler')
    id1 = e.args[1]

    stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')

    # We are now in members too
    e = q.expect('dbus-signal', signal='MembersChanged',
             args=[u'', [self_handle], [], [], [], self_handle,
                   cs.GC_REASON_NONE])

    # we are now both in members
    members = chan.Group.GetMembers()
    assert set(members) == set([self_handle, remote_handle]), members

    local_codecs = [('GSM', 3, 8000, {}),
                    ('PCMA', 8, 8000, {'helix':'woo yay'}),
                    ('PCMU', 0, 8000, {}) ]
    local_codecs_dbus = jt2.dbusify_codecs_with_params(local_codecs)

    stream_handler.NewNativeCandidate("fake", jt2.get_remote_transports_dbus())
    stream_handler.Ready(local_codecs_dbus)
    stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)

    stream_handler.CodecsUpdated(local_codecs_dbus)

    local_codecs = [('GSM', 3, 8000, {}),
                    ('PCMA', 8, 8000, {'gstreamer':'rock on'}),
                    ('PCMU', 0, 8000, {}) ]
    local_codecs_dbus = jt2.dbusify_codecs_with_params(local_codecs)
    stream_handler.CodecsUpdated(local_codecs_dbus)


    # First IQ is transport-info; also, we expect to be told what codecs the
    # other end wants.
    e, src = q.expect_many(
        EventPattern('stream-iq',
            predicate=jp.action_predicate('transport-info')),
        EventPattern('dbus-signal', signal='SetRemoteCodecs')
        )
    assertEquals('[email protected]/Foo', e.query['initiator'])

    assert jt2.audio_codecs == [ (name, id, rate, parameters)
        for id, name, type, rate, channels, parameters in unwrap(src.args[0]) ], \
        (jt2.audio_codecs, unwrap(src.args[0]))

    stream.send(jp.xml(jp.ResultIq('test@localhost', e.stanza, [])))

    # S-E reports codec intersection, after which gabble can send acceptance
    stream_handler.SupportedCodecs(local_codecs_dbus)

    # Second one is session-accept
    e = q.expect('stream-iq', predicate=jp.action_predicate('session-accept'))

    # farstream is buggy, and tells tp-fs to tell Gabble to change the third
    # codec's clockrate. This isn't legal, so Gabble says no.
    new_codecs = [ ('GSM', 3, 8000, {}),
                   ('PCMA', 8, 8000, {}),
                   ('PCMU', 0, 4000, {}) ]
    call_async(q, stream_handler, 'CodecsUpdated',
        jt2.dbusify_codecs(new_codecs))
    event = q.expect('dbus-error', method='CodecsUpdated')
    assert event.error.get_dbus_name() == cs.INVALID_ARGUMENT, \
        event.error.get_dbus_name()

    # With its tail between its legs, tp-fs decides it wants to add some
    # parameters to the first two codecs, not changing the third.
    new_codecs = [ ('GSM', 3, 8000, {'type': 'banana'}),
                   ('PCMA', 8, 8000, {'helix': 'BUFFERING'}),
                   ('PCMU', 0, 8000, {}) ]
    stream_handler.CodecsUpdated(jt2.dbusify_codecs_with_params(new_codecs))

    audio_content = jt2.audio_names[0]

    e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
        xpath.queryForNodes("/iq/jingle[@action='description-info']",
            x.stanza))
    payload_types = xpath.queryForNodes(
        "/iq/jingle/content[@name='%s']/description/payload-type"
            % audio_content,
        e.stanza)
    # Gabble SHOULD only include the changed codecs in description-info
    assert len(payload_types) == 2, payload_types

    payload_types_tupled = [ (pt['name'], int(pt['id']), int(pt['clockrate']),
                              extract_params(pt))
                             for pt in payload_types ]
    assert sorted(payload_types_tupled) == sorted(new_codecs[0:2]), \
        (payload_types_tupled, new_codecs[0:2])

    # The remote end decides it wants to change the number of channels in the
    # third codec. This is not meant to happen, so Gabble should send it an IQ
    # error back.
    node = jp.SetIq(jt2.peer, jt2.jid, [
        jp.Jingle(jt2.sid, jt2.peer, 'description-info', [
            jp.Content(audio_content, 'initiator', 'both',
                jp.Description('audio', [
                    jp.PayloadType('PCMU', '1600', '0') ])) ]) ])
    stream.send(jp.xml(node))
    q.expect('stream-iq', iq_type='error',
        predicate=lambda x: x.stanza['id'] == node[2]['id'])

    # Instead, the remote end decides to add a parameter to the third codec.
    new_codecs = [ ('GSM', 3, 8000, {}),
                   ('PCMA', 8, 8000, {}),
                   ('PCMU', 0, 8000, {'choppy': 'false'}),
                 ]
    # As per the XEP, it only sends the ones which have changed.
    c = new_codecs[2]
    node = jp.SetIq(jt2.peer, jt2.jid, [
        jp.Jingle(jt2.sid, jt2.peer, 'description-info', [
            jp.Content(audio_content, 'initiator', 'both',
                jp.Description('audio', [
                    jp.PayloadType(c[0], str(c[2]), str(c[1]), c[3])
                ])) ]) ])
    stream.send(jp.xml(node))

    # Gabble should patch its idea of the remote codecs with the update it just
    # got, and emit SetRemoteCodecs for them all.
    e = q.expect('dbus-signal', signal='SetRemoteCodecs')
    new_codecs_dbus = unwrap(jt2.dbusify_codecs_with_params(new_codecs))
    announced = unwrap(e.args[0])
    assert new_codecs_dbus == announced, (new_codecs_dbus, announced)

    # We close the session by removing the stream
    chan.StreamedMedia.RemoveStreams([id1])

    e = q.expect('stream-iq', iq_type='set', predicate=lambda x:
        xpath.queryForNodes("/iq/jingle[@action='session-terminate']",
            x.stanza))
def test(q, bus, conn, stream, bytestream_cls, address_type, access_control, access_control_param):
    if bytestream_cls in [BytestreamS5BRelay, BytestreamS5BRelayBugged]:
        # disable SOCKS5 relay tests because proxy can't be used with muc
        # contacts atm
        return

    conn.Connect()

    _, iq_event = q.expect_many(
        EventPattern("dbus-signal", signal="StatusChanged", args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
        EventPattern("stream-iq", to=None, query_ns="vcard-temp", query_name="vCard"),
    )

    acknowledge_iq(stream, iq_event.stanza)

    self_handle = conn.GetSelfHandle()
    self_name = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0]

    t.check_conn_properties(q, conn)

    room_handle, tubes_chan, tubes_iface = get_muc_tubes_channel(q, bus, conn, stream, "*****@*****.**")

    tubes_self_handle = tubes_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP)

    bob_handle = conn.RequestHandles(cs.HT_CONTACT, ["[email protected]/bob"])[0]

    address = t.create_server(q, address_type)

    # offer stream tube (old API) using an Unix socket
    call_async(
        q,
        tubes_iface,
        "OfferStreamTube",
        "echo",
        sample_parameters,
        address_type,
        address,
        access_control,
        access_control_param,
    )

    new_tube_event, stream_event, _, new_channels_event = q.expect_many(
        EventPattern("dbus-signal", signal="NewTube"),
        EventPattern("stream-presence", to="[email protected]/test"),
        EventPattern("dbus-return", method="OfferStreamTube"),
        EventPattern("dbus-signal", signal="NewChannels"),
    )

    # handle new_tube_event
    stream_tube_id = new_tube_event.args[0]
    assert new_tube_event.args[1] == tubes_self_handle
    assert new_tube_event.args[2] == 1  # Stream
    assert new_tube_event.args[3] == "echo"
    assert new_tube_event.args[4] == sample_parameters
    assert new_tube_event.args[5] == cs.TUBE_CHANNEL_STATE_OPEN

    # handle stream_event
    # We announce our newly created tube in our muc presence
    presence = stream_event.stanza
    x_nodes = xpath.queryForNodes('/presence/x[@xmlns="http://jabber.org/' 'protocol/muc"]', presence)
    assert x_nodes is not None
    assert len(x_nodes) == 1

    tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]' % ns.TUBES, presence)
    assert tubes_nodes is not None
    assert len(tubes_nodes) == 1

    tube_nodes = xpath.queryForNodes("/tubes/tube", tubes_nodes[0])
    assert tube_nodes is not None
    assert len(tube_nodes) == 1
    for tube in tube_nodes:
        assert tube["type"] == "stream"
        assert not tube.hasAttribute("initiator")
        assert tube["service"] == "echo"
        assert not tube.hasAttribute("stream-id")
        assert not tube.hasAttribute("dbus-name")
        assert tube["id"] == str(stream_tube_id)

    params = {}
    parameter_nodes = xpath.queryForNodes("/tube/parameters/parameter", tube)
    for node in parameter_nodes:
        assert node["name"] not in params
        params[node["name"]] = (node["type"], str(node))
    assert params == {"ay": ("bytes", "aGVsbG8="), "s": ("str", "hello"), "i": ("int", "-123"), "u": ("uint", "123")}

    # tube is also announced using new API
    channels = new_channels_event.args[0]
    assert len(channels) == 1
    path, props = channels[0]
    assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE
    assert props[cs.INITIATOR_HANDLE] == tubes_self_handle
    assert props[cs.INITIATOR_ID] == "[email protected]/test"
    assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE]
    assert props[cs.REQUESTED] == True
    assert props[cs.TARGET_HANDLE] == room_handle
    assert props[cs.TARGET_ID] == "*****@*****.**"
    assert props[cs.STREAM_TUBE_SERVICE] == "echo"

    tube_chan = bus.get_object(conn.bus_name, path)
    tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True)
    assert tube_props["Parameters"] == sample_parameters
    assert tube_props["State"] == cs.TUBE_CHANNEL_STATE_OPEN

    tubes = tubes_iface.ListTubes(byte_arrays=True)
    assert tubes == [
        (stream_tube_id, tubes_self_handle, 1, "echo", sample_parameters, cs.TUBE_CHANNEL_STATE_OPEN)  # Stream
    ]

    assert len(tubes) == 1, unwrap(tubes)
    expected_tube = (
        stream_tube_id,
        tubes_self_handle,
        cs.TUBE_TYPE_STREAM,
        "echo",
        sample_parameters,
        cs.TUBE_STATE_OPEN,
    )
    t.check_tube_in_tubes(expected_tube, tubes)

    # FIXME: if we use an unknown JID here, everything fails
    # (the code uses lookup where it should use ensure)

    bytestream = connect_to_tube(stream, q, bytestream_cls, "*****@*****.**", stream_tube_id)

    iq_event, socket_event, _, conn_event = q.expect_many(
        EventPattern("stream-iq", iq_type="result"),
        EventPattern("socket-connected"),
        EventPattern(
            "dbus-signal",
            signal="StreamTubeNewConnection",
            args=[stream_tube_id, bob_handle],
            interface=cs.CHANNEL_TYPE_TUBES,
        ),
        EventPattern("dbus-signal", signal="NewRemoteConnection", interface=cs.CHANNEL_TYPE_STREAM_TUBE),
    )

    protocol = socket_event.protocol

    # handle iq_event
    bytestream.check_si_reply(iq_event.stanza)
    tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza)
    assert len(tube) == 1

    handle, access, conn_id = conn_event.args
    assert handle == bob_handle

    use_tube(q, bytestream, protocol, conn_id)

    # offer a stream tube to another room (new API)
    address = t.create_server(q, address_type, block_reading=True)

    request = {
        cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
        cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
        cs.TARGET_ID: "*****@*****.**",
        cs.STREAM_TUBE_SERVICE: "newecho",
    }
    _, _, new_tube_path, new_tube_props = join_muc(q, bus, conn, stream, "*****@*****.**", request)

    # first text and tubes channels are announced
    event = q.expect("dbus-signal", signal="NewChannels")
    channels = event.args[0]
    assert len(channels) == 2
    path1, prop1 = channels[0]
    path2, prop2 = channels[1]
    assert sorted([prop1[cs.CHANNEL_TYPE], prop2[cs.CHANNEL_TYPE]]) == [cs.CHANNEL_TYPE_TEXT, cs.CHANNEL_TYPE_TUBES]

    got_text, got_tubes = False, False
    for path, props in channels:
        if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT:
            got_text = True
        elif props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TUBES:
            got_tubes = True
        else:
            assert False

        assert props[cs.INITIATOR_HANDLE] == self_handle
        assert props[cs.INITIATOR_ID] == self_name
        assert cs.CHANNEL_IFACE_GROUP in props[cs.INTERFACES]
        assert props[cs.TARGET_ID] == "*****@*****.**"
        assert props[cs.REQUESTED] == False

    assert (got_text, got_tubes) == (True, True)

    # now the tube channel is announced
    # FIXME: in this case, all channels should probably be announced together
    event = q.expect("dbus-signal", signal="NewChannels")
    channels = event.args[0]
    assert len(channels) == 1
    path, prop = channels[0]
    assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE
    assert prop[cs.INITIATOR_ID] == "[email protected]/test"
    assert prop[cs.REQUESTED] == True
    assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM
    assert prop[cs.TARGET_ID] == "*****@*****.**"
    assert prop[cs.STREAM_TUBE_SERVICE] == "newecho"

    # check that the tube channel is in the channels list
    all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, "Channels", dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True)
    assertContains((path, prop), all_channels)

    tube_chan = bus.get_object(conn.bus_name, path)
    stream_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE)
    chan_iface = dbus.Interface(tube_chan, cs.CHANNEL)
    tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE)

    assert tube_props["State"] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED

    # offer the tube
    call_async(q, stream_tube_iface, "Offer", address_type, address, access_control, {"foo": "bar"})

    new_tube_event, stream_event, _, status_event = q.expect_many(
        EventPattern("dbus-signal", signal="NewTube"),
        EventPattern("stream-presence", to="[email protected]/test"),
        EventPattern("dbus-return", method="Offer"),
        EventPattern("dbus-signal", signal="TubeChannelStateChanged", args=[cs.TUBE_CHANNEL_STATE_OPEN]),
    )

    tube_self_handle = tube_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP)
    assert conn.InspectHandles(cs.HT_CONTACT, [tube_self_handle]) == ["[email protected]/test"]

    # handle new_tube_event
    stream_tube_id = new_tube_event.args[0]
    assert new_tube_event.args[2] == 1  # Stream
    assert new_tube_event.args[3] == "newecho"
    assert new_tube_event.args[4] == {"foo": "bar"}
    assert new_tube_event.args[5] == cs.TUBE_CHANNEL_STATE_OPEN

    presence = stream_event.stanza
    x_nodes = xpath.queryForNodes('/presence/x[@xmlns="http://jabber.org/' 'protocol/muc"]', presence)
    assert x_nodes is not None
    assert len(x_nodes) == 1

    tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]' % ns.TUBES, presence)
    assert tubes_nodes is not None
    assert len(tubes_nodes) == 1

    tube_nodes = xpath.queryForNodes("/tubes/tube", tubes_nodes[0])
    assert tube_nodes is not None
    assert len(tube_nodes) == 1
    for tube in tube_nodes:
        assert tube["type"] == "stream"
        assert not tube.hasAttribute("initiator")
        assert tube["service"] == "newecho"
        assert not tube.hasAttribute("stream-id")
        assert not tube.hasAttribute("dbus-name")
        assert tube["id"] == str(stream_tube_id)

    params = {}
    parameter_nodes = xpath.queryForNodes("/tube/parameters/parameter", tube)
    for node in parameter_nodes:
        assert node["name"] not in params
        params[node["name"]] = (node["type"], str(node))
    assert params == {"foo": ("str", "bar")}

    bob_handle = conn.RequestHandles(cs.HT_CONTACT, ["[email protected]/bob"])[0]

    bytestream = connect_to_tube(stream, q, bytestream_cls, "*****@*****.**", stream_tube_id)

    iq_event, socket_event, conn_event = q.expect_many(
        EventPattern("stream-iq", iq_type="result"),
        EventPattern("socket-connected"),
        EventPattern("dbus-signal", signal="NewRemoteConnection", interface=cs.CHANNEL_TYPE_STREAM_TUBE),
    )

    handle, access, conn_id = conn_event.args
    assert handle == bob_handle

    protocol = socket_event.protocol
    # start to read from the transport so we can read the control byte
    protocol.transport.startReading()
    t.check_new_connection_access(q, access_control, access, protocol)

    # handle iq_event
    bytestream.check_si_reply(iq_event.stanza)
    tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza)
    assert len(tube) == 1

    use_tube(q, bytestream, protocol, conn_id)

    chan_iface.Close()
    q.expect_many(EventPattern("dbus-signal", signal="Closed"), EventPattern("dbus-signal", signal="ChannelClosed"))
示例#36
0
def test(q, bus, conn, sip):
    conn.Connect()
    q.expect('dbus-signal', signal='StatusChanged', args=[0, 1])

    self_handle = conn.Get(cs.CONN,
                           'SelfHandle',
                           dbus_interface=cs.PROPERTIES_IFACE)
    self_uri = conn.inspect_contact_sync(self_handle)

    contact = 'sip:[email protected]'
    handle = conn.get_contact_handle_sync(contact)

    chan, _ = conn.Requests.CreateChannel({
        cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
        cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
        cs.TARGET_HANDLE: handle
    })

    requested_obj, target_handle = test_new_channel(q,
                                                    bus,
                                                    conn,
                                                    target_uri=contact,
                                                    initiator_uri=self_uri,
                                                    requested=True)

    assert requested_obj.object_path == chan, requested_obj.object_path
    assert target_handle == handle, (target_handle, handle)

    iface = dbus.Interface(requested_obj, cs.CHANNEL_TYPE_TEXT)

    iface.Send(0, 'Hello')

    event = q.expect('sip-message', uri='sip:[email protected]', body='Hello')
    sip.deliverResponse(sip.responseFromRequest(404, event.sip_message))

    q.expect('dbus-signal', signal='SendError')

    iface.Send(0, 'Hello Again')

    event = q.expect('sip-message',
                     uri='sip:[email protected]',
                     body='Hello Again')
    sip.deliverResponse(sip.responseFromRequest(200, event.sip_message))

    ua_via = twisted.protocols.sip.parseViaHeader(event.headers['via'][0])

    conn.ReleaseHandles(1, [handle])

    call_id = 'XYZ@localhost'
    send_message(sip, ua_via, 'Hi', call_id=call_id, time=1234567890)

    incoming_obj, handle = test_new_channel(q,
                                            bus,
                                            conn,
                                            target_uri=FROM_URL,
                                            initiator_uri=FROM_URL,
                                            requested=False)

    iface = dbus.Interface(incoming_obj, cs.CHANNEL_TYPE_TEXT)

    name = conn.inspect_contact_sync(handle)
    assert name == FROM_URL

    event = q.expect('dbus-signal', signal='MessageReceived')
    msg = event.args[0]
    now = time.time()
    assert msg[0]['message-token'] == "%s;cseq=%u" % (call_id, cseq_num)
    assert now - 10 < msg[0]['message-received'] < now + 10
    assert msg[0]['message-sent'] == 1234567890
    assert msg[1]['content-type'] == 'text/plain'
    assert msg[1]['content'] == 'Hi'

    # FIXME: times out for some reason, the response is in fact sent;
    # race condition with the earlier wait for 'dbus-signal'?
    #event = q.expect('sip-response', code=200)

    iface.AcknowledgePendingMessages([msg[0]['pending-message-id']])

    # Test conversion from an 8-bit encoding.
    # Due to limited set of encodings available in some environments,
    # try with US ASCII and ISO 8859-1.

    send_message(sip,
                 ua_via,
                 u'straight ASCII'.encode('us-ascii'),
                 encoding='us-ascii')
    event = q.expect('dbus-signal', signal='Received')
    assert event.args[5] == 'straight ASCII'

    iface.AcknowledgePendingMessages([event.args[0]])

    send_message(sip,
                 ua_via,
                 u'Hyv\xe4!'.encode('iso-8859-1'),
                 encoding='iso-8859-1')
    event = q.expect('dbus-signal', signal='Received')
    assert event.args[5] == u'Hyv\xe4!'

    conn.ReleaseHandles(1, [handle])

    iface = dbus.Interface(incoming_obj, cs.CHANNEL_IFACE_DESTROYABLE)
    iface.Destroy()
    del iface
    event = q.expect('dbus-signal', signal='Closed')
    del incoming_obj

    # Sending the message to appear on the requested channel
    pending_msgs = []

    send_message(sip,
                 ua_via,
                 'How are you doing now, old pal?',
                 sender=contact)
    event = q.expect('dbus-signal', signal='Received', path=chan)
    assert event.args[5] == 'How are you doing now, old pal?'
    pending_msgs.append(tuple(event.args))

    send_message(sip, ua_via, 'I hope you can receive it', sender=contact)
    event = q.expect('dbus-signal', signal='Received')
    assert event.args[5] == 'I hope you can receive it'
    pending_msgs.append(tuple(event.args))

    # Don't acknowledge the last messages, close the channel so that it's reopened
    dbus.Interface(requested_obj, cs.CHANNEL).Close()
    del requested_obj

    event = q.expect('dbus-signal', signal='Closed', path=chan)

    requested_obj, handle = test_new_channel(q,
                                             bus,
                                             conn,
                                             target_uri=contact,
                                             initiator_uri=contact,
                                             requested=False)

    # Expect Channel_Text_Message_Flag_Resqued to be set
    pending_msgs = [message_with_resqued(msg) for msg in pending_msgs]
    # The first message is the delivery report of the message we failed to
    # send so we'll skip it.

    iface = dbus.Interface(requested_obj, cs.CHANNEL_TYPE_TEXT)

    pending_res = iface.ListPendingMessages(False)
    assert pending_msgs == pending_res[1:], (pending_msgs,
                                             unwrap(pending_res)[1:])

    pending_res = iface.ListPendingMessages(True)
    assert pending_msgs == pending_res[1:], (pending_msgs,
                                             unwrap(pending_res)[1:])

    # There should be no pending messages any more
    pending_res = iface.ListPendingMessages(False)
    assert pending_res == [], pending_res

    del iface

    # Hit also the code path for closing the channel with no pending messages
    dbus.Interface(requested_obj, cs.CHANNEL).Close()
    event = q.expect('dbus-signal', signal='Closed')
    del requested_obj

    # Hit the message zapping path when the connection is disconnected
    send_message(sip, ua_via, 'Will you leave this unacknowledged?')
    test_new_channel(q,
                     bus,
                     conn,
                     target_uri=FROM_URL,
                     initiator_uri=FROM_URL,
                     requested=False)

    conn.Disconnect()

    # Check the last channel with an unacknowledged message
    event = q.expect('dbus-signal', signal='Closed')

    q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])
        'resource': 'Resource',
        'server': 'localhost',
        'port': dbus.UInt32(4343),
    }
    conn2, jid2 = make_connection(bus, queue.append, params)
    authenticator = XmppAuthenticator('test2', 'pass')
    stream2 = make_stream(queue.append, authenticator, protocol=XmppXmlStream)

    factory = twisted.internet.protocol.Factory()
    factory.protocol = lambda: stream2
    port1 = reactor.listenTCP(4343, factory, interface='localhost')

    bus.add_signal_receiver(
        lambda *args, **kw: queue.append(
            Event('dbus-signal',
                  path=unwrap(kw['path']),
                  signal=kw['member'],
                  args=map(unwrap, args),
                  interface=kw['interface'])),
        None,  # signal name
        None,  # interface
        None,
        path_keyword='path',
        member_keyword='member',
        interface_keyword='interface',
        byte_arrays=True)

    try:
        test(queue, bus, conn1, conn2, stream1, stream2)
    finally:
        try:
示例#38
0
def test(q, bus, conn, stream):
    cm = bus.get_object(cs.CM + '.gabble',
        tp_path_prefix + '/ConnectionManager/gabble')
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['jabber']), set(protocols.keys()))

    jabber_props = protocols['jabber']

    proto = bus.get_object(cm.bus_name, cm.object_path + '/jabber')
    proto_iface = dbus.Interface(proto, cs.PROTOCOL)
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in ['Parameters', 'Interfaces', 'ConnectionInterfaces',
      'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon']:
        a = jabber_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('*****@*****.**',
        unwrap(proto_iface.NormalizeContact('[email protected]/Telepathy')))

    # Protocol.Interface.Presence
    expected_status = {'available': (cs.PRESENCE_AVAILABLE,     True,  True),
                       'dnd'      : (cs.PRESENCE_BUSY,          True,  True),
                       'unknown'  : (cs.PRESENCE_UNKNOWN,       False, False),
                       'away'     : (cs.PRESENCE_AWAY,          True,  True),
                       'xa'       : (cs.PRESENCE_EXTENDED_AWAY, True,  True),
                       'chat'     : (cs.PRESENCE_AVAILABLE,     True,  True),
                       'error'    : (cs.PRESENCE_ERROR,         False, False),
                       'offline'  : (cs.PRESENCE_OFFLINE,       False, False),
                       'testaway' : (cs.PRESENCE_AWAY,          False, False),
                       'testbusy' : (cs.PRESENCE_BUSY,          True,  False),
                       'hidden'   : (cs.PRESENCE_HIDDEN,        True,  True)}

    presences = proto_prop_iface.Get(cs.PROTOCOL_IFACE_PRESENCES, 'Statuses');
    # Plugins could add additional statuses, so we check if expected_status is
    # included in presences rather than equality.
    for k, v in expected_status.iteritems():
        assertEquals(expected_status[k], unwrap(presences[k]))

    # (Only) 'account' is mandatory for IdentifyAccount()
    call_async(q, proto_iface, 'IdentifyAccount', {})
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)

    test_params = { 'account': 'test@localhost' }
    acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
    assertEquals(test_params['account'], acc_name)

    assertContains(cs.PROTOCOL_IFACE_AVATARS, proto_props['Interfaces'])
    avatar_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL_IFACE_AVATARS))
    assertEquals(8192, avatar_props['MaximumAvatarBytes'])
    assertEquals(96, avatar_props['MaximumAvatarHeight'])
    assertEquals(96, avatar_props['MaximumAvatarWidth'])
    assertEquals(32, avatar_props['MinimumAvatarHeight'])
    assertEquals(32, avatar_props['MinimumAvatarWidth'])
    assertEquals(64, avatar_props['RecommendedAvatarHeight'])
    assertEquals(64, avatar_props['RecommendedAvatarWidth'])
    assertEquals(['image/png', 'image/jpeg', 'image/gif'], avatar_props['SupportedAvatarMIMETypes'])

    conn.Connect()
    q.expect('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTING, cs.CSR_REQUESTED])
    q.expect('stream-authenticated')
    q.expect('dbus-signal', signal='PresencesChanged',
        args=[{1L: (cs.PRESENCE_AVAILABLE, 'available', '')}])
示例#39
0
def test(q, bus, conn, stream):
    conn.Connect()

    properties = conn.GetAll(cs.CONN_IFACE_REQUESTS,
                             dbus_interface=cs.PROPERTIES_IFACE)
    assert properties.get('Channels') == [], properties['Channels']
    assert ({cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
             cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
             },
             [cs.TARGET_HANDLE, cs.TARGET_ID, cs.STREAM_TUBE_SERVICE]
             ) in properties.get('RequestableChannelClasses'),\
                     unwrap(properties['RequestableChannelClasses'])

    _, vcard_event, roster_event = q.expect_many(
        EventPattern('dbus-signal',
                     signal='StatusChanged',
                     args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
        EventPattern('stream-iq',
                     to=None,
                     query_ns='vcard-temp',
                     query_name='vCard'),
        EventPattern('stream-iq', query_ns=ns.ROSTER))

    acknowledge_iq(stream, vcard_event.stanza)

    roster = roster_event.stanza
    roster['type'] = 'result'
    item = roster_event.query.addElement('item')
    item['jid'] = 'bob@localhost'
    item['subscription'] = 'both'
    stream.send(roster)

    presence = domish.Element(('jabber:client', 'presence'))
    presence['from'] = 'bob@localhost/Bob'
    presence['to'] = 'test@localhost/Resource'
    c = presence.addElement('c')
    c['xmlns'] = 'http://jabber.org/protocol/caps'
    c['node'] = 'http://example.com/ICantBelieveItsNotTelepathy'
    c['ver'] = '1.2.3'
    stream.send(presence)

    event = q.expect('stream-iq',
                     iq_type='get',
                     query_ns='http://jabber.org/protocol/disco#info',
                     to='bob@localhost/Bob')
    result = event.stanza
    result['type'] = 'result'
    assert event.query['node'] == \
        'http://example.com/ICantBelieveItsNotTelepathy#1.2.3'
    feature = event.query.addElement('feature')
    feature['var'] = ns.TUBES
    stream.send(result)

    bob_handle = conn.get_contact_handle_sync('bob@localhost')

    def new_chan_predicate(e):
        types = []
        for _, props in e.args[0]:
            types.append(props[cs.CHANNEL_TYPE])

        return cs.CHANNEL_TYPE_STREAM_TUBE in types

    call_async(
        q, conn.Requests, 'CreateChannel', {
            cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
            cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
            cs.TARGET_HANDLE: bob_handle,
            cs.STREAM_TUBE_SERVICE: 'the.service',
        })

    ret, _ = q.expect_many(
        EventPattern('dbus-return', method='CreateChannel'),
        EventPattern('dbus-signal',
                     signal='NewChannels',
                     predicate=new_chan_predicate),
    )

    chan_path, props = ret.value

    # Ensure a tube to the same person; check it's the same one.
    #    call_async(q, conn.Requests, 'EnsureChannel',
    #            { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
    #              cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
    #              cs.TARGET_HANDLE: bob_handle,
    #              cs.STREAM_TUBE_SERVICE: 'the.service',
    #              })

    #    ret = q.expect('dbus-return', method='EnsureChannel')
    #    yours, ensured_path, _ = ret.value

    #    assert ensured_path == chan_path, (ensured_path, chan_path)
    #    assert not yours

    chan = bus.get_object(conn.bus_name, chan_path)
    chan.Close()

    # Now let's try ensuring a new tube.
    call_async(
        q, conn.Requests, 'EnsureChannel', {
            cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
            cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
            cs.TARGET_HANDLE: bob_handle,
            cs.STREAM_TUBE_SERVICE: 'the.service',
        })

    ret, new_sig = q.expect_many(
        EventPattern('dbus-return', method='EnsureChannel'),
        EventPattern('dbus-signal',
                     signal='NewChannels',
                     predicate=new_chan_predicate),
    )

    yours, path, props = ret.value
    assert yours

    emitted_props = new_sig.args[0][0][1]
    assert props == emitted_props, (props, emitted_props)

    chan = bus.get_object(conn.bus_name, path)
    chan.Close()
def test(q, bus, conn, stream, bytestream_cls,
       address_type, access_control, access_control_param):
    if bytestream_cls in [BytestreamS5BRelay, BytestreamS5BRelayBugged]:
        # disable SOCKS5 relay tests because proxy can't be used with muc
        # contacts atm
        return

    iq_event = q.expect('stream-iq', to=None, query_ns='vcard-temp',
            query_name='vCard')

    acknowledge_iq(stream, iq_event.stanza)

    self_handle = conn.GetSelfHandle()
    self_name = conn.InspectHandles(cs.HT_CONTACT, [self_handle])[0]

    t.check_conn_properties(q, conn)

    room_handle, tubes_chan, tubes_iface = get_muc_tubes_channel(q, bus, conn,
        stream, '*****@*****.**')

    tubes_self_handle = tubes_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP)

    bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['[email protected]/bob'])[0]

    address = t.create_server(q, address_type)

    # offer stream tube (old API) using an Unix socket
    call_async(q, tubes_iface, 'OfferStreamTube',
        'echo', sample_parameters, address_type, address,
        access_control, access_control_param)

    new_tube_event, stream_event, _, new_channels_event = q.expect_many(
        EventPattern('dbus-signal', signal='NewTube'),
        EventPattern('stream-presence', to='[email protected]/test'),
        EventPattern('dbus-return', method='OfferStreamTube'),
        EventPattern('dbus-signal', signal='NewChannels'))

    # handle new_tube_event
    stream_tube_id = new_tube_event.args[0]
    assert new_tube_event.args[1] == tubes_self_handle
    assert new_tube_event.args[2] == 1       # Stream
    assert new_tube_event.args[3] == 'echo'
    assert new_tube_event.args[4] == sample_parameters
    assert new_tube_event.args[5] == cs.TUBE_CHANNEL_STATE_OPEN

    # handle stream_event
    # We announce our newly created tube in our muc presence
    presence = stream_event.stanza
    tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]'
        % ns.TUBES, presence)
    assert tubes_nodes is not None
    assert len(tubes_nodes) == 1

    tube_nodes = xpath.queryForNodes('/tubes/tube', tubes_nodes[0])
    assert tube_nodes is not None
    assert len(tube_nodes) == 1
    for tube in tube_nodes:
        assert tube['type'] == 'stream'
        assert not tube.hasAttribute('initiator')
        assert tube['service'] == 'echo'
        assert not tube.hasAttribute('stream-id')
        assert not tube.hasAttribute('dbus-name')
        assert tube['id'] == str(stream_tube_id)

    params = {}
    parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube)
    for node in parameter_nodes:
        assert node['name'] not in params
        params[node['name']] = (node['type'], str(node))
    assert params == {'ay': ('bytes', 'aGVsbG8='),
                      's': ('str', 'hello'),
                      'i': ('int', '-123'),
                      'u': ('uint', '123'),
                     }

    # tube is also announced using new API
    channels = new_channels_event.args[0]
    assert len(channels) == 1
    path, props = channels[0]
    assert props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE
    assert props[cs.INITIATOR_HANDLE] == tubes_self_handle
    assert props[cs.INITIATOR_ID] == '[email protected]/test'
    assert props[cs.INTERFACES] == [cs.CHANNEL_IFACE_GROUP, cs.CHANNEL_IFACE_TUBE]
    assert props[cs.REQUESTED] == True
    assert props[cs.TARGET_HANDLE] == room_handle
    assert props[cs.TARGET_ID] == '*****@*****.**'
    assert props[cs.STREAM_TUBE_SERVICE] == 'echo'

    tube_chan = bus.get_object(conn.bus_name, path)
    tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE,
        byte_arrays=True)
    assert tube_props['Parameters'] == sample_parameters
    assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_OPEN

    tubes = tubes_iface.ListTubes(byte_arrays=True)
    assert tubes == [(
        stream_tube_id,
        tubes_self_handle,
        1,      # Stream
        'echo',
        sample_parameters,
        cs.TUBE_CHANNEL_STATE_OPEN
        )]

    assert len(tubes) == 1, unwrap(tubes)
    expected_tube = (stream_tube_id, tubes_self_handle, cs.TUBE_TYPE_STREAM,
        'echo', sample_parameters, cs.TUBE_STATE_OPEN)
    t.check_tube_in_tubes(expected_tube, tubes)

    # FIXME: if we use an unknown JID here, everything fails
    # (the code uses lookup where it should use ensure)

    bytestream = connect_to_tube(stream, q, bytestream_cls, '*****@*****.**', stream_tube_id)

    iq_event, socket_event, _, conn_event = q.expect_many(
        EventPattern('stream-iq', iq_type='result'),
        EventPattern('socket-connected'),
        EventPattern('dbus-signal', signal='StreamTubeNewConnection',
            args=[stream_tube_id, bob_handle], interface=cs.CHANNEL_TYPE_TUBES),
        EventPattern('dbus-signal', signal='NewRemoteConnection',
            interface=cs.CHANNEL_TYPE_STREAM_TUBE))

    protocol = socket_event.protocol

    # handle iq_event
    bytestream.check_si_reply(iq_event.stanza)
    tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza)
    assert len(tube) == 1

    handle, access, conn_id = conn_event.args
    assert handle == bob_handle

    use_tube(q, bytestream, protocol, conn_id)

    # offer a stream tube to another room (new API)
    address = t.create_server(q, address_type, block_reading=True)

    request = {
        cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
        cs.TARGET_HANDLE_TYPE: cs.HT_ROOM,
        cs.TARGET_ID: '*****@*****.**',
        cs.STREAM_TUBE_SERVICE: 'newecho',
    }
    _, _, new_tube_path, new_tube_props = \
        join_muc(q, bus, conn, stream, '*****@*****.**', request)

    # The order in which the NewChannels signals are fired is
    # undefined -- it could be the (tubes, text) channels first, or it
    # could be the tube channel first; so let's accept either order
    # here.

    first, second = q.expect_many(
        EventPattern('dbus-signal', signal='NewChannels'),
        EventPattern('dbus-signal', signal='NewChannels'))

    # NewChannels signal with the text and tubes channels together.
    def nc_textandtubes(event):
        channels = event.args[0]
        assert len(channels) == 2
        path1, prop1 = channels[0]
        path2, prop2 = channels[1]
        assert sorted([prop1[cs.CHANNEL_TYPE], prop2[cs.CHANNEL_TYPE]]) == \
            [cs.CHANNEL_TYPE_TEXT, cs.CHANNEL_TYPE_TUBES]

        got_text, got_tubes = False, False
        for path, props in channels:
            if props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TEXT:
                got_text = True
            elif props[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_TUBES:
                got_tubes = True
            else:
                assert False

            assert props[cs.INITIATOR_HANDLE] == self_handle
            assert props[cs.INITIATOR_ID] == self_name
            assert cs.CHANNEL_IFACE_GROUP in props[cs.INTERFACES]
            assert props[cs.TARGET_ID] == '*****@*****.**'
            assert props[cs.REQUESTED] == False

        assert (got_text, got_tubes) == (True, True)

    # NewChannels signal with the tube channel.
    def nc_tube(event):
        # FIXME: in this case, all channels should probably be announced together
        channels = event.args[0]
        assert len(channels) == 1
        path, prop = channels[0]
        assert prop[cs.CHANNEL_TYPE] == cs.CHANNEL_TYPE_STREAM_TUBE
        assert prop[cs.INITIATOR_ID] == '[email protected]/test'
        assert prop[cs.REQUESTED] == True
        assert prop[cs.TARGET_HANDLE_TYPE] == cs.HT_ROOM
        assert prop[cs.TARGET_ID] == '*****@*****.**'
        assert prop[cs.STREAM_TUBE_SERVICE] == 'newecho'

        return path, prop

    if len(first.args[0]) == 1:
        path, prop = nc_tube(first)
        nc_textandtubes(second)
    else:
        nc_textandtubes(first)
        path, prop = nc_tube(second)

    # check that the tube channel is in the channels list
    all_channels = conn.Get(cs.CONN_IFACE_REQUESTS, 'Channels',
        dbus_interface=cs.PROPERTIES_IFACE, byte_arrays=True)
    assertContains((path, prop), all_channels)

    tube_chan = bus.get_object(conn.bus_name, path)
    stream_tube_iface = dbus.Interface(tube_chan, cs.CHANNEL_TYPE_STREAM_TUBE)
    chan_iface = dbus.Interface(tube_chan, cs.CHANNEL)
    tube_props = tube_chan.GetAll(cs.CHANNEL_IFACE_TUBE, dbus_interface=cs.PROPERTIES_IFACE)

    assert tube_props['State'] == cs.TUBE_CHANNEL_STATE_NOT_OFFERED

    # offer the tube
    call_async(q, stream_tube_iface, 'Offer', address_type, address, access_control, {'foo': 'bar'})

    new_tube_event, stream_event, _, status_event = q.expect_many(
        EventPattern('dbus-signal', signal='NewTube'),
        EventPattern('stream-presence', to='[email protected]/test'),
        EventPattern('dbus-return', method='Offer'),
        EventPattern('dbus-signal', signal='TubeChannelStateChanged', args=[cs.TUBE_CHANNEL_STATE_OPEN]))

    tube_self_handle = tube_chan.GetSelfHandle(dbus_interface=cs.CHANNEL_IFACE_GROUP)
    assert conn.InspectHandles(cs.HT_CONTACT, [tube_self_handle]) == ['[email protected]/test']

    # handle new_tube_event
    stream_tube_id = new_tube_event.args[0]
    assert new_tube_event.args[2] == 1       # Stream
    assert new_tube_event.args[3] == 'newecho'
    assert new_tube_event.args[4] == {'foo': 'bar'}
    assert new_tube_event.args[5] == cs.TUBE_CHANNEL_STATE_OPEN

    presence = stream_event.stanza
    tubes_nodes = xpath.queryForNodes('/presence/tubes[@xmlns="%s"]'
        % ns.TUBES, presence)
    assert tubes_nodes is not None
    assert len(tubes_nodes) == 1

    tube_nodes = xpath.queryForNodes('/tubes/tube', tubes_nodes[0])
    assert tube_nodes is not None
    assert len(tube_nodes) == 1
    for tube in tube_nodes:
        assert tube['type'] == 'stream'
        assert not tube.hasAttribute('initiator')
        assert tube['service'] == 'newecho'
        assert not tube.hasAttribute('stream-id')
        assert not tube.hasAttribute('dbus-name')
        assert tube['id'] == str(stream_tube_id)

    params = {}
    parameter_nodes = xpath.queryForNodes('/tube/parameters/parameter', tube)
    for node in parameter_nodes:
        assert node['name'] not in params
        params[node['name']] = (node['type'], str(node))
    assert params == {'foo': ('str', 'bar')}

    bob_handle = conn.RequestHandles(cs.HT_CONTACT, ['[email protected]/bob'])[0]

    bytestream = connect_to_tube(stream, q, bytestream_cls, '*****@*****.**', stream_tube_id)

    iq_event, socket_event, conn_event = q.expect_many(
        EventPattern('stream-iq', iq_type='result'),
        EventPattern('socket-connected'),
        EventPattern('dbus-signal', signal='NewRemoteConnection',
            interface=cs.CHANNEL_TYPE_STREAM_TUBE))

    handle, access, conn_id = conn_event.args
    assert handle == bob_handle

    protocol = socket_event.protocol
    # start to read from the transport so we can read the control byte
    protocol.transport.startReading()
    t.check_new_connection_access(q, access_control, access, protocol)

    # handle iq_event
    bytestream.check_si_reply(iq_event.stanza)
    tube = xpath.queryForNodes('/iq//si/tube[@xmlns="%s"]' % ns.TUBES, iq_event.stanza)
    assert len(tube) == 1

    use_tube(q, bytestream, protocol, conn_id)

    chan_iface.Close()
    q.expect_many(
        EventPattern('dbus-signal', signal='Closed'),
        EventPattern('dbus-signal', signal='ChannelClosed'))
def test(jp, q, bus, conn, stream, peer='[email protected]/Foo'):
    jt = JingleTest2(jp, conn, q, stream, 'test@localhost', peer)
    jt.prepare()

    self_handle = conn.GetSelfHandle()
    remote_handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]

    # Remote end calls us
    jt.incoming_call()

    # If this is a Jingle dialect that supports it, Gabble should send a
    # <ringing/> notification when it gets the session-initiate until Telepathy
    # has a way for the UI to do this.
    # https://bugs.freedesktop.org/show_bug.cgi?id=21964
    ringing_event = jp.rtp_info_event_list("ringing")

    if jp.dialect == 'gtalk-v0.4':
        # With gtalk4, apparently we have to send transport-accept immediately,
        # not even just before we send our transport-info. wjt tested this, and
        # indeed if we don't send this for incoming calls, the call never
        # connects.
        ta_event = [
            EventPattern('stream-iq', predicate=lambda x:
                xpath.queryForNodes("/iq/session[@type='transport-accept']",
                    x.stanza)),
            ]
    else:
        ta_event = []

    nc, e = q.expect_many(
        EventPattern('dbus-signal', signal='NewChannel',
            predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
        EventPattern('dbus-signal', signal='NewSessionHandler'),
        *(ringing_event + ta_event)
        )[0:2]
    path, ct, ht, h, _ = nc.args

    assert ct == cs.CHANNEL_TYPE_STREAMED_MEDIA, ct
    assert ht == cs.HT_CONTACT, ht
    assert h == remote_handle, h

    media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
    media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')

    # S-E was notified about new session handler, and calls Ready on it
    assert e.args[1] == 'rtp'
    session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
    session_handler.Ready()

    nsh_event = q.expect('dbus-signal', signal='NewStreamHandler')

    # S-E gets notified about a newly-created stream
    stream_handler = make_channel_proxy(conn, nsh_event.args[0],
        'Media.StreamHandler')

    streams = media_iface.ListStreams()
    assertLength(1, streams)

    stream_id, stream_handle, stream_type, _, stream_direction, pending_flags =\
        streams[0]
    assertEquals(remote_handle, stream_handle)
    assertEquals(cs.MEDIA_STREAM_TYPE_AUDIO, stream_type)
    assertEquals(cs.MEDIA_STREAM_DIRECTION_RECEIVE, stream_direction)
    assertEquals(cs.MEDIA_STREAM_PENDING_LOCAL_SEND, pending_flags)

    # Exercise channel properties
    channel_props = media_chan.GetAll(
        cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)
    assertEquals(remote_handle, channel_props['TargetHandle'])
    assertEquals(cs.HT_CONTACT, channel_props['TargetHandleType'])
    assertEquals((cs.HT_CONTACT, remote_handle),
            media_chan.GetHandle(dbus_interface=cs.CHANNEL))
    assertEquals(jt.peer_bare_jid, channel_props['TargetID'])
    assertEquals(jt.peer_bare_jid, channel_props['InitiatorID'])
    assertEquals(remote_handle, channel_props['InitiatorHandle'])
    assertEquals(False, channel_props['Requested'])

    group_props = media_chan.GetAll(
        cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE)

    assert group_props['SelfHandle'] == self_handle, \
        (group_props['SelfHandle'], self_handle)

    flags = group_props['GroupFlags']
    assert flags & cs.GF_PROPERTIES, flags
    # Changing members in any way other than adding or removing yourself is
    # meaningless for incoming calls, and the flags need not be sent to change
    # your own membership.
    assert not flags & cs.GF_CAN_ADD, flags
    assert not flags & cs.GF_CAN_REMOVE, flags
    assert not flags & cs.GF_CAN_RESCIND, flags

    assert group_props['Members'] == [remote_handle], group_props['Members']
    assert group_props['RemotePendingMembers'] == [], \
        group_props['RemotePendingMembers']
    # We're local pending because remote_handle invited us.
    assert group_props['LocalPendingMembers'] == \
        [(self_handle, remote_handle, cs.GC_REASON_INVITED, '')], \
        unwrap(group_props['LocalPendingMembers'])

    streams = media_chan.ListStreams(
            dbus_interface=cs.CHANNEL_TYPE_STREAMED_MEDIA)
    assert len(streams) == 1, streams
    assert len(streams[0]) == 6, streams[0]
    # streams[0][0] is the stream identifier, which in principle we can't
    # make any assertion about (although in practice it's probably 1)
    assert streams[0][1] == remote_handle, (streams[0], remote_handle)
    assert streams[0][2] == cs.MEDIA_STREAM_TYPE_AUDIO, streams[0]
    # We haven't connected yet
    assert streams[0][3] == cs.MEDIA_STREAM_STATE_DISCONNECTED, streams[0]
    # In Gabble, incoming streams start off with remote send enabled, and
    # local send requested
    assert streams[0][4] == cs.MEDIA_STREAM_DIRECTION_RECEIVE, streams[0]
    assert streams[0][5] == cs.MEDIA_STREAM_PENDING_LOCAL_SEND, streams[0]

    # Connectivity checks happen before we have accepted the call
    stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
    stream_handler.Ready(jt.get_audio_codecs_dbus())
    stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
    stream_handler.SupportedCodecs(jt.get_audio_codecs_dbus())

    # peer gets the transport
    e = q.expect('stream-iq', predicate=jp.action_predicate('transport-info'))
    assertEquals(jt.peer, e.query['initiator'])

    if jp.dialect in ['jingle-v0.15', 'jingle-v0.31']:
        content = xpath.queryForNodes('/iq/jingle/content', e.stanza)[0]
        assertEquals('initiator', content['creator'])

    stream.send(make_result_iq(stream, e.stanza))

    # At last, accept the call
    media_chan.AddMembers([self_handle], 'accepted')

    # Call is accepted, we become a member, and the stream that was pending
    # local send is now sending.
    memb, acc, _, _, _ = q.expect_many(
        EventPattern('dbus-signal', signal='MembersChanged',
            args=[u'', [self_handle], [], [], [], self_handle,
                  cs.GC_REASON_NONE]),
        EventPattern('stream-iq',
            predicate=jp.action_predicate('session-accept')),
        EventPattern('dbus-signal', signal='SetStreamSending', args=[True]),
        EventPattern('dbus-signal', signal='SetStreamPlaying', args=[True]),
        EventPattern('dbus-signal', signal='StreamDirectionChanged',
            args=[stream_id, cs.MEDIA_STREAM_DIRECTION_BIDIRECTIONAL, 0]),
        )

    stream.send(make_result_iq(stream, acc.stanza))

    # Also, if this is a Jingle dialect that supports it, Gabble should send an
    # <active/> notification when the session-accept is acked (until the
    # Telepathy spec lets the UI say it's not ringing any more).
    active_event = jp.rtp_info_event("active")
    if active_event is not None:
        q.expect_many(active_event)

    # we are now both in members
    members = media_chan.GetMembers()
    assert set(members) == set([self_handle, remote_handle]), members

    # Connected! Blah, blah, ...

    # 'Nuff said
    jt.terminate()
    q.expect('dbus-signal', signal='Closed', path=path)
def _test_terminate_reason(jp, q, bus, conn, stream, incoming):
    jt = JingleTest2(jp, conn, q, stream, 'test@localhost', '[email protected]/Foo')
    jt.prepare()

    self_handle = conn.GetSelfHandle()
    remote_handle = conn.RequestHandles(cs.HT_CONTACT, [jt.peer])[0]

    if incoming:
        jt.incoming_call()
    else:
        ret = conn.Requests.CreateChannel(
            { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAMED_MEDIA,
              cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
              cs.TARGET_HANDLE: remote_handle,
              cs.INITIAL_AUDIO: True
              })

    nc, e = q.expect_many(
        EventPattern('dbus-signal', signal='NewChannel',
            predicate=lambda e: cs.CHANNEL_TYPE_CONTACT_LIST not in e.args),
        EventPattern('dbus-signal', signal='NewSessionHandler'))

    path = nc.args[0]

    media_chan = make_channel_proxy(conn, path, 'Channel.Interface.Group')
    media_iface = make_channel_proxy(conn, path, 'Channel.Type.StreamedMedia')

    # S-E was notified about new session handler, and calls Ready on it
    session_handler = make_channel_proxy(conn, e.args[0],
                                         'Media.SessionHandler')
    session_handler.Ready()

    nsh_event = q.expect('dbus-signal', signal='NewStreamHandler')

    # S-E gets notified about a newly-created stream
    stream_handler = make_channel_proxy(conn, nsh_event.args[0],
        'Media.StreamHandler')

    group_props = media_chan.GetAll(
        cs.CHANNEL_IFACE_GROUP, dbus_interface=dbus.PROPERTIES_IFACE)

    if incoming:
        assertEquals([remote_handle], group_props['Members'])
        assertEquals(unwrap(group_props['LocalPendingMembers']),
                     [(self_handle, remote_handle, cs.GC_REASON_INVITED, '')])
    else:
        assertEquals([self_handle], group_props['Members'])

    streams = media_chan.ListStreams(
            dbus_interface=cs.CHANNEL_TYPE_STREAMED_MEDIA)

    stream_id = streams[0][0]

    stream_handler.NewNativeCandidate("fake", jt.get_remote_transports_dbus())
    stream_handler.Ready(jt.dbusify_codecs([("FOO", 5, 8000, {})]))

    msg = u"None of the codecs are good for us, damn!"

    expected_events = []

    if incoming:
        q.expect('dbus-signal', signal='SetRemoteCodecs')
        stream_handler.Error(cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED,
                             msg)
        expected_events = [EventPattern(
                "stream-iq", iq_type="set",
                predicate=lambda x: _session_terminate_predicate(x, msg))]
        rejector = self_handle
    else:
        stream_handler.StreamState(cs.MEDIA_STREAM_STATE_CONNECTED)
        session_initiate = q.expect(
            'stream-iq',
            predicate=jp.action_predicate('session-initiate'))

        q.expect('dbus-signal', signal='MembersChanged', path=path,
                 args=['', [], [], [], [remote_handle], self_handle,
                       cs.GC_REASON_INVITED])

        jt.parse_session_initiate(session_initiate.query)
        stream.send(jp.xml(jp.ResultIq('test@localhost',
                                       session_initiate.stanza, [])))
        jt.terminate('failed-application', msg)
        rejector = remote_handle

    expected_events += [
        EventPattern('dbus-signal', signal='StreamError',
                     interface=cs.CHANNEL_TYPE_STREAMED_MEDIA, path=path,
                     args=[stream_id,
                           cs.MEDIA_STREAM_ERROR_CODEC_NEGOTIATION_FAILED,
                           msg]),
        EventPattern('dbus-signal', signal='MembersChanged',
                     interface=cs.CHANNEL_IFACE_GROUP, path=path,
                     args=[msg, [], [self_handle, remote_handle], [], [],
                      rejector, cs.GC_REASON_ERROR])]


    q.expect_many(*expected_events)

    q.expect('dbus-signal', signal='Closed', path=path)
def test(q, bus, conn, stream):
    conn.Connect()

    _, iq_event = q.expect_many(
        EventPattern('dbus-signal', signal='StatusChanged',
            args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
        EventPattern('stream-iq', to=None, query_ns='vcard-temp',
            query_name='vCard'))

    acknowledge_iq(stream, iq_event.stanza)

    call_async(q, conn, 'RequestHandles', cs.HT_ROOM, ['*****@*****.**'])

    event = q.expect('stream-iq', to='conf.localhost',
            query_ns='http://jabber.org/protocol/disco#info')
    result = make_result_iq(stream, event.stanza)
    feature = result.firstChildElement().addElement('feature')
    feature['var'] = 'http://jabber.org/protocol/muc'
    stream.send(result)

    event = q.expect('dbus-return', method='RequestHandles')
    handles = event.value[0]
    room_handle = handles[0]

    # join the muc
    call_async(q, conn, 'RequestChannel',
        cs.CHANNEL_TYPE_TEXT, cs.HT_ROOM, room_handle, True)

    _, stream_event = q.expect_many(
        EventPattern('dbus-signal', signal='MembersChanged',
            args=[u'', [], [], [], [2], 0, 0]),
        EventPattern('stream-presence', to='[email protected]/test'))

    # Send presence for other member of room.
    stream.send(make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob'))

    # Send presence for own membership of room.
    stream.send(make_muc_presence('none', 'participant', '*****@*****.**', 'test'))

    q.expect('dbus-signal', signal='MembersChanged',
            args=[u'', [2, 3], [], [], [], 0, 0])

    assert conn.InspectHandles(cs.HT_CONTACT, [2, 3]) == \
        ['[email protected]/test', '[email protected]/bob']
    bob_handle = 3

    event = q.expect('dbus-return', method='RequestChannel')
    text_chan = bus.get_object(conn.bus_name, event.value[0])

    # Bob offers a muc tube
    tube_id = 666
    stream_id = 1234
    presence = make_muc_presence('owner', 'moderator', '*****@*****.**', 'bob')
    tubes = presence.addElement((ns.TUBES, 'tubes'))
    tube = tubes.addElement((None, 'tube'))
    tube['type'] = 'dbus'
    tube['service'] = 'org.telepathy.freedesktop.test'
    tube['id'] = str(tube_id)
    tube['stream-id'] = str(stream_id)
    tube['dbus-name'] = ':2.Y2Fzc2lkeS10ZXN0MgAA'
    tube['initiator'] = '[email protected]/bob'
    parameters = tube.addElement((None, 'parameters'))
    parameter = parameters.addElement((None, 'parameter'))
    parameter['name'] = 's'
    parameter['type'] = 'str'
    parameter.addContent('hello')
    parameter = parameters.addElement((None, 'parameter'))
    parameter['name'] = 'ay'
    parameter['type'] = 'bytes'
    parameter.addContent('aGVsbG8=')
    parameter = parameters.addElement((None, 'parameter'))
    parameter['name'] = 'u'
    parameter['type'] = 'uint'
    parameter.addContent('123')
    parameter = parameters.addElement((None, 'parameter'))
    parameter['name'] = 'i'
    parameter['type'] = 'int'
    parameter.addContent('-123')

    stream.send(presence)

    # tubes channel is automatically created
    event = q.expect('dbus-signal', signal='NewChannel')

    if event.args[1] == cs.CHANNEL_TYPE_TEXT:
        # skip this one, try the next one
        event = q.expect('dbus-signal', signal='NewChannel')

    assert event.args[1] == cs.CHANNEL_TYPE_TUBES, event.args
    assert event.args[2] == cs.HT_ROOM
    assert event.args[3] == room_handle

    tubes_chan = bus.get_object(conn.bus_name, event.args[0])
    tubes_iface = dbus.Interface(tubes_chan, event.args[1])

    channel_props = tubes_chan.GetAll(
        cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)
    assert channel_props['TargetID'] == '*****@*****.**', channel_props
    assert channel_props['Requested'] == False
    assert channel_props['InitiatorID'] == ''
    assert channel_props['InitiatorHandle'] == 0

    tubes_self_handle = tubes_chan.GetSelfHandle(
        dbus_interface=cs.CHANNEL_IFACE_GROUP)

    q.expect('dbus-signal', signal='NewTube',
        args=[tube_id, bob_handle, 0, 'org.telepathy.freedesktop.test', sample_parameters, 0])

    expected_tube = (tube_id, bob_handle, cs.TUBE_TYPE_DBUS,
        'org.telepathy.freedesktop.test', sample_parameters,
        cs.TUBE_STATE_LOCAL_PENDING)
    tubes = tubes_iface.ListTubes(byte_arrays=True)
    assert len(tubes) == 1, unwrap(tubes)
    t.check_tube_in_tubes(expected_tube, tubes)

    # reject the tube
    tubes_iface.CloseTube(tube_id)
    q.expect('dbus-signal', signal='TubeClosed', args=[tube_id])

    # close the text channel
    text_chan.Close()
def test(q, bus, conn, sip):
    conn.Connect()
    q.expect('dbus-signal', signal='StatusChanged', args=[0, 1])

    self_handle = conn.Get(cs.CONN, 'SelfHandle', dbus_interface=cs.PROPERTIES_IFACE)
    self_uri = conn.inspect_contact_sync(self_handle)

    contact = 'sip:[email protected]'
    handle = conn.get_contact_handle_sync(contact)

    chan, _ = conn.Requests.CreateChannel(
            { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_TEXT,
                cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
                cs.TARGET_HANDLE: handle })

    requested_obj, target_handle = test_new_channel (q, bus, conn,
        target_uri=contact,
        initiator_uri=self_uri,
        requested=True)

    assert requested_obj.object_path == chan, requested_obj.object_path
    assert target_handle == handle, (target_handle, handle)

    iface = dbus.Interface(requested_obj, cs.CHANNEL_TYPE_TEXT)

    iface.Send(0, 'Hello')

    event = q.expect('sip-message', uri='sip:[email protected]', body='Hello')
    sip.deliverResponse(sip.responseFromRequest(404, event.sip_message))

    q.expect('dbus-signal', signal='SendError')

    iface.Send(0, 'Hello Again')

    event = q.expect('sip-message', uri='sip:[email protected]',
        body='Hello Again')
    sip.deliverResponse(sip.responseFromRequest(200, event.sip_message))

    ua_via = twisted.protocols.sip.parseViaHeader(event.headers['via'][0])

    conn.ReleaseHandles(1, [handle])

    call_id = 'XYZ@localhost'
    send_message(sip, ua_via, 'Hi', call_id=call_id, time=1234567890)

    incoming_obj, handle = test_new_channel (q, bus, conn,
        target_uri=FROM_URL,
        initiator_uri=FROM_URL,
        requested=False)

    iface = dbus.Interface(incoming_obj, cs.CHANNEL_TYPE_TEXT)

    name = conn.inspect_contact_sync(handle)
    assert name == FROM_URL

    event = q.expect('dbus-signal', signal='MessageReceived')
    msg = event.args[0]
    now = time.time()
    assert msg[0]['message-token'] == "%s;cseq=%u" % (call_id, cseq_num)
    assert now - 10 < msg[0]['message-received'] < now + 10
    assert msg[0]['message-sent'] == 1234567890
    assert msg[1]['content-type'] == 'text/plain'
    assert msg[1]['content'] == 'Hi'

    # FIXME: times out for some reason, the response is in fact sent;
    # race condition with the earlier wait for 'dbus-signal'?
    #event = q.expect('sip-response', code=200)

    iface.AcknowledgePendingMessages([msg[0]['pending-message-id']])

    # Test conversion from an 8-bit encoding.
    # Due to limited set of encodings available in some environments,
    # try with US ASCII and ISO 8859-1.

    send_message(sip, ua_via, u'straight ASCII'.encode('us-ascii'), encoding='us-ascii')
    event = q.expect('dbus-signal', signal='Received')
    assert event.args[5] == 'straight ASCII'

    iface.AcknowledgePendingMessages([event.args[0]])

    send_message(sip, ua_via, u'Hyv\xe4!'.encode('iso-8859-1'), encoding='iso-8859-1')
    event = q.expect('dbus-signal', signal='Received')
    assert event.args[5] == u'Hyv\xe4!'

    conn.ReleaseHandles(1, [handle])

    iface = dbus.Interface(incoming_obj, cs.CHANNEL_IFACE_DESTROYABLE)
    iface.Destroy()
    del iface
    event = q.expect('dbus-signal', signal='Closed')
    del incoming_obj

    # Sending the message to appear on the requested channel
    pending_msgs = []

    send_message(sip, ua_via, 'How are you doing now, old pal?',
                 sender=contact)
    event = q.expect('dbus-signal', signal='Received', path=chan)
    assert event.args[5] == 'How are you doing now, old pal?'
    pending_msgs.append(tuple(event.args))

    send_message(sip, ua_via, 'I hope you can receive it',
                 sender=contact)
    event = q.expect('dbus-signal', signal='Received')
    assert event.args[5] == 'I hope you can receive it'
    pending_msgs.append(tuple(event.args))

    # Don't acknowledge the last messages, close the channel so that it's reopened
    dbus.Interface(requested_obj, cs.CHANNEL).Close()
    del requested_obj

    event = q.expect('dbus-signal', signal='Closed', path=chan)

    requested_obj, handle = test_new_channel (q, bus, conn,
        target_uri=contact,
        initiator_uri=contact,
        requested=False)

    # Expect Channel_Text_Message_Flag_Resqued to be set
    pending_msgs = [message_with_resqued(msg) for msg in pending_msgs]
    # The first message is the delivery report of the message we failed to
    # send so we'll skip it.

    iface = dbus.Interface(requested_obj, cs.CHANNEL_TYPE_TEXT)

    pending_res = iface.ListPendingMessages(False)
    assert pending_msgs == pending_res[1:], (pending_msgs, unwrap(pending_res)[1:])

    pending_res = iface.ListPendingMessages(True)
    assert pending_msgs == pending_res[1:], (pending_msgs, unwrap(pending_res)[1:])

    # There should be no pending messages any more
    pending_res = iface.ListPendingMessages(False)
    assert pending_res == [], pending_res

    del iface

    # Hit also the code path for closing the channel with no pending messages
    dbus.Interface(requested_obj, cs.CHANNEL).Close()
    event = q.expect('dbus-signal', signal='Closed')
    del requested_obj

    # Hit the message zapping path when the connection is disconnected
    send_message(sip, ua_via, 'Will you leave this unacknowledged?')
    test_new_channel (q, bus, conn,
        target_uri=FROM_URL,
        initiator_uri=FROM_URL,
        requested=False)

    conn.Disconnect()

    # Check the last channel with an unacknowledged message 
    event = q.expect('dbus-signal', signal='Closed')

    q.expect('dbus-signal', signal='StatusChanged', args=[2,1])
示例#45
0
def test(q, bus, conn):
    cm = bus.get_object(cs.CM + '.salut',
                        tp_path_prefix + '/ConnectionManager/salut')
    cm_iface = dbus.Interface(cm, cs.CM)
    cm_prop_iface = dbus.Interface(cm, cs.PROPERTIES_IFACE)

    protocols = unwrap(cm_prop_iface.Get(cs.CM, 'Protocols'))
    assertEquals(set(['local-xmpp']), set(protocols.keys()))

    local_props = protocols['local-xmpp']
    local_params = local_props[cs.PROTOCOL + '.Parameters']

    proto = bus.get_object(cm.bus_name, cm.object_path + '/local_xmpp')
    proto_iface = dbus.Interface(proto, cs.PROTOCOL)
    proto_prop_iface = dbus.Interface(proto, cs.PROPERTIES_IFACE)
    proto_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL))

    for key in [
            'Parameters', 'Interfaces', 'ConnectionInterfaces',
            'RequestableChannelClasses', u'VCardField', u'EnglishName', u'Icon'
    ]:
        a = local_props[cs.PROTOCOL + '.' + key]
        b = proto_props[key]
        assertEquals(a, b)

    assertEquals('', proto_props['VCardField'])
    assertEquals('Link-local XMPP', proto_props['EnglishName'])
    assertEquals('im-local-xmpp', proto_props['Icon'])

    assertContains(cs.CONN_IFACE_ALIASING, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_AVATARS, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_CONTACTS, proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_SIMPLE_PRESENCE,
                   proto_props['ConnectionInterfaces'])
    assertContains(cs.CONN_IFACE_REQUESTS, proto_props['ConnectionInterfaces'])

    # local-xmpp has case-sensitive literals as identifiers
    assertEquals('SMcV@Reptile',
                 unwrap(proto_iface.NormalizeContact('SMcV@Reptile')))

    # (Only) 'first-name' and 'last-name' are mandatory for IdentifyAccount()
    call_async(q, proto_iface, 'IdentifyAccount', {'first-name': 'Simon'})
    q.expect('dbus-error', method='IdentifyAccount', name=cs.INVALID_ARGUMENT)

    # Identifying an account doesn't do much, anyway
    test_params = {'first-name': 'Simon', 'last-name': 'McVittie'}
    acc_name = unwrap(proto_iface.IdentifyAccount(test_params))
    assertEquals('', acc_name)

    assertContains(cs.PROTOCOL_IFACE_AVATARS, proto_props['Interfaces'])
    avatar_props = unwrap(proto_prop_iface.GetAll(cs.PROTOCOL_IFACE_AVATARS))
    assertEquals(65535, avatar_props['MaximumAvatarBytes'])
    assertEquals(0, avatar_props['MaximumAvatarHeight'])
    assertEquals(0, avatar_props['MaximumAvatarWidth'])
    assertEquals(0, avatar_props['MinimumAvatarHeight'])
    assertEquals(0, avatar_props['MinimumAvatarWidth'])
    assertEquals(64, avatar_props['RecommendedAvatarHeight'])
    assertEquals(64, avatar_props['RecommendedAvatarWidth'])
    assertEquals(['image/png', 'image/jpeg'],
                 avatar_props['SupportedAvatarMIMETypes'])

    assertContains(cs.PROTOCOL_IFACE_PRESENCES, proto_props['Interfaces'])

    expected_status = {
        'available': (cs.PRESENCE_AVAILABLE, True, True),
        'dnd': (cs.PRESENCE_BUSY, True, True),
        'away': (cs.PRESENCE_AWAY, True, True),
        'offline': (cs.PRESENCE_OFFLINE, False, False)
    }

    presences = proto_prop_iface.Get(cs.PROTOCOL_IFACE_PRESENCES, 'Statuses')
    assertEquals(expected_status, presences)
示例#46
0
def test(q, bus, conn, stream):
    conn.Connect()

    properties = conn.GetAll(
        cs.CONN_IFACE_REQUESTS, dbus_interface=cs.PROPERTIES_IFACE)
    assert properties.get('Channels') == [], properties['Channels']
    assert ({cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
             cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
             },
             [cs.TARGET_HANDLE, cs.TARGET_ID, cs.STREAM_TUBE_SERVICE]
             ) in properties.get('RequestableChannelClasses'),\
                     unwrap(properties['RequestableChannelClasses'])

    _, vcard_event, roster_event = q.expect_many(
        EventPattern('dbus-signal', signal='StatusChanged',
            args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
        EventPattern('stream-iq', to=None, query_ns='vcard-temp',
            query_name='vCard'),
        EventPattern('stream-iq', query_ns=ns.ROSTER))

    acknowledge_iq(stream, vcard_event.stanza)

    roster = roster_event.stanza
    roster['type'] = 'result'
    item = roster_event.query.addElement('item')
    item['jid'] = 'bob@localhost'
    item['subscription'] = 'both'
    stream.send(roster)

    presence = domish.Element(('jabber:client', 'presence'))
    presence['from'] = 'bob@localhost/Bob'
    presence['to'] = 'test@localhost/Resource'
    c = presence.addElement('c')
    c['xmlns'] = 'http://jabber.org/protocol/caps'
    c['node'] = 'http://example.com/ICantBelieveItsNotTelepathy'
    c['ver'] = '1.2.3'
    stream.send(presence)

    event = q.expect('stream-iq', iq_type='get',
        query_ns='http://jabber.org/protocol/disco#info',
        to='bob@localhost/Bob')
    result = event.stanza
    result['type'] = 'result'
    assert event.query['node'] == \
        'http://example.com/ICantBelieveItsNotTelepathy#1.2.3'
    feature = event.query.addElement('feature')
    feature['var'] = ns.TUBES
    stream.send(result)

    bob_handle = conn.get_contact_handle_sync('bob@localhost')

    def new_chan_predicate(e):
        types = []
        for _, props in e.args[0]:
            types.append(props[cs.CHANNEL_TYPE])

        return cs.CHANNEL_TYPE_STREAM_TUBE in types

    call_async(q, conn.Requests, 'CreateChannel',
            { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
              cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
              cs.TARGET_HANDLE: bob_handle,
              cs.STREAM_TUBE_SERVICE: 'the.service',
              })

    ret, _ = q.expect_many(
        EventPattern('dbus-return', method='CreateChannel'),
        EventPattern('dbus-signal', signal='NewChannels',
                     predicate=new_chan_predicate),
        )


    chan_path, props = ret.value

    # Ensure a tube to the same person; check it's the same one.
#    call_async(q, conn.Requests, 'EnsureChannel',
#            { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
#              cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
#              cs.TARGET_HANDLE: bob_handle,
#              cs.STREAM_TUBE_SERVICE: 'the.service',
#              })

#    ret = q.expect('dbus-return', method='EnsureChannel')
#    yours, ensured_path, _ = ret.value

#    assert ensured_path == chan_path, (ensured_path, chan_path)
#    assert not yours

    chan = bus.get_object(conn.bus_name, chan_path)
    chan.Close()

    # Now let's try ensuring a new tube.
    call_async(q, conn.Requests, 'EnsureChannel',
            { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE,
              cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
              cs.TARGET_HANDLE: bob_handle,
              cs.STREAM_TUBE_SERVICE: 'the.service',
              })

    ret, new_sig = q.expect_many(
        EventPattern('dbus-return', method='EnsureChannel'),
        EventPattern('dbus-signal', signal='NewChannels',
                     predicate=new_chan_predicate),
        )

    yours, path, props = ret.value
    assert yours

    emitted_props = new_sig.args[0][0][1]
    assert props == emitted_props, (props, emitted_props)

    chan = bus.get_object(conn.bus_name, path)
    chan.Close()