resource: Support waiting for reserved resources until available
Before this patch, almost everything was in place to support concurrent
osmo-gsm-tester instances sharing a common state dir. However, during
resource reservation, if the reservation couldn't be done due to too
many resources being in use, osmo-gsm-tester would fail and skip the
test suite.
With this patch, OGT will wait until some reserved resources are
released and then try requesting the reservation again.
Change-Id: I938602ee890712fda82fd3f812d8edb1bcd05e08
diff --git a/src/osmo_gsm_tester/core/util.py b/src/osmo_gsm_tester/core/util.py
index e035a72..691b489 100644
--- a/src/osmo_gsm_tester/core/util.py
+++ b/src/osmo_gsm_tester/core/util.py
@@ -28,6 +28,8 @@
import threading
import importlib.util
import subprocess
+from watchdog.observers import Observer
+from watchdog.events import FileSystemEventHandler
# This mirrors enum osmo_auth_algo in libosmocore/include/osmocom/crypt/auth.h
# so that the index within the tuple matches the enum value.
@@ -302,6 +304,51 @@
def __repr__(self):
return self.path
+class FileWatch(FileSystemEventHandler):
+ def __init__(self, origin, watch_path, event_func):
+ FileSystemEventHandler.__init__(self)
+ self.origin = origin
+ self.watch_path = watch_path
+ self.event_func = event_func
+ self.observer = Observer()
+ self.watch = None
+ self.mutex = threading.Lock()
+
+ def get_lock(self):
+ return self.mutex
+
+ def start(self):
+ dir = os.path.abspath(os.path.dirname(self.watch_path))
+ self.origin.dbg('FileWatch: scheduling watch for directory %s' % dir)
+ self.watch = self.observer.schedule(self, dir, recursive = False)
+ self.observer.start()
+
+ def stop(self):
+ if self.watch:
+ self.origin.dbg('FileWatch: unscheduling watch %r' % self.watch)
+ self.observer.unschedule(self.watch)
+ self.watch = None
+ if self.observer.is_alive():
+ self.observer.stop()
+ self.observer.join()
+
+ def __del__(self):
+ self.stop()
+ self.observer = None
+
+ # Override from FileSystemEventHandler
+ def on_any_event(self, event):
+ if event.is_directory:
+ return None
+ if os.path.abspath(event.src_path) != os.path.abspath(self.watch_path):
+ return None
+ self.origin.dbg('FileWatch: received event %r' % event)
+ try:
+ self.mutex.acquire()
+ self.event_func(event)
+ finally:
+ self.mutex.release()
+
def touch_file(path):
with open(path, 'a') as f:
f.close()