[lldb] Add expect_var_path to test variable path results
authorRaphael Isemann <teemperor@gmail.com>
Thu, 12 Nov 2020 15:07:58 +0000 (16:07 +0100)
committerRaphael Isemann <teemperor@gmail.com>
Thu, 12 Nov 2020 15:14:48 +0000 (16:14 +0100)
This adds `expect_var_path` to test variable paths so we no longer have to
use `frame var` and find substrs in the command output. The behaviour
is identical with `expect_expr` (and it also uses the same checking backend),
but it instead calls `GetValueForVariablePath` to evaluate the string as a variable
path.

Also rewrites a few of the tests that previously used `frame variable` to use
`expect_var_path`.

Reviewed By: labath

Differential Revision: https://reviews.llvm.org/D90450

lldb/packages/Python/lldbsuite/test/lldbtest.py
lldb/test/API/commands/process/launch-with-shellexpand/TestLaunchWithShellExpand.py
lldb/test/API/functionalities/archives/TestBSDArchives.py
lldb/test/API/lang/cpp/wchar_t/TestCxxWCharT.py

index 89c25eb..a02c445 100644 (file)
@@ -2592,6 +2592,35 @@ FileCheck output:
         value_check.check_value(self, eval_result, str(eval_result))
         return eval_result
 
+    def expect_var_path(
+            self,
+            var_path,
+            summary=None,
+            value=None,
+            type=None,
+            children=None
+            ):
+        """
+        Evaluates the given variable path and verifies the result.
+        See also 'frame variable' and SBFrame.GetValueForVariablePath.
+        :param var_path: The variable path as a string.
+        :param summary: The summary that the variable should have. None if the summary should not be checked.
+        :param value: The value that the variable should have. None if the value should not be checked.
+        :param type: The type that the variable result should have. None if the type should not be checked.
+        :param children: The expected children of the variable  as a list of ValueChecks.
+                         None if the children shouldn't be checked.
+        """
+        self.assertTrue(var_path.strip() == var_path,
+                        "Expression contains trailing/leading whitespace: '" + var_path + "'")
+
+        frame = self.frame()
+        eval_result = frame.GetValueForVariablePath(var_path)
+
+        value_check = ValueCheck(type=type, value=value,
+                                 summary=summary, children=children)
+        value_check.check_value(self, eval_result, str(eval_result))
+        return eval_result
+
     def invoke(self, obj, name, trace=False):
         """Use reflection to call a method dynamically with no argument."""
         trace = (True if traceAlways else trace)
index 8602f7f..9ade3db 100644 (file)
@@ -60,21 +60,14 @@ class LaunchWithShellExpandTestCase(TestBase):
             stop_reason == lldb.eStopReasonBreakpoint,
             "Thread in process stopped in 'main' should have a stop reason of eStopReasonBreakpoint")
 
-        self.expect("frame variable argv[1]", substrs=['file1.txt'])
-        self.expect("frame variable argv[2]", substrs=['file2.txt'])
-        self.expect("frame variable argv[3]", substrs=['file3.txt'])
-        self.expect("frame variable argv[4]", substrs=['file4.txy'])
-        self.expect("frame variable argv[5]", substrs=['()'])
-        self.expect("frame variable argv[6]", substrs=['>'])
-        self.expect("frame variable argv[7]", substrs=['<'])
-        self.expect(
-            "frame variable argv[5]",
-            substrs=['file5.tyx'],
-            matching=False)
-        self.expect(
-            "frame variable argv[8]",
-            substrs=['file5.tyx'],
-            matching=False)
+        self.expect_var_path("argv[1]", summary='"file1.txt"')
+        self.expect_var_path("argv[2]", summary='"file2.txt"')
+        self.expect_var_path("argv[3]", summary='"file3.txt"')
+        self.expect_var_path("argv[4]", summary='"file4.txy"')
+        self.expect_var_path("argv[5]", summary='"()"')
+        self.expect_var_path("argv[6]", summary='">"')
+        self.expect_var_path("argv[7]", summary='"<"')
+        self.expect_var_path("argc", value='8')
 
         self.runCmd("process kill")
 
index b412ac4..4464edd 100644 (file)
@@ -43,8 +43,7 @@ class BSDArchivesTestCase(TestBase):
         # Break at a(int) first.
         self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY,
                     substrs=['(int) arg = 1'])
-        self.expect("frame variable __a_global", VARIABLES_DISPLAYED_CORRECTLY,
-                    substrs=['(int) __a_global = 1'])
+        self.expect_var_path("__a_global", type="int", value="1")
 
         # Set breakpoint for b() next.
         lldbutil.run_break_set_by_symbol(
@@ -57,5 +56,4 @@ class BSDArchivesTestCase(TestBase):
                              'stop reason = breakpoint'])
         self.expect("frame variable", VARIABLES_DISPLAYED_CORRECTLY,
                     substrs=['(int) arg = 2'])
-        self.expect("frame variable __b_global", VARIABLES_DISPLAYED_CORRECTLY,
-                    substrs=['(int) __b_global = 2'])
+        self.expect_var_path("__b_global", type="int", value="2")
index bb041ef..79f6552 100644 (file)
@@ -20,20 +20,16 @@ class CxxWCharTTestCase(TestBase):
         lldbutil.run_to_source_breakpoint(self, "// break here", lldb.SBFileSpec("main.cpp"))
 
         # Check that we correctly report templates on wchar_t
-        self.expect("frame variable foo_y",
-                    substrs=['(Foo<wchar_t>) foo_y = '])
+        self.expect_var_path("foo_y", type="Foo<wchar_t>")
 
         # Check that we correctly report templates on int
-        self.expect("frame variable foo_x",
-                    substrs=['(Foo<int>) foo_x = '])
+        self.expect_var_path("foo_x", type="Foo<int>")
 
         # Check that we correctly report wchar_t
-        self.expect("frame variable foo_y.object",
-                    substrs=['(wchar_t) foo_y.object = '])
+        self.expect_var_path("foo_y.object", type="wchar_t")
 
         # Check that we correctly report int
-        self.expect("frame variable foo_x.object",
-                    substrs=['(int) foo_x.object = '])
+        self.expect_var_path("foo_x.object", type="int")
 
         # Check that we can run expressions that return wchar_t
         self.expect("expression L'a'", substrs=['(wchar_t) $', "L'a'"])