[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