integration-test: Move to using umockdev

Setting $SYSFS_PATH does not work any more with recent libudev versions, our
homwbrew sysfs sandbox building limits us to coldplug tests only. umockdev
works with both old and new libudevs and can also emulate uevents for future
hotplugging tests.

Skip the test if umockdev is not available, so that check and distcheck don't
bail out.
This commit is contained in:
Martin Pitt 2013-02-20 14:38:25 +01:00
parent 8bbf566dc8
commit 7105ed8a04

View file

@ -32,6 +32,12 @@ except ImportError as e:
sys.stderr.write('Skipping tests, PyGobject not available for Python 3, or missing GI typelibs: %s\n' % str(e))
sys.exit(0)
try:
from gi.repository import UMockdev
except ImportError:
sys.stderr.write('Skipping tests, umockdev not available (https://launchpad.net/umockdev/)\n')
sys.exit(0)
UP = 'org.freedesktop.UPower'
(UP_DEVICE_STATE_UNKNOWN,
@ -70,90 +76,38 @@ class Tests(unittest.TestCase):
subprocess.call(['killall', 'upowerd'])
cls.dbus = Gio.bus_get_sync(Gio.BusType.SYSTEM, None)
cls.daemon_argv = [daemon_path]
cls.daemon_argv = ['umockdev-wrapper', daemon_path]
print('Testing as root on the system bus')
else:
cls.dbus = Gio.bus_get_sync(Gio.BusType.SESSION, None)
cls.daemon_argv = [daemon_path, '--test']
cls.daemon_argv = ['umockdev-wrapper', daemon_path, '--test']
# use dbus-lauch if possible
print('Testing as user on the session bus')
def setUp(self):
'''Set up a local sysfs tree and determine paths.
'''Set up a local umockdev testbed.
The sysfs tree is empty initially and needs to be populated with
@add_device.
The testbed is initially empty.
'''
self.sysfs = tempfile.mkdtemp()
self.testbed = UMockdev.Testbed.new()
self.proxy = None
self.log = None
self.daemon = None
def tearDown(self):
del self.testbed
self.stop_daemon()
shutil.rmtree(self.sysfs)
# on failures, print daemon log
if not self._outcomeForDoCleanups.success:
if not self._outcomeForDoCleanups.success and self.log:
with open(self.log.name) as f:
sys.stderr.write('\n-------------- daemon log: ----------------\n')
sys.stderr.write(f.read())
sys.stderr.write('------------------------------\n')
#
# Methods for fake sysfs
#
def add_device(self, subsystem, name, attributes, properties=None):
'''Add a new device to the local sysfs tree.
Return the device path.
'''
dev_dir = os.path.join(self.sysfs, 'devices', name)
if not os.path.isdir(dev_dir):
os.makedirs(dev_dir)
class_dir = os.path.join(self.sysfs, 'class', subsystem)
if not os.path.isdir(class_dir):
os.makedirs(class_dir)
os.symlink(os.path.join('..', '..', 'devices', name), os.path.join(class_dir, name))
os.symlink(os.path.join('..', '..', 'class', subsystem), os.path.join(dev_dir, 'subsystem'))
attributes['uevent'] = self._props_to_str(properties)
for a, v in attributes.items():
self.set_sys_attribute(dev_dir, a, v)
return dev_dir
def get_sys_attribute(self, devpath, name):
'''Get device attribute from the local sysfs tree.'''
with open(os.path.join(devpath, name), 'r') as f:
return f.read()
def set_sys_attribute(self, devpath, name, value):
'''Set device attribute in the local sysfs tree.'''
with open(os.path.join(devpath, name), 'w') as f:
f.write(value)
def set_sys_property(self, devpath, name, value):
'''Set device udev property in the local sysfs tree.'''
prop_str = self.get_sys_attribute(devpath, 'uevent')
props = {}
for l in prop_str.splitlines():
(k, v) = l.split('=')
props[k] = v.rstrip()
props[name] = value
self.set_sys_attribute(devpath, 'uevent', self._props_to_str(props))
#
# Daemon control and D-BUS I/O
#
@ -169,7 +123,9 @@ class Tests(unittest.TestCase):
'''
env = os.environ.copy()
env['G_DEBUG'] = 'fatal-criticals'
env['SYSFS_PATH'] = self.sysfs
# note: Python doesn't propagate the setenv from Testbed.new(), so we
# have to do that ourselves
env['UMOCKDEV_DIR'] = self.testbed.get_root_dir()
self.log = tempfile.NamedTemporaryFile()
self.daemon = subprocess.Popen(self.daemon_argv,
env=env, stdout=self.log, stderr=subprocess.STDOUT)
@ -247,8 +203,8 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# online AC
ac = self.add_device('power_supply', 'AC',
{'type': 'Mains', 'online': '1' })
ac = self.testbed.add_device('power_supply', 'AC', None,
['type', 'Mains', 'online', '1' ], [])
self.start_daemon()
devs = self.proxy.EnumerateDevices()
@ -263,7 +219,7 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# offline AC
self.set_sys_attribute(ac, 'online', '0')
self.testbed.set_attribute(ac, 'online', '0')
self.start_daemon()
devs = self.proxy.EnumerateDevices()
self.assertEqual(len(devs), 1)
@ -274,14 +230,14 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# offline AC + discharging battery
bat0 = self.add_device('power_supply', 'BAT0',
{'type': 'Battery',
'present': '1',
'status': 'Discharging',
'energy_full': '60000000',
'energy_full_design': '80000000',
'energy_now': '48000000',
'voltage_now': '12000000'})
bat0 = self.testbed.add_device('power_supply', 'BAT0', None,
['type', 'Battery',
'present', '1',
'status', 'Discharging',
'energy_full', '60000000',
'energy_full_design', '80000000',
'energy_now', '48000000',
'voltage_now', '12000000'], [])
self.start_daemon()
devs = self.proxy.EnumerateDevices()
@ -304,7 +260,7 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# offline AC + discharging low battery
self.set_sys_attribute(bat0, 'energy_now', '1500000')
self.testbed.set_attribute(bat0, 'energy_now', '1500000')
self.start_daemon()
self.assertEqual(self.get_dbus_property('OnBattery'), True)
self.assertEqual(self.get_dbus_property('OnLowBattery'), True)
@ -314,7 +270,7 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# now connect AC again
self.set_sys_attribute(ac, 'online', '1')
self.testbed.set_attribute(ac, 'online', '1')
self.start_daemon()
devs = self.proxy.EnumerateDevices()
self.assertEqual(len(devs), 2)
@ -328,23 +284,23 @@ class Tests(unittest.TestCase):
'''Multiple batteries'''
# one well charged, one low
bat0 = self.add_device('power_supply', 'BAT0',
{'type': 'Battery',
'present': '1',
'status': 'Discharging',
'energy_full': '60000000',
'energy_full_design': '80000000',
'energy_now': '48000000',
'voltage_now': '12000000'})
bat0 = self.testbed.add_device('power_supply', 'BAT0', None,
['type', 'Battery',
'present', '1',
'status', 'Discharging',
'energy_full', '60000000',
'energy_full_design', '80000000',
'energy_now', '48000000',
'voltage_now', '12000000'], [])
bat1 = self.add_device('power_supply', 'BAT1',
{'type': 'Battery',
'present': '1',
'status': 'Discharging',
'energy_full': '60000000',
'energy_full_design': '80000000',
'energy_now': '1500000',
'voltage_now': '12000000'})
bat1 = self.testbed.add_device('power_supply', 'BAT1', None,
['type', 'Battery',
'present', '1',
'status', 'Discharging',
'energy_full', '60000000',
'energy_full_design', '80000000',
'energy_now', '1500000',
'voltage_now', '12000000'], [])
self.start_daemon()
devs = self.proxy.EnumerateDevices()
@ -357,7 +313,7 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# now set both to low
self.set_sys_attribute(bat0, 'energy_now', '1500000')
self.testbed.set_attribute(bat0, 'energy_now', '1500000')
self.start_daemon()
self.assertEqual(self.get_dbus_property('OnBattery'), True)
self.assertEqual(self.get_dbus_property('OnLowBattery'), True)
@ -366,14 +322,14 @@ class Tests(unittest.TestCase):
def test_unknown_battery_status(self):
'''Unknown battery charge status'''
bat0 = self.add_device('power_supply', 'BAT0',
{'type': 'Battery',
'present': '1',
'status': 'unknown',
'energy_full': '60000000',
'energy_full_design': '80000000',
'energy_now': '48000000',
'voltage_now': '12000000'})
bat0 = self.testbed.add_device('power_supply', 'BAT0', None,
['type', 'Battery',
'present', '1',
'status', 'unknown',
'energy_full', '60000000',
'energy_full_design', '80000000',
'energy_now', '48000000',
'voltage_now', '12000000'], [])
# with no other power sources, the OnBattery value here is really
# arbitrary, so don't test it. The only thing we know for sure is that
@ -383,14 +339,14 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# However, if we have an AC, we can infer
ac = self.add_device('power_supply', 'AC',
{'type': 'Mains', 'online': '0' })
ac = self.testbed.add_device('power_supply', 'AC', None,
['type', 'Mains', 'online', '0'], [])
self.start_daemon()
self.assertEqual(self.get_dbus_property('OnBattery'), True)
self.assertEqual(self.get_dbus_property('OnLowBattery'), False)
self.stop_daemon()
self.set_sys_attribute(ac, 'online', '1')
self.testbed.set_attribute(ac, 'online', '1')
self.start_daemon()
self.assertEqual(self.get_dbus_property('OnBattery'), False)
self.assertEqual(self.get_dbus_property('OnLowBattery'), False)
@ -401,15 +357,15 @@ class Tests(unittest.TestCase):
energy_* is in uWh, while charge_* is in uAh.
'''
bat0 = self.add_device('power_supply', 'BAT0',
{'type': 'Battery',
'present': '1',
'status': 'Discharging',
'charge_full': '10500000',
'charge_full_design': '11000000',
'charge_now': '7875000',
'current_now': '787000',
'voltage_now': '12000000'})
bat0 = self.testbed.add_device('power_supply', 'BAT0', None,
['type', 'Battery',
'present', '1',
'status', 'Discharging',
'charge_full', '10500000',
'charge_full_design', '11000000',
'charge_now', '7875000',
'current_now', '787000',
'voltage_now', '12000000'], [])
self.start_daemon()
devs = self.proxy.EnumerateDevices()
@ -431,14 +387,14 @@ class Tests(unittest.TestCase):
def test_battery_energy_charge_mixed(self):
'''battery which reports current energy, but full charge'''
bat0 = self.add_device('power_supply', 'BAT0',
{'type': 'Battery',
'present': '1',
'status': 'Discharging',
'charge_full': '10500000',
'charge_full_design': '11000000',
'energy_now': '50400000',
'voltage_now': '12000000'})
bat0 = self.testbed.add_device('power_supply', 'BAT0', None,
['type', 'Battery',
'present', '1',
'status', 'Discharging',
'charge_full', '10500000',
'charge_full_design', '11000000',
'energy_now', '50400000',
'voltage_now', '12000000'], [])
self.start_daemon()
devs = self.proxy.EnumerateDevices()
@ -461,12 +417,12 @@ class Tests(unittest.TestCase):
'''UPS properties with and without AC'''
# add a charging UPS
ups0 = self.add_device('usb', 'hiddev0', {},
{'DEVNAME': 'null', 'UPOWER_VENDOR': 'APC',
'UPOWER_BATTERY_TYPE': 'ups',
'UPOWER_FAKE_DEVICE': '1',
'UPOWER_FAKE_HID_CHARGING': '1',
'UPOWER_FAKE_HID_PERCENTAGE': '70'})
ups0 = self.testbed.add_device('usb', 'hiddev0', None, [],
['DEVNAME', 'null', 'UPOWER_VENDOR', 'APC',
'UPOWER_BATTERY_TYPE', 'ups',
'UPOWER_FAKE_DEVICE', '1',
'UPOWER_FAKE_HID_CHARGING', '1',
'UPOWER_FAKE_HID_PERCENTAGE', '70'])
self.start_daemon()
devs = self.proxy.EnumerateDevices()
@ -482,7 +438,7 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# now switch to discharging UPS
self.set_sys_property(ups0, 'UPOWER_FAKE_HID_CHARGING', '0')
self.testbed.set_property(ups0, 'UPOWER_FAKE_HID_CHARGING', '0')
self.start_daemon()
devs = self.proxy.EnumerateDevices()
@ -497,7 +453,7 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# low UPS charge
self.set_sys_property(ups0, 'UPOWER_FAKE_HID_PERCENTAGE', '2')
self.testbed.set_property(ups0, 'UPOWER_FAKE_HID_PERCENTAGE', '2')
self.start_daemon()
self.assertEqual(self.get_dbus_dev_property(ups0_up, 'Percentage'), 2.0)
self.assertEqual(self.get_dbus_dev_property(ups0_up, 'State'), UP_DEVICE_STATE_DISCHARGING)
@ -506,8 +462,8 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# now add an offline AC, should still be on battery
ac = self.add_device('power_supply', 'AC',
{'type': 'Mains', 'online': '0' })
ac = self.testbed.add_device('power_supply', 'AC', None,
['type', 'Mains', 'online', '0'], [])
self.start_daemon()
devs = self.proxy.EnumerateDevices()
self.assertEqual(len(devs), 2)
@ -523,7 +479,7 @@ class Tests(unittest.TestCase):
self.stop_daemon()
# now plug in the AC, should switch to OnBattery=False
self.set_sys_attribute(ac, 'online', '1')
self.testbed.set_attribute(ac, 'online', '1')
self.start_daemon()
self.assertEqual(self.get_dbus_property('OnBattery'), False)
self.assertEqual(self.get_dbus_property('OnLowBattery'), False)