From 1bd26fe9ab81f1a53d6516f9e755c62cdcba4550 Mon Sep 17 00:00:00 2001 From: Renato Alves Date: Sun, 15 Feb 2015 18:05:52 +0000 Subject: [PATCH] Tests - Default to having Python objects as "hook log" --- test/basetest/hooks.py | 92 +++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/test/basetest/hooks.py b/test/basetest/hooks.py index d97c3fc58..d8b7b3377 100644 --- a/test/basetest/hooks.py +++ b/test/basetest/hooks.py @@ -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(