From 2d8475392413dc95b3648f4d4b38a98d6f8a6255 Mon Sep 17 00:00:00 2001 From: Frederik Leonhardt Date: Thu, 4 Jul 2024 00:18:46 +1200 Subject: [PATCH] bluez5: Fix AttributeError when registering an agent twice --- dbusmock/templates/bluez5.py | 2 +- tests/test_bluez5.py | 67 ++++++++++++++++++++++++++++++++++++ 2 files changed, 68 insertions(+), 1 deletion(-) diff --git a/dbusmock/templates/bluez5.py b/dbusmock/templates/bluez5.py index a7ef79e..45fa250 100644 --- a/dbusmock/templates/bluez5.py +++ b/dbusmock/templates/bluez5.py @@ -56,7 +56,7 @@ def RegisterAgent(manager, agent_path, capability): if agent_path in manager.agent_paths: raise dbus.exceptions.DBusException( - "Another agent is already registered " + manager.agent_path, name="org.bluez.Error.AlreadyExists" + "Another agent is already registered " + agent_path, name="org.bluez.Error.AlreadyExists" ) # Fallback to "KeyboardDisplay" as per BlueZ spec diff --git a/tests/test_bluez5.py b/tests/test_bluez5.py index bbd190e..ef39c1c 100644 --- a/tests/test_bluez5.py +++ b/tests/test_bluez5.py @@ -438,6 +438,73 @@ def test_monitor(self): path, *_ = mock_calls[0][1] self.assertEqual(path, "/") + def test_register_agent(self): + # Given BlueZ with the AgentManager1 interface + bluez = self.dbus_con.get_object("org.bluez", "/org/bluez") + agent_manager = dbus.Interface(bluez, "org.bluez.AgentManager1") + agent_path = "/org/dbusmock/bluezagent" + + # When an agent with the default capabiities is registered + # Then no error is raised + agent_manager.RegisterAgent(agent_path, "") + + def test_register_agent_duplicate(self): + # Given BlueZ with the AgentManager1 interface + bluez = self.dbus_con.get_object("org.bluez", "/org/bluez") + agent_manager = dbus.Interface(bluez, "org.bluez.AgentManager1") + agent_path = "/org/dbusmock/bluezagent" + + # When an agent is registered twice + agent_manager.RegisterAgent(agent_path, "") + + # Then an error is raised + with self.assertRaisesRegex( + dbus.exceptions.DBusException, f"Another agent is already registered {agent_path}" + ) as ctx: + agent_manager.RegisterAgent(agent_path, "") + self.assertEqual(ctx.exception.get_dbus_name(), "org.bluez.Error.AlreadyExists") + + def test_unregister_agent(self): + # Given BlueZ with the AgentManager1 interface + bluez = self.dbus_con.get_object("org.bluez", "/org/bluez") + agent_manager = dbus.Interface(bluez, "org.bluez.AgentManager1") + agent_path = "/org/dbusmock/bluezagent" + + # And a registered agent + agent_manager.RegisterAgent(agent_path, "") + # When the agent is unregistered + # Then no error is raised + agent_manager.UnregisterAgent(agent_path) + + def test_unregister_agent_unknown(self): + # Given BlueZ with the AgentManager1 interface + bluez = self.dbus_con.get_object("org.bluez", "/org/bluez") + agent_manager = dbus.Interface(bluez, "org.bluez.AgentManager1") + agent_path = "/org/dbusmock/bluezagent" + + # When an agent is unregistered without registering it first + # Then an error is raised + with self.assertRaisesRegex(dbus.exceptions.DBusException, f"Agent not registered {agent_path}") as ctx: + agent_manager.UnregisterAgent(agent_path) + self.assertEqual(ctx.exception.get_dbus_name(), "org.bluez.Error.DoesNotExist") + + def test_agent(self): + # Given BlueZ with the AgentManager1 interface + bluez = self.dbus_con.get_object("org.bluez", "/org/bluez") + + # When bluetoothctl is started + out = _run_bluetoothctl("list") + + # Then it reports that the agent was registered + self.assertIn("Agent registered", out) + + # And the RegisterAgent method was called + mock_calls = bluez.GetMethodCalls("RegisterAgent", dbus_interface="org.freedesktop.DBus.Mock") + self.assertEqual(len(mock_calls), 1) + path, capabilities = mock_calls[0][1] + self.assertEqual(path, "/org/bluez/agent") + self.assertEqual(capabilities, "") + @unittest.skipUnless(have_pbap_client, "pbap-client not installed (copy it from bluez/test)") class TestBlueZObex(dbusmock.DBusTestCase):