[Git][NTPsec/ntpsec][master] Unit bug fixes
Gary E. Miller
gitlab at mg.gitlab.com
Thu Apr 13 16:48:37 UTC 2017
Gary E. Miller pushed to branch master at NTPsec / ntpsec
Commits:
609b1225 by Ian Bruene at 2017-04-13T16:47:45+00:00
Unit bug fixes
- - - - -
4 changed files:
- ntpclients/ntpmon
- ntpclients/ntpq
- pylib/util.py
- tests/pylib/test_util.py
Changes:
=====================================
ntpclients/ntpmon
=====================================
--- a/ntpclients/ntpmon
+++ b/ntpclients/ntpmon
@@ -103,21 +103,18 @@ def peer_detail(variables, showunits=False):
for name in ntp.util.MS_VARS:
if name in vcopy:
vcopy[name] = ntp.util.unitify(vcopyraw[name],
- ntp.util.UNITS_SEC,
ntp.util.UNIT_MS,
strip=True,
width=None)
for name in ntp.util.PPM_VARS:
if name in vcopy:
vcopy[name] = ntp.util.unitify(vcopyraw[name],
- ntp.util.UNITS_PPX,
ntp.util.UNIT_PPM,
strip=True,
width=None)
for name in ntp.util.S_VARS:
if name in vcopy:
vcopy[name] = ntp.util.unitify(vcopyraw[name],
- ntp.util.UNITS_SEC,
ntp.util.UNIT_S,
strip=True,
width=None)
=====================================
ntpclients/ntpq
=====================================
--- a/ntpclients/ntpq
+++ b/ntpclients/ntpq
@@ -228,7 +228,12 @@ Called when a line that starts with ! is entered in response to the prompt.
return
def say(self, msg):
- sys.stdout.write(polystr(msg))
+ try:
+ sys.stdout.write(polystr(msg))
+ except UnicodeEncodeError as e:
+ print("Unicode failure:", e)
+ print("msg:\n", repr(msg))
+ raise e
sys.stdout.flush() # In case we're piping the output
def warn(self, msg):
@@ -466,7 +471,9 @@ usage: timeout [ msec ]
def collect_display(self, associd, variables, decodestatus):
"Query and display a collection of variables from the system."
try:
- queried = self.session.readvar(associd, [v[0] for v in variables])
+ queried = self.session.readvar(associd,
+ [v[0] for v in variables],
+ raw=True)
except ntp.packet.ControlException as e:
if ntp.control.CERR_UNKNOWNVAR == e.errorcode:
self.warn("Unknown variable. Trying one at a time.\n")
@@ -477,7 +484,7 @@ usage: timeout [ msec ]
queried = self.session.readvar(associd, [var],
raw=True)
for (name, (value, rawvalue)) in queried.items():
- items.append((name, value))
+ items.append((name, (value, rawvalue)))
except ntp.packet.ControlException as e:
if ntp.control.CERR_UNKNOWNVAR == e.errorcode:
items.append((var, "???"))
@@ -505,7 +512,8 @@ usage: timeout [ msec ]
for (name, legend, fmt) in variables:
if name not in queried:
continue
- value = queried[name]
+ value = queried[name][0]
+ rawvalue = queried[name][1]
if fmt in (NTP_ADD, NTP_ADP):
if self.showhostnames:
if self.debug:
@@ -519,7 +527,12 @@ usage: timeout [ msec ]
if value:
self.say("%s %s\n" % (legend, value))
elif fmt in (NTP_UINT, NTP_INT, NTP_FLOAT):
- self.say("%s %s\n" % (legend, value))
+ if self.showunits:
+ displayvalue = ntp.util.unitifyvar(rawvalue, name,
+ strip=True)
+ else:
+ displayvalue = value
+ self.say("%s %s\n" % (legend, displayvalue))
elif fmt == NTP_LFP:
self.say("%s %s\n" % (legend, ntp.ntpc.prettydate(value)))
elif fmt == NTP_2BIT:
=====================================
pylib/util.py
=====================================
--- a/pylib/util.py
+++ b/pylib/util.py
@@ -33,21 +33,22 @@ OLD_CTL_PST_SEL_SYSPEER = 3
# Units for formatting
-UNIT_NS = 0
-UNIT_US = 1
-UNIT_MS = 2
-UNIT_S = 3
-UNIT_KS = 4
-UNITS_SEC = ["ns", u"\u03bcs", "ms", "s", "ks"]
-UNIT_PPT = 0
-UNIT_PPB = 1
-UNIT_PPM = 2
-UNIT_PPK = 3
-UNITS_PPX = ["ppt", "ppb", "ppm", "ppk"]
+UNIT_NS = "ns"
+UNIT_US = u"\u03bcs"
+UNIT_MS = "ms"
+UNIT_S = "s"
+UNIT_KS = "ks"
+UNITS_SEC = (UNIT_NS, UNIT_US, UNIT_MS, UNIT_S, UNIT_KS)
+UNIT_PPT = "ppt"
+UNIT_PPB = "ppb"
+UNIT_PPM = "ppm"
+UNIT_PPK = "ppk"
+UNITS_PPX = (UNIT_PPT, UNIT_PPB, UNIT_PPM, UNIT_PPK)
+unitgroups = (UNITS_SEC, UNITS_PPX)
# Variables that have units
-S_VARS = ("tai",)
+S_VARS = ("tai", "poll")
MS_VARS = ("rootdelay", "rootdisp", "offset", "sys_jitter", "clk_jitter",
"leapsmearoffset", "authdelay", "koffset", "kmaxerr", "kesterr",
"kprecis", "kppsjitter", "fuzz", "clk_wander_threshold", "tick",
@@ -111,7 +112,7 @@ def stringfiltcooker(data):
if count > highestcount:
mostcommon = key
highestcount = count
- newunit = UNITS_SEC[mostcommon + UNIT_MS]
+ newunit = UNITS_SEC[mostcommon + 2] # 2==UNIT_MS
# Shift all values to the new unit
cooked = []
for part in parts:
@@ -206,8 +207,21 @@ def formatdigitsplit(f, fieldsize, oomstobase):
return formatter
+def getunitgroup(unit):
+ for group in unitgroups:
+ if unit in group:
+ return group
+
+
def oomsbetweenunits(a, b):
- return abs((a - b) * 3)
+ group = getunitgroup(a)
+ if b is None: # asking for baseunit
+ return group.index(a)
+ elif b in group:
+ ia = group.index(a)
+ ib = group.index(b)
+ return abs((ia - ib) * 3)
+ return None
def breaknumberstring(value):
@@ -355,27 +369,55 @@ def isstringzero(value):
return True
-def unitify(value, unitgroup, startingunit, baseunit=0,
- strip=False, width=8):
+def unitrelativeto(unit, move):
+ "Returns a unit at a different scale from the input unit"
+ for group in unitgroups:
+ if unit in group:
+ if move is None: # asking for the base unit
+ return group[0]
+ else:
+ index = group.index(unit)
+ index += move # index of the new unit
+ if 0 <= index < len(group): # found the new unit
+ return group[index]
+ else: # not in range
+ return None
+ return None # couldn't find anything
+
+
+def unitifyvar(value, varname, baseunit=None, strip=False, width=8):
+ if varname in S_VARS:
+ start = UNIT_S
+ elif varname in MS_VARS:
+ start = UNIT_MS
+ elif varname in PPM_VARS:
+ start = UNIT_PPM
+ else:
+ return value
+ return unitify(value, start, baseunit, strip, width)
+
+
+def unitify(value, startingunit, baseunit=None, strip=False, width=8):
"Formats a numberstring with relevant units. Attemps to fit in width."
+ if baseunit is None:
+ baseunit = getunitgroup(startingunit)[0]
if isstringzero(value) is True: # display highest precision zero
- base = unitgroup[baseunit]
if strip is False:
- value = fitinfield("0", width - len(base)) + base
+ value = fitinfield("0", width - len(baseunit))
+ value = value + baseunit
return value
ooms = oomsbetweenunits(startingunit, baseunit)
newvalue = cropprecision(value, ooms)
newvalue, unitsmoved = scalestring(newvalue)
- unitget = startingunit + unitsmoved
- if 0 <= unitget < len(unitgroup): # We have a unit
- unit = unitgroup[unitget]
+ unitget = unitrelativeto(startingunit, unitsmoved)
+ if unitget is not None: # We have a unit
if width is None:
realwidth = None
else:
- realwidth = width - len(unit)
- newvalue = fitinfield(newvalue, realwidth) + unit
+ realwidth = width - len(unitget)
+ newvalue = fitinfield(newvalue, realwidth) + unitget
else: # don't have a replacement unit, use original
- newvalue = value + unitgroup[startingunit]
+ newvalue = value + startingunit
if strip is True:
newvalue = newvalue.strip()
return newvalue
@@ -667,19 +709,19 @@ def cook(variables, showunits=False):
# missing variables here.
# Completion cannot occur until all units are tracked down.
if showunits:
- item += unitify(rawvalue, UNITS_SEC, UNIT_MS, UNIT_NS,
+ item += unitify(rawvalue, UNIT_MS, UNIT_NS,
True, width=None)
else:
item += repr(value)
elif name in S_VARS:
if showunits:
- item += unitify(rawvalue, UNITS_SEC, UNIT_S, UNIT_NS,
+ item += unitify(rawvalue, UNIT_S, UNIT_NS,
True, width=None)
else:
item += repr(value)
elif name in PPM_VARS:
if showunits:
- item += unitify(rawvalue, UNITS_PPX, UNIT_PPM,
+ item += unitify(rawvalue, UNIT_PPM,
strip=True, width=None)
else:
item += repr(value)
@@ -933,9 +975,9 @@ class PeerSummary:
if self.showunits:
line += (
" %s %s %s" %
- (unitify(estdelay, UNITS_SEC, UNIT_MS),
- unitify(estoffset, UNITS_SEC, UNIT_MS),
- unitify(jd, UNITS_SEC, UNIT_MS)))
+ (unitify(estdelay, UNIT_MS),
+ unitify(estoffset, UNIT_MS),
+ unitify(jd, UNIT_MS)))
else:
line += (
" %s %s %s" %
@@ -946,9 +988,9 @@ class PeerSummary:
if self.showunits:
line += (
" %s %s %s" %
- (unitify(estdelay, UNITS_SEC, UNIT_MS),
- unitify(estoffset, UNITS_SEC, UNIT_MS),
- unitify(jd, UNITS_SEC, UNIT_MS)))
+ (unitify(estdelay, UNIT_MS),
+ unitify(estoffset, UNIT_MS),
+ unitify(jd, UNIT_MS)))
else:
line += (
" %s %s %s" %
=====================================
tests/pylib/test_util.py
=====================================
--- a/tests/pylib/test_util.py
+++ b/tests/pylib/test_util.py
@@ -73,10 +73,10 @@ class TestPylibUtilMethods(unittest.TestCase):
(1.000001, 0))
def test_oomsbetweenunits(self):
- self.assertEqual(ntp.util.oomsbetweenunits(3, 2),
- 3)
- self.assertEqual(ntp.util.oomsbetweenunits(2, 3),
- 3)
+ f = ntp.util.oomsbetweenunits
+
+ self.assertEqual(f(ntp.util.UNIT_KS, ntp.util.UNIT_MS), 6)
+ self.assertEqual(f(ntp.util.UNIT_PPM, ntp.util.UNIT_PPB), 3)
def test_filtcooker(self):
self.assertEqual(ntp.util.filtcooker(
@@ -288,44 +288,35 @@ class TestPylibUtilMethods(unittest.TestCase):
nu = ntp.util
# Zero
- self.assertEqual(f("0.000", nu.UNITS_SEC, nu.UNIT_MS),
- " 0ns")
+ self.assertEqual(f("0.000", nu.UNIT_MS), " 0ns")
# Standard, width=8
- self.assertEqual(f("1.234", nu.UNITS_SEC, nu.UNIT_MS),
- " 1.234ms")
+ self.assertEqual(f("1.234", nu.UNIT_MS), " 1.234ms")
# ditto, negative
- self.assertEqual(f("-1.234", nu.UNITS_SEC, nu.UNIT_MS),
- "-1.234ms")
+ self.assertEqual(f("-1.234", nu.UNIT_MS), "-1.234ms")
# Scale to larger unit, width=8
- self.assertEqual(f("1234.5", nu.UNITS_SEC, nu.UNIT_MS),
- " 1.2345s")
+ self.assertEqual(f("1234.5", nu.UNIT_MS), " 1.2345s")
# ditto, negative
- self.assertEqual(f("-1234.5", nu.UNITS_SEC, nu.UNIT_MS),
- "-1.2345s")
+ self.assertEqual(f("-1234.5", nu.UNIT_MS), "-1.2345s")
# Scale to smaller unit, width=8
- self.assertEqual(f("0.01234", nu.UNITS_SEC, nu.UNIT_MS),
- u" 12.34\u03bcs")
+ self.assertEqual(f("0.01234", nu.UNIT_MS), u" 12.34\u03bcs")
# ditto, negative
- self.assertEqual(f("-0.01234", nu.UNITS_SEC, nu.UNIT_MS),
- u"-12.34\u03bcs")
+ self.assertEqual(f("-0.01234", nu.UNIT_MS), u"-12.34\u03bcs")
# At baseunit
- self.assertEqual(f("12.0", nu.UNITS_SEC, nu.UNIT_NS),
- " 12ns")
+ self.assertEqual(f("12.0", nu.UNIT_NS), " 12ns")
# Scale to baseunit
- self.assertEqual(f(".042", nu.UNITS_SEC, nu.UNIT_US),
- " 42ns")
+ self.assertEqual(f(".042", nu.UNIT_US), " 42ns")
# Below baseunit
- self.assertEqual(f("23.42", nu.UNITS_SEC, nu.UNIT_NS),
- " 23ns")
+ self.assertEqual(f("23.42", nu.UNIT_NS), " 23ns")
# Different units
- self.assertEqual(f("12.345", nu.UNITS_PPX, nu.UNIT_PPM),
- "12.35ppm")
+ self.assertEqual(f("12.345", nu.UNIT_PPM), "12.35ppm")
# Strip
- self.assertEqual(f("1.23", nu.UNITS_SEC, nu.UNIT_MS, strip=True),
- "1.23ms")
+ self.assertEqual(f("1.23", nu.UNIT_MS, strip=True), "1.23ms")
# Different width
- self.assertEqual(f("1.234", nu.UNITS_SEC, nu.UNIT_MS, width=12),
- " 1.234ms")
+ self.assertEqual(f("1.234", nu.UNIT_MS, width=12), " 1.234ms")
+ # Outside of available units
+ self.assertEqual(f("1234.5", nu.UNIT_KS), "1234.5ks")
+ # Seconds
+ self.assertEqual(f("42.23", nu.UNIT_S), " 42.23s")
def test_stringfiltcooker(self):
# No scale
@@ -339,5 +330,21 @@ class TestPylibUtilMethods(unittest.TestCase):
"1.00002 3.4005 0.00068 -0.0230 9.001 0.0067 0.00100 1.234 s"
)
+ def test_unitrelativeto(self):
+ f = ntp.util.unitrelativeto
+
+ # Scale to smaller unit
+ self.assertEqual(f(ntp.util.UNIT_S, -1), ntp.util.UNIT_MS)
+ # Scale to larger unit
+ self.assertEqual(f(ntp.util.UNIT_S, 1), ntp.util.UNIT_KS)
+ # Scale smaller, outside of range
+ self.assertEqual(f(ntp.util.UNIT_S, -10), None)
+ # Scale larger, outside of range
+ self.assertEqual(f(ntp.util.UNIT_NS, 10), None)
+ # Get base unit
+ self.assertEqual(f(ntp.util.UNIT_KS, None), ntp.util.UNIT_NS)
+ # Different unitgroup
+ self.assertEqual(f(ntp.util.UNIT_PPM, -1), ntp.util.UNIT_PPB)
+
if __name__ == '__main__':
unittest.main()
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/609b1225b071e19cb86f43d72b7aecf68739b520
---
View it on GitLab: https://gitlab.com/NTPsec/ntpsec/commit/609b1225b071e19cb86f43d72b7aecf68739b520
You're receiving this email because of your account on gitlab.com.
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.ntpsec.org/pipermail/vc/attachments/20170413/e3280ac3/attachment.html>
More information about the vc
mailing list