def realm_property_test(self): """Test the realm property.""" realm_in = { "name": "domain.example.com", "discover-options": ["--client-software=sssd"], "join-options": ["--one-time-password=password"], "discovered": True } realm_out = { "name": get_variant(Str, "domain.example.com"), "discover-options": get_variant(List[Str], ["--client-software=sssd"]), "join-options": get_variant(List[Str], ["--one-time-password=password"]), "discovered": get_variant(Bool, True), "required-packages": get_variant(List[Str], []) } self.security_interface.SetRealm(realm_in) self.assertEqual(realm_out, self.security_interface.Realm) self.callback.assert_called_once_with(SECURITY.interface_name, {'Realm': realm_out}, [])
def realmd_requirements_test(self): """Test that package requirements in realm data propagate correctly.""" realm_in = { "name": "domain.example.com", "discover-options": ["--client-software=sssd"], "join-options": ["--one-time-password=password"], "discovered": True, "required-packages" : ["realmd", "foo", "bar"] } self.security_interface.SetRealm(realm_in) # check that the teamd package is requested self.assertEqual(self.security_interface.CollectRequirements(), [ { "type": get_variant(Str, "package"), "name": get_variant(Str, "realmd"), "reason": get_variant(Str, "Needed to join a realm.") }, { "type": get_variant(Str, "package"), "name": get_variant(Str, "foo"), "reason": get_variant(Str, "Needed to join a realm.") }, { "type": get_variant(Str, "package"), "name": get_variant(Str, "bar"), "reason": get_variant(Str, "Needed to join a realm.") } ])
def method_test(self, register): """Test the method publishing.""" self._publish_object(""" <node> <interface name="Interface"> <method name="Method1"/> <method name="Method2"> <arg direction="in" name="x" type="i"/> </method> <method name="Method3"> <arg direction="out" name="return" type="i"/> </method> <method name="Method4"> <arg direction="in" name="x" type="ad"/> <arg direction="in" name="y" type="o"/> <arg direction="out" name="return" type="(ib)"/> </method> </interface> </node> """) self.object.Method2.return_value = None self._call_method("Interface", "Method2", parameters=get_variant("(i)", (1, ))) self.object.Method2.assert_called_once_with(1) self.object.Method1.return_value = None self._call_method("Interface", "Method1") self.object.Method1.assert_called_once_with() self.object.Method3.return_value = 0 self._call_method("Interface", "Method3", reply=get_variant("(i)", (0, ))) self.object.Method3.assert_called_once_with() self.object.Method4.return_value = (1, True) self._call_method("Interface", "Method4", parameters=get_variant("(ado)", ([1.2, 2.3], "/my/path")), reply=get_variant("((ib))", ((1, True), ))) self.object.Method4.assert_called_once_with([1.2, 2.3], "/my/path") self._call_method_with_error( "Interface", "MethodInvalid", error_name="not.known.Error.DBusSpecificationError", error_message= "Unknown member MethodInvalid of the interface Interface.")
def get_data_variant(self, obj): """Get a variant of the data attribute. :param obj: a data object :return: a variant """ return get_variant(self.type_hint, self.get_data(obj))
def get_data_variant(self, obj): """Get a variant of the data attribute. :param obj: a data object :return: a variant """ return get_variant(self.type_hint, self.get_data(obj))
def async_method_test(self, register): """Test asynchronous calls of a method proxy.""" self._create_proxy(""" <node> <interface name="Interface"> <method name="Method1"/> <method name="Method2"> <arg direction="in" name="x" type="i"/> <arg direction="in" name="y" type="i"/> <arg direction="out" name="return" type="i"/> </method> </interface> </node> """) callback = Mock() callback_args = ("A", "B") self.proxy.Method1(callback=callback, callback_args=callback_args) self._check_async_call("Interface", "Method1", callback, callback_args) self._finish_async_call(self.NO_REPLY, callback, callback_args) callback.assert_called_once_with(None, "A", "B") callback = Mock() callback_args = ("A", "B") self.proxy.Method2(1, 2, callback=callback, callback_args=callback_args) self._check_async_call("Interface", "Method2", callback, callback_args, get_variant("(ii)", (1, 2)), get_variant_type("(i)")) self._finish_async_call(get_variant("(i)", (3, )), callback, callback_args) callback.assert_called_once_with(3, "A", "B") callback = Mock() callback_args = ("A", "B") register.map_exception_to_name(FakeException, "org.test.Unknown") error = Gio.DBusError.new_for_dbus_error("org.test.Unknown", "My message.") with self.assertRaises(FakeException) as cm: self._finish_async_call(error, callback, callback_args) self.assertEqual(str(cm.exception), "My message.") callback.assert_not_called()
def realm_property_test(self): """Test the realm property.""" realm_in = { "name": "domain.example.com", "discover-options": ["--client-software=sssd"], "join-options": ["--one-time-password=password"] } realm_out = { "name": get_variant(Str, "domain.example.com"), "discover-options": get_variant(List[Str], ["--client-software=sssd"]), "join-options": get_variant(List[Str], ["--one-time-password=password"]) } self.security_interface.SetRealm(realm_in) self.assertEqual(realm_out, self.security_interface.Realm) self.callback.assert_called_once_with(SECURITY.interface_name, {'Realm': realm_out}, [])
def realm_property_test(self): """Test the realm property.""" realm_in = { REALM_NAME: "domain.example.com", REALM_DISCOVER: ["--client-software=sssd"], REALM_JOIN: ["--one-time-password=password"] } realm_out = { REALM_NAME: get_variant(Str, "domain.example.com"), REALM_DISCOVER: get_variant(List[Str], ["--client-software=sssd"]), REALM_JOIN: get_variant(List[Str], ["--one-time-password=password"]) } self.security_interface.SetRealm(realm_in) self.assertEqual(realm_out, self.security_interface.Realm) self.callback.assert_called_once_with(SECURITY.interface_name, {'Realm': realm_out}, [])
def set_call_reply(cls, invocation, out_type, out_value): """Set the reply of the DBus call. :param invocation: an invocation of a DBus call :param out_type: a type of the reply :param out_value: a value of the reply """ reply_value = None if out_type is not None: reply_value = get_variant(out_type, (out_value, )) invocation.return_value(reply_value)
def _get_property(self, interface_name, property_name): """The default handler of the Get method. :param interface_name: an interface name :param property_name: a property name :return: a property value """ member = self._find_member_spec(interface_name, property_name) if not member.readable: raise AttributeError("The property {}.{} is not readable.".format( interface_name, property_name)) value = getattr(self._object, property_name) return get_variant(member.type, value)
def _emit_signal(self, interface_name, signal_name, *parameters): """Handle a DBus signal. :param interface_name: a DBus interface name :param signal_name: a DBus signal name :param parameters: a signal parameters """ member = self._find_member_spec(interface_name, signal_name) if not parameters: parameters = None if member.type is not None: parameters = get_variant(member.type, parameters) self._server.emit_signal(self._message_bus.connection, self._object_path, interface_name, signal_name, parameters)
def introspect_test(self): """Test the introspection.""" self._set_reply( get_variant("(s)", (dedent(""" <node> <interface name="Interface"> <method name="Method1"/> </interface> </node> """), ))) self.handler = ClientObjectHandler(self.message_bus, self.service_name, self.object_path) self.assertIsNotNone(self.handler.specification) self._check_call("org.freedesktop.DBus.Introspectable", "Introspect", reply_type=get_variant_type("(s)")) self.assertIn( DBusSpecification.Method("Method1", "Interface", None, None), self.handler.specification.members)
def signal_test(self): """Test the signal publishing.""" self._publish_object(""" <node> <interface name="Interface"> <signal name="Signal1" /> <signal name="Signal2"> <arg direction="out" name="x" type="i"/> <arg direction="out" name="y" type="s"/> </signal> </interface> </node> """) self.object.Signal1() self.message_bus.connection.emit_signal.assert_called_once_with( None, self.object_path, "Interface", "Signal1", None) self.message_bus.connection.emit_signal.reset_mock() self.object.Signal2(1, "Test") self.message_bus.connection.emit_signal.assert_called_once_with( None, self.object_path, "Interface", "Signal2", get_variant("(is)", (1, "Test")))
def signal_test(self): """Test the signal publishing.""" self._create_proxy(""" <node> <interface name="Interface"> <signal name="Signal1" /> <signal name="Signal2"> <arg direction="out" name="x" type="i"/> <arg direction="out" name="y" type="s"/> </signal> </interface> </node> """) self.assertIsInstance(self.proxy.Signal1, Signal) self.assertEqual(self.proxy.Signal1, self.proxy.Signal1) self._check_signal("Interface", "Signal1", self.proxy.Signal1.emit) self._emit_signal(self.NO_REPLY, self.proxy.Signal1.emit) self.assertEqual(len(self.handler._subscriptions), 1) self._check_signal("Interface", "Signal2", self.proxy.Signal2.emit) self._emit_signal(get_variant("(is)", (1, "Test")), self.proxy.Signal2.emit) self.assertEqual(len(self.handler._subscriptions), 2) with self.assertRaises(AttributeError): self.fail(self.proxy.SignalInvalid) with self.assertRaises(AttributeError): self.proxy.Signal1 = self.handler._signal_factory() del self.proxy.Signal1 self.connection.signal_unsubscribe.assert_called_once() self.assertEqual(self.handler._subscriptions["Interface", "Signal1"], [])
def property_test(self): """Test the property proxy.""" self._create_proxy(""" <node> <interface name="Interface"> <property name="Property1" type="i" access="readwrite" /> <property name="Property2" type="s" access="read" /> <property name="Property3" type="b" access="write" /> </interface> </node> """) self._set_reply(self.NO_REPLY) self.proxy.Property1 = 10 self._check_set_property("Property1", get_variant("i", 10)) self._set_reply(get_variant("(v)", (get_variant("i", 20), ))) self.assertEqual(self.proxy.Property1, 20) self._check_get_property("Property1") with self.assertRaises(AttributeError): self.proxy.Property2 = "World" self._set_reply(get_variant("(v)", (get_variant("s", "Hello"), ))) self.assertEqual(self.proxy.Property2, "Hello") self._check_get_property("Property2") self._set_reply(self.NO_REPLY) self.proxy.Property3 = False self._check_set_property("Property3", get_variant("b", False)) with self.assertRaises(AttributeError): self.fail(self.proxy.Property3) with self.assertRaises(AttributeError): self.proxy.PropertyInvalid = 0 with self.assertRaises(AttributeError): self.fail(self.proxy.PropertyInvalid)
def gather_requests_combination_test(self): """Test GatherRequests with user requests.""" self.module.on_storage_reset(create_storage()) # Add devices dev1 and dev2. self._add_device( StorageDevice("dev1", size=Size("1 GiB"), fmt=get_format("ext4", mountpoint="/"))) self._add_device( StorageDevice("dev2", size=Size("1 GiB"), fmt=get_format("swap"))) # Add requests for dev1 and dev3. req1 = MountPointRequest() req1.device_spec = '/dev/dev1' req1.format_options = '-L BOOT' req1.format_type = 'xfs' req1.mount_options = 'user' req1.mount_point = '/home' req1.reformat = True req3 = MountPointRequest() req3.device_spec = '/dev/dev3' req3.mount_point = '/' self.module.set_requests([req1, req3]) # Get requests for dev1 and dev2. self.assertEqual(self.interface.GatherRequests(), [{ 'device-spec': get_variant(Str, '/dev/dev1'), 'format-options': get_variant(Str, '-L BOOT'), 'format-type': get_variant(Str, 'xfs'), 'mount-options': get_variant(Str, 'user'), 'mount-point': get_variant(Str, '/home'), 'reformat': get_variant(Bool, True) }, { 'device-spec': get_variant(Str, '/dev/dev2'), 'format-options': get_variant(Str, ''), 'format-type': get_variant(Str, 'swap'), 'mount-options': get_variant(Str, ''), 'mount-point': get_variant(Str, ''), 'reformat': get_variant(Bool, False) }])
def gather_requests_test(self): """Test GatherRequests.""" self.module.on_storage_reset(create_storage()) self._add_device( StorageDevice("dev1", size=Size("1 GiB"), fmt=get_format("ext4", mountpoint="/"))) self._add_device( StorageDevice("dev2", size=Size("1 GiB"), fmt=get_format("swap"))) self.assertEqual(self.interface.GatherRequests(), [{ 'device-spec': get_variant(Str, '/dev/dev1'), 'format-options': get_variant(Str, ''), 'format-type': get_variant(Str, 'ext4'), 'mount-options': get_variant(Str, ''), 'mount-point': get_variant(Str, '/'), 'reformat': get_variant(Bool, False) }, { 'device-spec': get_variant(Str, '/dev/dev2'), 'format-options': get_variant(Str, ''), 'format-type': get_variant(Str, 'swap'), 'mount-options': get_variant(Str, ''), 'mount-point': get_variant(Str, ''), 'reformat': get_variant(Bool, False) }])
def get_data_variant(self, obj): """Get a variant of the data attribute.""" value = self._data_type.to_structure_list(super().get_data(obj)) return get_variant(self._type_hint, value)
def _check_set_property(self, name, value): """Check the DBus call that sets a property.""" self._check_call("org.freedesktop.DBus.Properties", "Set", get_variant("(ssv)", ("Interface", name, value)), None)
def _check_get_property(self, name): """Check the DBus call that gets a property.""" self._check_call("org.freedesktop.DBus.Properties", "Get", get_variant("(ss)", ("Interface", name)), get_variant_type("(v)"))
def property_test(self): """Test the property publishing.""" self._publish_object(""" <node> <interface name="Interface"> <property name="Property1" type="i" access="readwrite" /> <property name="Property2" type="s" access="read" /> <property name="Property3" type="b" access="write" /> </interface> </node> """) self.object.Property1 = 0 self._call_method("org.freedesktop.DBus.Properties", "Get", parameters=get_variant("(ss)", ("Interface", "Property1")), reply=get_variant("(v)", (get_variant("i", 0), ))) self._call_method( "org.freedesktop.DBus.Properties", "Set", parameters=get_variant( "(ssv)", ("Interface", "Property1", get_variant("i", 1))), ) self.assertEqual(self.object.Property1, 1) self.object.Property2 = "Hello" self._call_method("org.freedesktop.DBus.Properties", "Get", parameters=get_variant("(ss)", ("Interface", "Property2")), reply=get_variant("(v)", (get_variant("s", "Hello"), ))) self._call_method_with_error( "org.freedesktop.DBus.Properties", "Set", parameters=get_variant( "(ssv)", ("Interface", "Property2", get_variant("s", "World"))), error_name="not.known.AttributeError", error_message="Property2 of Interface is not writable.") self.assertEqual(self.object.Property2, "Hello") self.object.Property3 = True self._call_method_with_error( "org.freedesktop.DBus.Properties", "Get", parameters=get_variant("(ss)", ("Interface", "Property3")), error_name="not.known.AttributeError", error_message="Property3 of Interface is not readable.") self._call_method( "org.freedesktop.DBus.Properties", "Set", parameters=get_variant( "(ssv)", ("Interface", "Property3", get_variant("b", False))), ) self.assertEqual(self.object.Property3, False) self._call_method( "org.freedesktop.DBus.Properties", "GetAll", parameters=get_variant("(s)", ("Interface", )), reply=get_variant("(a{sv})", ({ "Property1": get_variant("i", 1), "Property2": get_variant("s", "Hello") }, ))) self.object.PropertiesChanged("Interface", {"Property1": get_variant("i", 1)}, ["Property2"]) self.message_bus.connection.emit_signal.assert_called_once_with( None, self.object_path, "org.freedesktop.DBus.Properties", "PropertiesChanged", get_variant("(sa{sv}as)", ("Interface", { "Property1": get_variant("i", 1) }, ["Property2"])))
def method_test(self, register): """Test the method proxy.""" self._create_proxy(""" <node> <interface name="Interface"> <method name="Method1"/> <method name="Method2"> <arg direction="in" name="x" type="i"/> </method> <method name="Method3"> <arg direction="out" name="return" type="i"/> </method> <method name="Method4"> <arg direction="in" name="x" type="ad"/> <arg direction="in" name="y" type="o"/> <arg direction="out" name="return" type="(ib)"/> </method> <method name="Method5"> <arg direction="out" name="return_x" type="i"/> <arg direction="out" name="return_y" type="i"/> </method> </interface> </node> """) self.assertTrue(callable(self.proxy.Method1)) self.assertEqual(self.proxy.Method1, self.proxy.Method1) self._set_reply(self.NO_REPLY) self.assertEqual(self.proxy.Method1(), None) self._check_call("Interface", "Method1") self._set_reply(self.NO_REPLY) self.assertEqual(self.proxy.Method2(1), None) self._check_call("Interface", "Method2", parameters=get_variant("(i)", (1, ))) self._set_reply(get_variant("(i)", (0, ))) self.assertEqual(self.proxy.Method3(), 0) self._check_call("Interface", "Method3", reply_type=get_variant_type("(i)")) self._set_reply(get_variant("((ib))", ((1, True), ))) self.assertEqual(self.proxy.Method4([1.2, 2.3], "/my/path"), (1, True)) self._check_call("Interface", "Method4", parameters=get_variant("(ado)", ([1.2, 2.3], "/my/path")), reply_type=get_variant_type("((ib))")) self._set_reply(get_variant("(ii)", (1, 2))) self.assertEqual(self.proxy.Method5(), (1, 2)) self._check_call("Interface", "Method5", reply_type=get_variant_type("(ii)")) register.map_exception_to_name(FakeException, "org.test.Unknown") self._set_reply( Gio.DBusError.new_for_dbus_error("org.test.Unknown", "My message.")) with self.assertRaises(FakeException) as cm: self.proxy.Method1() self.assertEqual(str(cm.exception), "My message.") with self.assertRaises(AttributeError): self.proxy.MethodInvalid() with self.assertRaises(AttributeError): self.proxy.Method1 = lambda: 1
class DBusServerTestCase(unittest.TestCase): """Test DBus server support.""" NO_PARAMETERS = get_variant("()", tuple()) def setUp(self): self.message_bus = Mock() self.connection = self.message_bus.connection self.object = None self.object_path = "/my/path" self.handler = None def _publish_object(self, xml="<node />"): """Publish an mocked object.""" self.object = Mock(__dbus_xml__=dedent(xml)) # Raise AttributeError for default methods. del self.object.Get del self.object.Set del self.object.GetAll # Create object signals. self.object.Signal1 = Signal() self.object.Signal2 = Signal() # Create default object signals. self.object.PropertiesChanged = Signal() self.handler = ServerObjectHandler(self.message_bus, self.object_path, self.object) self.handler.connect_object() def _call_method(self, interface, method, parameters=NO_PARAMETERS, reply=None): invocation = Mock() GLibServer._object_callback(self.connection, Mock(), self.object_path, interface, method, parameters, invocation, (self.handler._method_callback, ())) invocation.return_dbus_error.assert_not_called() invocation.return_value.assert_called_once_with(reply) def _call_method_with_error(self, interface, method, parameters=NO_PARAMETERS, error_name="", error_message=""): invocation = Mock() self.handler._method_callback(invocation, interface, method, parameters) invocation.return_dbus_error(error_name, error_message) invocation.return_value.assert_not_called() def register_test(self): """Test the object registration.""" with self.assertRaises(DBusSpecificationError): self._publish_object("<node />") self._publish_object(""" <node> <interface name="Interface" /> </node> """) self.message_bus.connection.register_object.assert_called() self.handler.disconnect_object() self.message_bus.connection.unregister_object.assert_called() @patch("pyanaconda.dbus.error.GLibErrorHandler.register", new_callable=ErrorRegister) def method_test(self, register): """Test the method publishing.""" self._publish_object(""" <node> <interface name="Interface"> <method name="Method1"/> <method name="Method2"> <arg direction="in" name="x" type="i"/> </method> <method name="Method3"> <arg direction="out" name="return" type="i"/> </method> <method name="Method4"> <arg direction="in" name="x" type="ad"/> <arg direction="in" name="y" type="o"/> <arg direction="out" name="return" type="(ib)"/> </method> </interface> </node> """) self.object.Method2.return_value = None self._call_method("Interface", "Method2", parameters=get_variant("(i)", (1, ))) self.object.Method2.assert_called_once_with(1) self.object.Method1.return_value = None self._call_method("Interface", "Method1") self.object.Method1.assert_called_once_with() self.object.Method3.return_value = 0 self._call_method("Interface", "Method3", reply=get_variant("(i)", (0, ))) self.object.Method3.assert_called_once_with() self.object.Method4.return_value = (1, True) self._call_method("Interface", "Method4", parameters=get_variant("(ado)", ([1.2, 2.3], "/my/path")), reply=get_variant("((ib))", ((1, True), ))) self.object.Method4.assert_called_once_with([1.2, 2.3], "/my/path") self._call_method_with_error( "Interface", "MethodInvalid", error_name="not.known.Error.DBusSpecificationError", error_message= "Unknown member MethodInvalid of the interface Interface.") def property_test(self): """Test the property publishing.""" self._publish_object(""" <node> <interface name="Interface"> <property name="Property1" type="i" access="readwrite" /> <property name="Property2" type="s" access="read" /> <property name="Property3" type="b" access="write" /> </interface> </node> """) self.object.Property1 = 0 self._call_method("org.freedesktop.DBus.Properties", "Get", parameters=get_variant("(ss)", ("Interface", "Property1")), reply=get_variant("(v)", (get_variant("i", 0), ))) self._call_method( "org.freedesktop.DBus.Properties", "Set", parameters=get_variant( "(ssv)", ("Interface", "Property1", get_variant("i", 1))), ) self.assertEqual(self.object.Property1, 1) self.object.Property2 = "Hello" self._call_method("org.freedesktop.DBus.Properties", "Get", parameters=get_variant("(ss)", ("Interface", "Property2")), reply=get_variant("(v)", (get_variant("s", "Hello"), ))) self._call_method_with_error( "org.freedesktop.DBus.Properties", "Set", parameters=get_variant( "(ssv)", ("Interface", "Property2", get_variant("s", "World"))), error_name="not.known.AttributeError", error_message="Property2 of Interface is not writable.") self.assertEqual(self.object.Property2, "Hello") self.object.Property3 = True self._call_method_with_error( "org.freedesktop.DBus.Properties", "Get", parameters=get_variant("(ss)", ("Interface", "Property3")), error_name="not.known.AttributeError", error_message="Property3 of Interface is not readable.") self._call_method( "org.freedesktop.DBus.Properties", "Set", parameters=get_variant( "(ssv)", ("Interface", "Property3", get_variant("b", False))), ) self.assertEqual(self.object.Property3, False) self._call_method( "org.freedesktop.DBus.Properties", "GetAll", parameters=get_variant("(s)", ("Interface", )), reply=get_variant("(a{sv})", ({ "Property1": get_variant("i", 1), "Property2": get_variant("s", "Hello") }, ))) self.object.PropertiesChanged("Interface", {"Property1": get_variant("i", 1)}, ["Property2"]) self.message_bus.connection.emit_signal.assert_called_once_with( None, self.object_path, "org.freedesktop.DBus.Properties", "PropertiesChanged", get_variant("(sa{sv}as)", ("Interface", { "Property1": get_variant("i", 1) }, ["Property2"]))) def signal_test(self): """Test the signal publishing.""" self._publish_object(""" <node> <interface name="Interface"> <signal name="Signal1" /> <signal name="Signal2"> <arg direction="out" name="x" type="i"/> <arg direction="out" name="y" type="s"/> </signal> </interface> </node> """) self.object.Signal1() self.message_bus.connection.emit_signal.assert_called_once_with( None, self.object_path, "Interface", "Signal1", None) self.message_bus.connection.emit_signal.reset_mock() self.object.Signal2(1, "Test") self.message_bus.connection.emit_signal.assert_called_once_with( None, self.object_path, "Interface", "Signal2", get_variant("(is)", (1, "Test")))
def mount_points_property_test(self): """Test the mount points property.""" self._test_dbus_property("Requests", []) in_value = [{"mount-point": "/boot", "device-spec": "/dev/sda1"}] out_value = [{ "mount-point": get_variant(Str, "/boot"), "device-spec": get_variant(Str, "/dev/sda1"), "reformat": get_variant(Bool, False), "format-type": get_variant(Str, ""), "format-options": get_variant(Str, ""), "mount-options": get_variant(Str, "") }] self._test_dbus_property("Requests", in_value, out_value) in_value = [{ "mount-point": "/boot", "device-spec": "/dev/sda1", "reformat": True, "format-type": "xfs", "format-options": "-L BOOT", "mount-options": "user" }] out_value = [{ "mount-point": get_variant(Str, "/boot"), "device-spec": get_variant(Str, "/dev/sda1"), "reformat": get_variant(Bool, True), "format-type": get_variant(Str, "xfs"), "format-options": get_variant(Str, "-L BOOT"), "mount-options": get_variant(Str, "user") }] self._test_dbus_property( "Requests", in_value, out_value, ) in_value = [{ "mount-point": "/boot", "device-spec": "/dev/sda1" }, { "mount-point": "/", "device-spec": "/dev/sda2", "reformat": True }] out_value = [{ "mount-point": get_variant(Str, "/boot"), "device-spec": get_variant(Str, "/dev/sda1"), "reformat": get_variant(Bool, False), "format-type": get_variant(Str, ""), "format-options": get_variant(Str, ""), "mount-options": get_variant(Str, "") }, { "mount-point": get_variant(Str, "/"), "device-spec": get_variant(Str, "/dev/sda2"), "reformat": get_variant(Bool, True), "format-type": get_variant(Str, ""), "format-options": get_variant(Str, ""), "mount-options": get_variant(Str, "") }] self._test_dbus_property("Requests", in_value, out_value)
def mount_points_property_test(self): """Test the mount points property.""" self._test_dbus_property("MountPoints", []) in_value = [{"mount-point": "/boot", "device": "/dev/sda1"}] out_value = [{ MOUNT_POINT_PATH: get_variant(Str, "/boot"), MOUNT_POINT_DEVICE: get_variant(Str, "/dev/sda1"), MOUNT_POINT_REFORMAT: get_variant(Bool, False), MOUNT_POINT_FORMAT: get_variant(Str, ""), MOUNT_POINT_FORMAT_OPTIONS: get_variant(Str, ""), MOUNT_POINT_MOUNT_OPTIONS: get_variant(Str, "") }] self._test_dbus_property("MountPoints", in_value, out_value) in_value = [{ "mount-point": "/boot", "device": "/dev/sda1", "reformat": True, "format": "xfs", "format-options": "-L BOOT", "mount-options": "user" }] out_value = [{ MOUNT_POINT_PATH: get_variant(Str, "/boot"), MOUNT_POINT_DEVICE: get_variant(Str, "/dev/sda1"), MOUNT_POINT_REFORMAT: get_variant(Bool, True), MOUNT_POINT_FORMAT: get_variant(Str, "xfs"), MOUNT_POINT_FORMAT_OPTIONS: get_variant(Str, "-L BOOT"), MOUNT_POINT_MOUNT_OPTIONS: get_variant(Str, "user") }] self._test_dbus_property( "MountPoints", in_value, out_value, ) in_value = [{ "mount-point": "/boot", "device": "/dev/sda1" }, { "mount-point": "/", "device": "/dev/sda2", "reformat": True }] out_value = [{ MOUNT_POINT_PATH: get_variant(Str, "/boot"), MOUNT_POINT_DEVICE: get_variant(Str, "/dev/sda1"), MOUNT_POINT_REFORMAT: get_variant(Bool, False), MOUNT_POINT_FORMAT: get_variant(Str, ""), MOUNT_POINT_FORMAT_OPTIONS: get_variant(Str, ""), MOUNT_POINT_MOUNT_OPTIONS: get_variant(Str, "") }, { MOUNT_POINT_PATH: get_variant(Str, "/"), MOUNT_POINT_DEVICE: get_variant(Str, "/dev/sda2"), MOUNT_POINT_REFORMAT: get_variant(Bool, True), MOUNT_POINT_FORMAT: get_variant(Str, ""), MOUNT_POINT_FORMAT_OPTIONS: get_variant(Str, ""), MOUNT_POINT_MOUNT_OPTIONS: get_variant(Str, "") }] self._test_dbus_property("MountPoints", in_value, out_value)
class DBusClientTestCase(unittest.TestCase): """Test DBus clinet support.""" NO_REPLY = get_variant("()", ()) def setUp(self): self.maxDiff = None self.message_bus = Mock() self.connection = self.message_bus.connection self.service_name = "my.service" self.object_path = "/my/object" self.handler = None self.proxy = None self.variant_type_factory = VariantTypeFactory() self.variant_type_factory.set_up() def tearDown(self): self.variant_type_factory.tear_down() def variant_type_factory_test(self): """Test the variant type factory.""" self.assertEqual(str(get_variant_type("s")), "s") self.assertEqual(repr(get_variant_type("i")), "i") self.assertEqual(get_variant_type("s"), get_variant_type("s")) self.assertEqual(get_variant_type("i"), get_variant_type("i")) self.assertNotEqual(get_variant_type("b"), get_variant_type("i")) self.assertNotEqual(get_variant_type("s"), get_variant_type("u")) def _create_proxy(self, xml, proxy_factory=ObjectProxy): """Create a proxy with a mocked message bus.""" self.proxy = proxy_factory(self.message_bus, self.service_name, self.object_path) self.handler = self.proxy._handler self.handler._specification = DBusSpecification.from_xml(xml) def introspect_test(self): """Test the introspection.""" self._set_reply( get_variant("(s)", (dedent(""" <node> <interface name="Interface"> <method name="Method1"/> </interface> </node> """), ))) self.handler = ClientObjectHandler(self.message_bus, self.service_name, self.object_path) self.assertIsNotNone(self.handler.specification) self._check_call("org.freedesktop.DBus.Introspectable", "Introspect", reply_type=get_variant_type("(s)")) self.assertIn( DBusSpecification.Method("Method1", "Interface", None, None), self.handler.specification.members) @patch("pyanaconda.dbus.error.GLibErrorHandler.register", new_callable=ErrorRegister) def method_test(self, register): """Test the method proxy.""" self._create_proxy(""" <node> <interface name="Interface"> <method name="Method1"/> <method name="Method2"> <arg direction="in" name="x" type="i"/> </method> <method name="Method3"> <arg direction="out" name="return" type="i"/> </method> <method name="Method4"> <arg direction="in" name="x" type="ad"/> <arg direction="in" name="y" type="o"/> <arg direction="out" name="return" type="(ib)"/> </method> <method name="Method5"> <arg direction="out" name="return_x" type="i"/> <arg direction="out" name="return_y" type="i"/> </method> </interface> </node> """) self.assertTrue(callable(self.proxy.Method1)) self.assertEqual(self.proxy.Method1, self.proxy.Method1) self._set_reply(self.NO_REPLY) self.assertEqual(self.proxy.Method1(), None) self._check_call("Interface", "Method1") self._set_reply(self.NO_REPLY) self.assertEqual(self.proxy.Method2(1), None) self._check_call("Interface", "Method2", parameters=get_variant("(i)", (1, ))) self._set_reply(get_variant("(i)", (0, ))) self.assertEqual(self.proxy.Method3(), 0) self._check_call("Interface", "Method3", reply_type=get_variant_type("(i)")) self._set_reply(get_variant("((ib))", ((1, True), ))) self.assertEqual(self.proxy.Method4([1.2, 2.3], "/my/path"), (1, True)) self._check_call("Interface", "Method4", parameters=get_variant("(ado)", ([1.2, 2.3], "/my/path")), reply_type=get_variant_type("((ib))")) self._set_reply(get_variant("(ii)", (1, 2))) self.assertEqual(self.proxy.Method5(), (1, 2)) self._check_call("Interface", "Method5", reply_type=get_variant_type("(ii)")) register.map_exception_to_name(FakeException, "org.test.Unknown") self._set_reply( Gio.DBusError.new_for_dbus_error("org.test.Unknown", "My message.")) with self.assertRaises(FakeException) as cm: self.proxy.Method1() self.assertEqual(str(cm.exception), "My message.") with self.assertRaises(AttributeError): self.proxy.MethodInvalid() with self.assertRaises(AttributeError): self.proxy.Method1 = lambda: 1 def _set_reply(self, reply_value): """Set the reply of the DBus call.""" self.connection.call_sync.reset_mock() if isinstance(reply_value, Exception): self.connection.call_sync.side_effect = reply_value else: self.connection.call_sync.return_value = reply_value def _check_call(self, interface_name, method_name, parameters=None, reply_type=None): """Check the DBus call.""" self.connection.call_sync.assert_called_once_with( self.service_name, self.object_path, interface_name, method_name, parameters, reply_type, DBUS_FLAG_NONE, GLibClient.DBUS_TIMEOUT_NONE, None) self.connection.call_sync.reset_mock() @patch("pyanaconda.dbus.error.GLibErrorHandler.register", new_callable=ErrorRegister) def async_method_test(self, register): """Test asynchronous calls of a method proxy.""" self._create_proxy(""" <node> <interface name="Interface"> <method name="Method1"/> <method name="Method2"> <arg direction="in" name="x" type="i"/> <arg direction="in" name="y" type="i"/> <arg direction="out" name="return" type="i"/> </method> </interface> </node> """) callback = Mock() callback_args = ("A", "B") self.proxy.Method1(callback=callback, callback_args=callback_args) self._check_async_call("Interface", "Method1", callback, callback_args) self._finish_async_call(self.NO_REPLY, callback, callback_args) callback.assert_called_once_with(None, "A", "B") callback = Mock() callback_args = ("A", "B") self.proxy.Method2(1, 2, callback=callback, callback_args=callback_args) self._check_async_call("Interface", "Method2", callback, callback_args, get_variant("(ii)", (1, 2)), get_variant_type("(i)")) self._finish_async_call(get_variant("(i)", (3, )), callback, callback_args) callback.assert_called_once_with(3, "A", "B") callback = Mock() callback_args = ("A", "B") register.map_exception_to_name(FakeException, "org.test.Unknown") error = Gio.DBusError.new_for_dbus_error("org.test.Unknown", "My message.") with self.assertRaises(FakeException) as cm: self._finish_async_call(error, callback, callback_args) self.assertEqual(str(cm.exception), "My message.") callback.assert_not_called() def _check_async_call(self, interface_name, method_name, callback, callback_args, parameters=None, reply_type=None): """Check the asynchronous DBus call.""" self.connection.call.assert_called_once_with( self.service_name, self.object_path, interface_name, method_name, parameters, reply_type, DBUS_FLAG_NONE, GLibClient.DBUS_TIMEOUT_NONE, callback=GLibClient._async_call_finish, user_data=(self.handler._method_callback, (callback, callback_args))) self.connection.call.reset_mock() def _finish_async_call(self, result, callback, callback_args): """Finish the asynchronous call.""" def _call_finish(result_object): if isinstance(result_object, Exception): raise result_object return result_object def _callback(finish, *args): callback(finish(), *args) GLibClient._async_call_finish( source_object=Mock(call_finish=_call_finish), result_object=result, user_data=(self.handler._method_callback, (_callback, callback_args))) def property_test(self): """Test the property proxy.""" self._create_proxy(""" <node> <interface name="Interface"> <property name="Property1" type="i" access="readwrite" /> <property name="Property2" type="s" access="read" /> <property name="Property3" type="b" access="write" /> </interface> </node> """) self._set_reply(self.NO_REPLY) self.proxy.Property1 = 10 self._check_set_property("Property1", get_variant("i", 10)) self._set_reply(get_variant("(v)", (get_variant("i", 20), ))) self.assertEqual(self.proxy.Property1, 20) self._check_get_property("Property1") with self.assertRaises(AttributeError): self.proxy.Property2 = "World" self._set_reply(get_variant("(v)", (get_variant("s", "Hello"), ))) self.assertEqual(self.proxy.Property2, "Hello") self._check_get_property("Property2") self._set_reply(self.NO_REPLY) self.proxy.Property3 = False self._check_set_property("Property3", get_variant("b", False)) with self.assertRaises(AttributeError): self.fail(self.proxy.Property3) with self.assertRaises(AttributeError): self.proxy.PropertyInvalid = 0 with self.assertRaises(AttributeError): self.fail(self.proxy.PropertyInvalid) def _check_set_property(self, name, value): """Check the DBus call that sets a property.""" self._check_call("org.freedesktop.DBus.Properties", "Set", get_variant("(ssv)", ("Interface", name, value)), None) def _check_get_property(self, name): """Check the DBus call that gets a property.""" self._check_call("org.freedesktop.DBus.Properties", "Get", get_variant("(ss)", ("Interface", name)), get_variant_type("(v)")) def signal_test(self): """Test the signal publishing.""" self._create_proxy(""" <node> <interface name="Interface"> <signal name="Signal1" /> <signal name="Signal2"> <arg direction="out" name="x" type="i"/> <arg direction="out" name="y" type="s"/> </signal> </interface> </node> """) self.assertIsInstance(self.proxy.Signal1, Signal) self.assertEqual(self.proxy.Signal1, self.proxy.Signal1) self._check_signal("Interface", "Signal1", self.proxy.Signal1.emit) self._emit_signal(self.NO_REPLY, self.proxy.Signal1.emit) self.assertEqual(len(self.handler._subscriptions), 1) self._check_signal("Interface", "Signal2", self.proxy.Signal2.emit) self._emit_signal(get_variant("(is)", (1, "Test")), self.proxy.Signal2.emit) self.assertEqual(len(self.handler._subscriptions), 2) with self.assertRaises(AttributeError): self.fail(self.proxy.SignalInvalid) with self.assertRaises(AttributeError): self.proxy.Signal1 = self.handler._signal_factory() del self.proxy.Signal1 self.connection.signal_unsubscribe.assert_called_once() self.assertEqual(self.handler._subscriptions["Interface", "Signal1"], []) def _check_signal(self, interface_name, signal_name, signal_callback): """Check the DBus signal subscription.""" self.connection.signal_subscribe.assert_called_once_with( self.service_name, interface_name, signal_name, self.object_path, None, DBUS_FLAG_NONE, callback=GLibClient._signal_callback, user_data=(self.handler._signal_callback, (signal_callback, ))) self.connection.signal_subscribe.reset_mock() def _emit_signal(self, parameters, signal_callback): """Emit a DBus signal.""" GLibClient._signal_callback(self.connection, None, self.object_path, None, None, parameters=parameters, user_data=(self.handler._signal_callback, (signal_callback, )))