164e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley# Copyright 2015 The Chromium OS Authors. All rights reserved.
264e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley# Use of this source code is governed by a BSD-style license that can be
364e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley# found in the LICENSE file.
464e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
564e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wileyimport dbus
664e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wileyimport time
764e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
864e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wileyfrom autotest_lib.client.bin import test
964e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wileyfrom autotest_lib.client.common_lib import error
1064e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wileyfrom autotest_lib.client.common_lib.cros.tendo import peerd_config
1164e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wileyfrom autotest_lib.client.cros import dbus_util
1264e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
1364e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
1464e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher WileySERVICE_ID = 'test-service'
1564e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
1664e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wileyclass peerd_MonitorsDBusConnections(test.test):
1764e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley    """Test that peerd removes services when processes disconnect from DBus."""
1864e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
1964e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley    version = 1
2064e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
2164e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
2264e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley    def _check_has_test_service(self, expect_service=True):
2364e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        services = dbus_util.get_objects_with_interface(
2464e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                peerd_config.SERVICE_NAME,
2564e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                peerd_config.OBJECT_MANAGER_PATH,
2664e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                peerd_config.DBUS_INTERFACE_SERVICE,
2764e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                path_prefix=peerd_config.DBUS_PATH_SELF,
2864e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                bus=self._bus)
2964e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        found_service = False
3064e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        # services is a map of object path to dicts of DBus interface to
3164e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        # properties exposed by that interface.
3264e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        for path, interfaces in services.iteritems():
3364e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley            for interface, properties in interfaces.iteritems():
3464e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                if interface != peerd_config.DBUS_INTERFACE_SERVICE:
3564e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                    continue
3664e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                if (properties[peerd_config.SERVICE_PROPERTY_SERVICE_ID]
3764e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                        != SERVICE_ID):
3864e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                    continue
3964e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                if found_service:
4064e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                    raise error.TestFail('Found multiple test service '
4164e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                                         'instances?')
4264e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                found_service = True
4364e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
4464e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        if expect_service != found_service:
4564e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley            raise error.TestFail('Expected to see test service, but did not.')
4664e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
4764e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley
4864e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley    def run_once(self):
4964e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        self._bus = dbus.SystemBus()
5064e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        config = peerd_config.PeerdConfig(verbosity_level=5)
5164e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        config.restart_with_config()
5264e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        self._check_has_test_service(expect_service=False)
5364e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        self._manager = dbus.Interface(
5464e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                self._bus.get_object(peerd_config.SERVICE_NAME,
5564e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                                     peerd_config.DBUS_PATH_MANAGER),
5664e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                peerd_config.DBUS_INTERFACE_MANAGER)
5764e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        self._manager.ExposeService(SERVICE_ID,
5864e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                                    dbus.Dictionary(signature='ss'),
5964e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley                                    dbus.Dictionary(signature='sv'))
6064e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        # Python keeps the DBus connection sitting around unless we
6164e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        # explicitly close it.  The service should still be there.
6264e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        time.sleep(1)  # Peerd might take some time to publish the service.
6364e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        self._check_has_test_service()
6464e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        # Close our previous connection, open a new one.
6564e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        self._bus.close()
6664e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        self._bus = dbus.SystemBus()
6764e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        time.sleep(1)  # Peerd might take some time to remove the service.
6864e4d34e0f030275db9a4d1332ed36ca91c8013aChristopher Wiley        self._check_has_test_service(expect_service=False)
69