[telepathy-gabble/master] Add a test for call states.

Will Thompson will.thompson at collabora.co.uk
Wed Apr 1 11:23:35 PDT 2009


---
 tests/twisted/Makefile.am          |    1 +
 tests/twisted/constants.py         |    6 ++
 tests/twisted/gabbletest.py        |    1 +
 tests/twisted/jingle/call-state.py |  138 ++++++++++++++++++++++++++++++++++++
 4 files changed, 146 insertions(+), 0 deletions(-)
 create mode 100644 tests/twisted/jingle/call-state.py

diff --git a/tests/twisted/Makefile.am b/tests/twisted/Makefile.am
index a860739..c317116 100644
--- a/tests/twisted/Makefile.am
+++ b/tests/twisted/Makefile.am
@@ -70,6 +70,7 @@ TWISTED_TESTS = \
 	vcard/test-vcard-cache.py \
 	vcard/test-vcard-race.py \
 	jingle/accept-extra-stream.py \
+	jingle/call-state.py \
 	jingle/google-relay.py \
 	jingle/hold-audio.py \
 	jingle/hold-av.py \
diff --git a/tests/twisted/constants.py b/tests/twisted/constants.py
index 36a37c0..1775bd2 100644
--- a/tests/twisted/constants.py
+++ b/tests/twisted/constants.py
@@ -11,6 +11,7 @@ CHANNEL = "org.freedesktop.Telepathy.Channel"
 CHANNEL_IFACE_GROUP = CHANNEL + ".Interface.Group"
 CHANNEL_IFACE_HOLD = CHANNEL + ".Interface.Hold"
 CHANNEL_IFACE_MEDIA_SIGNALLING = CHANNEL + ".Interface.MediaSignalling"
+CHANNEL_IFACE_CALL_STATE = CHANNEL + ".Interface.CallState"
 CHANNEL_TYPE_TEXT = CHANNEL + ".Type.Text"
 CHANNEL_TYPE_TUBES = CHANNEL + ".Type.Tubes"
 CHANNEL_IFACE_TUBE = CHANNEL + ".Interface.Tube.DRAFT"
@@ -131,3 +132,8 @@ HS_PENDING_UNHOLD = 3
 HSR_NONE = 0
 HSR_REQUESTED = 1
 HSR_RESOURCE_NOT_AVAILABLE = 2
+
+CALL_STATE_RINGING = 1
+CALL_STATE_QUEUED = 2
+CALL_STATE_HELD = 4
+CALL_STATE_FORWARDED = 8
diff --git a/tests/twisted/gabbletest.py b/tests/twisted/gabbletest.py
index 9c7e9e6..721302a 100644
--- a/tests/twisted/gabbletest.py
+++ b/tests/twisted/gabbletest.py
@@ -198,6 +198,7 @@ def make_stream_event(type, stanza):
 def make_iq_event(iq):
     event = make_stream_event('stream-iq', iq)
     event.iq_type = iq.getAttribute("type")
+    event.iq_id = iq.getAttribute("id")
     query = iq.firstChildElement()
 
     if query:
