From 93f4c4bd6b7e2299f39b984c2759a052251c3460 Mon Sep 17 00:00:00 2001 From: Damien Nozay Date: Mon, 16 Nov 2020 08:13:33 -0800 Subject: [PATCH] make time measurements monotonic - `time.time()` is the system time. "it's great" (tm) however it is not reliable for measuring time spent. it gives you the "current" time, but oh... time can move backwards (thanks NTP). - `time.monotonic()` is a monotonic time source. "it's great" (tm) it only goes forward, making measurements a peach. however it cannot be used as a reference point. --- xmlrunner/builder.py | 11 ++++++++--- xmlrunner/runner.py | 4 ++-- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/xmlrunner/builder.py b/xmlrunner/builder.py index 50c469a..3eff61d 100644 --- a/xmlrunner/builder.py +++ b/xmlrunner/builder.py @@ -58,7 +58,9 @@ def __init__(self, xml_doc, parent_context=None): """ self.xml_doc = xml_doc self.parent = parent_context - self._start_time = self._stop_time = 0 + self._start_time_m = 0 + self._stop_time_m = 0 + self._stop_time = 0 self.counters = {} def element_tag(self): @@ -72,12 +74,15 @@ def begin(self, tag, name): """ self.element = self.xml_doc.createElement(tag) self.element.setAttribute('name', replace_nontext(name)) - self._start_time = time.time() + self._start_time = time.monotonic() def end(self): """Closes this context (started with a call to `begin`) and creates an attribute for each counter and another for the elapsed time. """ + # time.monotonic is reliable for measuring differences, not affected by NTP + self._stop_time_m = time.monotonic() + # time.time is used for reference point self._stop_time = time.time() self.element.setAttribute('time', self.elapsed_time()) self.element.setAttribute('timestamp', self.timestamp()) @@ -120,7 +125,7 @@ def elapsed_time(self): """Returns the time the context took to run between the calls to `begin()` and `end()`, in seconds. """ - return format(self._stop_time - self._start_time, '.3f') + return format(self._stop_time_m - self._start_time_m, '.3f') def timestamp(self): """Returns the time the context ended as ISO-8601-formatted timestamp. diff --git a/xmlrunner/runner.py b/xmlrunner/runner.py index 538f187..dec0a66 100644 --- a/xmlrunner/runner.py +++ b/xmlrunner/runner.py @@ -62,9 +62,9 @@ def run(self, test): self.stream.writeln(result.separator2) # Execute tests - start_time = time.time() + start_time = time.monotonic() test(result) - stop_time = time.time() + stop_time = time.monotonic() time_taken = stop_time - start_time # Print results