mirror of
https://github.com/GothenburgBitFactory/taskwarrior.git
synced 2025-06-26 10:54:26 +02:00
Tests - Default to having Python objects as "hook log"
This commit is contained in:
parent
80c01f3ffb
commit
1bd26fe9ab
1 changed files with 36 additions and 56 deletions
|
@ -368,8 +368,30 @@ class LoggedHook(Hook):
|
|||
# Cache is up to date
|
||||
return True
|
||||
|
||||
def _parse_log(self):
|
||||
"""Parse the logs generated by the hook
|
||||
def enable(self):
|
||||
"""Make hookfile executable to allow triggering
|
||||
"""
|
||||
super(LoggedHook, self).enable()
|
||||
os.chmod(self.wrappedfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
|
||||
|
||||
def disable(self):
|
||||
"""Remove hookfile executable bit to deny triggering
|
||||
"""
|
||||
super(LoggedHook, self).disable()
|
||||
os.chmod(self.wrappedfile, stat.S_IREAD | stat.S_IWRITE)
|
||||
|
||||
def is_active(self):
|
||||
"""Check if hook is active by verifying the execute bit
|
||||
"""
|
||||
parent_is_active = super(LoggedHook, self).disable()
|
||||
return parent_is_active and os.access(self.wrappedfile, os.X_OK)
|
||||
|
||||
def get_logs(self):
|
||||
"""Parse the logs generated by the hook and return a dictionary
|
||||
containing the logs collected with the wrapper in a python friendly
|
||||
format:
|
||||
* JSON is parsed as python dictionaries
|
||||
* timestamps are parsed as datetime objects
|
||||
|
||||
It should look something like this:
|
||||
|
||||
|
@ -404,9 +426,13 @@ class LoggedHook(Hook):
|
|||
if line.startswith("%"):
|
||||
# Timestamp includes nanosecond resolution
|
||||
timestamp = line.split(" ")[-1]
|
||||
log["calls"].append(timestamp)
|
||||
# convert timestamp to python datetime object
|
||||
log["calls"].append(
|
||||
datetime.fromtimestamp(float(timestamp))
|
||||
)
|
||||
elif line.startswith("{"):
|
||||
log["input"]["json"].append(line)
|
||||
# Decode json input (to hook)
|
||||
log["input"]["json"].append(json_decoder(line))
|
||||
else:
|
||||
raise IOError("Unexpected content on STDIN line {0}: {1}"
|
||||
.format(i, line))
|
||||
|
@ -418,10 +444,13 @@ class LoggedHook(Hook):
|
|||
exitcode = int(line.split(" ")[-1])
|
||||
log["exitcode"] = exitcode
|
||||
elif line.startswith("{"):
|
||||
log["output"]["json"].append(line)
|
||||
# Decode json output (from hook)
|
||||
log["output"]["json"].append(json_decoder(line))
|
||||
else:
|
||||
log["output"]["msgs"].append(line)
|
||||
|
||||
# NOTE convert all lists to tuples to prevent tampering?
|
||||
|
||||
self._cache["log"] = log
|
||||
|
||||
# Update last modification timestamp in cache
|
||||
|
@ -429,60 +458,11 @@ class LoggedHook(Hook):
|
|||
|
||||
return self._cache["log"]
|
||||
|
||||
def enable(self):
|
||||
"""Make hookfile executable to allow triggering
|
||||
"""
|
||||
super(LoggedHook, self).enable()
|
||||
os.chmod(self.wrappedfile, stat.S_IREAD | stat.S_IWRITE | stat.S_IEXEC)
|
||||
|
||||
def disable(self):
|
||||
"""Remove hookfile executable bit to deny triggering
|
||||
"""
|
||||
super(LoggedHook, self).disable()
|
||||
os.chmod(self.wrappedfile, stat.S_IREAD | stat.S_IWRITE)
|
||||
|
||||
def is_active(self):
|
||||
"""Check if hook is active by verifying the execute bit
|
||||
"""
|
||||
parent_is_active = super(LoggedHook, self).disable()
|
||||
return parent_is_active and os.access(self.wrappedfile, os.X_OK)
|
||||
|
||||
def get_logs(self):
|
||||
"""Return a dictionary containing the logs collected with the wrapper
|
||||
in a python friendly format:
|
||||
* JSON is parsed as python dictionaries
|
||||
* timestamps are parsed as datetime objects
|
||||
"""
|
||||
log = self._parse_log()
|
||||
newlog = {}
|
||||
|
||||
for k1 in log:
|
||||
# Timestamps
|
||||
if k1 == "calls":
|
||||
timestamp = lambda x: datetime.fromtimestamp(float(x))
|
||||
newlog[k1] = map(timestamp, log[k1])
|
||||
|
||||
elif k1 in ("input", "output"):
|
||||
newlog[k1] = {}
|
||||
|
||||
for k2 in log[k1]:
|
||||
if k2 == "json":
|
||||
# JSON replies
|
||||
newlog[k1][k2] = map(json_decoder, log[k1][k2])
|
||||
else:
|
||||
# Messages and future fields
|
||||
newlog[k1][k2] = deepcopy(log[k1][k2])
|
||||
else:
|
||||
# exitcode and future fields
|
||||
newlog[k1] = deepcopy(log[k1])
|
||||
|
||||
return newlog
|
||||
|
||||
def assertTriggeredCount(self, count):
|
||||
"""Check if current hook file was triggered/used by taskwarrior and
|
||||
how many times.
|
||||
"""
|
||||
log = self._parse_log()
|
||||
log = self.get_logs()
|
||||
|
||||
assert len(log["calls"]) == count, ("{0} calls expected for {1} but "
|
||||
"found {2}".format(
|
||||
|
@ -494,7 +474,7 @@ class LoggedHook(Hook):
|
|||
def assertExitcode(self, exitcode):
|
||||
"""Check if current hook finished with the expected exit code
|
||||
"""
|
||||
log = self._parse_log()
|
||||
log = self.get_logs()
|
||||
|
||||
assert log["exitcode"] == exitcode, ("Expected exit code {0} for {1} "
|
||||
"but found {2}".format(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue