1"""
2Test the format of API test suite assert failure messages
3"""
4
5
6import lldb
7import lldbsuite.test.lldbutil as lldbutil
8from lldbsuite.test.lldbtest import *
9from lldbsuite.test.decorators import *
10from textwrap import dedent
11
12
13class AssertMessagesTestCase(TestBase):
14    NO_DEBUG_INFO_TESTCASE = True
15
16    def assert_expect_fails_with(self, cmd, expect_args, expected_msg):
17        try:
18            # This expect should fail
19            self.expect(cmd, **expect_args)
20        except AssertionError as e:
21            # Then check message from previous expect
22            self.expect(str(e), exe=False, substrs=[dedent(expected_msg)])
23        else:
24            self.fail("Initial expect should have raised AssertionError!")
25
26    @expectedFailureAll(remote=True)
27    def test_createTestTarget(self):
28        try:
29           self.createTestTarget("doesnt_exist")
30        except AssertionError as e:
31           self.assertIn("Couldn't create target for path 'doesnt_exist': "
32                         "error: unable to find executable for 'doesnt_exist'",
33                         str(e))
34
35
36    def test_expect(self):
37        """Test format of messages produced by expect(...)"""
38
39        # When an expect passes the messages are sent to the trace
40        # file which we can't access here. So really, these only
41        # check what failures look like, but it *should* be the same
42        # content for the trace log too.
43
44        # Will stop at startstr fail
45        self.assert_expect_fails_with("settings list prompt",
46            dict(startstr="dog", endstr="cat"),
47            """\
48               Ran command:
49               "settings list prompt"
50
51               Got output:
52                 prompt -- The debugger command line prompt displayed for the user.
53
54               Expecting start string: "dog" (was not found)""")
55
56        # startstr passes, endstr fails
57        # We see both reported
58        self.assert_expect_fails_with("settings list prompt",
59            dict(startstr="  prompt -- ", endstr="foo"),
60            """\
61               Ran command:
62               "settings list prompt"
63
64               Got output:
65                 prompt -- The debugger command line prompt displayed for the user.
66
67               Expecting start string: "  prompt -- " (was found)
68               Expecting end string: "foo" (was not found)""")
69
70        # Same thing for substrs, regex patterns ignored because of substr failure
71        # Any substr after the first missing is also ignored
72        self.assert_expect_fails_with("abcdefg",
73            dict(substrs=["abc", "ijk", "xyz"],
74            patterns=["foo", "bar"], exe=False),
75            """\
76               Checking string:
77               "abcdefg"
78
79               Expecting sub string: "abc" (was found)
80               Expecting sub string: "ijk" (was not found)""")
81
82        # Regex patterns also stop at first failure, subsequent patterns ignored
83        # They are last in the chain so no other check gets skipped
84        # Including the rest of the conditions here to prove they are run and shown
85        self.assert_expect_fails_with("0123456789",
86            dict(startstr="012", endstr="789", substrs=["345", "678"],
87            patterns=["[0-9]+", "[a-f]+", "a|b|c"], exe=False),
88            """\
89               Checking string:
90               "0123456789"
91
92               Expecting start string: "012" (was found)
93               Expecting end string: "789" (was found)
94               Expecting sub string: "345" (was found)
95               Expecting sub string: "678" (was found)
96               Expecting regex pattern: "[0-9]+" (was found, matched "0123456789")
97               Expecting regex pattern: "[a-f]+" (was not found)""")
98
99        # This time we dont' want matches but we do get them
100        self.assert_expect_fails_with("the quick brown fox",
101            # Note that the second pattern *will* match
102            dict(patterns=["[0-9]+", "fox"], exe=False, matching=False,
103            startstr="cat", endstr="rabbit", substrs=["abc", "def"]),
104            """\
105               Checking string:
106               "the quick brown fox"
107
108               Not expecting start string: "cat" (was not found)
109               Not expecting end string: "rabbit" (was not found)
110               Not expecting sub string: "abc" (was not found)
111               Not expecting sub string: "def" (was not found)
112               Not expecting regex pattern: "[0-9]+" (was not found)
113               Not expecting regex pattern: "fox" (was found, matched "fox")""")
114
115        # Extra assert messages are only printed when we get a failure
116        # So I can't test that from here, just how it looks when it's printed
117        self.assert_expect_fails_with("mouse",
118            dict(startstr="cat", exe=False, msg="Reason for check goes here!"),
119            """\
120               Checking string:
121               "mouse"
122
123               Expecting start string: "cat" (was not found)
124               Reason for check goes here!""")
125
126        # Verify expect() preconditions.
127        # Both `patterns` and `substrs` cannot be of type string.
128        self.assert_expect_fails_with("any command",
129            dict(patterns="some substring"),
130            "patterns must be a collection of strings")
131        self.assert_expect_fails_with("any command",
132            dict(substrs="some substring"),
133            "substrs must be a collection of strings")
134        # Prevent `self.expect("cmd", "substr")`
135        self.assert_expect_fails_with("any command",
136            dict(msg="some substring"),
137            "expect() missing a matcher argument")
138        # Prevent `self.expect("cmd", "msg", "substr")`
139        self.assert_expect_fails_with("any command",
140            dict(msg="a message", patterns="some substring"),
141            "must be a collection of strings")
142