From eac71fc1109f2edc6b71e62a6cff38d762bebe63 Mon Sep 17 00:00:00 2001 From: "Chris St. Pierre" Date: Tue, 25 Sep 2012 11:49:15 -0400 Subject: expanded pylint coverage --- src/lib/Bcfg2/Server/FileMonitor/Fam.py | 31 ++++++++++--------- src/lib/Bcfg2/Server/FileMonitor/Gamin.py | 4 +-- src/lib/Bcfg2/Server/FileMonitor/Inotify.py | 39 ++++++++++++------------ src/lib/Bcfg2/Server/FileMonitor/Pseudo.py | 11 +++---- src/lib/Bcfg2/Server/FileMonitor/__init__.py | 45 ++++++++++++++++++---------- 5 files changed, 73 insertions(+), 57 deletions(-) (limited to 'src/lib/Bcfg2/Server/FileMonitor') diff --git a/src/lib/Bcfg2/Server/FileMonitor/Fam.py b/src/lib/Bcfg2/Server/FileMonitor/Fam.py index aef74add4..9c6031be9 100644 --- a/src/lib/Bcfg2/Server/FileMonitor/Fam.py +++ b/src/lib/Bcfg2/Server/FileMonitor/Fam.py @@ -7,21 +7,24 @@ import logging from time import time from Bcfg2.Server.FileMonitor import FileMonitor -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) + class Fam(FileMonitor): + """ file monitor with support for FAM """ + __priority__ = 90 def __init__(self, ignore=None, debug=False): FileMonitor.__init__(self, ignore=ignore, debug=debug) - self.fm = _fam.open() + self.filemonitor = _fam.open() self.users = {} def fileno(self): """Return fam file handle number.""" - return self.fm.fileno() + return self.filemonitor.fileno() - def handle_event_set(self, _): + def handle_event_set(self, _=None): self.Service() def handle_events_in_interval(self, interval): @@ -30,13 +33,13 @@ class Fam(FileMonitor): if self.Service(): now = time() - def AddMonitor(self, path, obj): + def AddMonitor(self, path, obj, _=None): """Add a monitor to path, installing a callback to obj.HandleEvent.""" mode = os.stat(path)[stat.ST_MODE] if stat.S_ISDIR(mode): - handle = self.fm.monitorDirectory(path, None) + handle = self.filemonitor.monitorDirectory(path, None) else: - handle = self.fm.monitorFile(path, None) + handle = self.filemonitor.monitorFile(path, None) self.handles[handle.requestID()] = handle if obj != None: self.users[handle.requestID()] = obj @@ -50,10 +53,10 @@ class Fam(FileMonitor): start = time() now = time() while (time() - now) < interval: - if self.fm.pending(): - while self.fm.pending(): + if self.filemonitor.pending(): + while self.filemonitor.pending(): count += 1 - rawevents.append(self.fm.nextEvent()) + rawevents.append(self.filemonitor.nextEvent()) now = time() unique = [] bookkeeping = [] @@ -73,10 +76,10 @@ class Fam(FileMonitor): if event.requestID in self.users: try: self.users[event.requestID].HandleEvent(event) - except: - logger.error("Handling event for file %s" % event.filename, + except: # pylint: disable=W0702 + LOGGER.error("Handling event for file %s" % event.filename, exc_info=1) end = time() - logger.info("Processed %s fam events in %03.03f seconds. %s coalesced" % - (count, (end - start), collapsed)) + LOGGER.info("Processed %s fam events in %03.03f seconds. " + "%s coalesced" % (count, (end - start), collapsed)) return count diff --git a/src/lib/Bcfg2/Server/FileMonitor/Gamin.py b/src/lib/Bcfg2/Server/FileMonitor/Gamin.py index 9d4330e89..d0ba59cd8 100644 --- a/src/lib/Bcfg2/Server/FileMonitor/Gamin.py +++ b/src/lib/Bcfg2/Server/FileMonitor/Gamin.py @@ -2,15 +2,12 @@ import os import stat -import logging # pylint: disable=F0401 from gamin import WatchMonitor, GAMCreated, GAMExists, GAMEndExist, \ GAMChanged, GAMDeleted # pylint: enable=F0401 from Bcfg2.Server.FileMonitor import Event, FileMonitor -logger = logging.getLogger(__name__) - class GaminEvent(Event): """ @@ -28,6 +25,7 @@ class GaminEvent(Event): class Gamin(FileMonitor): + """ file monitor with gamin support """ __priority__ = 10 def __init__(self, ignore=None, debug=False): diff --git a/src/lib/Bcfg2/Server/FileMonitor/Inotify.py b/src/lib/Bcfg2/Server/FileMonitor/Inotify.py index 75eff3bc5..5a8a1e1c6 100644 --- a/src/lib/Bcfg2/Server/FileMonitor/Inotify.py +++ b/src/lib/Bcfg2/Server/FileMonitor/Inotify.py @@ -1,17 +1,18 @@ """ Inotify driver for file alteration events """ import os -import sys import logging import pyinotify # pylint: disable=F0401 -from Bcfg2.Compat import reduce +from Bcfg2.Compat import reduce # pylint: disable=W0622 from Bcfg2.Server.FileMonitor import Event from Bcfg2.Server.FileMonitor.Pseudo import Pseudo -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) class Inotify(Pseudo, pyinotify.ProcessEvent): + """ file monitor with inotify support """ + __priority__ = 1 # pylint: disable=E1101 action_map = {pyinotify.IN_CREATE: 'created', @@ -24,18 +25,18 @@ class Inotify(Pseudo, pyinotify.ProcessEvent): def __init__(self, ignore=None, debug=False): Pseudo.__init__(self, ignore=ignore, debug=debug) - pyinotify.ProcessEvent(self) + pyinotify.ProcessEvent.__init__(self) self.event_filter = dict() self.watches_by_path = dict() # these are created in start() after the server is done forking self.notifier = None - self.wm = None + self.watchmgr = None self.add_q = [] def start(self): Pseudo.start(self) - self.wm = pyinotify.WatchManager() - self.notifier = pyinotify.ThreadedNotifier(self.wm, self) + self.watchmgr = pyinotify.WatchManager() + self.notifier = pyinotify.ThreadedNotifier(self.watchmgr, self) self.notifier.start() for monitor in self.add_q: self.AddMonitor(*monitor) @@ -43,7 +44,7 @@ class Inotify(Pseudo, pyinotify.ProcessEvent): def fileno(self): if self.started: - return self.wm.get_fd() + return self.watchmgr.get_fd() else: return None @@ -54,9 +55,9 @@ class Inotify(Pseudo, pyinotify.ProcessEvent): action = aname break try: - watch = self.wm.watches[ievent.wd] + watch = self.watchmgr.watches[ievent.wd] except KeyError: - logger.error("Error handling event for %s: Watch %s not found" % + LOGGER.error("Error handling event for %s: Watch %s not found" % (ievent.pathname, ievent.wd)) return # FAM-style file monitors return the full path to the parent @@ -87,7 +88,7 @@ class Inotify(Pseudo, pyinotify.ProcessEvent): ievent.pathname in self.event_filter[ievent.wd]): self.events.append(evt) - def AddMonitor(self, path, obj): + def AddMonitor(self, path, obj, handleID=None): # strip trailing slashes path = path.rstrip("/") @@ -116,18 +117,18 @@ class Inotify(Pseudo, pyinotify.ProcessEvent): # see if this path is already being watched try: - wd = self.watches_by_path[watch_path] + watchdir = self.watches_by_path[watch_path] except KeyError: - wd = self.wm.add_watch(watch_path, self.mask, - quiet=False)[watch_path] - self.watches_by_path[watch_path] = wd + watchdir = self.watchmgr.add_watch(watch_path, self.mask, + quiet=False)[watch_path] + self.watches_by_path[watch_path] = watchdir produce_exists = True if not is_dir: - if wd not in self.event_filter: - self.event_filter[wd] = [path] - elif path not in self.event_filter[wd]: - self.event_filter[wd].append(path) + if watchdir not in self.event_filter: + self.event_filter[watchdir] = [path] + elif path not in self.event_filter[watchdir]: + self.event_filter[watchdir].append(path) else: # we've been asked to watch a file that we're already # watching, so we don't need to produce 'exists' diff --git a/src/lib/Bcfg2/Server/FileMonitor/Pseudo.py b/src/lib/Bcfg2/Server/FileMonitor/Pseudo.py index 089d4cf0f..9062cbfd8 100644 --- a/src/lib/Bcfg2/Server/FileMonitor/Pseudo.py +++ b/src/lib/Bcfg2/Server/FileMonitor/Pseudo.py @@ -1,12 +1,13 @@ """ Pseudo provides static monitor support for file alteration events """ import os -import logging from Bcfg2.Server.FileMonitor import FileMonitor, Event -logger = logging.getLogger(__name__) class Pseudo(FileMonitor): + """ file monitor that only produces events on server startup and + doesn't actually monitor at all """ + __priority__ = 99 def AddMonitor(self, path, obj, handleID=None): @@ -15,9 +16,9 @@ class Pseudo(FileMonitor): handleID = len(list(self.handles.keys())) self.events.append(Event(handleID, path, 'exists')) if os.path.isdir(path): - dirList = os.listdir(path) - for includedFile in dirList: - self.events.append(Event(handleID, includedFile, 'exists')) + dirlist = os.listdir(path) + for fname in dirlist: + self.events.append(Event(handleID, fname, 'exists')) self.events.append(Event(handleID, path, 'endExist')) if obj != None: diff --git a/src/lib/Bcfg2/Server/FileMonitor/__init__.py b/src/lib/Bcfg2/Server/FileMonitor/__init__.py index fd0cb66f1..1b12ab703 100644 --- a/src/lib/Bcfg2/Server/FileMonitor/__init__.py +++ b/src/lib/Bcfg2/Server/FileMonitor/__init__.py @@ -4,12 +4,13 @@ import os import sys import fnmatch import logging -import pkgutil from time import sleep, time -logger = logging.getLogger(__name__) +LOGGER = logging.getLogger(__name__) + class Event(object): + """ Base class for all FAM events """ def __init__(self, request_id, filename, code): self.requestID = request_id self.filename = filename @@ -53,33 +54,40 @@ class FileMonitor(object): self.started = True def debug_log(self, msg): + """ log a debug message """ if self.debug: - logger.info(msg) + LOGGER.info(msg) def should_ignore(self, event): + """ returns true if an event should be ignored """ for pattern in self.ignore: - if (fnmatch.fnmatch(event.filename, pattern) or + if (fnmatch.fnmatch(event.filename, pattern) or fnmatch.fnmatch(os.path.split(event.filename)[-1], pattern)): self.debug_log("Ignoring %s" % event) return True return False def pending(self): + """ returns True if there are pending events """ return bool(self.events) def get_event(self): + """ get the oldest pending event """ return self.events.pop(0) def fileno(self): + """ get the file descriptor of the file monitor thread """ return 0 def handle_one_event(self, event): + """ handle the given event by dispatching it to the object + that handles events for the path """ if not self.started: self.start() if self.should_ignore(event): return if event.requestID not in self.handles: - logger.info("Got event for unexpected id %s, file %s" % + LOGGER.info("Got event for unexpected id %s, file %s" % (event.requestID, event.filename)) return self.debug_log("Dispatching event %s %s to obj %s" % @@ -87,12 +95,13 @@ class FileMonitor(object): self.handles[event.requestID])) try: self.handles[event.requestID].HandleEvent(event) - except: + except: # pylint: disable=W0702 err = sys.exc_info()[1] - logger.error("Error in handling of event %s for %s: %s" % + LOGGER.error("Error in handling of event %s for %s: %s" % (event.code2str(), event.filename, err)) def handle_event_set(self, lock=None): + """ Handle all pending events """ if not self.started: self.start() count = 1 @@ -100,19 +109,18 @@ class FileMonitor(object): start = time() if lock: lock.acquire() - try: - self.handle_one_event(event) - while self.pending(): - self.handle_one_event(self.get_event()) - count += 1 - except: - pass + self.handle_one_event(event) + while self.pending(): + self.handle_one_event(self.get_event()) + count += 1 if lock: lock.release() end = time() - logger.info("Handled %d events in %.03fs" % (count, (end - start))) + LOGGER.info("Handled %d events in %.03fs" % (count, (end - start))) def handle_events_in_interval(self, interval): + """ handle events for the specified period of time (in + seconds) """ if not self.started: self.start() end = time() + interval @@ -124,10 +132,15 @@ class FileMonitor(object): sleep(0.5) def shutdown(self): + """ shutdown the monitor """ self.started = False + def AddMonitor(self, path, obj, handleID=None): + """ watch the specified path, alerting obj to events """ + raise NotImplementedError + -available = dict() +available = dict() # pylint: disable=C0103 # todo: loading the monitor drivers should be automatic from Bcfg2.Server.FileMonitor.Pseudo import Pseudo -- cgit v1.2.3-1-g7c22