[telepathy-gabble/master] Test sending <hold/> and <active/> notifications

Will Thompson will.thompson at collabora.co.uk
Tue Mar 31 05:09:42 PDT 2009


---
 tests/twisted/jingle/hold-audio.py  |   83 +++++++++++++++++++++++++++++++++-
 tests/twisted/jingle/hold-av.py     |   57 +++++++++++++++++++++++-
 tests/twisted/jingle/jingletest2.py |   19 ++++++++
 tests/twisted/ns.py                 |    1 +
 4 files changed, 156 insertions(+), 4 deletions(-)

diff --git a/tests/twisted/jingle/hold-audio.py b/tests/twisted/jingle/hold-audio.py
index 2fddd78..8bb0c03 100644
--- a/tests/twisted/jingle/hold-audio.py
+++ b/tests/twisted/jingle/hold-audio.py
@@ -2,8 +2,9 @@
 Test the Hold API.
 """
 
-from gabbletest import make_result_iq
+from gabbletest import make_result_iq, sync_stream
 from servicetest import make_channel_proxy, call_async, EventPattern
+import ns
 import constants as cs
 
 from jingletest2 import JingleTest2, test_all_dialects
@@ -51,6 +52,10 @@ def test(jp, q, bus, conn, stream):
 
     q.expect('stream-iq', iq_type='result')
 
+    # These are 0- (for old dialects) or 1- (for new dialects) element lists
+    # that can be splatted into expect_many with *
+    hold_event = jp.hold_notification_event_list(True)
+    active_event = jp.hold_notification_event_list(False)
     # ---- Test 1: GetHoldState returns unheld and unhold is a no-op ----
 
     hold_state = hold_iface.GetHoldState()
@@ -65,6 +70,7 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
         EventPattern('dbus-return', method='RequestHold', value=()),
+        *hold_event
         )
 
     call_async(q, stream_handler, 'HoldState', True)
@@ -82,6 +88,8 @@ def test(jp, q, bus, conn, stream):
 
     # ---- Test 4: successful unhold ----
 
+    q.forbid_events(hold_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
@@ -90,11 +98,17 @@ def test(jp, q, bus, conn, stream):
         EventPattern('dbus-return', method='RequestHold', value=()),
         )
 
+    # Ensure that if Gabble sent the <active/> stanza too early it's already
+    # arrived.
+    sync_stream(q, stream)
+    q.unforbid_events(hold_event)
+
     call_async(q, stream_handler, 'HoldState', False)
     q.expect_many(
         EventPattern('dbus-return', method='HoldState', value=()),
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
+        *active_event
         )
 
     # ---- Test 5: GetHoldState returns False and unhold is a no-op ----
@@ -116,6 +130,7 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
         EventPattern('dbus-return', method='RequestHold', value=()),
+        *hold_event
         )
 
     call_async(q, stream_handler, 'HoldState', True)
@@ -127,6 +142,8 @@ def test(jp, q, bus, conn, stream):
 
     # ---- Test 7: 3 parallel calls to unhold ----
 
+    q.forbid_events(active_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
     call_async(q, hold_iface, 'RequestHold', False)
     call_async(q, hold_iface, 'RequestHold', False)
@@ -137,11 +154,17 @@ def test(jp, q, bus, conn, stream):
         EventPattern('dbus-return', method='RequestHold', value=()),
         )
 
+    # Ensure that if Gabble sent the <active/> stanza too early it's already
+    # arrived.
+    sync_stream(q, stream)
+    q.unforbid_events(active_event)
+
     call_async(q, stream_handler, 'HoldState', False)
     q.expect_many(
         EventPattern('dbus-return', method='HoldState', value=()),
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
+        *active_event
         )
 
     # ---- Test 8: hold, then change our minds before s-e has responded ----
@@ -150,24 +173,36 @@ def test(jp, q, bus, conn, stream):
     assert hold_state[0] == cs.HS_UNHELD, hold_state
 
     call_async(q, hold_iface, 'RequestHold', True)
-    call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
+        *hold_event
         )
+
+    q.forbid_events(active_event)
+
+    call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
+        # Gabble shouldn't send <active/> here because s-e might have already
+        # relinquished the audio hardware.
         )
 
+    sync_stream(q, stream)
+    q.unforbid_events(active_event)
+
     call_async(q, stream_handler, 'HoldState', True)
+    q.expect('dbus-return', method='HoldState', value=())
+
     call_async(q, stream_handler, 'HoldState', False)
     q.expect_many(
         EventPattern('dbus-return', method='HoldState', value=()),
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
+        *active_event
         )
 
     hold_state = hold_iface.GetHoldState()
@@ -182,6 +217,7 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
         EventPattern('dbus-return', method='RequestHold', value=()),
+        *hold_event
         )
     call_async(q, stream_handler, 'HoldState', True)
     q.expect_many(
@@ -195,19 +231,25 @@ def test(jp, q, bus, conn, stream):
     hold_state = hold_iface.GetHoldState()
     assert hold_state[0] == cs.HS_HELD, hold_state
 
+    # Check that Gabble doesn't send another <hold/>, or send <active/> before
+    # we change our minds.
+    q.forbid_events(active_event + hold_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
-    call_async(q, hold_iface, 'RequestHold', True)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
         )
+
+    call_async(q, hold_iface, 'RequestHold', True)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
         )
 
+
     call_async(q, stream_handler, 'HoldState', False)
     call_async(q, stream_handler, 'HoldState', True)
     q.expect_many(
@@ -219,8 +261,15 @@ def test(jp, q, bus, conn, stream):
     hold_state = hold_iface.GetHoldState()
     assert hold_state[0] == cs.HS_HELD, hold_state
 
+    sync_stream(q, stream)
+    q.unforbid_events(active_event + hold_event)
+
     # ---- Test 10: attempting to unhold fails ----
 
+    # Check that Gabble doesn't send another <hold/>, or send <active/> even
+    # though unholding fails.
+    q.forbid_events(active_event + hold_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
@@ -237,6 +286,34 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_HELD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
         )
 
+    sync_stream(q, stream)
+    q.unforbid_events(active_event + hold_event)
+
+    # ---- Test 11: when we successfully unhold, the peer gets <active/> ---
+
+    q.forbid_events(active_event)
+
+    call_async(q, hold_iface, 'RequestHold', False)
+    q.expect_many(
+        EventPattern('dbus-signal', signal='HoldStateChanged',
+            args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
+        EventPattern('dbus-signal', signal='SetStreamHeld', args=[False]),
+        EventPattern('dbus-return', method='RequestHold', value=()),
+        )
+
+    # Ensure that if Gabble sent the <active/> stanza too early it's already
+    # arrived.
+    sync_stream(q, stream)
+    q.unforbid_events(active_event)
+
+    call_async(q, stream_handler, 'HoldState', False)
+    q.expect_many(
+        EventPattern('dbus-return', method='HoldState', value=()),
+        EventPattern('dbus-signal', signal='HoldStateChanged',
+            args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
+        *active_event
+        )
+
     # ---- The end ----
 
     group_iface.RemoveMembers([self_handle], 'closed')
diff --git a/tests/twisted/jingle/hold-av.py b/tests/twisted/jingle/hold-av.py
index 15967ef..32cf07f 100644
--- a/tests/twisted/jingle/hold-av.py
+++ b/tests/twisted/jingle/hold-av.py
@@ -82,6 +82,11 @@ def test(jp, q, bus, conn, stream):
 
     q.expect('stream-iq', iq_type='result')
 
+    # These are 0- (for old dialects) or 1- (for new dialects) element lists
+    # that can be splatted into expect_many with *
+    hold_event = jp.hold_notification_event_list(True)
+    active_event = jp.hold_notification_event_list(False)
+
     # ---- Test 1: GetHoldState returns unheld and unhold is a no-op ----
 
     hold_state = hold_iface.GetHoldState()
@@ -96,6 +101,7 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
         EventPattern('dbus-return', method='RequestHold', value=()),
+        *hold_event
         )
 
     call_async(q, audio_stream_handler, 'HoldState', True)
@@ -108,12 +114,19 @@ def test(jp, q, bus, conn, stream):
 
     # ---- Test 3: GetHoldState returns held and hold is a no-op ----
 
+    q.forbid_events(hold_event)
+
     hold_state = hold_iface.GetHoldState()
     assert hold_state[0] == cs.HS_HELD, hold_state
     hold_iface.RequestHold(True)
 
+    sync_stream(q, stream)
+    q.unforbid_events(hold_event)
+
     # ---- Test 4: successful unhold ----
 
+    q.forbid_events(active_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
@@ -122,12 +135,16 @@ def test(jp, q, bus, conn, stream):
         EventPattern('dbus-return', method='RequestHold', value=()),
         )
 
+    sync_stream(q, stream)
+    q.unforbid_events(active_event)
+
     call_async(q, audio_stream_handler, 'HoldState', False)
     call_async(q, video_stream_handler, 'HoldState', False)
     q.expect_many(
         EventPattern('dbus-return', method='HoldState', value=()),
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
+        *active_event
         )
 
     # ---- Test 5: GetHoldState returns False and unhold is a no-op ----
@@ -149,6 +166,7 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
         EventPattern('dbus-return', method='RequestHold', value=()),
+        *hold_event
         )
 
     call_async(q, audio_stream_handler, 'HoldState', True)
@@ -161,6 +179,8 @@ def test(jp, q, bus, conn, stream):
 
     # ---- Test 7: 3 parallel calls to unhold ----
 
+    q.forbid_events(active_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
     call_async(q, hold_iface, 'RequestHold', False)
     call_async(q, hold_iface, 'RequestHold', False)
@@ -171,12 +191,16 @@ def test(jp, q, bus, conn, stream):
         EventPattern('dbus-return', method='RequestHold', value=()),
         )
 
+    sync_stream(q, stream)
+    q.unforbid_events(active_event)
+
     call_async(q, audio_stream_handler, 'HoldState', False)
     call_async(q, video_stream_handler, 'HoldState', False)
     q.expect_many(
         EventPattern('dbus-return', method='HoldState', value=()),
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
+        *active_event
         )
 
     # ---- Test 8: hold, then change our minds before s-e has responded ----
@@ -185,12 +209,17 @@ def test(jp, q, bus, conn, stream):
     assert hold_state[0] == cs.HS_UNHELD, hold_state
 
     call_async(q, hold_iface, 'RequestHold', True)
-    call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
+        *hold_event
         )
+
+    # Gabble can't send Active until s-e confirms it has the resources
+    q.forbid_events(active_event)
+
+    call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_PENDING_UNHOLD, cs.HSR_REQUESTED]),
@@ -200,11 +229,16 @@ def test(jp, q, bus, conn, stream):
     call_async(q, audio_stream_handler, 'HoldState', True)
     call_async(q, video_stream_handler, 'HoldState', True)
     call_async(q, audio_stream_handler, 'HoldState', False)
+
+    sync_stream(q, stream)
+    q.unforbid_events(active_event)
+
     call_async(q, video_stream_handler, 'HoldState', False)
     q.expect_many(
         EventPattern('dbus-return', method='HoldState', value=()),
         EventPattern('dbus-signal', signal='HoldStateChanged',
             args=[cs.HS_UNHELD, cs.HSR_REQUESTED]),
+        *active_event
         )
 
     hold_state = hold_iface.GetHoldState()
@@ -219,6 +253,7 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_PENDING_HOLD, cs.HSR_REQUESTED]),
         EventPattern('dbus-signal', signal='SetStreamHeld', args=[True]),
         EventPattern('dbus-return', method='RequestHold', value=()),
+        *hold_event
         )
     call_async(q, audio_stream_handler, 'HoldState', True)
     call_async(q, video_stream_handler, 'HoldState', True)
@@ -230,6 +265,8 @@ def test(jp, q, bus, conn, stream):
 
     # Actually do test 9
 
+    q.forbid_events(hold_event + active_event)
+
     hold_state = hold_iface.GetHoldState()
     assert hold_state[0] == cs.HS_HELD, hold_state
 
@@ -256,11 +293,16 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_HELD, cs.HSR_REQUESTED]),
         )
 
+    sync_stream(q, stream)
+    q.unforbid_events(hold_event + active_event)
+
     hold_state = hold_iface.GetHoldState()
     assert hold_state[0] == cs.HS_HELD, hold_state
 
     # ---- Test 10: attempting to unhold fails (both streams) ----
 
+    q.forbid_events(hold_event + active_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
@@ -278,8 +320,13 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_HELD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
         )
 
+    sync_stream(q, stream)
+    q.unforbid_events(hold_event + active_event)
+
     # ---- Test 11: attempting to unhold fails (first stream) ----
 
+    q.forbid_events(hold_event + active_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
@@ -296,8 +343,13 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_HELD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
         )
 
+    sync_stream(q, stream)
+    q.unforbid_events(hold_event + active_event)
+
     # ---- Test 12: attempting to unhold partially fails, so roll back ----
 
+    q.forbid_events(hold_event + active_event)
+
     call_async(q, hold_iface, 'RequestHold', False)
     q.expect_many(
         EventPattern('dbus-signal', signal='HoldStateChanged',
@@ -326,6 +378,9 @@ def test(jp, q, bus, conn, stream):
             args=[cs.HS_HELD, cs.HSR_RESOURCE_NOT_AVAILABLE]),
         )
 
+    sync_stream(q, stream)
+    q.unforbid_events(hold_event + active_event)
+
     # ---- The end ----
 
     group_iface.RemoveMembers([self_handle], 'closed')
diff --git a/tests/twisted/jingle/jingletest2.py b/tests/twisted/jingle/jingletest2.py
index 5daeb45..f42ee71 100644
--- a/tests/twisted/jingle/jingletest2.py
+++ b/tests/twisted/jingle/jingletest2.py
@@ -12,6 +12,7 @@ import random
 from gabbletest import sync_stream, exec_test
 from servicetest import EventPattern
 import dbus
+import ns
 
 class JingleProtocol:
     """
