teemperor updated this revision to Diff 238189. teemperor added a comment. - Moved to using the SBAPI.
We can't get fully rid of parsing some output as GetDescription of SBValue returns `(type) $0 = VALUE\n` but there seems to be no way to get rid of the stuff around the value we want. But we now only strip it away instead of trying to parse the type etc. CHANGES SINCE LAST ACTION https://reviews.llvm.org/D70314/new/ https://reviews.llvm.org/D70314 Files: lldb/packages/Python/lldbsuite/test/commands/expression/call-function/TestCallBuiltinFunction.py lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py lldb/packages/Python/lldbsuite/test/lldbtest.py
Index: lldb/packages/Python/lldbsuite/test/lldbtest.py =================================================================== --- lldb/packages/Python/lldbsuite/test/lldbtest.py +++ lldb/packages/Python/lldbsuite/test/lldbtest.py @@ -2366,6 +2366,95 @@ self.assertTrue(matched if matching else not matched, msg if msg else EXP_MSG(str, output, exe)) + class ExpressionRunMode: + # Run the expression in the expression evaluator (similar to 'expression'). + EXPRESSION = object() + # Interpret the expression as just a variable that should be printed (similar to 'frame var'). + PRINT_VAR = object() + + def expect_expr( + self, + expr, + result_value=None, + result_type=None, + error_msg=None, + run_mode=ExpressionRunMode.EXPRESSION + ): + """ + Evaluates the given expression and verifies the result. + :param expr: The expression as a string. + :param result_value: The value that the expression should have. None if the value should not be checked. + :param result_type: The type that the expression result should have. None if the type should not be checked. + :param error_msg: The error message the expression should return. None if the error output should not be checked. + :param run_type: How the expression should be run. See ExpressionRunMode. + + result_value, result_type and error_message can have the following types which influences how + their values are compared to their respective output: + * A list of strings: expect_expr will search for the list of strings in the respective output. + The output is expected to contain these strings in the listed order. + * Any string type: expect_expr will assume that the respective output is equal to the given string. + """ + # Utility method that checks result_value, result_type and error_message. + def check_str(outer_self, expected, got): + self.assertIsNotNone(expected) + self.assertIsNotNone(got) + # We got a list, so treat is as a list of needles we need to find in the given order. + if type(expected) is list: + remaining = got + for expected_part in expected: + # Find the expected string. + i = remaining.find(expected_part) + # Assert that we found the string. + outer_self.assertTrue(i != -1, "Couldn't find '" + expected_part + + "' in remaining output '" + remaining + + "'.\nFull string was: '" + got + "'") + # Keep searching only the rest of the string to ensure the + # strings are found in the given order. + remaining = remaining[i + len(expected_part):] + else: # Otherwise we probably got one of Python's many string classes. + outer_self.assertEqual(got, expected) + + self.assertTrue(expr.strip() == expr, "Expression contains trailing/leading whitespace: '" + expr + "'") + + frame = self.dbg.GetTargetAtIndex(0).GetProcess().GetThreadAtIndex(0).GetFrameAtIndex(0) + + if run_mode is self.ExpressionRunMode.PRINT_VAR: + eval_result = frame.FindVariable(expr) + elif run_mode is self.ExpressionRunMode.EXPRESSION: + eval_result = frame.EvaluateExpression(expr) + else: + self.fail("Unknown run mode " + str(run_mode)) + + if error_msg: + self.assertFalse(eval_result.IsValid()) + check_str(self, error_msg, eval_result.GetError().GetCString()) + return + + if not eval_result.GetError().Success(): + self.assertTrue(eval_result.GetError().Success(), + "Unexpected failure with msg: " + eval_result.GetError().GetCString()) + + if result_type: + check_str(self, result_type, eval_result.GetTypeName()) + if result_value: + ss = lldb.SBStream() + eval_result.GetDescription(ss) + description = ss.GetData() + # Strip out the value from the description text that looks like this: + # (the_type) $434 = VALUE\n + value_desc = description.split(" = ", 1)[1].rstrip("\n") + check_str(self, result_value, value_desc) + + def expect_simple_expr(self, var, result_value=None, result_type=None): + """ + Takes a trivial expression such as a plain variable name or accessing a member ('instance.member') + and verifies that all ways LLDB can evaluate these expressions do it correctly + (e.g., 'frame var', 'expression' commands) + See expect_expr for documentation for result_value and result_type. + """ + self.expect_expr(var, result_value=result_value, result_type=result_type, run_mode=self.ExpressionRunMode.EXPRESSION) + self.expect_expr(var, result_value=result_value, result_type=result_type, run_mode=self.ExpressionRunMode.PRINT_VAR) + def invoke(self, obj, name, trace=False): """Use reflection to call a method dynamically with no argument.""" trace = (True if traceAlways else trace) Index: lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py =================================================================== --- lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py +++ lldb/packages/Python/lldbsuite/test/functionalities/data-formatter/data-formatter-stl/libcxx/map/TestDataFormatterLibccMap.py @@ -51,28 +51,11 @@ self.addTearDownHook(cleanup) ns = self.namespace - self.expect('p ii', - substrs=['%s::map' % ns, - 'size=0', - '{}']) - self.expect('frame var ii', - substrs=['%s::map' % ns, - 'size=0', - '{}']) + self.expect_simple_expr('ii', result_type=['%s::map' % ns], result_value=['size=0', "{}"]) lldbutil.continue_to_breakpoint(self.process(), bkpt) - self.expect('p ii', - substrs=['%s::map' % ns, 'size=2', - '[0] = ', - 'first = 0', - 'second = 0', - '[1] = ', - 'first = 1', - 'second = 1']) - - self.expect('frame variable ii', - substrs=['%s::map' % ns, 'size=2', + self.expect_simple_expr('ii', result_type=['%s::map' % ns], result_value=['size=2', '[0] = ', 'first = 0', 'second = 0', @@ -82,8 +65,7 @@ lldbutil.continue_to_breakpoint(self.process(), bkpt) - self.expect('frame variable ii', - substrs=['%s::map' % ns, 'size=4', + self.expect_simple_expr('ii', result_type=['%s::map' % ns], result_value=['size=4', '[2] = ', 'first = 2', 'second = 0', @@ -93,17 +75,7 @@ lldbutil.continue_to_breakpoint(self.process(), bkpt) - self.expect("p ii", - substrs=['%s::map' % ns, 'size=8', - '[5] = ', - 'first = 5', - 'second = 0', - '[7] = ', - 'first = 7', - 'second = 1']) - - self.expect("frame var ii", - substrs=['%s::map' % ns, 'size=8', + self.expect_simple_expr('ii', result_type=['%s::map' % ns], result_value=['size=8', '[5] = ', 'first = 5', 'second = 0', Index: lldb/packages/Python/lldbsuite/test/commands/expression/call-function/TestCallBuiltinFunction.py =================================================================== --- lldb/packages/Python/lldbsuite/test/commands/expression/call-function/TestCallBuiltinFunction.py +++ lldb/packages/Python/lldbsuite/test/commands/expression/call-function/TestCallBuiltinFunction.py @@ -39,7 +39,7 @@ # Test different builtin functions. - self.expect("expr __builtin_isinf(0.0f)", substrs=["(int) $", " = 0\n"]) - self.expect("expr __builtin_isnormal(0.0f)", substrs=["(int) $", " = 0\n"]) - self.expect("expr __builtin_constant_p(1)", substrs=["(int) $", " = 1\n"]) - self.expect("expr __builtin_abs(-14)", substrs=["(int) $", " = 14\n"]) + self.expect_expr("__builtin_isinf(0.0f)", result_type="int", result_value="0") + self.expect_expr("__builtin_isnormal(0.0f)", result_type="int", result_value="0") + self.expect_expr("__builtin_constant_p(1)", result_type="int", result_value="1") + self.expect_expr("__builtin_abs(-14)", result_type="int", result_value="14")
_______________________________________________ lldb-commits mailing list lldb-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/lldb-commits