3
0
mirror of https://git.kernel.org/pub/scm/network/wireless/iwd.git synced 2024-11-25 17:59:25 +01:00

auto-t: iwd.py: update to work with test-runner rewrite

iwd.py was updated to use the TestContext APIs to start/stop
IWD. This makes the process managment consistent between starting
IWD from test-runner or from the IWD() constructor.

The psk agent is now tracked, and destroyed upon __del__. This is
to fix issues where a test throws an exception and never
unregisters the agent, causing future tests to fail.

The configuration directory was also chaged to /tmp by
default. This was done since all tests which used this used /tmp
anyways.

The GLib mainloop was removed, and instead put into test-runner
itself. Now any mainloop operations can use ctx.mainloop instead
This commit is contained in:
James Prestwood 2020-09-10 16:12:27 -07:00 committed by Denis Kenzior
parent ad97dbee08
commit 91adbcb7f4

View File

@ -15,7 +15,7 @@ import weakref
from abc import ABCMeta, abstractmethod from abc import ABCMeta, abstractmethod
from enum import Enum from enum import Enum
import wiphy from config import ctx
IWD_STORAGE_DIR = '/var/lib/iwd' IWD_STORAGE_DIR = '/var/lib/iwd'
IWD_CONFIG_DIR = '/etc/iwd' IWD_CONFIG_DIR = '/etc/iwd'
@ -39,10 +39,6 @@ IWD_STATION_INTERFACE = 'net.connman.iwd.Station'
IWD_AGENT_MANAGER_PATH = '/net/connman/iwd' IWD_AGENT_MANAGER_PATH = '/net/connman/iwd'
IWD_TOP_LEVEL_PATH = '/' IWD_TOP_LEVEL_PATH = '/'
dbus.mainloop.glib.DBusGMainLoop(set_as_default=True)
class UnknownDBusEx(Exception): pass class UnknownDBusEx(Exception): pass
class InProgressEx(dbus.DBusException): pass class InProgressEx(dbus.DBusException): pass
class FailedEx(dbus.DBusException): pass class FailedEx(dbus.DBusException): pass
@ -108,7 +104,7 @@ class AsyncOpAbstract(object):
self._exception = _convert_dbus_ex(ex) self._exception = _convert_dbus_ex(ex)
def _wait_for_async_op(self): def _wait_for_async_op(self):
context = mainloop.get_context() context = ctx.mainloop.get_context()
while not self._is_completed: while not self._is_completed:
context.iteration(may_block=True) context.iteration(may_block=True)
@ -533,8 +529,8 @@ class Device(IWDDBusAbstract):
if addr not in props['ConnectedPeers']: if addr not in props['ConnectedPeers']:
return return
GLib.timeout_add(int(30 * 1000), wait_timeout_cb) GLib.timeout_add(int(50 * 1000), wait_timeout_cb)
context = mainloop.get_context() context = ctx.mainloop.get_context()
while not self._adhoc_prop_found: while not self._adhoc_prop_found:
context.iteration(may_block=True) context.iteration(may_block=True)
if self._adhoc_timed_out: if self._adhoc_timed_out:
@ -561,8 +557,8 @@ class Device(IWDDBusAbstract):
if addr in props['ConnectedPeers']: if addr in props['ConnectedPeers']:
return return
GLib.timeout_add(int(15 * 1000), wait_timeout_cb) GLib.timeout_add(int(50 * 1000), wait_timeout_cb)
context = mainloop.get_context() context = ctx.mainloop.get_context()
while not self._adhoc_prop_found: while not self._adhoc_prop_found:
context.iteration(may_block=True) context.iteration(may_block=True)
if self._adhoc_timed_out: if self._adhoc_timed_out:
@ -873,7 +869,11 @@ class DeviceList(collections.Mapping):
class IWD(AsyncOpAbstract): class IWD(AsyncOpAbstract):
'''''' '''
Start an IWD instance. By default IWD should already be running, but
some tests do require starting IWD using this constructor (by passing
start_iwd_daemon=True)
'''
_bus = dbus.SystemBus() _bus = dbus.SystemBus()
_object_manager_if = None _object_manager_if = None
@ -881,41 +881,22 @@ class IWD(AsyncOpAbstract):
_iwd_proc = None _iwd_proc = None
_devices = None _devices = None
_instance = None _instance = None
psk_agent = None
def __init__(self, start_iwd_daemon = False, def __init__(self, start_iwd_daemon = False, iwd_config_dir = '/tmp'):
iwd_config_dir = IWD_CONFIG_DIR): if start_iwd_daemon and ctx.is_process_running('iwd'):
global mainloop raise Exception("IWD requested to start but is already running")
mainloop = GLib.MainLoop()
if start_iwd_daemon: if start_iwd_daemon:
args = [] self._iwd_proc = ctx.start_iwd(iwd_config_dir)
iwd_wiphys = [wname for wname, wiphy in wiphy.wiphy_map.items()
if wiphy.use == 'iwd']
whitelist = ','.join(iwd_wiphys)
if os.environ.get('IWD_TEST_VALGRIND', None) == 'on':
args.append('valgrind')
args.append('--leak-check=full')
args.append('--log-file=/tmp/valgrind.log')
os.environ["CONFIGURATION_DIRECTORY"] = iwd_config_dir;
args.append('iwd')
args.append('-p')
args.append(whitelist)
args.append('-d')
import subprocess
iwd_proc = subprocess.Popen(args)
self._iwd_proc = iwd_proc
tries = 0 tries = 0
while not self._bus.name_has_owner(IWD_SERVICE): while not self._bus.name_has_owner(IWD_SERVICE):
if os.environ['IWD_TEST_TIMEOUTS'] == 'on': if ctx.args.gdb == 'None':
if tries > 100: if tries > 100:
if start_iwd_daemon: if start_iwd_daemon:
iwd_proc.terminate() ctx.stop_process(self._iwd_proc)
self._iwd_proc = None
raise TimeoutError('IWD has failed to start') raise TimeoutError('IWD has failed to start')
tries += 1 tries += 1
time.sleep(0.1) time.sleep(0.1)
@ -927,20 +908,17 @@ class IWD(AsyncOpAbstract):
IWD._instance = weakref.ref(self) IWD._instance = weakref.ref(self)
def __del__(self): def __del__(self):
if self._iwd_proc is None: if self.psk_agent:
return self.unregister_psk_agent(self.psk_agent)
self._object_manager_if = None self._object_manager_if = None
self._agent_manager_if = None self._agent_manager_if = None
self._known_networks = None self._known_networks = None
self._devices = None self._devices = None
self._iwd_proc.terminate() if self._iwd_proc is not None:
self._iwd_proc.wait() ctx.stop_process(self._iwd_proc)
self._iwd_proc = None
self._iwd_proc = None
del os.environ["CONFIGURATION_DIRECTORY"]
@property @property
def _object_manager(self): def _object_manager(self):
@ -966,15 +944,18 @@ class IWD(AsyncOpAbstract):
self._wait_timed_out = True self._wait_timed_out = True
return False return False
timeout = GLib.timeout_add_seconds(max_wait, wait_timeout_cb) try:
context = mainloop.get_context() timeout = GLib.timeout_add_seconds(max_wait, wait_timeout_cb)
while not eval(condition_str): context = ctx.mainloop.get_context()
context.iteration(may_block=True) while not eval(condition_str):
if self._wait_timed_out and os.environ['IWD_TEST_TIMEOUTS'] == 'on': context.iteration(may_block=True)
raise TimeoutError('[' + condition_str + ']'\ if self._wait_timed_out and ctx.args.gdb == None:
' condition was not met in '\ raise TimeoutError('[' + condition_str + ']'\
+ str(max_wait) + ' sec') ' condition was not met in '\
GLib.source_remove(timeout) + str(max_wait) + ' sec')
finally:
if not self._wait_timed_out:
GLib.source_remove(timeout)
def wait(self, time): def wait(self, time):
self._wait_timed_out = False self._wait_timed_out = False
@ -982,10 +963,14 @@ class IWD(AsyncOpAbstract):
self._wait_timed_out = True self._wait_timed_out = True
return False return False
GLib.timeout_add(int(time * 1000), wait_timeout_cb) try:
context = mainloop.get_context() timeout = GLib.timeout_add(int(time * 1000), wait_timeout_cb)
while not self._wait_timed_out: context = ctx.mainloop.get_context()
context.iteration(may_block=True) while not self._wait_timed_out:
context.iteration(may_block=True)
finally:
if not self._wait_timed_out:
GLib.source_remove(timeout)
@staticmethod @staticmethod
def clear_storage(): def clear_storage():
@ -1031,14 +1016,16 @@ class IWD(AsyncOpAbstract):
self._wait_timed_out = True self._wait_timed_out = True
return False return False
timeout = GLib.timeout_add_seconds(max_wait, wait_timeout_cb) try:
context = mainloop.get_context() timeout = GLib.timeout_add_seconds(max_wait, wait_timeout_cb)
while len(self._devices) < wait_to_appear: context = ctx.mainloop.get_context()
context.iteration(may_block=True) while len(self._devices) < wait_to_appear:
if self._wait_timed_out: context.iteration(may_block=True)
raise TimeoutError('IWD has no associated devices') if self._wait_timed_out:
raise TimeoutError('IWD has no associated devices')
GLib.source_remove(timeout) finally:
if not self._wait_timed_out:
GLib.source_remove(timeout)
return list(self._devices.values()) return list(self._devices.values())
@ -1062,6 +1049,7 @@ class IWD(AsyncOpAbstract):
reply_handler=self._success, reply_handler=self._success,
error_handler=self._failure) error_handler=self._failure)
self._wait_for_async_op() self._wait_for_async_op()
self.psk_agent = psk_agent
def unregister_psk_agent(self, psk_agent): def unregister_psk_agent(self, psk_agent):
self._agent_manager.UnregisterAgent( self._agent_manager.UnregisterAgent(
@ -1070,6 +1058,7 @@ class IWD(AsyncOpAbstract):
reply_handler=self._success, reply_handler=self._success,
error_handler=self._failure) error_handler=self._failure)
self._wait_for_async_op() self._wait_for_async_op()
self.psk_agent = None
@staticmethod @staticmethod
def get_instance(): def get_instance():