@@ -115,6 +116,13 @@ class JingleProtocol:
     def is_modern_jingle(self):
         return False
 
+    def hold_notification_event(self, hold=True):
+        return None
+
+    def hold_notification_event_list(self, hold=True):
+        e = self.hold_notification_event(hold)
+        return [e] if e is not None else []
+
 class GtalkProtocol03(JingleProtocol):
     features = [ 'http://www.google.com/xmpp/protocol/voice/v1' ]
 
@@ -261,6 +269,17 @@ class JingleProtocol031(JingleProtocol):
     def is_modern_jingle(self):
         return True
 
+    def hold_notification_event(self, hold=True):
+        def p(e):
+            query = e.query
+            if not self.match_jingle_action(query, 'session-info'):
+                return False
+            n = query.firstChildElement()
+            name = "hold" if hold else "active"
+            return n is not None and n.uri == ns.JINGLE_RTP_INFO_1 and \
+                n.name == name
+
+        return EventPattern('stream-iq', predicate=p)
 
 class JingleTest2:
     # Default caps for the remote end
diff --git a/tests/twisted/ns.py b/tests/twisted/ns.py
index 2b2dc6d..28b5f8a 100644
--- a/tests/twisted/ns.py
+++ b/tests/twisted/ns.py
@@ -11,6 +11,7 @@ GOOGLE_ROSTER = 'google:roster'
 IBB = 'http://jabber.org/protocol/ibb'
 JINGLE = "http://jabber.org/protocol/jingle"
 JINGLE_AUDIO = "http://jabber.org/protocol/jingle/description/audio"
+JINGLE_RTP_INFO_1 = "urn:xmpp:jingle:apps:rtp:info:1"
 MUC = 'http://jabber.org/protocol/muc'
 MUC_BYTESTREAM = 'http://telepathy.freedesktop.org/xmpp/protocol/muc-bytestream'
 MUC_OWNER = '%s#owner' % MUC
-- 
1.5.6.5




More information about the telepathy-commits mailing list