summaryrefslogtreecommitdiff
path: root/tests/twisted/jingle/test-wait-for-caps.py
blob: f7eaa96a3d7d86f202be0210dcc8d11e802e3ed7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
"""
Test use-case when client requests going online and immediately
attempts to call a contact. Gabble should delay the RequestStreams
call until caps have arrived.
"""

from gabbletest import exec_test
from servicetest import make_channel_proxy, call_async, sync_dbus
import jingletest

import dbus

import constants as cs
import ns

from config import VOIP_ENABLED

if not VOIP_ENABLED:
    print "NOTE: built with --disable-voip"
    raise SystemExit(77)

def test(q, bus, conn, stream, channel_type):
    jt = jingletest.JingleTest(stream, 'test@localhost', 'foo@bar.com/Foo')
    jt2 = jingletest.JingleTest(stream, 'test@localhost', 'foo2@bar.com/Foo')
    # Make gabble think this is a different client
    jt2.remote_caps['node'] = 'http://example.com/fake-client1'

    run_test(q, bus, conn, stream, jt, True, channel_type)
    run_test(q, bus, conn, stream, jt2, False, channel_type)

def run_test(q, bus, conn, stream, jt, request_before_presence, channel_type):
    """
    Requests streams on a media channel to jt.remote_jid, either before their
    presence is received (if request_before_presence is True) or after their
    presence is received but before we've got a disco response for their
    capabilities (otherwise).
    """

    # We intentionally DON'T set remote presence yet. Since Gabble is still
    # unsure whether to treat contact as offline for this purpose, it
    # will tentatively allow channel creation and contact handle addition
    request = dbus.Dictionary({ cs.CHANNEL_TYPE: channel_type,
                                cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT,
                                cs.TARGET_ID: jt.remote_jid
                              }, signature='sv')

    if channel_type == cs.CHANNEL_TYPE_CALL:
        request[cs.CALL_INITIAL_AUDIO] = True

    if channel_type == cs.CHANNEL_TYPE_STREAMED_MEDIA:
        path, props = conn.CreateChannel(request,
            dbus_interface=cs.CONN_IFACE_REQUESTS)
        media_iface = make_channel_proxy(conn, path,
            'Channel.Type.StreamedMedia')

        handle = props[cs.TARGET_HANDLE]

    sync_dbus(bus, q, conn)

    def call_request_streams():
        if channel_type == cs.CHANNEL_TYPE_STREAMED_MEDIA:
            call_async(q, media_iface, 'RequestStreams', handle,
                [cs.MEDIA_STREAM_TYPE_AUDIO])
        else:
            call_async(q, conn.Requests, 'CreateChannel', request)

    def send_presence():
        jt.send_remote_presence()
        return q.expect('stream-iq', query_ns=ns.DISCO_INFO, to=jt.remote_jid)

    if request_before_presence:
        # Request streams before either <presence> or caps have arrived. Gabble
        # should wait for both to arrive before returning from RequestStreams.
        call_request_streams()

        # Ensure Gabble's received the method call.
        sync_dbus(bus, q, conn)

        # Now send the presence.
        info_event = send_presence()
    else:
        info_event = send_presence()

        # Now call RequestStreams; it should wait for the disco reply.
        call_request_streams()

    jt.send_remote_disco_reply(info_event.stanza)

    # RequestStreams should now happily complete
    if channel_type == cs.CHANNEL_TYPE_STREAMED_MEDIA:
        q.expect('dbus-return', method='RequestStreams')
    else:
        q.expect('dbus-return', method='CreateChannel')

if __name__ == '__main__':
    exec_test(lambda q, bus, conn, stream:
        test(q, bus, conn, stream, cs.CHANNEL_TYPE_STREAMED_MEDIA), timeout=10)
    exec_test(lambda q, bus, conn, stream:
        test(q, bus, conn, stream, cs.CHANNEL_TYPE_CALL), timeout=10)