diff --git a/tests/twisted/jingle/call-state.py b/tests/twisted/jingle/call-state.py
new file mode 100644
index 0000000..cf6c5a5
--- /dev/null
+++ b/tests/twisted/jingle/call-state.py
@@ -0,0 +1,138 @@
+"""
+Test exposing incoming <hold/> and <active/> notifications via the CallState
+interface.
+"""
+
+from twisted.words.xish import xpath
+
+from gabbletest import make_result_iq, sync_stream
+from servicetest import wrap_channel, make_channel_proxy, call_async, \
+    EventPattern
+import ns
+import constants as cs
+
+from jingletest2 import JingleTest2, test_all_dialects
+
+def test(jp, q, bus, conn, stream):
+    # We can only get call state notifications on modern jingle.
+    # TODO: but if we fake Hold by changing senders="", we could check for that
+    # here.
+    if not jp.is_modern_jingle():
+        return
+
+    remote_jid = 'foo at bar.com/Foo'
+    jt = JingleTest2(jp, conn, q, stream, 'test at localhost', remote_jid)
+
+    jt.prepare()
+
+    self_handle = conn.GetSelfHandle()
+    handle = conn.RequestHandles(cs.HT_CONTACT, [remote_jid])[0]
+
+    path = conn.RequestChannel(cs.CHANNEL_TYPE_STREAMED_MEDIA, cs.HT_CONTACT,
+        handle, True)
+
+    chan = wrap_channel(bus.get_object(conn.bus_name, path), 'StreamedMedia',
+        ['MediaSignalling', 'Group', 'CallState'])
+    chan_props = chan.Properties.GetAll(cs.CHANNEL)
+    assert cs.CHANNEL_IFACE_CALL_STATE in chan_props['Interfaces'], \
+        chan_props['Interfaces']
+
+    chan.StreamedMedia.RequestStreams(handle, [cs.MEDIA_STREAM_TYPE_AUDIO])
+
+    # 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'
+
+    session_handler = make_channel_proxy(conn, e.args[0], 'Media.SessionHandler')
+    session_handler.Ready()
+
+    e = q.expect('dbus-signal', signal='NewStreamHandler')
+
+    stream_handler = make_channel_proxy(conn, e.args[0], 'Media.StreamHandler')
+
+    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)
+
+    e = q.expect('stream-iq', predicate=lambda e:
+        jp.match_jingle_action(e.query, 'session-initiate'))
+    stream.send(make_result_iq(stream, e.stanza))
+
+    jt.set_sid_from_initiate(e.query)
+    jt.accept()
+
+    # Various misc happens; among other things, Gabble tells s-e to start
+    # sending.
+    q.expect('dbus-signal', signal='SetStreamSending', args=[True])
+
+    call_states = chan.CallState.GetCallStates()
+    assert call_states == { handle: 0 } or call_states == {}, call_states
+
+    # The other person puts us on hold.  Gabble should ack the session-info IQ,
+    # tell s-e to stop sending on the held stream, and set the call state.
+    node = jp.SetIq(jt.peer, jt.jid, [
+        jp.Jingle(jt.sid, jt.jid, 'session-info', [
+            ('hold', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
+    stream.send(jp.xml(node))
+
+    q.expect_many(
+        EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
+        EventPattern('dbus-signal', signal='SetStreamSending', args=[False]),
+        EventPattern('dbus-signal', signal='CallStateChanged',
+            args=[handle, cs.CALL_STATE_HELD]),
+        )
+
+    call_states = chan.CallState.GetCallStates()
+    assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
+
+    # The peer pings us with an empty session-info; Gabble should just ack it.
+    node = jp.SetIq(jt.peer, jt.jid, [
+        jp.Jingle(jt.sid, jt.jid, 'session-info', [])])
+    stream.send(jp.xml(node))
+
+    q.expect('stream-iq', iq_type='result', iq_id=node[2]['id'])
+
+    call_states = chan.CallState.GetCallStates()
+    assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
+
+    # The peer sends us some unknown-namespaced misc in a session-info; Gabble
+    # should nak it with <unsupported-info/>
+    node = jp.SetIq(jt.peer, jt.jid, [
+        jp.Jingle(jt.sid, jt.jid, 'session-info', [
+            ('boiling', 'com.example.Kettle', {}, []) ]) ])
+    stream.send(jp.xml(node))
+
+    e = q.expect('stream-iq', iq_type='error', iq_id=node[2]['id'])
+    xpath.queryForNodes("/jingle/error/unsupported-info", e.query)
+
+    call_states = chan.CallState.GetCallStates()
+    assert call_states == { handle: cs.CALL_STATE_HELD }, call_states
+
+    # The other person unholds us; Gabble should ack the session-info IQ, tell
+    # s-e to start sending on the now-active stream, and set the call state.
+    node = jp.SetIq(jt.peer, jt.jid, [
+        jp.Jingle(jt.sid, jt.jid, 'session-info', [
+            ('active', ns.JINGLE_RTP_INFO_1, {}, []) ]) ])
+    stream.send(jp.xml(node))
+
+    q.expect_many(
+        EventPattern('stream-iq', iq_type='result', iq_id=node[2]['id']),
+        EventPattern('dbus-signal', signal='SetStreamSending', args=[True]),
+        EventPattern('dbus-signal', signal='CallStateChanged',
+            args=[handle, 0]),
+        )
+
+    call_states = chan.CallState.GetCallStates()
+    assert call_states == { handle: 0 } or call_states == {}, call_states
+
+    # Test completed, close the connection
+
+    chan.Group.RemoveMembers([self_handle], 'closed')
+    e = q.expect('dbus-signal', signal='Close') #XXX - match against the path
+
+    conn.Disconnect()
+    q.expect('dbus-signal', signal='StatusChanged', args=[2, 1])
+
+if __name__ == '__main__':
+    test_all_dialects(test)
+
-- 
1.5.6.5




More information about the telepathy-commits mailing list