Commit 8bc17ebb authored by Iustin Pop's avatar Iustin Pop
Browse files

Add optional formatting for OP_DSC_FIELD



For some opcodes, the output is not "stable", and depends on the exact
input values; this makes it harder to check consistency against
Haskell code.

To compensate for this, we add a way to override the formatting of the
OP_DSC_FIELD; by default, this is always "%s", but if the
OP_DSC_FORMATTER is defined (must be a callable), it is used to format
the actual value.
Signed-off-by: default avatarIustin Pop <iustin@google.com>
Reviewed-by: default avatarGuido Trotter <ultrotter@google.com>
parent 5cd95d46
......@@ -434,6 +434,10 @@ class _AutoOpParamSlots(objectutils.AutoSlots):
slots = mcs._GetSlots(attrs)
assert "OP_DSC_FIELD" not in attrs or attrs["OP_DSC_FIELD"] in slots, \
"Class '%s' uses unknown field in OP_DSC_FIELD" % name
assert ("OP_DSC_FORMATTER" not in attrs or
callable(attrs["OP_DSC_FORMATTER"])), \
("Class '%s' uses non-callable in OP_DSC_FORMATTER (%s)" %
(name, type(attrs["OP_DSC_FORMATTER"])))
attrs["OP_ID"] = _NameToId(name)
......@@ -598,6 +602,9 @@ class OpCode(BaseOpCode):
@cvar OP_DSC_FIELD: The name of a field whose value will be included in the
string returned by Summary(); see the docstring of that
method for details).
@cvar OP_DSC_FORMATTER: A callable that should format the OP_DSC_FIELD; if
not present, then the field will be simply converted
to string
@cvar OP_PARAMS: List of opcode attributes, the default values they should
get if not already defined, and types they must match.
@cvar OP_RESULT: Callable to verify opcode result
......@@ -685,7 +692,10 @@ class OpCode(BaseOpCode):
field_name = getattr(self, "OP_DSC_FIELD", None)
if field_name:
field_value = getattr(self, field_name, None)
if isinstance(field_value, (list, tuple)):
field_formatter = getattr(self, "OP_DSC_FORMATTER", None)
if callable(field_formatter):
field_value = field_formatter(field_value)
elif isinstance(field_value, (list, tuple)):
field_value = ",".join(str(i) for i in field_value)
txt = "%s(%s)" % (txt, field_value)
return txt
......@@ -1958,6 +1968,16 @@ class OpTestDelay(OpCode):
("repeat", 0, ht.TNonNegativeInt, None),
]
def OP_DSC_FORMATTER(self, value): # pylint: disable=C0103,R0201
"""Custom formatter for duration.
"""
try:
v = float(value)
except TypeError:
v = value
return str(v)
class OpTestAllocator(OpCode):
"""Allocator framework testing.
......
......@@ -121,6 +121,16 @@ class TestOpcodes(unittest.TestCase):
self.assertEqual(OpTest(data="node1.example.com").Summary(),
"TEST(node1.example.com)")
def testSummaryFormatter(self):
class OpTest(opcodes.OpCode):
OP_DSC_FIELD = "data"
OP_DSC_FORMATTER = lambda _, v: "a"
OP_PARAMS = [
("data", ht.NoDefault, ht.TString, None),
]
self.assertEqual(OpTest(data="").Summary(), "TEST(a)")
self.assertEqual(OpTest(data="b").Summary(), "TEST(a)")
def testTinySummary(self):
self.assertFalse(utils.FindDuplicates(opcodes._SUMMARY_PREFIX.values()))
self.assertTrue(compat.all(prefix.endswith("_") and supplement.endswith("_")
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment