コード例 #1
0
ファイル: clusterhost.py プロジェクト: fipar/percona-server
    def env(self):
        if not self._env:
            ctx = { 'str': self.exec_blocking(self.hostInfo.envcmd), 'properties': {} }
            util.parse_properties(ctx)
            self._env = ctx['properties']

        return self._env
コード例 #2
0
    def env(self):
        if not self._env:
            ctx = { 'str': self.exec_blocking(self.hostInfo.envcmd), 'properties': {} }
            util.parse_properties(ctx)
            self._env = ctx['properties']

        return self._env
コード例 #3
0
    def add_generic_record(self,
                           absolute_name,
                           type,
                           rdata,
                           ttl=-1,
                           properties={}):
        """Add a new Generic record of specified type.

        :param absolute_name: The FQDN of the record. If you are adding a record in a zone that is linked
            to a incremental Naming Policy, a single hash (#) sign must be added at the
            appropriate location in the FQDN. Depending on the policy order value, the
            location of the single hash (#) sign varies.
        :param type: The type of record being added. Valid settings for this parameter are the
            generic resource record types supported in Address Manager: A6, AAAA,
            AFSDB, APL, CERT, DNAME, DNSKEY, DS, ISDN, KEY, KX, LOC, MB,
            MG, MINFO, MR, NS, NSAP, PX, RP, RT, SINK, SSHFP, WKS, and X25.
        :param rdata: The data for the resource record in BIND format (for example, for A records,
            A 10.0.0.4).
        :param ttl: The time-to-live value for the record. TTL is ignored by default.
        :param properties: Adds object properties, including comments and user-defined fields.
        :return: An instance of generic_record.
        """
        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addGenericRecord(
                    self.get_id(), absolute_name, type, rdata, ttl,
                    util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #4
0
    def add_srv_record(self,
                       absolute_name,
                       priority,
                       port,
                       weight,
                       linked_record_name,
                       ttl=-1,
                       properties={}):
        """Add a new SRV record.

        This method adds the record under a zone.

        :param absolute_name: The FQDN of the SRV record. If you are adding a record in a zone that
            is linked to a incremental Naming Policy, a single hash (#) sign must be
            added at the appropriate location in the FQDN. Depending on the policy
            order value, the location of the single hash (#) sign varies.
        :param priority: Specifies which SRV record to use when multiple matching SRV records
            are present. The record with the lowest value takes precedence.
        :param port: The TCP/UDP port on which the service is available.
        :param weight: If two matching SRV records within a zone have equal priority, the weight
            value is checked. If the weight value for one object is higher than the other,
            the record with the highest weight has its resource records returned first.
        :param linked_record_name: The FQDN of the host record to which this SRV record is linked.
        :param ttl: The time-to-live value for the record. TTL is ignored by default.
        :param properties: Adds object properties, including comments and user-defined fields.
        :return: An instance of srv_record.
        """
        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addSRVRecord(
                    self.get_id(), absolute_name, priority, port,
                    weight, linked_record_name, ttl,
                    util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #5
0
    def add_alias_record(self,
                         absolute_name,
                         linked_record,
                         ttl=-1,
                         properties={}):
        """Add a new CNAME record for an existing host record.

        This method adds the record under a zone.

        :param absolute_name: The FQDN of the alias. If you are adding a record in a zone that is linked to a
            incremental Naming Policy, a single hash (#) sign must be added at the
            appropriate location in the FQDN. Depending on the policy order value, the
            location of the single hash (#) sign varies.
        :param linked_record: The name of the record to which this alias will link.
        :param ttl: The time-to-live value for the record. TTL is ignored by default.
        :param properties: Adds object properties, including comments and user-defined fields.
        :return: An instance of alias_record.
        """
        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addAliasRecord(
                    self.get_id(), absolute_name, linked_record, ttl,
                    util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #6
0
    def add_mx_record(self,
                      absolute_name,
                      priority,
                      linked_record_name,
                      ttl=-1,
                      properties={}):
        """Add a new Mail Exchanger MX record.

        This method adds the record under a zone.

        :param absolute_name: The FQDN for the record. If you are adding a record in a zone that is linked
            to a incremental Naming Policy, a single hash (#) sign must be added at the
            appropriate location in the FQDN. Depending on the policy order value, the
            location of the single hash (#) sign varies.
        :param priority: Specifies which mail server to send clients to first when multiple matching MX
            records are present. Multiple MX records with equal priority values are referred
            to in a round-robin fashion.
        :param ttl: The time-to-live value for the record. TTL is ignored by default.
        :param properties: Adds object properties, including comments and user-defined fields.
        :return: An instance of mx_record.
        """
        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addMXRecord(
                    self.get_id(), absolute_name, priority, linked_record_name,
                    ttl, util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #7
0
    def add_host_record(self, absolute_name, addresses, ttl=-1, properties={}):
        try:

            return self._api.get_entity_by_id(
                self._soap_client.service.addHostRecord(
                    self.get_id(), absolute_name, ','.join(addresses), ttl,
                    util.parse_properties(properties)))

        except WebFault as e:
            raise api_exception(e.message)
コード例 #8
0
    def add_enum_zone(self, prefix, deployable=False, **properties):
        """Add a new ENUM zone.

        :param prefix: The number prefix for the ENUM zone.
        :param deployable: Sets whether this zone is deployable. Default is False.
        :param properties: Adds object properties, including user-defined fields.
        :return: An instance of ENUM zone.
        """
        properties['deployable'] = 'true' if deployable else 'false'
        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addEnumZone(
                    self.get_id(), prefix, util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #9
0
    def add_external_host_record(self, absolute_name, properties={}):
        """Add a new External Host record.

        This method adds the record under a zone.

        :param absolute_name: FQDN for the host record.
        :param properties: Adds object properties, including comments and user-defined fields.
        :return: An instance of external_host_record.
        """
        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addExternalHostRecord(
                    self.get_id(), absolute_name,
                    util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #10
0
    def add_hinfo_record(self, absolute_name, cpu, os, ttl=-1, properties={}):
        """Add a new Host Info HINFO record.

        :param absolute_name: The FQDN of the HINFO record. If you are adding a record in a zone that is
            linked to a incremental Naming Policy, a single hash (#) sign must be added at
            the appropriate location in the FQDN. Depending on the policy order value, the
            location of the single hash (#) sign varies.
        :param cpu: A string providing central processing unit information.
        :param os: A string providing operating system information.
        :param ttl: The time-to-live value for the record. TTL is ignored by default.
        :param properties: Adds object properties, including comments and user-defined fields.
        :return: An instance of host_info_record.
        """
        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addHINFORecord(
                    self.get_id(), absolute_name, cpu, os, ttl,
                    util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #11
0
    def add_naptr_record(self,
                         absolute_name,
                         order,
                         preference,
                         service,
                         regexp,
                         replacement,
                         flags,
                         ttl=-1,
                         properties={}):
        """Add a new NAPTR record.

        :param absolute_name: The FQDN for the record. If you are adding a record in a zone that is linked
            to a incremental Naming Policy, a single hash (#) sign must be added at the
            appropriate location in the FQDN. Depending on the policy order value, the
            location of the single hash (#) sign varies.
        :param order: Specifies the order in which NAPTR records are read if several are present and
            are possible matches. The lower ordervalue takes precedence.
        :param preference: Specifies the order in which NAPTR records are read if the ordervalues are the
            same in multiple records. The lower preferencevalue takes precedence.
        :param service: Specifies the service used for the NAPTR record. Valid settings for this
            parameter are listed in ENUM Services on page 192 in BAM API Guide.
        :param regexp: A regular expression, enclosed in double quotation marks, used to transform
            the client data. If a regular expression is not specified, a domain name must be
            specified in the replacement parameter.
        :param replacement: Specifies a domain name as an alternative to the regexp. This parameter
            replaces client data with a domain name.
        :param flags: An optional parameter used to set flag values for the record.
        :param ttl: The time-to-live value for the record. TTL is ignored by default.
        :param properties: Adds object properties, including comments and user-defined fields.
        :return: An instance of naptr_record.
        """
        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addNAPTRRecord(
                    self.get_id(), absolute_name, order, preference, service,
                    regexp, replacement, flags, ttl,
                    util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #12
0
    def add_resource_record(self,
                            absolute_name,
                            type,
                            rdata,
                            ttl=-1,
                            properties={}):
        """Generic method for adding resource records of any type.

        :param absolute_name: The absolute name of the record, specified as an FQDN. If you are adding a
            record in a zone that is linked to a incremental Naming Policy, a single hash (#)
            sign must be added at the appropriate location in the FQDN. Depending on the
            policy order value, the location of the single hash (#) sign varies.
        :param type: The type of record being added. Supported types using this method:
            AliasRecord
            HINFORecord
            HostRecord
            MXRecord
            TXTRecord
        :param rdata: The data for the resource record in BIND format (for example, for A records,
            A 10.0.0.4). You can specify either a single IPv4 or IPv6 address for the record.
        :param ttl: The time-to-live value for the record.
        :param properties: Adds object properties, including user-defined fields.
        :return: An instance of the resource record type that was added.
        """
        supported_types = [
            self.AliasRecord, self.HINFORecord, self.HostRecord, self.MXRecord,
            self.TXTRecord
        ]
        if type not in supported_types:
            raise api_exception('Type %s is not supported by this method' %
                                type)

        try:
            self._api.get_entity_by_id(
                self._soap_client.service.addResourceRecord(
                    self.get_id(), absolute_name, type, rdata, ttl,
                    util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #13
0
    def add_enum_number(self, number, service_data, name='', **properties):
        """Add an ENUM number object to the ENUM zone.

        :param number: The ENUM phone number.
        :param service_data: List of enum_number.ServiceData objects.
        :param name: Optional name for the ENUM number.
        :param properties: Adds object properties, including user-defined fields.
        :return: An instance of the new enum_number.
        """
        data = ''
        for d in service_data:
            data = ','.join([str(x) for x in d]) + ','

        properties['data'] = data
        if name:
            properties['name'] = name

        try:
            return self._api.get_entity_by_id(
                self._soap_client.service.addEnumNumber(
                    self.get_id(), number, util.parse_properties(properties)))
        except WebFault as e:
            raise api_exception(e.message)
コード例 #14
0
def test(q, bus, conn, stream):
    conn.Connect()

    handles = {}

    _, iq_event, disco_event = q.expect_many(
        EventPattern('dbus-signal', signal='StatusChanged',
            args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
        EventPattern('stream-iq', to=None, query_ns='vcard-temp',
            query_name='vCard'),
        EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS))

    acknowledge_iq(stream, iq_event.stanza)

    activity_prop_iface = dbus.Interface(conn,
            'org.laptop.Telepathy.ActivityProperties')
    buddy_prop_iface = dbus.Interface(conn, 'org.laptop.Telepathy.BuddyInfo')
    gadget_iface = dbus.Interface(conn, 'org.laptop.Telepathy.Gadget')
    requests_iface = dbus.Interface(conn, cs.CONN_IFACE_REQUESTS)

    # Gadget was not announced yet
    call_async(q, requests_iface, 'CreateChannel',
        { cs.CHANNEL_TYPE:
            'org.laptop.Telepathy.Channel.Type.ActivityView',
            'org.laptop.Telepathy.Channel.Interface.View.MaxSize': 5,
          })

    event = q.expect('dbus-error', method='CreateChannel')
    announce_gadget(q, stream, disco_event.stanza)
    sync_stream(q, stream)

    # check if we can request Activity views
    properties = conn.GetAll(
        cs.CONN_IFACE_REQUESTS, dbus_interface=dbus.PROPERTIES_IFACE)

    assert ({cs.CHANNEL_TYPE:
            olpc_name_prefix + '.Channel.Type.ActivityView'},

            [olpc_name_prefix + '.Channel.Interface.View.MaxSize',
             olpc_name_prefix + '.Channel.Type.ActivityView.Properties',
             olpc_name_prefix + '.Channel.Type.ActivityView.Participants'],
         ) in properties.get('RequestableChannelClasses'),\
                 properties['RequestableChannelClasses']

    # request 3 random activities (view 1)
    view_path = request_random_activity_view(q, stream, conn, 3, '1',
            [('activity1', '*****@*****.**',
                {'color': ('str', '#005FE4,#00A0FF')},
                [('lucien@localhost', {'color': ('str', '#AABBCC,#CCBBAA')}),
                 ('jean@localhost', {})]),])

    view1 = bus.get_object(conn.bus_name, view_path)

    # check org.freedesktop.Telepathy.Channel D-Bus properties
    props = view1.GetAll(cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)

    assert props['ChannelType'] == 'org.laptop.Telepathy.Channel.Type.ActivityView'
    assert 'org.laptop.Telepathy.Channel.Interface.View' in props['Interfaces']
    assert props['TargetHandle'] == 0
    assert props['TargetID'] == ''
    assert props['TargetHandleType'] == 0

    # check org.laptop.Telepathy.Channel.Interface.View D-Bus properties
    props = view1.GetAll(
        'org.laptop.Telepathy.Channel.Interface.View',
        dbus_interface=dbus.PROPERTIES_IFACE)

    assert props['MaxSize'] == 3

    # check org.laptop.Telepathy.Channel.Type.ActivityView D-Bus properties
    props = view1.GetAll(
        'org.laptop.Telepathy.Channel.Type.ActivityView',
        dbus_interface=dbus.PROPERTIES_IFACE)

    assert props['Properties'] == {}
    assert props['Participants'] == []

    assert view1.GetChannelType(dbus_interface=cs.CHANNEL) ==\
            'org.laptop.Telepathy.Channel.Type.ActivityView'

    ## Current views ##
    # view 1: activity 1 (with: Lucien, Jean)

    handles['lucien'], handles['jean'] = \
            conn.RequestHandles(1, ['lucien@localhost', 'jean@localhost'])

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    handles['room1'], props = event.args
    assert conn.InspectHandles(2, [handles['room1']])[0] == \
            '*****@*****.**'
    assert props == {'color': '#005FE4,#00A0FF'}

    q.expect('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.Channel.Interface.View',
            args=[[('activity1', handles['room1'])], []])

    # participants are added to view
    q.expect('dbus-signal', signal='BuddiesChanged',
            args=[[handles['lucien'], handles['jean']], []])

    # participants are added to activity
    q.expect_many(
        EventPattern('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.BuddyInfo',
            args=[handles['lucien'], [('activity1', handles['room1'])]]),
        EventPattern('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.BuddyInfo',
            args=[handles['jean'], [('activity1', handles['room1'])]]))

    # check activities and buddies in view
    check_view(view1, conn, [('activity1', handles['room1'])],
            ['lucien@localhost', 'jean@localhost'])

    # we can now get activity properties
    props = activity_prop_iface.GetProperties(handles['room1'])
    assert props == {'color': '#005FE4,#00A0FF'}

    # and we can get participant's properties too
    props = buddy_prop_iface.GetProperties(handles['lucien'])
    assert props == {'color': '#AABBCC,#CCBBAA'}

    # and their activities
    call_async (q, buddy_prop_iface, 'GetActivities', handles['lucien'])

    event = q.expect('stream-iq', to='lucien@localhost', query_name='pubsub',
            query_ns=ns.PUBSUB)
    # return an error, we can't query pubsub node
    answer_error_to_pubsub_request(stream, event.stanza)

    q.expect('dbus-return', method='GetActivities',
            value=([('activity1', handles['room1'])],))

    # activity search by properties (view 2)
    props = dbus.Dictionary({'color': '#AABBCC,#001122'}, signature='sv')

    call_async(q, requests_iface, 'CreateChannel',
        { cs.CHANNEL_TYPE:
            'org.laptop.Telepathy.Channel.Type.ActivityView',
            'org.laptop.Telepathy.Channel.Interface.View.MaxSize': 5,
            'org.laptop.Telepathy.Channel.Type.ActivityView.Properties': props,
          })

    iq_event, return_event = q.expect_many(
        EventPattern('stream-iq', to='gadget.localhost',
            query_ns=ns.OLPC_ACTIVITY),
        EventPattern('dbus-return', method='CreateChannel'))

    properties_nodes = xpath.queryForNodes('/iq/view/activity/properties',
            iq_event.stanza)
    props = parse_properties(properties_nodes[0])
    assert props == {'color': ('str', '#AABBCC,#001122')}

    view = iq_event.stanza.firstChildElement()
    assert view.name == 'view'
    assert view['id'] == '2'
    assert view['size'] == '5'

    send_reply_to_activity_view_request(stream, iq_event.stanza,
            [('activity2', '*****@*****.**',
                {'color': ('str', '#AABBCC,#001122')}, [])])

    ## Current views ##
    # view 1: activity 1 (with: Lucien, Jean)
    # view 2: activity 2

    view_path = return_event.value[0]
    view2 = bus.get_object(conn.bus_name, view_path)

    props = return_event.value[1]
    assert props['org.laptop.Telepathy.Channel.Type.ActivityView.Properties'] == \
            {'color': '#AABBCC,#001122'}
    assert props['org.laptop.Telepathy.Channel.Type.ActivityView.Participants'] == []

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    handles['room2'], props = event.args
    assert conn.InspectHandles(2, [handles['room2']])[0] == '*****@*****.**'
    assert props == {'color': '#AABBCC,#001122'}

    q.expect('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.Channel.Interface.View',
            args=[[('activity2', handles['room2'])], []])

    act = view2.Get(olpc_name_prefix + '.Channel.Interface.View',
        'Activities', dbus_interface=dbus.PROPERTIES_IFACE)
    assert sorted(act) == [('activity2', handles['room2'])]

    buddies = view2.Get(olpc_name_prefix + '.Channel.Interface.View',
        'Buddies', dbus_interface=dbus.PROPERTIES_IFACE)
    assert buddies == []

    # activity search by participants (view 3)
    participants = conn.RequestHandles(1, ["alice@localhost", "bob@localhost"])

    call_async(q, requests_iface, 'CreateChannel',
        { cs.CHANNEL_TYPE:
            'org.laptop.Telepathy.Channel.Type.ActivityView',
            'org.laptop.Telepathy.Channel.Interface.View.MaxSize': 5,
            'org.laptop.Telepathy.Channel.Type.ActivityView.Participants': participants,
          })

    iq_event, return_event = q.expect_many(
        EventPattern('stream-iq', to='gadget.localhost',
            query_ns=ns.OLPC_ACTIVITY),
        EventPattern('dbus-return', method='CreateChannel'))

    buddies = xpath.queryForNodes('/iq/view/activity/buddy', iq_event.stanza)
    view = iq_event.stanza.firstChildElement()
    assert view.name == 'view'
    assert view['id'] == '3'
    assert view['size'] == '5'
    assert len(buddies) == 2
    assert (buddies[0]['jid'], buddies[1]['jid']) == ('alice@localhost',
            'bob@localhost')

    send_reply_to_activity_view_request(stream, iq_event.stanza,
            [('activity3', '*****@*****.**',
                {'color': ('str', '#AABBCC,#001122')}, [])])

    ## Current views ##
    # view 1: activity 1 (with: Lucien, Jean)
    # view 2: activity 2
    # view 3: activity 3

    view_path = return_event.value[0]
    view3 = bus.get_object(conn.bus_name, view_path)

    event = q.expect('dbus-signal', signal='ActivityPropertiesChanged')
    handles['room3'], props = event.args
    assert conn.InspectHandles(2, [handles['room3']])[0] == '*****@*****.**'
    assert props == {'color': '#AABBCC,#001122'}

    q.expect('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.Channel.Interface.View',
            args=[[('activity3', handles['room3'])], []])

    act = view3.Get(olpc_name_prefix + '.Channel.Interface.View',
        'Activities',
        dbus_interface=dbus.PROPERTIES_IFACE)
    assert sorted(act) == [('activity3', handles['room3'])]

    # add activity 4 to view 1
    message = create_gadget_message('alice@localhost')

    added = message.addElement((ns.OLPC_ACTIVITY, 'added'))
    added['id'] = '1'
    activity = added.addElement((None, 'activity'))
    activity['id'] = 'activity4'
    activity['room'] = '*****@*****.**'
    properties = activity.addElement((ns.OLPC_ACTIVITY_PROPS, "properties"))
    for node in properties_to_xml({'color': ('str', '#DDEEDD,#EEDDEE')}):
        properties.addChild(node)
    buddy = activity.addElement((None, 'buddy'))
    buddy['jid'] = 'fernand@localhost'
    properties = buddy.addElement((ns.OLPC_BUDDY_PROPS, "properties"))
    for node in properties_to_xml({'color': ('str', '#AABBAA,#BBAABB')}):
        properties.addChild(node)
    buddy = activity.addElement((None, 'buddy'))
    buddy['jid'] = 'jean@localhost'

    stream.send(message)

    ## Current views ##
    # view 1: activity 1 (with: Lucien, Jean), activity 4 (with: Fernand, Jean)
    # view 2: activity 2
    # view 3: activity 3
    # participants are added to view

    handles['fernand'] = conn.RequestHandles(1, ['fernand@localhost',])[0]

    # activity is added
    event = q.expect('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.Channel.Interface.View')
    added, removed = event.args
    assert len(added) == 1
    id, handles['room4'] = added[0]
    assert id == 'activity4'
    assert sorted(conn.InspectHandles(2, [handles['room4']])) == \
            ['*****@*****.**']

    # buddies are added to view
    q.expect('dbus-signal', signal='BuddiesChanged',
            args=[[handles['fernand'], handles['jean']], []])

    # buddies are added to activity
    q.expect_many(
        EventPattern('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.BuddyInfo',
            args=[handles['fernand'], [('activity4', handles['room4'])]]),
        EventPattern('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.BuddyInfo',
            args=[handles['jean'], [('activity1', handles['room1']),
                ('activity4', handles['room4'])]]))

    # check activities and buddies in view
    check_view(view1, conn, [
        ('activity1', handles['room1']), ('activity4', handles['room4'])],
        ['fernand@localhost', 'lucien@localhost', 'jean@localhost'])

    # check activity's properties
    props = activity_prop_iface.GetProperties(handles['room4'])
    assert props == {'color': '#DDEEDD,#EEDDEE'}

    # Gadget informs us about an activity properties change
    message = create_gadget_message('alice@localhost')

    change = message.addElement((ns.OLPC_ACTIVITY, 'change'))
    change['activity'] = 'activity1'
    change['room'] = '*****@*****.**'
    change['id'] = '1'
    properties = change.addElement((ns.OLPC_ACTIVITY_PROPS, 'properties'))
    for node in properties_to_xml({'tags': ('str', 'game'), \
            'color': ('str', '#AABBAA,#BBAABB')}):
        properties.addChild(node)

    stream.send(message)

    q.expect('dbus-signal', signal='ActivityPropertiesChanged',
            args=[handles['room1'], {'tags': 'game', 'color': '#AABBAA,#BBAABB'}])

    # we now get the new activity properties
    props = activity_prop_iface.GetProperties(handles['room1'])
    assert props == {'tags': 'game', 'color': '#AABBAA,#BBAABB'}

    # Marcel joined activity 1
    message = create_gadget_message('alice@localhost')

    activity = message.addElement((ns.OLPC_ACTIVITY, 'activity'))
    activity['room'] = '*****@*****.**'
    activity['view'] = '1'
    joined = activity.addElement((None, 'joined'))
    joined['jid'] = 'marcel@localhost'
    properties = joined.addElement((ns.OLPC_BUDDY_PROPS, "properties"))
    for node in properties_to_xml({'color': ('str', '#CCCCCC,#DDDDDD')}):
        properties.addChild(node)

    stream.send(message)

    ## Current views ##
    # view 1: activity 1 (with: Lucien, Jean, Marcel), activity 4 (with
    # Fernand, Jean)
    # view 2: activity 2
    # view 3: activity 3

    handles['marcel'] = conn.RequestHandles(1, ['marcel@localhost',])[0]

    q.expect_many(
            EventPattern('dbus-signal', signal='BuddiesChanged',
                args=[[handles['marcel']], []]),
            EventPattern('dbus-signal', signal='PropertiesChanged',
                args=[handles['marcel'], {'color': '#CCCCCC,#DDDDDD'}]),
            EventPattern('dbus-signal', signal='ActivitiesChanged',
                interface='org.laptop.Telepathy.BuddyInfo',
                args=[handles['marcel'], [('activity1', handles['room1'])]]))

    # check activities and buddies in view
    check_view(view1, conn, [
        ('activity1', handles['room1']),('activity4', handles['room4'])],
        ['fernand@localhost', 'lucien@localhost', 'jean@localhost',
            'marcel@localhost'])

    # Marcel left activity 1
    message = create_gadget_message('alice@localhost')

    activity = message.addElement((ns.OLPC_ACTIVITY, 'activity'))
    activity['room'] = '*****@*****.**'
    activity['view'] = '1'
    left = activity.addElement((None, 'left'))
    left['jid'] = 'marcel@localhost'

    stream.send(message)

    ## Current views ##
    # view 1: activity 1 (with: Lucien, Jean), activity 4 (with Fernand, Jean)
    # view 2: activity 2
    # view 3: activity 3

    q.expect_many(
            EventPattern('dbus-signal', signal='BuddiesChanged',
                args=[[], [handles['marcel']]]),
            EventPattern('dbus-signal', signal='ActivitiesChanged',
                interface='org.laptop.Telepathy.BuddyInfo',
                args=[handles['marcel'], []]))

    # check activities and buddies in view
    check_view(view1, conn, [
        ('activity1', handles['room1']),('activity4', handles['room4'])],
        ['fernand@localhost', 'lucien@localhost', 'jean@localhost'])

    # Jean left activity 1
    message = create_gadget_message('alice@localhost')

    activity = message.addElement((ns.OLPC_ACTIVITY, 'activity'))
    activity['room'] = '*****@*****.**'
    activity['view'] = '1'
    left = activity.addElement((None, 'left'))
    left['jid'] = 'jean@localhost'

    stream.send(message)

    ## Current views ##
    # view 1: activity 1 (with: Lucien), activity 4 (with Fernand, Jean)
    # view 2: activity 2
    # view 3: activity 3

    q.expect('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.BuddyInfo',
            args=[handles['jean'], [('activity4', handles['room4'])]])

    # Jean wasn't removed from the view as he is still in activity 4
    check_view(view1, conn, [
        ('activity1', handles['room1']),('activity4', handles['room4'])],
        ['fernand@localhost', 'lucien@localhost', 'jean@localhost'])

    # remove activity 1 from view 1
    message = create_gadget_message('alice@localhost')

    removed = message.addElement((ns.OLPC_ACTIVITY, 'removed'))
    removed['id'] = '1'
    activity = removed.addElement((None, 'activity'))
    activity['id'] = 'activity1'
    activity['room'] = '*****@*****.**'

    stream.send(message)

    ## Current views ##
    # view 1: activity 4 (with Jean, Fernand)
    # view 2: activity 2
    # view 3: activity 3

    q.expect_many(
    # participants are removed from the view
            EventPattern('dbus-signal', signal='BuddiesChanged',
                args=[[], [handles['lucien']]]),
    # activity is removed from the view
            EventPattern('dbus-signal', signal='ActivitiesChanged',
                interface='org.laptop.Telepathy.Channel.Interface.View',
                args=[[], [('activity1', handles['room1'])]]),
            EventPattern('dbus-signal', signal='ActivitiesChanged',
                interface='org.laptop.Telepathy.BuddyInfo',
                args=[handles['lucien'], []]))

    # check activities and buddies in view
    check_view(view1, conn, [
        ('activity4', handles['room4'])],
        ['fernand@localhost', 'jean@localhost'])

    # close view 1
    call_async(q, view1, 'Close')
    event_msg, _, _, _ = q.expect_many(
        EventPattern('stream-message', to='gadget.localhost'),
        EventPattern('dbus-return', method='Close'),
        # Jean and Fernand left activity4
        EventPattern('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.BuddyInfo',
            args=[handles['jean'], []]),
        EventPattern('dbus-signal', signal='ActivitiesChanged',
            interface='org.laptop.Telepathy.BuddyInfo',
            args=[handles['fernand'], []]))

    close = xpath.queryForNodes('/message/close', event_msg.stanza)
    assert len(close) == 1
    assert close[0]['id'] == '1'

    close_view(q, view2, '2')

    close_view(q, view3, '3')

    # View request without MaxSize property
    call_async(q, requests_iface, 'CreateChannel',
        { cs.CHANNEL_TYPE:
            'org.laptop.Telepathy.Channel.Type.ActivityView',
          })

    event = q.expect('dbus-error', method='CreateChannel')
    assert event.error.get_dbus_name() == cs.INVALID_ARGUMENT

    # test participants and properties search
    props = dbus.Dictionary({'color': '#AABBCC,#001122'}, signature='sv')
    participants = conn.RequestHandles(1, ["alice@localhost", "bob@localhost"])

    call_async(q, requests_iface, 'CreateChannel',
        { cs.CHANNEL_TYPE:
            'org.laptop.Telepathy.Channel.Type.ActivityView',
            'org.laptop.Telepathy.Channel.Interface.View.MaxSize': 5,
            'org.laptop.Telepathy.Channel.Type.ActivityView.Properties': props,
            'org.laptop.Telepathy.Channel.Type.ActivityView.Participants': participants,
          })

    iq_event, return_event = q.expect_many(
        EventPattern('stream-iq', to='gadget.localhost', query_ns=ns.OLPC_ACTIVITY),
        EventPattern('dbus-return', method='CreateChannel'))

    view = iq_event.stanza.firstChildElement()
    assert view.name == 'view'
    assert view['id'] == '4'
    assert view['size'] == '5'

    properties_nodes = xpath.queryForNodes('/iq/view/activity/properties',
            iq_event.stanza)
    props = parse_properties(properties_nodes[0])
    assert props == {'color': ('str', '#AABBCC,#001122')}

    buddies = xpath.queryForNodes('/iq/view/activity/buddy', iq_event.stanza)
    assert len(buddies) == 2
    assert (buddies[0]['jid'], buddies[1]['jid']) == ('alice@localhost',
            'bob@localhost')

    view_path = return_event.value[0]
    props = return_event.value[1]
    view4 = bus.get_object(conn.bus_name, view_path)

    assert props['org.laptop.Telepathy.Channel.Type.ActivityView.Properties'] == \
            dbus.Dictionary({'color': '#AABBCC,#001122'}, signature='sv')
    assert conn.InspectHandles(1, props['org.laptop.Telepathy.Channel.Type.ActivityView.Participants']) == \
            ["alice@localhost", "bob@localhost"]
コード例 #15
0
def parse_reply(ctx):
    """Return False unless ctx['str'] is an mgmd reply. Assign first line to ctx['reply_type], parse property list and return True otherwise."""
    return _parse_until_delim(ctx, 'reply_type', '\n') and parse_properties(ctx,': ')
コード例 #16
0
def parse_reply(ctx):
    """Return False unless ctx['str'] is an mgmd reply. Assign first line to ctx['reply_type], parse property list and return True otherwise."""
    return _parse_until_delim(ctx, 'reply_type', '\n') and parse_properties(
        ctx, ': ')
コード例 #17
0
def test(q, bus, conn, stream):
    conn.Connect()

    _, iq_event, disco_event = q.expect_many(
        EventPattern('dbus-signal', signal='StatusChanged',
            args=[cs.CONN_STATUS_CONNECTED, cs.CSR_REQUESTED]),
        EventPattern('stream-iq', to=None, query_ns='vcard-temp',
            query_name='vCard'),
        EventPattern('stream-iq', to='localhost', query_ns=ns.DISCO_ITEMS))

    acknowledge_iq(stream, iq_event.stanza)

    buddy_info_iface = dbus.Interface(conn, 'org.laptop.Telepathy.BuddyInfo')
    gadget_iface = dbus.Interface(conn, 'org.laptop.Telepathy.Gadget')
    requests_iface = dbus.Interface(conn, tp_name_prefix + '.Connection.Interface.Requests')

    # Gadget was not announced yet
    call_async(q, requests_iface, 'CreateChannel',
        { cs.CHANNEL_TYPE:
            'org.laptop.Telepathy.Channel.Type.BuddyView',
            'org.laptop.Telepathy.Channel.Interface.View.MaxSize': 5,
          })

    event = q.expect('dbus-error', method='CreateChannel')
    announce_gadget(q, stream, disco_event.stanza)
    call_async(q, conn, 'RequestHandles', 1, ['bob@localhost'])

    event = q.expect('dbus-return', method='RequestHandles')
    handles = event.value[0]
    bob_handle = handles[0]

    call_async(q, buddy_info_iface, 'GetProperties', bob_handle)

    # wait for pubsub query
    event = q.expect('stream-iq', to='bob@localhost', query_ns=ns.PUBSUB)
    query = event.stanza
    assert query['to'] == 'bob@localhost'

    # send an error as reply
    reply = IQ(stream, 'error')
    reply['id'] = query['id']
    reply['to'] = 'alice@localhost'
    reply['from'] = 'bob@localhost'
    stream.send(reply)

    # wait for buddy search query
    event = q.expect('stream-iq', to='gadget.localhost',
            query_ns=ns.OLPC_BUDDY)
    buddies = xpath.queryForNodes('/iq/query/buddy', event.stanza)
    assert len(buddies) == 1
    buddy = buddies[0]
    assert buddy['jid'] == 'bob@localhost'

    # send reply to the search query
    reply = make_result_iq(stream, event.stanza)
    reply['from'] = 'gadget.localhost'
    reply['to'] = 'alice@localhost'
    query = xpath.queryForNodes('/iq/query', reply)[0]
    buddy = query.addElement((None, "buddy"))
    buddy['jid'] = 'bob@localhost'
    properties = buddy.addElement((ns.OLPC_BUDDY_PROPS, "properties"))
    for node in properties_to_xml({'color': ('str', '#005FE4,#00A0FF')}):
        properties.addChild(node)
    stream.send(reply)

    event = q.expect('dbus-return', method='GetProperties')
    props = event.value[0]

    assert props == {'color': '#005FE4,#00A0FF' }

    # check if we can request Buddy views
    properties = conn.GetAll(
        cs.CONN_IFACE_REQUESTS, dbus_interface=dbus.PROPERTIES_IFACE)

    assert ({tp_name_prefix + '.Channel.ChannelType':
            olpc_name_prefix + '.Channel.Type.BuddyView'},
            [olpc_name_prefix + '.Channel.Interface.View.MaxSize',
             olpc_name_prefix + '.Channel.Type.BuddyView.Properties',
             olpc_name_prefix + '.Channel.Type.BuddyView.Alias'],
         ) in properties.get('RequestableChannelClasses'),\
                 properties['RequestableChannelClasses']

    # request 3 random buddies
    call_async(q, requests_iface, 'CreateChannel',
        { tp_name_prefix + '.Channel.ChannelType':
            olpc_name_prefix + '.Channel.Type.BuddyView',
          olpc_name_prefix + '.Channel.Interface.View.MaxSize': 3
          })

    iq_event, return_event, new_channels_event, new_channel_event = q.expect_many(
        EventPattern('stream-iq', to='gadget.localhost',
            query_ns=ns.OLPC_BUDDY),
        EventPattern('dbus-return', method='CreateChannel'),
        EventPattern('dbus-signal', signal='NewChannels'),
        EventPattern('dbus-signal', signal='NewChannel'))

    view = iq_event.stanza.firstChildElement()
    assert view.name == 'view'
    assert view['id'] == '1'
    assert view['size'] == '3'

    # reply to random query
    reply = make_result_iq(stream, iq_event.stanza)
    reply['from'] = 'gadget.localhost'
    reply['to'] = 'alice@localhost'
    view = xpath.queryForNodes('/iq/view', reply)[0]
    buddy = view.addElement((None, "buddy"))
    buddy['jid'] = 'charles@localhost'
    properties = buddy.addElement((ns.OLPC_BUDDY_PROPS, "properties"))
    for node in properties_to_xml({'color': ('str', '#AAAAAA,#BBBBBB')}):
        properties.addChild(node)
    buddy = view.addElement((None, "buddy"))
    buddy['jid'] = 'bob@localhost'
    properties = buddy.addElement((ns.OLPC_BUDDY_PROPS, "properties"))
    for node in properties_to_xml({'color': ('str', '#005FE4,#00A0FF')}):
        properties.addChild(node)
    stream.send(reply)

    view_path = return_event.value[0]
    props = return_event.value[1]
    view1 = bus.get_object(conn.bus_name, view_path)

    # check NewChannels arg
    channels = new_channels_event.args[0]
    assert len(channels) == 1
    chan, props_ = channels[0]
    assert chan == view_path
    assert props == props_

    # check NewChannel arg
    chan = new_channel_event.args[0]
    assert chan == view_path

    assert props['org.laptop.Telepathy.Channel.Type.BuddyView.Properties'] == {}
    assert props['org.laptop.Telepathy.Channel.Type.BuddyView.Alias'] == ''

    # check org.freedesktop.Telepathy.Channel D-Bus properties
    props = view1.GetAll(cs.CHANNEL, dbus_interface=dbus.PROPERTIES_IFACE)

    assert props['ChannelType'] == 'org.laptop.Telepathy.Channel.Type.BuddyView'
    assert 'org.laptop.Telepathy.Channel.Interface.View' in props['Interfaces']
    assert props['TargetHandle'] == 0
    assert props['TargetID'] == ''
    assert props['TargetHandleType'] == 0

    # check org.laptop.Telepathy.Channel.Interface.View D-Bus properties
    props = view1.GetAll(
        'org.laptop.Telepathy.Channel.Interface.View',
        dbus_interface=dbus.PROPERTIES_IFACE)

    assert props['MaxSize'] == 3

    # check org.laptop.Telepathy.Channel.Type.BuddyView D-Bus properties
    props = view1.GetAll(
        'org.laptop.Telepathy.Channel.Type.BuddyView',
        dbus_interface=dbus.PROPERTIES_IFACE)

    assert props['Properties'] == {}
    assert props['Alias'] == ''

    assert view1.GetChannelType(dbus_interface=cs.CHANNEL) ==\
            'org.laptop.Telepathy.Channel.Type.BuddyView'

    event = q.expect('dbus-signal', signal='BuddiesChanged')
    added, removed = event.args
    assert removed == []
    assert len(added) == 2
    assert sorted(conn.InspectHandles(1, added)) == ['bob@localhost',
            'charles@localhost']

    event = q.expect('dbus-signal', signal='PropertiesChanged')
    event = q.expect('dbus-signal', signal='PropertiesChanged')

    # we can now get bob's properties
    bob_handle = conn.RequestHandles(1, ['bob@localhost'])[0]
    props = buddy_info_iface.GetProperties(bob_handle)
    assert props == {'color': '#005FE4,#00A0FF'}

    # Bob changed his properties
    message = create_gadget_message("test@localhost")

    change = message.addElement((ns.OLPC_BUDDY, 'change'))
    change['jid'] = 'bob@localhost'
    change['id'] = '1'
    properties = change.addElement((ns.OLPC_BUDDY_PROPS, 'properties'))
    for node in properties_to_xml({'color': ('str', '#FFFFFF,#AAAAAA')}):
        properties.addChild(node)

    stream.send(message)

    event = q.expect('dbus-signal', signal='PropertiesChanged',
            args=[bob_handle, {'color': '#FFFFFF,#AAAAAA'}])

    # we now get the new properties
    props = buddy_info_iface.GetProperties(bob_handle)
    assert props == {'color': '#FFFFFF,#AAAAAA'}

    # buddy search
    props = dbus.Dictionary({'color': '#AABBCC,#001122'}, signature='sv')
    call_async(q, requests_iface, 'CreateChannel',
        { tp_name_prefix + '.Channel.ChannelType':
            olpc_name_prefix + '.Channel.Type.BuddyView',
          olpc_name_prefix + '.Channel.Interface.View.MaxSize': 10,
          olpc_name_prefix + '.Channel.Type.BuddyView.Properties': props
          })

    iq_event, return_event = q.expect_many(
        EventPattern('stream-iq', to='gadget.localhost', query_ns=ns.OLPC_BUDDY),
        EventPattern('dbus-return', method='CreateChannel'))

    properties_node = xpath.queryForNodes('/iq/view/buddy/properties',
            iq_event.stanza)
    props = parse_properties(properties_node[0])
    assert props == {'color': ('str', '#AABBCC,#001122')}

    view = iq_event.stanza.firstChildElement()
    assert view.name == 'view'
    assert view['id'] == '2'
    assert view['size'] == '10'

    # reply to request
    reply = make_result_iq(stream, iq_event.stanza)
    reply['from'] = 'gadget.localhost'
    reply['to'] = 'alice@localhost'
    view = xpath.queryForNodes('/iq/view', reply)[0]
    buddy = view.addElement((None, "buddy"))
    buddy['jid'] = 'charles@localhost'
    properties = buddy.addElement((ns.OLPC_BUDDY_PROPS, "properties"))
    for node in properties_to_xml({'color': ('str', '#AABBCC,#001122')}):
        properties.addChild(node)
    stream.send(reply)

    view_path = return_event.value[0]
    props = return_event.value[1]
    view2 = bus.get_object(conn.bus_name, view_path)

    assert props['org.laptop.Telepathy.Channel.Type.BuddyView.Properties'] == dbus.Dictionary({'color': '#AABBCC,#001122'}, signature='sv')
    assert props['org.laptop.Telepathy.Channel.Type.BuddyView.Alias'] == ''

    # check org.laptop.Telepathy.Channel.Type.BuddyView D-Bus properties
    props = view2.GetAll(
        'org.laptop.Telepathy.Channel.Type.BuddyView',
        dbus_interface=dbus.PROPERTIES_IFACE)

    assert props['Properties'] == {'color': '#AABBCC,#001122'}
    assert props['Alias'] == ''

    event = q.expect('dbus-signal', signal='BuddiesChanged')
    added, removed = event.args
    assert removed == []
    assert len(added) == 1
    handle = added[0]
    assert conn.InspectHandles(1, [handle])[0] == 'charles@localhost'

    event = q.expect('dbus-signal', signal='PropertiesChanged')
    handle, props = event.args
    assert conn.InspectHandles(1, [handle])[0] == 'charles@localhost'
    assert props == {'color': '#AABBCC,#001122'}

    # add a buddy to view 1
    message = create_gadget_message("test@localhost")

    added = message.addElement((ns.OLPC_BUDDY, 'added'))
    added['id'] = '1'
    buddy = added.addElement((None, 'buddy'))
    buddy['jid'] = 'oscar@localhost'
    properties = buddy.addElement((ns.OLPC_BUDDY_PROPS, "properties"))
    for node in properties_to_xml({'color': ('str', '#000000,#AAAAAA')}):
        properties.addChild(node)

    stream.send(message)

    event = q.expect('dbus-signal', signal='BuddiesChanged')
    added, removed = event.args
    assert removed == []
    assert len(added) == 1
    handle = added[0]
    assert conn.InspectHandles(1, added)[0] == 'oscar@localhost'

    members = view1.Get(olpc_name_prefix + '.Channel.Interface.View',
        'Buddies', dbus_interface=dbus.PROPERTIES_IFACE)

    members = sorted(conn.InspectHandles(1, members))
    assert sorted(members) == ['bob@localhost', 'charles@localhost',
            'oscar@localhost']

    # remove a buddy from view 1
    message = create_gadget_message("test@localhost")

    added = message.addElement((ns.OLPC_BUDDY, 'removed'))
    added['id'] = '1'
    buddy = added.addElement((None, 'buddy'))
    buddy['jid'] = 'bob@localhost'

    stream.send(message)

    event = q.expect('dbus-signal', signal='BuddiesChanged')
    added, removed = event.args
    assert added == []
    assert len(removed) == 1
    handle = removed[0]
    assert conn.InspectHandles(1, [handle])[0] == 'bob@localhost'

    members = view1.Get(olpc_name_prefix + '.Channel.Interface.View',
        'Buddies', dbus_interface=dbus.PROPERTIES_IFACE)
    members = sorted(conn.InspectHandles(1, members))
    assert sorted(members) == ['charles@localhost', 'oscar@localhost']

    # test alias search
    call_async(q, requests_iface, 'CreateChannel',
        { tp_name_prefix + '.Channel.ChannelType':
            olpc_name_prefix + '.Channel.Type.BuddyView',
          olpc_name_prefix + '.Channel.Interface.View.MaxSize': 10,
          olpc_name_prefix + '.Channel.Type.BuddyView.Alias': 'tom'
          })


    iq_event, return_event = q.expect_many(
        EventPattern('stream-iq', to='gadget.localhost',
            query_ns=ns.OLPC_BUDDY),
        EventPattern('dbus-return', method='CreateChannel'))

    view = iq_event.stanza.firstChildElement()
    assert view.name == 'view'
    assert view['id'] == '3'
    assert view['size'] == '10'
    buddy = xpath.queryForNodes('/iq/view/buddy', iq_event.stanza)
    assert len(buddy) == 1
    assert buddy[0]['alias'] == 'tom'

    # reply to random query
    reply = make_result_iq(stream, iq_event.stanza)
    reply['from'] = 'gadget.localhost'
    reply['to'] = 'alice@localhost'
    view = xpath.queryForNodes('/iq/view', reply)[0]
    buddy = view.addElement((None, "buddy"))
    buddy['jid'] = 'tom@localhost'
    buddy = view.addElement((None, "buddy"))
    buddy['jid'] = 'thomas@localhost'
    stream.send(reply)

    view_path = return_event.value[0]
    props = return_event.value[1]
    view3 = bus.get_object(conn.bus_name, view_path)

    assert props['org.laptop.Telepathy.Channel.Type.BuddyView.Properties'] == {}
    assert props['org.laptop.Telepathy.Channel.Type.BuddyView.Alias'] == 'tom'

    # check org.laptop.Telepathy.Channel.Type.BuddyView D-Bus properties
    props = view3.GetAll(
        'org.laptop.Telepathy.Channel.Type.BuddyView',
        dbus_interface=dbus.PROPERTIES_IFACE)

    assert props['Properties'] == {}
    assert props['Alias'] == 'tom'

    event = q.expect('dbus-signal', signal='BuddiesChanged')
    added, removed = event.args
    assert removed == []
    assert len(added) == 2
    assert sorted(conn.InspectHandles(1, added)) == ['thomas@localhost',
            'tom@localhost']

    close_view(q, view1, '1')

    close_view(q, view2, '2')

    close_view(q, view3, '3')

    # View request without MaxSize property
    call_async(q, requests_iface, 'CreateChannel',
        { cs.CHANNEL_TYPE:
            'org.laptop.Telepathy.Channel.Type.BuddyView',
          })

    event = q.expect('dbus-error', method='CreateChannel')
    assert event.error.get_dbus_name() == cs.INVALID_ARGUMENT

    # test alias and properties search
    props = dbus.Dictionary({'color': '#AABBCC,#001122'}, signature='sv')
    call_async(q, requests_iface, 'CreateChannel',
        { tp_name_prefix + '.Channel.ChannelType':
            olpc_name_prefix + '.Channel.Type.BuddyView',
          olpc_name_prefix + '.Channel.Interface.View.MaxSize': 5,
          olpc_name_prefix + '.Channel.Type.BuddyView.Properties': props,
          olpc_name_prefix + '.Channel.Type.BuddyView.Alias': 'jean'
          })

    iq_event, return_event = q.expect_many(
        EventPattern('stream-iq', to='gadget.localhost', query_ns=ns.OLPC_BUDDY),
        EventPattern('dbus-return', method='CreateChannel'))

    view = iq_event.stanza.firstChildElement()
    assert view.name == 'view'
    assert view['id'] == '4'
    assert view['size'] == '5'

    properties_node = xpath.queryForNodes('/iq/view/buddy/properties',
            iq_event.stanza)
    props = parse_properties(properties_node[0])
    assert props == {'color': ('str', '#AABBCC,#001122')}

    buddy = xpath.queryForNodes('/iq/view/buddy', iq_event.stanza)
    assert len(buddy) == 1
    assert buddy[0]['alias'] == 'jean'

    view_path = return_event.value[0]
    props = return_event.value[1]
    view4 = bus.get_object(conn.bus_name, view_path)

    assert props['org.laptop.Telepathy.Channel.Type.BuddyView.Properties'] == dbus.Dictionary({'color': '#AABBCC,#001122'}, signature='sv')
    assert props['org.laptop.Telepathy.Channel.Type.BuddyView.Alias'] == 'jean'