159 lines · python
1"""2Test DarwinLog "source include debug-level" functionality provided by the3StructuredDataDarwinLog plugin.4 5These tests are currently only supported when running against Darwin6targets.7"""8 9 10import lldb11import platform12import re13import sys14 15from lldbsuite.test.decorators import *16from lldbsuite.test.lldbtest import *17from lldbsuite.test import lldbtest_config18 19 20class DarwinNSLogOutputTestCase(TestBase):21 NO_DEBUG_INFO_TESTCASE = True22 23 def setUp(self):24 # Call super's setUp().25 TestBase.setUp(self)26 self.child = None27 self.child_prompt = "(lldb) "28 self.strict_sources = False29 30 # Source filename.31 self.source = "main.m"32 33 # Output filename.34 self.exe_name = self.getBuildArtifact("a.out")35 self.d = {"OBJC_SOURCES": self.source, "EXE": self.exe_name}36 37 # Locate breakpoint.38 self.line = line_number(self.source, "// break here")39 40 def tearDown(self):41 # Shut down the process if it's still running.42 if self.child:43 self.runCmd("process kill")44 self.expect_prompt()45 self.runCmd("quit")46 47 # Let parent clean up48 super(DarwinNSLogOutputTestCase, self).tearDown()49 50 def run_lldb_to_breakpoint(self, exe, source_file, line, settings_commands=None):51 # Set self.child_prompt, which is "(lldb) ".52 prompt = self.child_prompt53 54 # So that the child gets torn down after the test.55 import pexpect56 57 self.child = pexpect.spawn(58 "%s %s %s" % (lldbtest_config.lldbExec, self.lldbOption, exe),59 encoding="utf-8",60 )61 child = self.child62 63 # Turn on logging for what the child sends back.64 if self.TraceOn():65 child.logfile_read = sys.stdout66 67 # Disable showing of source lines at our breakpoint.68 # This is necessary for the logging tests, because the very69 # text we want to match for output from the running inferior70 # will show up in the source as well. We don't want the source71 # output to erroneously make a match with our expected output.72 self.runCmd("settings set stop-line-count-before 0")73 self.expect_prompt()74 self.runCmd("settings set stop-line-count-after 0")75 self.expect_prompt()76 77 # Run any test-specific settings commands now.78 if settings_commands is not None:79 for setting_command in settings_commands:80 self.runCmd(setting_command)81 self.expect_prompt()82 83 # Set the breakpoint, and run to it.84 child.sendline("breakpoint set -f %s -l %d" % (source_file, line))85 child.expect_exact(prompt)86 child.sendline("run")87 child.expect_exact(prompt)88 89 # Ensure we stopped at a breakpoint.90 self.runCmd("thread list")91 self.expect(re.compile(r"stop reason = .*breakpoint"))92 93 def runCmd(self, cmd):94 if self.child:95 self.child.sendline(cmd)96 97 def expect_prompt(self, exactly=True):98 self.expect(self.child_prompt, exactly=exactly)99 100 def expect(self, pattern, exactly=False, *args, **kwargs):101 if exactly:102 return self.child.expect_exact(pattern, *args, **kwargs)103 return self.child.expect(pattern, *args, **kwargs)104 105 def do_test(self, expect_regexes=None, settings_commands=None):106 """Run a test."""107 self.build(dictionary=self.d)108 self.setTearDownCleanup(dictionary=self.d)109 110 exe = self.getBuildArtifact(self.exe_name)111 self.run_lldb_to_breakpoint(112 exe, self.source, self.line, settings_commands=settings_commands113 )114 self.expect_prompt()115 116 # Now go.117 self.runCmd("process continue")118 self.expect(expect_regexes)119 120 @skipIfAsan # avoid dealing with pexpect timeout flakyness on bots121 @skipIf(oslist=["linux"], archs=["arm$", "aarch64"])122 @skipUnlessDarwin123 @skipIfRemote # this test is currently written using lldb commands & assumes running on local system124 def test_nslog_output_is_displayed(self):125 """Test that NSLog() output shows up in the command-line debugger."""126 self.do_test(127 expect_regexes=[128 re.compile(r"(This is a message from NSLog)"),129 re.compile(r"Process \d+ exited with status"),130 ]131 )132 self.assertIsNotNone(self.child.match)133 self.assertGreater(len(self.child.match.groups()), 0)134 self.assertEqual("This is a message from NSLog", self.child.match.group(1))135 136 @skipIfAsan # avoid dealing with pexpect timeout flakyness on bots137 @skipIf(oslist=["linux"], archs=["arm$", "aarch64"])138 @skipUnlessDarwin139 @skipIfRemote # this test is currently written using lldb commands & assumes running on local system140 def test_nslog_output_is_suppressed_with_env_var(self):141 """Test that NSLog() output does not show up with the ignore env var."""142 # This test will only work properly on macOS 10.12+. Skip it on earlier versions.143 # This will require some tweaking on iOS.144 match = re.match(r"^\d+\.(\d+)", platform.mac_ver()[0])145 if match is None or int(match.group(1)) < 12:146 self.skipTest("requires macOS 10.12 or higher")147 148 self.do_test(149 expect_regexes=[150 re.compile(r"(This is a message from NSLog)"),151 re.compile(r"Process \d+ exited with status"),152 ],153 settings_commands=[154 "settings set target.env-vars " '"IDE_DISABLED_OS_ACTIVITY_DT_MODE=1"'155 ],156 )157 self.assertIsNotNone(self.child.match)158 self.assertEqual(len(self.child.match.groups()), 0)159