Script 'mail_helper' called by obssrc
Hello community,
here is the log from the commit of package python-python-dbusmock for
openSUSE:Factory checked in at 2024-08-20 16:12:28
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/python-python-dbusmock (Old)
and /work/SRC/openSUSE:Factory/.python-python-dbusmock.new.2698 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "python-python-dbusmock"
Tue Aug 20 16:12:28 2024 rev:12 rq:1194576 version:0.32.1
Changes:
--------
---
/work/SRC/openSUSE:Factory/python-python-dbusmock/python-python-dbusmock.changes
2024-03-18 16:44:32.170908315 +0100
+++
/work/SRC/openSUSE:Factory/.python-python-dbusmock.new.2698/python-python-dbusmock.changes
2024-08-20 16:12:31.083980002 +0200
@@ -1,0 +2,8 @@
+Sun Aug 18 17:06:33 UTC 2024 - Dirk Müller <[email protected]>
+
+- update to 0.32.1:
+ * ModemManager: Add initial mock
+ * bluez5: Add advertising API
+ * Fix loading of libglib on macOS
+
+-------------------------------------------------------------------
Old:
----
python-dbusmock-0.31.1.tar.gz
New:
----
python-dbusmock-0.32.1.tar.gz
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Other differences:
------------------
++++++ python-python-dbusmock.spec ++++++
--- /var/tmp/diff_new_pack.OkB9uR/_old 2024-08-20 16:12:31.692005257 +0200
+++ /var/tmp/diff_new_pack.OkB9uR/_new 2024-08-20 16:12:31.692005257 +0200
@@ -17,7 +17,7 @@
Name: python-python-dbusmock
-Version: 0.31.1
+Version: 0.32.1
Release: 0
Summary: Python library for creating mock D-Bus objects
License: LGPL-3.0-or-later
++++++ python-dbusmock-0.31.1.tar.gz -> python-dbusmock-0.32.1.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/.github/workflows/release.yml
new/python-dbusmock-0.32.1/.github/workflows/release.yml
--- old/python-dbusmock-0.31.1/.github/workflows/release.yml 2024-02-23
14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/.github/workflows/release.yml 2024-07-14
09:17:09.000000000 +0200
@@ -45,7 +45,7 @@
rm -rf tmp
- name: Create GitHub release
- uses:
cockpit-project/action-release@88d994da62d1451c7073e26748c18413fcdf46e9
+ uses:
cockpit-project/action-release@7d2e2657382e8d34f88a24b5987f2b81ea165785
with:
filename: "dist/python-dbusmock-${{ github.ref_name }}.tar.gz"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/.github/workflows/tests.yml
new/python-dbusmock-0.32.1/.github/workflows/tests.yml
--- old/python-dbusmock-0.31.1/.github/workflows/tests.yml 2024-02-23
14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/.github/workflows/tests.yml 2024-07-14
09:17:09.000000000 +0200
@@ -17,8 +17,8 @@
- docker.io/ubuntu:latest
- registry.fedoraproject.org/fedora:latest
- registry.fedoraproject.org/fedora:rawhide
- - quay.io/centos/centos:stream8
- quay.io/centos/centos:stream9
+ - quay.io/centos/centos:stream10-development
timeout-minutes: 30
steps:
@@ -28,6 +28,14 @@
# need this to also fetch tags
fetch-depth: 0
+ - name: Workaround for https://github.com/actions/checkout/pull/697
+ run: |
+ set -ex
+ TAG=$(git describe --tags)
+ if echo "$TAG" | grep -q '^[0-9.]\+$'; then
+ git fetch --force origin $TAG:refs/tags/$TAG
+ fi
+
- name: Run unit tests
run: |
dpkg -s podman docker || true
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/PKG-INFO
new/python-dbusmock-0.32.1/PKG-INFO
--- old/python-dbusmock-0.31.1/PKG-INFO 2024-02-23 14:06:27.321855500 +0100
+++ new/python-dbusmock-0.32.1/PKG-INFO 2024-07-14 09:17:21.458633000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: python-dbusmock
-Version: 0.31.1
+Version: 0.32.1
Summary: Mock D-Bus objects
Home-page: https://github.com/martinpitt/python-dbusmock
Author: Martin Pitt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/dbusmock/__main__.py
new/python-dbusmock-0.32.1/dbusmock/__main__.py
--- old/python-dbusmock-0.31.1/dbusmock/__main__.py 2024-02-23
14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/dbusmock/__main__.py 2024-07-14
09:17:09.000000000 +0200
@@ -16,6 +16,7 @@
import argparse
import json
import os
+import platform
import subprocess
import sys
@@ -51,7 +52,7 @@
help="template to load (instead of specifying name, path, interface)",
)
parser.add_argument(
- "name", # fmt: off
+ "name",
metavar="NAME",
nargs="?",
help='D-Bus name to claim (e. g. "com.example.MyService") (if not
using -t)',
@@ -160,7 +161,10 @@
if args.template:
main_object.AddTemplate(args.template, parameters)
- libglib = ctypes.cdll.LoadLibrary("libglib-2.0.so.0")
+ if platform.system() == "Darwin":
+ libglib = ctypes.cdll.LoadLibrary("libglib-2.0.dylib")
+ else:
+ libglib = ctypes.cdll.LoadLibrary("libglib-2.0.so.0")
dbusmock.mockobject.objects[args.path] = main_object
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/dbusmock/_version.py
new/python-dbusmock-0.32.1/dbusmock/_version.py
--- old/python-dbusmock-0.31.1/dbusmock/_version.py 2024-02-23
14:06:27.000000000 +0100
+++ new/python-dbusmock-0.32.1/dbusmock/_version.py 2024-07-14
09:17:21.000000000 +0200
@@ -1,2 +1,2 @@
'''auto-generated version from setuptools_scm'''
-__version__ = "0.31.1"
+__version__ = "0.32.1"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/dbusmock/templates/bluez5.py
new/python-dbusmock-0.32.1/dbusmock/templates/bluez5.py
--- old/python-dbusmock-0.31.1/dbusmock/templates/bluez5.py 2024-02-23
14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/dbusmock/templates/bluez5.py 2024-07-14
09:17:09.000000000 +0200
@@ -38,9 +38,17 @@
NETWORK_SERVER_IFACE = "org.bluez.Network1"
DEVICE_IFACE = "org.bluez.Device1"
+LE_ADVERTISING_MANAGER_IFACE = "org.bluez.LEAdvertisingManager1"
+LE_ADVERTISEMENT_IFACE = "org.bluez.LEAdvertisement1"
+ADVERTISEMENT_MONITOR_MANAGER_IFACE = "org.bluez.AdvertisementMonitorManager1"
+ADVERTISEMENT_MONITOR_IFACE = "org.bluez.AdvertisementMonitor1"
+
# The device class of some arbitrary Android phone.
MOCK_PHONE_CLASS = 5898764
+# Maximum number of BLE advertisements supported per adapter.
+MAX_ADVERTISEMENT_INSTANCES = 5
+
@dbus.service.method(AGENT_MANAGER_IFACE, in_signature="os", out_signature="")
def RegisterAgent(manager, agent_path, capability):
@@ -48,9 +56,13 @@
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
+ if not capability:
+ capability = "KeyboardDisplay"
+
if capability not in all_caps:
raise dbus.exceptions.DBusException(
"Unsupported capability " + capability,
name="org.bluez.Error.InvalidArguments"
@@ -107,6 +119,11 @@
bluez.capabilities = {}
bluez.default_agent = None
+ # whether to expose the LEAdvertisingManager1 interface on adapters (BLE
advertising)
+ bluez.enable_advertise_api = _parameters.get("enable_advertise_api", True)
+ # whether to expose the AdvertisementMonitorManager1 interface on adapters
(Passive scanning)
+ bluez.enable_monitor_api = _parameters.get("enable_monitor_api", True)
+
@dbus.service.method(ADAPTER_IFACE, in_signature="o", out_signature="")
def RemoveDevice(adapter, path):
@@ -221,6 +238,7 @@
"Class": dbus.UInt32(268, variant_level=1), # Computer, Laptop
"DiscoverableTimeout": dbus.UInt32(180, variant_level=1),
"PairableTimeout": dbus.UInt32(0, variant_level=1),
+ "Roles": dbus.Array(["central", "peripheral"], variant_level=1),
}
self.AddObject(
@@ -253,6 +271,63 @@
],
)
+ bluez = mockobject.objects["/org/bluez"]
+
+ # Advertising Manager
+ if bluez.enable_advertise_api:
+ # Example values below from an Intel AX200 adapter
+ advertising_manager_properties = {
+ "ActiveInstances": dbus.Byte(0, variant_level=1),
+ "SupportedInstances": dbus.Byte(MAX_ADVERTISEMENT_INSTANCES,
variant_level=1),
+ "SupportedIncludes": dbus.Array(["tx-power", "appearance",
"local-name", "rssi"], variant_level=1),
+ "SupportedSecondaryChannels": dbus.Array(["1M", "2M", "Coded"],
variant_level=1),
+ "SupportedCapabilities": dbus.Dictionary(
+ {
+ "MaxAdvLen": dbus.Byte(251),
+ "MaxScnRspLen": dbus.Byte(251),
+ "MinTxPower": dbus.Int16(-34),
+ "MaxTxPower": dbus.Int16(7),
+ },
+ signature="sv",
+ variant_level=1,
+ ),
+ "SupportedFeatures": dbus.Array(
+ [
+ "CanSetTxPower",
+ "HardwareOffload",
+ ],
+ variant_level=1,
+ ),
+ }
+ adapter.AddProperties(LE_ADVERTISING_MANAGER_IFACE,
advertising_manager_properties)
+ adapter.AddMethods(
+ LE_ADVERTISING_MANAGER_IFACE,
+ [
+ ("RegisterAdvertisement", "oa{sv}", "", RegisterAdvertisement),
+ ("UnregisterAdvertisement", "o", "", UnregisterAdvertisement),
+ ],
+ )
+
+ # Track advertisements per adapter
+ adapter.advertisements = []
+
+ # Advertisement Monitor Manager
+ if bluez.enable_monitor_api:
+ advertisement_monitor_manager_properties = {
+ "SupportedMonitorTypes": dbus.Array(["or_patterns"],
variant_level=1),
+ }
+ adapter.AddProperties(ADVERTISEMENT_MONITOR_MANAGER_IFACE,
advertisement_monitor_manager_properties)
+ adapter.AddMethods(
+ ADVERTISEMENT_MONITOR_MANAGER_IFACE,
+ [
+ ("RegisterMonitor", "o", "", RegisterMonitor),
+ ("UnregisterMonitor", "o", "", UnregisterMonitor),
+ ],
+ )
+
+ # Track advertisement monitors per adapter
+ adapter.monitors = []
+
manager = mockobject.objects["/"]
manager.EmitSignal(
OBJECT_MANAGER_IFACE,
@@ -652,3 +727,137 @@
[],
],
)
+
+
+def RegisterAdvertisement(manager, adv_path, options): # pylint:
disable=unused-argument
+ if adv_path in manager.advertisements:
+ raise dbus.exceptions.DBusException("Already registered: " + adv_path,
name="org.bluez.Error.AlreadyExists")
+
+ if len(manager.advertisements) >= MAX_ADVERTISEMENT_INSTANCES:
+ raise dbus.exceptions.DBusException(
+ f"Maximum number of advertisements reached:
{MAX_ADVERTISEMENT_INSTANCES}",
+ name="org.bluez.Error.NotPermitted",
+ )
+
+ manager.advertisements.append(adv_path)
+
+ manager.UpdateProperties(
+ LE_ADVERTISING_MANAGER_IFACE,
+ {
+ "ActiveInstances": dbus.Byte(len(manager.advertisements)),
+ "SupportedInstances": dbus.Byte(MAX_ADVERTISEMENT_INSTANCES -
len(manager.advertisements)),
+ },
+ )
+
+
+def UnregisterAdvertisement(manager, adv_path):
+ try:
+ manager.advertisements.remove(adv_path)
+ except ValueError:
+ raise dbus.exceptions.DBusException(
+ "Unknown advertisement: " + adv_path,
name="org.bluez.Error.DoesNotExist"
+ ) from None
+
+ manager.UpdateProperties(
+ LE_ADVERTISING_MANAGER_IFACE,
+ {
+ "ActiveInstances": dbus.Byte(len(manager.advertisements)),
+ "SupportedInstances": dbus.Byte(MAX_ADVERTISEMENT_INSTANCES -
len(manager.advertisements)),
+ },
+ )
+
+
[email protected](BLUEZ_MOCK_IFACE, in_signature="s", out_signature="s")
+def AddAdvertisement(self, adv_name):
+ """Convenience method to add an Advertisement object
+
+ Creates a simple broadcast advertisement with some manufacturer data.
+
+ Returns the new object path.
+ """
+ path = "/org/dbusmock/bluez/advertisement/" + adv_name
+
+ adv_properties = {
+ "Type": dbus.String("broadcast", variant_level=1),
+ "ManufacturerData": dbus.Dictionary(
+ # 0xFFFF is the Bluetooth Company Identifier reserved for internal
use and testing.
+ {dbus.UInt16(0xFFFF): dbus.Array([0x00, 0x01], variant_level=2)},
+ signature="qv",
+ variant_level=1,
+ ),
+ "Includes": dbus.Array(["local-name"], variant_level=1),
+ }
+
+ self.AddObject(
+ path,
+ LE_ADVERTISEMENT_IFACE,
+ adv_properties,
+ [
+ ("Release", "", "", ""),
+ ],
+ )
+
+ return path
+
+
[email protected](BLUEZ_MOCK_IFACE, in_signature="s", out_signature="s")
+def AddMonitor(self, monitor_name):
+ """Convenience method to add an Advertisement Monitor
+
+ Returns the new object path.
+ """
+ path = "/org/dbusmock/bluez/monitor/" + monitor_name
+
+ monitor_properties = {
+ "Type": dbus.String("or_patterns", variant_level=1),
+ # Example pattern that could be used to scan for an advertisement
created by AddAdvertisement()
+ "Patterns": dbus.Struct(
+ (
+ # Start position: 0
+ dbus.Byte(0),
+ # AD data type: Manufacturer data
+ dbus.Byte(0xFF),
+ # Vaue of the pattern: 0xFFFF (company identifier), followed
by 0x01
+ dbus.Array(
+ [
+ dbus.UInt16(0xFFFF),
+ dbus.Byte(0x01),
+ ]
+ ),
+ ),
+ signature="yyay",
+ variant_level=2,
+ ),
+ }
+
+ self.AddObject(
+ path,
+ ADVERTISEMENT_MONITOR_IFACE,
+ monitor_properties,
+ [
+ ("Release", "", "", ""),
+ ("Activate", "", "", ""),
+ ("DeviceFound", "o", "", ""),
+ ("DeviceLost", "o", "", ""),
+ ],
+ )
+
+ return path
+
+
+def RegisterMonitor(manager, monitor_path):
+ if monitor_path in manager.monitors:
+ raise dbus.exceptions.DBusException(
+ "Already registered: " + monitor_path,
name="org.bluez.Error.AlreadyExists"
+ )
+
+ manager.monitors.append(monitor_path)
+
+
+def UnregisterMonitor(manager, monitor_path):
+ try:
+ manager.monitors.remove(monitor_path)
+ except ValueError:
+ raise dbus.exceptions.DBusException(
+ "Unknown monitor: " + monitor_path,
name="org.bluez.Error.DoesNotExist"
+ ) from None
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-dbusmock-0.31.1/dbusmock/templates/gnome_screensaver.py
new/python-dbusmock-0.32.1/dbusmock/templates/gnome_screensaver.py
--- old/python-dbusmock-0.31.1/dbusmock/templates/gnome_screensaver.py
2024-02-23 14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/dbusmock/templates/gnome_screensaver.py
2024-07-14 09:17:09.000000000 +0200
@@ -28,8 +28,12 @@
[
("GetActive", "", "b", "ret = self.is_active"),
("GetActiveTime", "", "u", "ret = 1"),
- # fmt: off
- ("SetActive", "b", "", 'self.is_active = args[0];
self.EmitSignal("", "ActiveChanged", "b", [self.is_active])'),
+ (
+ "SetActive",
+ "b",
+ "",
+ 'self.is_active = args[0]; self.EmitSignal("",
"ActiveChanged", "b", [self.is_active])',
+ ),
("Lock", "", "", "time.sleep(1); self.SetActive(True)"),
("ShowMessage", "sss", "", ""),
("SimulateUserActivity", "", "", ""),
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-dbusmock-0.31.1/dbusmock/templates/modemmanager.py
new/python-dbusmock-0.32.1/dbusmock/templates/modemmanager.py
--- old/python-dbusmock-0.31.1/dbusmock/templates/modemmanager.py
1970-01-01 01:00:00.000000000 +0100
+++ new/python-dbusmock-0.32.1/dbusmock/templates/modemmanager.py
2024-07-14 09:17:09.000000000 +0200
@@ -0,0 +1,209 @@
+"""ModemManager mock template
+
+This creates the expected methods and properties of the main
+ModemManager object, but no devices. You can specify any property
+such as DaemonVersion in "parameters".
+"""
+
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your option) any
+# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text
+# of the license.
+
+__author__ = "Guido Günther"
+__copyright__ = "2024 The Phosh Developers"
+
+import dbus
+
+from dbusmock import MOCK_IFACE, OBJECT_MANAGER_IFACE, mockobject
+
+BUS_NAME = "org.freedesktop.ModemManager1"
+MAIN_OBJ = "/org/freedesktop/ModemManager1"
+MAIN_IFACE = "org.freedesktop.ModemManager1"
+SYSTEM_BUS = True
+IS_OBJECT_MANAGER = True
+MODEM_IFACE = "org.freedesktop.ModemManager1.Modem"
+MODEM_3GPP_IFACE = "org.freedesktop.ModemManager1.Modem.Modem3gpp"
+MODEM_VOICE_IFACE = "org.freedesktop.ModemManager1.Modem.Voice"
+SIM_IFACE = "org.freedesktop.ModemManager1.Sim"
+
+
+class MMModemMode:
+ """
+ See
+
https://www.freedesktop.org/software/ModemManager/doc/latest/ModemManager/ModemManager-Flags-and-Enumerations.html#MMModemMode
+ """
+
+ MODE_NONE = 0
+ MODE_CS = 1 << 0
+ MODE_2G = 1 << 1
+ MODE_3G = 1 << 2
+ MODE_4G = 1 << 3
+ MODE_5G = 1 << 4
+
+
+class MMModemState:
+ """
+ See
+
https://www.freedesktop.org/software/ModemManager/doc/latest/ModemManager/ModemManager-Flags-and-Enumerations.html#MMModemState
+ """
+
+ STATE_FAILED = -1
+ STATE_UNKNOWN = 0
+ STATE_INITIALIZING = 1
+ STATE_LOCKED = 2
+ STATE_DISABLED = 3
+ STATE_DISABLING = 4
+ STATE_ENABLING = 5
+ STATE_ENABLED = 6
+ STATE_SEARCHING = 7
+ STATE_REGISTERED = 8
+ STATE_DISCONNECTING = 9
+ STATE_CONNECTING = 10
+ STATE_CONNECTED = 11
+
+
+class MMModemPowerState:
+ """
+ See
+
https://www.freedesktop.org/software/ModemManager/doc/latest/ModemManager/ModemManager-Flags-and-Enumerations.html#MMModemPowerState
+ """
+
+ POWER_STATE_UNKNOWN = 0
+ POWER_STATE_OFF = 1
+ POWER_STATE_LOW = 2
+ POWER_STATE_ON = 3
+
+
+class MMModemAccesssTechnology:
+ """
+ See
+
https://www.freedesktop.org/software/ModemManager/doc/latest/ModemManager/ModemManager-Flags-and-Enumerations.html#MMModemAccessTechnology
+ """
+
+ ACCESS_TECHNOLOGY_UNKNOWN = 0
+ ACCESS_TECHNOLOGY_POTS = 1 << 0
+ ACCESS_TECHNOLOGY_GSM = 1 << 1
+ ACCESS_TECHNOLOGY_GSM_COMPACT = 1 << 2
+ ACCESS_TECHNOLOGY_GPRS = 1 << 3
+ ACCESS_TECHNOLOGY_EDGE = 1 << 4
+ ACCESS_TECHNOLOGY_UMTS = 1 << 5
+ ACCESS_TECHNOLOGY_HSDPA = 1 << 6
+ ACCESS_TECHNOLOGY_HSUPA = 1 << 7
+ ACCESS_TECHNOLOGY_HSPA = 1 << 8
+ ACCESS_TECHNOLOGY_HSPA_PLUS = 1 << 9
+ ACCESS_TECHNOLOGY_1XRTT = 1 << 10
+ ACCESS_TECHNOLOGY_EVDO0 = 1 << 11
+ ACCESS_TECHNOLOGY_EVDOA = 1 << 12
+ ACCESS_TECHNOLOGY_EVDOB = 1 << 13
+ ACCESS_TECHNOLOGY_LTE = 1 << 14
+ ACCESS_TECHNOLOGY_5GNR = 1 << 15
+ ACCESS_TECHNOLOGY_LTE_CAT_M = 1 << 16
+ ACCESS_TECHNOLOGY_LTE_NB_IOT = 1 << 17
+
+
+def load(mock, parameters):
+ methods = [
+ ("ScanDevices", "", "", ""),
+ ]
+
+ props = dbus.Dictionary(
+ {
+ "Version": parameters.get("DaemonVersion", "1.22"),
+ },
+ signature="sv",
+ )
+
+ mock.AddMethods(MAIN_IFACE, methods)
+ mock.AddProperties(MAIN_IFACE, props)
+
+
[email protected](MOCK_IFACE, in_signature="", out_signature="ss")
+def AddSimpleModem(self):
+ """Convenience method to add a simple Modem object
+
+ Please note that this does not set any global properties.
+
+ Returns the new object path.
+ """
+ modem_path = "/org/freedesktop/ModemManager1/Modems/8"
+ sim_path = "/org/freedesktop/ModemManager1/SIM/2"
+ manager = mockobject.objects[MAIN_OBJ]
+
+ modem_props = {
+ "State": dbus.Int32(MMModemState.STATE_ENABLED),
+ "Model": dbus.String("E1750"),
+ "Revision": dbus.String("11.126.08.01.00"),
+ "AccessTechnologies":
dbus.UInt32(MMModemAccesssTechnology.ACCESS_TECHNOLOGY_LTE),
+ "PowerState": dbus.UInt32(MMModemPowerState.POWER_STATE_ON),
+ "UnlockRequired": dbus.UInt32(0),
+ "UnlockRetries": dbus.Dictionary([], signature="uu"),
+ "CurrentModes": dbus.Struct(
+ (dbus.UInt32(MMModemMode.MODE_4G),
dbus.UInt32(MMModemMode.MODE_4G)), signature="(uu)"
+ ),
+ "SignalQuality": dbus.Struct(
+ (dbus.UInt32(70), dbus.Boolean(True)),
+ ),
+ "Sim": dbus.ObjectPath(sim_path),
+ "SupportedModes": [
+ (dbus.UInt32(MMModemMode.MODE_4G),
dbus.UInt32(MMModemMode.MODE_4G)),
+ (dbus.UInt32(MMModemMode.MODE_3G | MMModemMode.MODE_2G),
dbus.UInt32(MMModemMode.MODE_3G)),
+ ],
+ "SupportedBands": [dbus.UInt32(0)],
+ }
+ self.AddObject(modem_path, MODEM_IFACE, modem_props, [])
+
+ modem_3gpp_props = {
+ "Imei": dbus.String("doesnotmatter", variant_level=1),
+ "OperatorName": dbus.String("TheOperator"),
+ "Pco": dbus.Array([], signature="(ubay)"),
+ }
+ modem = mockobject.objects[modem_path]
+ modem.AddProperties(MODEM_3GPP_IFACE, modem_3gpp_props)
+
+ modem_voice_props = {
+ "Calls": dbus.Array([], signature="o"),
+ "EmergencyOnly": False,
+ }
+
+ modem.call_waiting = False
+ modem_voice_methods = [
+ ("CallWaitingQuery", "", "b", "ret = self.call_waiting"),
+ ("CallWaitingSetup", "b", "", "self.call_waiting = args[0]"),
+ ]
+ modem = mockobject.objects[modem_path]
+ modem.AddProperties(MODEM_VOICE_IFACE, modem_voice_props)
+ modem.AddMethods(MODEM_VOICE_IFACE, modem_voice_methods)
+
+ manager.EmitSignal(
+ OBJECT_MANAGER_IFACE,
+ "InterfacesAdded",
+ "oa{sa{sv}}",
+ [
+ dbus.ObjectPath(modem_path),
+ {
+ MODEM_IFACE: modem_props,
+ MODEM_3GPP_IFACE: modem_3gpp_props,
+ MODEM_VOICE_IFACE: modem_voice_props,
+ },
+ ],
+ )
+
+ sim_props = {
+ "Active": dbus.Boolean(True),
+ "Imsi": dbus.String("doesnotmatter"),
+ "PreferredNetworks": dbus.Array([], signature="(su)"),
+ }
+ self.AddObject(sim_path, SIM_IFACE, sim_props, [])
+ manager.EmitSignal(
+ OBJECT_MANAGER_IFACE,
+ "InterfacesAdded",
+ "oa{sa{sv}}",
+ [
+ dbus.ObjectPath(sim_path),
+ {SIM_IFACE: sim_props},
+ ],
+ )
+
+ return (modem_path, sim_path)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-dbusmock-0.31.1/dbusmock/templates/networkmanager.py
new/python-dbusmock-0.32.1/dbusmock/templates/networkmanager.py
--- old/python-dbusmock-0.31.1/dbusmock/templates/networkmanager.py
2024-02-23 14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/dbusmock/templates/networkmanager.py
2024-07-14 09:17:09.000000000 +0200
@@ -42,7 +42,7 @@
# these really want to be dataclasses, but need to drop support for Python 3.6
for that
-class NMState: # pylint: disable=too-few-public-methods
+class NMState:
"""Global state
As per
https://developer.gnome.org/NetworkManager/unstable/nm-dbus-types.html#NMState
@@ -58,7 +58,7 @@
NM_STATE_CONNECTED_GLOBAL = 70
-class NMConnectivityState: # pylint: disable=too-few-public-methods
+class NMConnectivityState:
"""Connectvity state
As per
https://developer.gnome.org/NetworkManager/unstable/nm-dbus-types.html#NMConnectivityState
@@ -71,7 +71,7 @@
NM_CONNECTIVITY_FULL = 4
-class NMActiveConnectionState: # pylint: disable=too-few-public-methods
+class NMActiveConnectionState:
"""Active connection state
As per
https://developer.gnome.org/NetworkManager/unstable/nm-dbus-types.html#NMActiveConnectionState
@@ -84,7 +84,7 @@
NM_ACTIVE_CONNECTION_STATE_DEACTIVATED = 4
-class InfrastructureMode: # pylint: disable=too-few-public-methods
+class InfrastructureMode:
"""Infrastructure mode
As per
https://developer.gnome.org/NetworkManager/unstable/nm-dbus-types.html#NM80211Mode
@@ -103,7 +103,7 @@
}
-class DeviceState: # pylint: disable=too-few-public-methods
+class DeviceState:
"""Device states
As per
https://developer.gnome.org/NetworkManager/unstable/nm-dbus-types.html#NMDeviceState
@@ -124,7 +124,7 @@
FAILED = 120
-class NM80211ApSecurityFlags: # pylint: disable=too-few-public-methods
+class NM80211ApSecurityFlags:
"""Security flags
As per
https://developer.gnome.org/NetworkManager/unstable/nm-dbus-types.html#NM80211ApSecurityFlags
@@ -147,7 +147,7 @@
}
-class NM80211ApFlags: # pylint: disable=too-few-public-methods
+class NM80211ApFlags:
"""Device flags
As per
https://developer.gnome.org/NetworkManager/unstable/nm-dbus-types.html#NM80211ApFlags
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-dbusmock-0.31.1/packaging/python-dbusmock.spec
new/python-dbusmock-0.32.1/packaging/python-dbusmock.spec
--- old/python-dbusmock-0.31.1/packaging/python-dbusmock.spec 2024-02-23
14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/packaging/python-dbusmock.spec 2024-07-14
09:17:09.000000000 +0200
@@ -34,7 +34,7 @@
%description -n python3-dbusmock %_description
%prep
-%autosetup -n %{name}-%{version} -S git
+%autosetup -n %{name}-%{version}
rm -rf python-%{modname}.egg-info
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/packit.yaml
new/python-dbusmock-0.32.1/packit.yaml
--- old/python-dbusmock-0.31.1/packit.yaml 2024-02-23 14:06:17.000000000
+0100
+++ new/python-dbusmock-0.32.1/packit.yaml 2024-07-14 09:17:09.000000000
+0200
@@ -23,15 +23,17 @@
trigger: pull_request
targets:
- fedora-all
- - centos-stream-8-x86_64
- centos-stream-9-x86_64
+ # FIXME: broken
+ # - centos-stream-10-x86_64
- job: tests
trigger: pull_request
targets:
- fedora-all
- - centos-stream-8-x86_64
- centos-stream-9-x86_64
+ # FIXME: broken rpm build above
+ # - centos-stream-10-x86_64
- job: propose_downstream
trigger: release
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-dbusmock-0.31.1/python_dbusmock.egg-info/PKG-INFO
new/python-dbusmock-0.32.1/python_dbusmock.egg-info/PKG-INFO
--- old/python-dbusmock-0.31.1/python_dbusmock.egg-info/PKG-INFO
2024-02-23 14:06:27.000000000 +0100
+++ new/python-dbusmock-0.32.1/python_dbusmock.egg-info/PKG-INFO
2024-07-14 09:17:21.000000000 +0200
@@ -1,6 +1,6 @@
Metadata-Version: 2.1
Name: python-dbusmock
-Version: 0.31.1
+Version: 0.32.1
Summary: Mock D-Bus objects
Home-page: https://github.com/martinpitt/python-dbusmock
Author: Martin Pitt
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-dbusmock-0.31.1/python_dbusmock.egg-info/SOURCES.txt
new/python-dbusmock-0.32.1/python_dbusmock.egg-info/SOURCES.txt
--- old/python-dbusmock-0.31.1/python_dbusmock.egg-info/SOURCES.txt
2024-02-23 14:06:27.000000000 +0100
+++ new/python-dbusmock-0.32.1/python_dbusmock.egg-info/SOURCES.txt
2024-07-14 09:17:21.000000000 +0200
@@ -26,6 +26,7 @@
dbusmock/templates/iio-sensors-proxy.py
dbusmock/templates/logind.py
dbusmock/templates/low_memory_monitor.py
+dbusmock/templates/modemmanager.py
dbusmock/templates/networkmanager.py
dbusmock/templates/notification_daemon.py
dbusmock/templates/ofono.py
@@ -62,6 +63,7 @@
tests/test_iio_sensors_proxy.py
tests/test_logind.py
tests/test_low_memory_monitor.py
+tests/test_modemmanager.py
tests/test_networkmanager.py
tests/test_notification_daemon.py
tests/test_ofono.py
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/tests/run-centos
new/python-dbusmock-0.32.1/tests/run-centos
--- old/python-dbusmock-0.31.1/tests/run-centos 2024-02-23 14:06:17.000000000
+0100
+++ new/python-dbusmock-0.32.1/tests/run-centos 2024-07-14 09:17:09.000000000
+0200
@@ -2,11 +2,14 @@
set -eux
# install build dependencies
dnf -y install python3-setuptools python3 python3-gobject-base \
- python3-dbus python3-pytest dbus-x11 util-linux \
+ python3-dbus dbus-x11 util-linux \
upower NetworkManager bluez libnotify polkit
if ! grep -q :el /etc/os-release; then
- dnf -y install power-profiles-daemon iio-sensor-proxy
+ dnf -y install power-profiles-daemon iio-sensor-proxy python3-pytest
+else
+ dnf -y install python3-pip
+ pip install pytest
fi
if [ "$SKIP_STATIC_CHECKS" != "1" ]; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/tests/run-debian
new/python-dbusmock-0.32.1/tests/run-debian
--- old/python-dbusmock-0.31.1/tests/run-debian 2024-02-23 14:06:17.000000000
+0100
+++ new/python-dbusmock-0.32.1/tests/run-debian 2024-07-14 09:17:09.000000000
+0200
@@ -14,7 +14,8 @@
eatmydata apt-get install --no-install-recommends -y git \
python3-all python3-setuptools python3-setuptools-scm python3-build
python3-venv \
python3-dbus python3-pytest python3-gi gir1.2-glib-2.0 \
- dbus libnotify-bin upower network-manager bluez ofono ofono-scripts
power-profiles-daemon
+ dbus libnotify-bin upower network-manager bluez ofono ofono-scripts
power-profiles-daemon \
+ modemmanager
# systemd's tools otherwise fail on "not been booted with systemd"
mkdir -p /run/systemd/system
@@ -39,16 +40,14 @@
# test sdist with direct setuptools
./setup.py sdist
-tar --wildcards --strip-components=1 -xvf
dist/python-dbusmock-\${my_version}*.tar.gz '*/PKG-INFO'
+tar --wildcards --strip-components=1 -xvf
dist/python[_-]dbusmock-\${my_version}*.tar.gz '*/PKG-INFO'
grep "^Version: \${my_version}" PKG-INFO
grep "^## Purpose" PKG-INFO
git clean -ffdx
-# test sdist with PyPA build; note https://bugs.debian.org/1009916
-if dpkg --compare-versions \$(dpkg-query -f '\${Version}' --show
python3-build) '>=' 0.7.0-3; then
- python3 -m build --sdist
- tar --wildcards --strip-components=1 -xvf
dist/python-dbusmock-\${my_version}*.tar.gz '*/PKG-INFO'
- grep "^Version: \${my_version}" PKG-INFO
- grep "^## Purpose" PKG-INFO
-fi
+# test sdist with PyPA build
+python3 -m build --sdist
+tar --wildcards --strip-components=1 -xvf
dist/python_dbusmock-\${my_version}*.tar.gz '*/PKG-INFO'
+grep "^Version: \${my_version}" PKG-INFO
+grep "^## Purpose" PKG-INFO
EOF
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/tests/run-fedora
new/python-dbusmock-0.32.1/tests/run-fedora
--- old/python-dbusmock-0.31.1/tests/run-fedora 2024-02-23 14:06:17.000000000
+0100
+++ new/python-dbusmock-0.32.1/tests/run-fedora 2024-07-14 09:17:09.000000000
+0200
@@ -2,11 +2,14 @@
set -eux
# install build dependencies
dnf -y install python3-setuptools python3 python3-gobject-base \
- python3-dbus python3-pytest dbus-x11 util-linux \
+ python3-dbus dbus-x11 util-linux \
upower NetworkManager bluez libnotify polkit
if ! grep -q :el /etc/os-release; then
- dnf -y install power-profiles-daemon iio-sensor-proxy
+ dnf -y install power-profiles-daemon iio-sensor-proxy python3-pytest
+else
+ dnf -y install python3-pip
+ pip install pytest
fi
if [ "$SKIP_STATIC_CHECKS" != "1" ]; then
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/tests/run-ubuntu
new/python-dbusmock-0.32.1/tests/run-ubuntu
--- old/python-dbusmock-0.31.1/tests/run-ubuntu 2024-02-23 14:06:17.000000000
+0100
+++ new/python-dbusmock-0.32.1/tests/run-ubuntu 2024-07-14 09:17:09.000000000
+0200
@@ -14,7 +14,8 @@
eatmydata apt-get install --no-install-recommends -y git \
python3-all python3-setuptools python3-setuptools-scm python3-build
python3-venv \
python3-dbus python3-pytest python3-gi gir1.2-glib-2.0 \
- dbus libnotify-bin upower network-manager bluez ofono ofono-scripts
power-profiles-daemon
+ dbus libnotify-bin upower network-manager bluez ofono ofono-scripts
power-profiles-daemon \
+ modemmanager
# systemd's tools otherwise fail on "not been booted with systemd"
mkdir -p /run/systemd/system
@@ -39,16 +40,14 @@
# test sdist with direct setuptools
./setup.py sdist
-tar --wildcards --strip-components=1 -xvf
dist/python-dbusmock-\${my_version}*.tar.gz '*/PKG-INFO'
+tar --wildcards --strip-components=1 -xvf
dist/python[_-]dbusmock-\${my_version}*.tar.gz '*/PKG-INFO'
grep "^Version: \${my_version}" PKG-INFO
grep "^## Purpose" PKG-INFO
git clean -ffdx
-# test sdist with PyPA build; note https://bugs.debian.org/1009916
-if dpkg --compare-versions \$(dpkg-query -f '\${Version}' --show
python3-build) '>=' 0.7.0-3; then
- python3 -m build --sdist
- tar --wildcards --strip-components=1 -xvf
dist/python-dbusmock-\${my_version}*.tar.gz '*/PKG-INFO'
- grep "^Version: \${my_version}" PKG-INFO
- grep "^## Purpose" PKG-INFO
-fi
+# test sdist with PyPA build
+python3 -m build --sdist
+tar --wildcards --strip-components=1 -xvf
dist/python_dbusmock-\${my_version}*.tar.gz '*/PKG-INFO'
+grep "^Version: \${my_version}" PKG-INFO
+grep "^## Purpose" PKG-INFO
EOF
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/tests/test_bluez5.py
new/python-dbusmock-0.32.1/tests/test_bluez5.py
--- old/python-dbusmock-0.31.1/tests/test_bluez5.py 2024-02-23
14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/tests/test_bluez5.py 2024-07-14
09:17:09.000000000 +0200
@@ -25,6 +25,7 @@
from gi.repository import GLib
import dbusmock
+from packaging.version import Version
tracemalloc.start(25)
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
@@ -89,6 +90,10 @@
cls.dbus_con = cls.get_dbus(True)
(cls.p_mock, cls.obj_bluez) = cls.spawn_server_template("bluez5", {},
stdout=subprocess.PIPE)
+ out = _run_bluetoothctl("version")
+ version = next(line.split(" ")[-1] for line in out if
line.startswith("Version"))
+ cls.bluez5_version = Version(version)
+
def setUp(self):
self.obj_bluez.Reset()
self.dbusmock = dbus.Interface(self.obj_bluez, dbusmock.MOCK_IFACE)
@@ -128,6 +133,43 @@
self.assertIn("Discoverable: no", out)
self.assertIn("Pairable: yes", out)
self.assertIn("Discovering: no", out)
+ self.assertIn("Roles: central", out)
+ self.assertIn("Roles: peripheral", out)
+
+ # Advertising Manager
+ self.assertIn("Advertising Features:", out)
+ self.assertIn("ActiveInstances: 0x00 (0)", out)
+ self.assertIn("SupportedInstances: 0x05 (5)", out)
+ self.assertIn("SupportedIncludes: tx-power", out)
+ self.assertIn("SupportedIncludes: appearance", out)
+ self.assertIn("SupportedIncludes: local-name", out)
+ self.assertIn("SupportedSecondaryChannels: 1M", out)
+ self.assertIn("SupportedSecondaryChannels: 2M", out)
+
+ # SupportedFeatures was added to the API with BlueZ 5.57
+ if self.bluez5_version >= Version("5.57"):
+ self.assertIn("SupportedFeatures: CanSetTxPower", out)
+ self.assertIn("SupportedFeatures: HardwareOffload", out)
+
+ # Capabilities key-value format was changed in BlueZ 5.70
+ if self.bluez5_version <= Version("5.70"):
+ capabilities = [
+ ["SupportedCapabilities Key: MinTxPower",
"SupportedCapabilities Value: -34"],
+ ["SupportedCapabilities Key: MaxTxPower",
"SupportedCapabilities Value: 7"],
+ ["SupportedCapabilities Key: MaxAdvLen",
"SupportedCapabilities Value: 0xfb (251)"],
+ ["SupportedCapabilities Key: MaxScnRspLen",
"SupportedCapabilities Value: 0xfb (251)"],
+ ]
+ for capability in capabilities:
+ self.assertTrue(all(cap in out for cap in capability),
f"Expected ${capability} in: ${out}")
+ else:
+ self.assertIn("SupportedCapabilities.MinTxPower: 0xffffffde
(-34)", out)
+ self.assertIn("SupportedCapabilities.MaxTxPower: 0x0007 (7)", out)
+ self.assertIn("SupportedCapabilities.MaxAdvLen: 0xfb (251)", out)
+ self.assertIn("SupportedCapabilities.MaxScnRspLen: 0xfb (251)",
out)
+
+ # Advertisement Monitor
+ self.assertIn("Advertisement Monitor Features:", out)
+ self.assertIn("SupportedMonitorTypes: or_patterns", out)
def test_no_devices(self):
# Add an adapter.
@@ -187,6 +229,283 @@
self.assertIn("Device " + address, out)
self.assertIn("Paired: yes", out)
+ def test_add_advertisement(self):
+ # When an advertisement is added
+ adv_path = self.dbusmock_bluez.AddAdvertisement("bc001")
+ # Then the path is returned
+ self.assertEqual(adv_path, "/org/dbusmock/bluez/advertisement/bc001")
+ # And the object is exported on the bus
+ adv = self.dbus_con.get_object("org.bluez", adv_path)
+ adv_type = adv.Get("org.bluez.LEAdvertisement1", "Type",
dbus_interface="org.freedesktop.DBus.Properties")
+ # And has the correct properties
+ self.assertEqual(adv_type, "broadcast")
+
+ def test_register_advertisement(self):
+ # Given an adapter with the LEAdvertisingManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_manager = dbus.Interface(adapter,
"org.bluez.LEAdvertisingManager1")
+ props = dbus.Interface(adapter, "org.freedesktop.DBus.Properties")
+ active_instances = props.Get(adv_manager.dbus_interface,
"ActiveInstances")
+ supported_instances = props.Get(adv_manager.dbus_interface,
"SupportedInstances")
+
+ # And no active instances
+ self.assertEqual(active_instances, 0)
+ self.assertEqual(supported_instances, 5)
+
+ # When an advertisement is registered
+ # Then no error is raised
+ adv_manager.RegisterAdvertisement("/adv0", {})
+
+ # And active instances is incremented
+ active_instances = props.Get(adv_manager.dbus_interface,
"ActiveInstances")
+ self.assertEqual(active_instances, 1)
+ # And supported instances is decremented
+ supported_instances = props.Get(adv_manager.dbus_interface,
"SupportedInstances")
+ self.assertEqual(supported_instances, 4)
+
+ def test_register_advertisement_duplicate(self):
+ # Given an adapter with the LEAdvertisingManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_manager = dbus.Interface(adapter,
"org.bluez.LEAdvertisingManager1")
+ props = dbus.Interface(adapter, "org.freedesktop.DBus.Properties")
+
+ # When an advertisement is registered twice
+ adv_manager.RegisterAdvertisement("/adv0", {})
+
+ # Then an error is raised
+ with self.assertRaisesRegex(dbus.exceptions.DBusException, "Already
registered") as ctx:
+ adv_manager.RegisterAdvertisement("/adv0", {})
+ self.assertEqual(ctx.exception.get_dbus_name(),
"org.bluez.Error.AlreadyExists")
+
+ # And active instances is not incremented
+ active_instances = props.Get(adv_manager.dbus_interface,
"ActiveInstances")
+ self.assertEqual(active_instances, 1)
+ # And supported instances is not decremented
+ supported_instances = props.Get(adv_manager.dbus_interface,
"SupportedInstances")
+ self.assertEqual(supported_instances, 4)
+
+ def test_register_advertisement_max_instances(self):
+ # Given an adapter with the LEAdvertisingManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_manager = dbus.Interface(adapter,
"org.bluez.LEAdvertisingManager1")
+ props = dbus.Interface(adapter, "org.freedesktop.DBus.Properties")
+ max_instances = props.Get(adv_manager.dbus_interface,
"SupportedInstances")
+
+ # When more advertisements are registered than supported
+ for i in range(max_instances):
+ adv_manager.RegisterAdvertisement(f"/adv{i}", {})
+
+ # Then an error is raised
+ with self.assertRaisesRegex(dbus.exceptions.DBusException, "Maximum
number of advertisements reached") as ctx:
+ adv_manager.RegisterAdvertisement(f"/adv{int(max_instances)}", {})
+ self.assertEqual(ctx.exception.get_dbus_name(),
"org.bluez.Error.NotPermitted")
+
+ # And active instances is equal to the number of supported instances
+ active_instances = props.Get(adv_manager.dbus_interface,
"ActiveInstances")
+ self.assertEqual(active_instances, max_instances)
+ # And supported instances is now zero
+ supported_instances = props.Get(adv_manager.dbus_interface,
"SupportedInstances")
+ self.assertEqual(supported_instances, 0)
+
+ def test_unregister_advertisement(self):
+ # Given an adapter with the LEAdvertisingManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_manager = dbus.Interface(adapter,
"org.bluez.LEAdvertisingManager1")
+ props = dbus.Interface(adapter, "org.freedesktop.DBus.Properties")
+
+ # And a registered advertisement
+ adv_manager.RegisterAdvertisement("/adv0", {})
+ active_instances = props.Get(adv_manager.dbus_interface,
"ActiveInstances")
+ supported_instances = props.Get(adv_manager.dbus_interface,
"SupportedInstances")
+ self.assertEqual(active_instances, 1)
+ self.assertEqual(supported_instances, 4)
+
+ # When the advertisement is unregistered
+ # Then no error is raised
+ adv_manager.UnregisterAdvertisement("/adv0")
+ # And active instances is decremented
+ active_instances = props.Get(adv_manager.dbus_interface,
"ActiveInstances")
+ self.assertEqual(active_instances, 0)
+ # And supported instances is incremented
+ supported_instances = props.Get(adv_manager.dbus_interface,
"SupportedInstances")
+ self.assertEqual(supported_instances, 5)
+
+ def test_unregister_advertisement_unknown(self):
+ # Given an adapter with the LEAdvertisingManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_manager = dbus.Interface(adapter,
"org.bluez.LEAdvertisingManager1")
+
+ # When an advertisement is unregistered without registering it first
+ # Then an error is raised
+ with self.assertRaisesRegex(dbus.exceptions.DBusException, "Unknown
advertisement") as ctx:
+ adv_manager.UnregisterAdvertisement("/adv0")
+ self.assertEqual(ctx.exception.get_dbus_name(),
"org.bluez.Error.DoesNotExist")
+
+ def test_add_monitor(self):
+ # When an advertisement monitor is added
+ adv_path = self.dbusmock_bluez.AddMonitor("mon001")
+ # Then the path is returned
+ self.assertEqual(adv_path, "/org/dbusmock/bluez/monitor/mon001")
+ # And the object is exported on the bus
+ adv = self.dbus_con.get_object("org.bluez", adv_path)
+ adv_type = adv.Get(
+ "org.bluez.AdvertisementMonitor1", "Type",
dbus_interface="org.freedesktop.DBus.Properties"
+ )
+ # And has the correct properties
+ self.assertEqual(adv_type, "or_patterns")
+
+ def test_register_monitor(self):
+ # Given an adapter with the AdvertisementMonitorManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_monitor_manager = dbus.Interface(adapter,
"org.bluez.AdvertisementMonitorManager1")
+
+ # When an advertisement monitor is registered
+ # Then no error is raised
+ adv_monitor_manager.RegisterMonitor("/monitor0")
+
+ def test_register_monitor_duplicate(self):
+ # Given an adapter with the AdvertisementMonitorManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_monitor_manager = dbus.Interface(adapter,
"org.bluez.AdvertisementMonitorManager1")
+
+ # When an advertisement monitor is registered twice
+ adv_monitor_manager.RegisterMonitor("/monitor0")
+
+ # Then an error is raised
+ with self.assertRaisesRegex(dbus.exceptions.DBusException, "Already
registered") as ctx:
+ adv_monitor_manager.RegisterMonitor("/monitor0")
+ self.assertEqual(ctx.exception.get_dbus_name(),
"org.bluez.Error.AlreadyExists")
+
+ def test_unregister_monitor(self):
+ # Given an adapter with the AdvertisementMonitorManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_monitor_manager = dbus.Interface(adapter,
"org.bluez.AdvertisementMonitorManager1")
+
+ # And a registered advertisement monitor
+ adv_monitor_manager.RegisterMonitor("/monitor0")
+ # When the advertisement monitor is unregistered
+ # Then no error is raised
+ adv_monitor_manager.UnregisterMonitor("/monitor0")
+
+ def test_unregister_monitor_unknown(self):
+ # Given an adapter with the AdvertisementMonitorManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+ adv_monitor_manager = dbus.Interface(adapter,
"org.bluez.AdvertisementMonitorManager1")
+
+ # When an advertisement monitor is unregistered without registering it
first
+ # Then an error is raised
+ with self.assertRaisesRegex(dbus.exceptions.DBusException, "Unknown
monitor") as ctx:
+ adv_monitor_manager.UnregisterMonitor("/monitor0")
+ self.assertEqual(ctx.exception.get_dbus_name(),
"org.bluez.Error.DoesNotExist")
+
+ def test_advertise(self):
+ # Given an adapter with the LEAdvertisingManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+
+ # When an advertisement is started via bluetoothctl
+ _run_bluetoothctl("advertise broadcast")
+
+ # Then the RegisterAdvertisement method was called
+ mock_calls = adapter.GetMethodCalls("RegisterAdvertisement",
dbus_interface="org.freedesktop.DBus.Mock")
+ self.assertEqual(len(mock_calls), 1)
+ path, *_ = mock_calls[0][1]
+ self.assertEqual(path, "/org/bluez/advertising")
+
+ def test_monitor(self):
+ # Given an adapter with the AdvertisementMonitorManager1 interface
+ path = self.dbusmock_bluez.AddAdapter("hci0", "my-computer")
+ adapter = self.dbus_con.get_object("org.bluez", path)
+
+ # When an advertisement monitor is configured via bluetoothctl
+ out = _run_bluetoothctl("monitor.add-or-pattern 0 255 0x01")
+
+ # Then bluetoothctl reports success
+ self.assertIn("Advertisement Monitor 0 added", out)
+
+ # And the RegisterMonitor method was called
+ mock_calls = adapter.GetMethodCalls("RegisterMonitor",
dbus_interface="org.freedesktop.DBus.Mock")
+ self.assertEqual(len(mock_calls), 1)
+ 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
+ if self.bluez5_version >= Version("5.57"):
+ 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):
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/tests/test_code.py
new/python-dbusmock-0.32.1/tests/test_code.py
--- old/python-dbusmock-0.31.1/tests/test_code.py 2024-02-23
14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/tests/test_code.py 2024-07-14
09:17:09.000000000 +0200
@@ -35,6 +35,7 @@
"--score=n",
"--disable=missing-function-docstring,R0801",
"--disable=too-many-arguments,too-many-instance-attributes",
+ "--disable=too-few-public-methods",
"dbusmock/templates/",
]
)
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore' old/python-dbusmock-0.31.1/tests/test_modemmanager.py
new/python-dbusmock-0.32.1/tests/test_modemmanager.py
--- old/python-dbusmock-0.31.1/tests/test_modemmanager.py 1970-01-01
01:00:00.000000000 +0100
+++ new/python-dbusmock-0.32.1/tests/test_modemmanager.py 2024-07-14
09:17:09.000000000 +0200
@@ -0,0 +1,144 @@
+""" Tests for accounts service """
+
+# This program is free software; you can redistribute it and/or modify it under
+# the terms of the GNU Lesser General Public License as published by the Free
+# Software Foundation; either version 3 of the License, or (at your option) any
+# later version. See http://www.gnu.org/copyleft/lgpl.html for the full text
+# of the license.
+
+__author__ = "Guido Günther"
+__copyright__ = """
+(c) 2024 The Phosh Developers
+"""
+
+import shutil
+import subprocess
+import sys
+import unittest
+
+import dbus
+import dbus.mainloop.glib
+
+import dbusmock
+
+dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
+
+have_mmcli = shutil.which("mmcli")
+
+
+class TestModemManagerBase(dbusmock.DBusTestCase):
+ """Test mocking ModemManager"""
+
+ dbus_interface = ""
+
+ @classmethod
+ def setUpClass(cls):
+ super().setUpClass()
+ cls.start_system_bus()
+ cls.dbus_con = cls.get_dbus(True)
+
+ def setUp(self):
+ super().setUp()
+ (self.p_mock, self.p_obj) = self.spawn_server_template("modemmanager",
{}, stdout=subprocess.PIPE)
+
+ def tearDown(self):
+ if self.p_mock:
+ self.p_mock.stdout.close()
+ self.p_mock.terminate()
+ self.p_mock.wait()
+
+ super().tearDown()
+
+ def get_property(self, name):
+ return self.p_obj.Get(self.dbus_interface, name,
dbus_interface=dbus.PROPERTIES_IFACE)
+
+
[email protected](have_mmcli, "mmcli utility not available")
+class TestModemManagerMmcliBase(TestModemManagerBase):
+ """Base ModemManager interface tests using mmcli"""
+
+ ret = None
+
+ def run_mmcli(self, args):
+ self.assertIsNone(self.ret)
+ self.ret = subprocess.run( # pylint: disable=subprocess-run-check
+ ["mmcli", *args], capture_output=True, text=True
+ )
+
+ def assertOutputEquals(self, expected_lines):
+ self.assertIsNotNone(self.ret)
+ lines = self.ret.stdout.split("\n")
+ self.assertEqual(len(lines), len(expected_lines))
+ for expected, line in zip(expected_lines, lines):
+ self.assertEqual(expected, line)
+
+ def assertOutputContainsLine(self, expected_line, ret=0):
+ self.assertEqual(self.ret.returncode, ret)
+ self.assertIn(expected_line, self.ret.stdout)
+
+
+class TestModemManagerModemMmcli(TestModemManagerMmcliBase):
+ """main ModemManager interface tests using mmcli"""
+
+ def test_no_modems(self):
+ self.run_mmcli(["-m", "any"])
+ self.assertEqual(self.ret.returncode, 1)
+ self.assertIn("error: couldn't find modem", self.ret.stderr)
+
+ def test_modem(self):
+ self.p_obj.AddSimpleModem()
+ self.run_mmcli(["-m", "any"])
+ self.assertOutputEquals(
+ [
+ " -----------------------------",
+ " General | path:
/org/freedesktop/ModemManager1/Modems/8",
+ " -----------------------------",
+ " Hardware | model: E1750",
+ " | firmware revision: 11.126.08.01.00",
+ " -----------------------------",
+ " Status | state: enabled",
+ " | power state: on",
+ " | access tech: lte",
+ " | signal quality: 70% (recent)",
+ " -----------------------------",
+ " Modes | supported: allowed: 4g; preferred: 4g",
+ " | allowed: 2g, 3g; preferred:
3g",
+ " | current: allowed: 4g; preferred: 4g",
+ " -----------------------------",
+ " 3GPP | imei: doesnotmatter",
+ " | operator name: TheOperator",
+ " | registration: idle",
+ " -----------------------------",
+ " SIM | primary sim path:
/org/freedesktop/ModemManager1/SIM/2",
+ "",
+ ]
+ )
+
+ def test_sim(self):
+ self.p_obj.AddSimpleModem()
+ self.run_mmcli(["-i", "any"])
+ self.assertOutputEquals(
+ [
+ " --------------------",
+ " General | path: /org/freedesktop/ModemManager1/SIM/2",
+ " --------------------",
+ " Properties | active: yes",
+ " | imsi: doesnotmatter",
+ "",
+ ]
+ )
+
+ def test_voice_call_list(self):
+ self.p_obj.AddSimpleModem()
+ self.run_mmcli(["-m", "any", "--voice-list-calls"])
+ self.assertOutputContainsLine("No calls were found\n")
+
+ def test_voice_status(self):
+ self.p_obj.AddSimpleModem()
+ self.run_mmcli(["-m", "any", "--voice-status"])
+ self.assertOutputContainsLine("emergency only: no\n")
+
+
+if __name__ == "__main__":
+ # avoid writing to stderr
+ unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout))
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn'
'--exclude=.svnignore'
old/python-dbusmock-0.31.1/tests/test_power_profiles_daemon.py
new/python-dbusmock-0.32.1/tests/test_power_profiles_daemon.py
--- old/python-dbusmock-0.31.1/tests/test_power_profiles_daemon.py
2024-02-23 14:06:17.000000000 +0100
+++ new/python-dbusmock-0.32.1/tests/test_power_profiles_daemon.py
2024-07-14 09:17:09.000000000 +0200
@@ -12,6 +12,7 @@
import fcntl
import os
+import re
import shutil
import subprocess
import sys
@@ -40,9 +41,8 @@
def setUp(self):
# depending on the installed client version, we need to pick the right
template
try:
- version = subprocess.run(
- ["powerprofilesctl", "version"], capture_output=True,
text=True, check=True
- ).stdout
+ out = subprocess.run(["powerprofilesctl", "version"],
capture_output=True, text=True, check=True).stdout
+ version = re.search(r"[0-9.]+", out).group(0)
version = ".".join(version.strip().split(".")[:2])
template = "power_profiles_daemon" if float(version) < 0.2 else
"upower_power_profiles_daemon"
except subprocess.CalledProcessError as e: