def run_test(q, bus, conn, stream): initial_presence = q.expect('stream-presence') _, namespaces = disco_caps(q, stream, initial_presence) # For some reason, until we advertise any capabilities, these caps turn # up in our presence check_caps(namespaces, [ ns.JINGLE, ns.JINGLE_015, ns.JINGLE_TRANSPORT_ICEUDP, ns.JINGLE_TRANSPORT_RAWUDP, ns.GOOGLE_P2P ])
def advertise_caps(q, bus, conn, service, filters, expected_features, unexpected_features, expected_caps): # make sure nothing from a previous update is still running sync_dbus(bus, q, conn) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") ret_caps = conn.ContactCapabilities.UpdateCapabilities( [(cs.CLIENT + '.Foo', filters, [])]) presence, event_dbus = q.expect_many( EventPattern('service-resolved', service=service), EventPattern('dbus-signal', signal='ContactCapabilitiesChanged') ) assertLength(1, event_dbus.args) signaled_caps = event_dbus.args[0] outbound = connect_to_stream(q, 'test@foobar', self_handle_name, str(presence.pt), presence.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection=outbound) # Expect Salut to reply with the correct caps event, namespaces = disco_caps(q, outbound, presence.txt) assertSameElements(expected_caps, signaled_caps[self_handle]) assertContains(ns.TP_FT_METADATA, namespaces) for var in expected_features: assertContains(var, namespaces) for var in unexpected_features: assertDoesNotContain(var, namespaces) # check the Contacts interface give the same caps caps_via_contacts_iface = conn.Contacts.GetContactAttributes( [self_handle], [cs.CONN_IFACE_CONTACT_CAPS], False) \ [self_handle][cs.ATTR_CONTACT_CAPABILITIES] assertSameElements(expected_caps, caps_via_contacts_iface) # close things... outbound.send('</stream:stream>') sync_dbus(bus, q, conn) outbound.transport.loseConnection()
def advertise_caps(q, bus, conn, service, filters, expected_features, unexpected_features, expected_caps): # make sure nothing from a previous update is still running sync_dbus(bus, q, conn) self_handle = conn.Properties.Get(cs.CONN, "SelfHandle") self_handle_name = conn.Properties.Get(cs.CONN, "SelfID") ret_caps = conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.Foo', filters, []) ]) presence, event_dbus = q.expect_many( EventPattern('service-resolved', service=service), EventPattern('dbus-signal', signal='ContactCapabilitiesChanged')) assertLength(1, event_dbus.args) signaled_caps = event_dbus.args[0] outbound = connect_to_stream(q, 'test@foobar', self_handle_name, str(presence.pt), presence.port) e = q.expect('connection-result') assert e.succeeded, e.reason e = q.expect('stream-opened', connection=outbound) # Expect Salut to reply with the correct caps event, namespaces = disco_caps(q, outbound, presence.txt) assertSameElements(expected_caps, signaled_caps[self_handle]) assertContains(ns.TP_FT_METADATA, namespaces) for var in expected_features: assertContains(var, namespaces) for var in unexpected_features: assertDoesNotContain(var, namespaces) # check the Contacts interface give the same caps caps_via_contacts_iface = conn.Contacts.GetContactAttributes( [self_handle], [cs.CONN_IFACE_CONTACT_CAPS], False) \ [self_handle][cs.ATTR_CONTACT_CAPABILITIES] assertSameElements(expected_caps, caps_via_contacts_iface) # close things... outbound.send('</stream:stream>') sync_dbus(bus, q, conn) outbound.transport.loseConnection()
def run_test(q, bus, conn, stream): initial_presence = q.expect('stream-presence') _, namespaces, _ = disco_caps(q, stream, initial_presence) # For some reason, until we advertise any capabilities, these caps turn # up in our presence if VOIP_ENABLED: caps = [ ns.JINGLE, ns.JINGLE_015, ns.JINGLE_TRANSPORT_ICEUDP, ns.JINGLE_TRANSPORT_RAWUDP, ns.GOOGLE_P2P ] else: caps = [] check_caps(namespaces, caps)
def run_test(q, bus, conn, stream): conn.Connect() _, initial_presence = q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-presence'), ) _, namespaces = disco_caps(q, stream, initial_presence) # For some reason, until we advertise any capabilities, these caps turn # up in our presence check_caps(namespaces, [ ns.JINGLE, ns.JINGLE_015, ns.JINGLE_TRANSPORT_ICEUDP, ns.JINGLE_TRANSPORT_RAWUDP, ns.GOOGLE_P2P ])
def run_test(q, bus, conn, stream, media_channel_type, media_interface, initial_audio, initial_video): conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, ], []), ]) conn.Connect() _, initial_presence = q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-presence'), ) (disco_response, namespaces, _) = disco_caps(q, stream, initial_presence) check_caps(namespaces, [ns.TUBES + '/stream#x-abiword']) conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, ], []), (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_audio: True}, { cs.CHANNEL_TYPE: media_channel_type, initial_video: True}, ], [ media_interface + '/gtalk-p2p', media_interface + '/ice-udp', media_interface + '/video/h264', ]), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, JINGLE_CAPS + [ns.TUBES + '/stream#x-abiword']) # Removing our H264 codec removes our ability to do Google Video conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_audio: True}, { cs.CHANNEL_TYPE: media_channel_type, initial_video: True}, ], [ media_interface + '/gtalk-p2p', media_interface + '/ice-udp', ]), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, JINGLE_CAPS_EXCEPT_GVIDEO + [ns.TUBES + '/stream#x-abiword']) # Remove AbiWord's caps conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, JINGLE_CAPS_EXCEPT_GVIDEO) # Remove KCall's caps too conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, []) # If AbiWord claims that it can do MediaSignalling things on its Tubes # channels, then it's wrong, and that still doesn't make us callable. conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, ], [ media_interface + '/gtalk-p2p', media_interface + '/ice-udp', media_interface + '/video/h264', ]), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ns.TUBES + '/stream#x-abiword']) # Remove the broken version of AbiWord's caps conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, []) # Add caps selectively. Here we're callable, but not via ICE-UDP, and not # with video. # # (Jingle and raw UDP need no special client support, so are automatically # enabled whenever we can do audio or video.) conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_audio: True}, ], [media_interface + '/gtalk-p2p']), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ns.GOOGLE_P2P, ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE, ns.JINGLE_015, ns.GOOGLE_FEAT_VOICE, ns.JINGLE_RTP_AUDIO, ns.JINGLE_RTP, ns.JINGLE_015_AUDIO]) # With AUDIO but no transport, we are only callable via raw UDP, which # Google clients cannot do. conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_audio: True}, ], []) ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE, ns.JINGLE_015, ns.JINGLE_RTP_AUDIO, ns.JINGLE_RTP, ns.JINGLE_015_AUDIO]) # With VIDEO and ICE-UDP only, we are very futuristic indeed. # Google clients cannot interop with us. conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_video: True}, ], [ media_interface + '/ice-udp', media_interface + '/video/theora', ]), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ns.JINGLE_TRANSPORT_ICEUDP, ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE, ns.JINGLE_015, ns.JINGLE_RTP_VIDEO, ns.JINGLE_RTP, ns.JINGLE_015_VIDEO]) # Remove KCall to simplify subsequent checks conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, []) # Support file transfer if FILE_TRANSFER_ENABLED: conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.FileReceiver', [{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_FILE_TRANSFER, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, }], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ns.FILE_TRANSFER])
def run_test(q, bus, conn, stream, media_channel_type, media_interface, initial_audio, initial_video): conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, ], []), ]) conn.Connect() _, initial_presence = q.expect_many( EventPattern('dbus-signal', signal='StatusChanged', args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]), EventPattern('stream-presence'), ) (disco_response, namespaces, _) = disco_caps(q, stream, initial_presence) check_caps(namespaces, [ns.TUBES + '/stream#x-abiword']) conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, ], []), (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_audio: True }, { cs.CHANNEL_TYPE: media_channel_type, initial_video: True }, ], [ media_interface + '/gtalk-p2p', media_interface + '/ice-udp', media_interface + '/video/h264', ]), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, JINGLE_CAPS + [ns.TUBES + '/stream#x-abiword']) # Removing our H264 codec removes our ability to do Google Video conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_audio: True }, { cs.CHANNEL_TYPE: media_channel_type, initial_video: True }, ], [ media_interface + '/gtalk-p2p', media_interface + '/ice-udp', ]), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, JINGLE_CAPS_EXCEPT_GVIDEO + [ns.TUBES + '/stream#x-abiword']) # Remove AbiWord's caps conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, JINGLE_CAPS_EXCEPT_GVIDEO) # Remove KCall's caps too conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, []) # If AbiWord claims that it can do MediaSignalling things on its Tubes # channels, then it's wrong, and that still doesn't make us callable. conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [ { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, { cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_STREAM_TUBE, cs.TARGET_HANDLE_TYPE: cs.HT_ROOM, cs.STREAM_TUBE_SERVICE: 'x-abiword' }, ], [ media_interface + '/gtalk-p2p', media_interface + '/ice-udp', media_interface + '/video/h264', ]), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ns.TUBES + '/stream#x-abiword']) # Remove the broken version of AbiWord's caps conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.AbiWord', [], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, []) # Add caps selectively. Here we're callable, but not via ICE-UDP, and not # with video. # # (Jingle and raw UDP need no special client support, so are automatically # enabled whenever we can do audio or video.) conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_audio: True }, ], [media_interface + '/gtalk-p2p']), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ ns.GOOGLE_P2P, ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE, ns.JINGLE_015, ns.GOOGLE_FEAT_VOICE, ns.JINGLE_RTP_AUDIO, ns.JINGLE_RTP, ns.JINGLE_015_AUDIO ]) # With AUDIO but no transport, we are only callable via raw UDP, which # Google clients cannot do. conn.ContactCapabilities.UpdateCapabilities([(cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_audio: True }, ], [])]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE, ns.JINGLE_015, ns.JINGLE_RTP_AUDIO, ns.JINGLE_RTP, ns.JINGLE_015_AUDIO ]) # With VIDEO and ICE-UDP only, we are very futuristic indeed. # Google clients cannot interop with us. conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [ { cs.CHANNEL_TYPE: media_channel_type }, { cs.CHANNEL_TYPE: media_channel_type, initial_video: True }, ], [ media_interface + '/ice-udp', media_interface + '/video/theora', ]), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ ns.JINGLE_TRANSPORT_ICEUDP, ns.JINGLE_TRANSPORT_RAWUDP, ns.JINGLE, ns.JINGLE_015, ns.JINGLE_RTP_VIDEO, ns.JINGLE_RTP, ns.JINGLE_015_VIDEO ]) # Remove KCall to simplify subsequent checks conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.KCall', [], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, []) # Support file transfer if FILE_TRANSFER_ENABLED: conn.ContactCapabilities.UpdateCapabilities([ (cs.CLIENT + '.FileReceiver', [{ cs.CHANNEL_TYPE: cs.CHANNEL_TYPE_FILE_TRANSFER, cs.TARGET_HANDLE_TYPE: cs.HT_CONTACT, }], []), ]) (disco_response, namespaces, _, _) = receive_presence_and_ask_caps(q, stream, False) check_caps(namespaces, [ns.FILE_TRANSFER])