diff options
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test')
44 files changed, 2721 insertions, 0 deletions
diff --git a/lldb/packages/Python/lldbsuite/test/darwin_log.py b/lldb/packages/Python/lldbsuite/test/darwin_log.py new file mode 100644 index 00000000000..f2d4f1df6e2 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/darwin_log.py @@ -0,0 +1,430 @@ +""" +Base class for DarwinLog tests. +""" + +# System imports +from __future__ import print_function + +import json +import os +import pexpect +import platform +import re +import sys +import threading + + +# lldb imports +import lldb +from lldb import SBProcess, SBTarget + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import lldbtest_config +from lldbsuite.test import lldbutil + + +def expand_darwinlog_command(command): + return "plugin structured-data darwin-log " + command + + +def expand_darwinlog_settings_set_command(command): + return "settings set plugin.structured-data.darwin-log." + command + + +class DarwinLogTestBase(lldbtest.TestBase): + """Base class for DarwinLog test cases that are pexpect-based.""" + NO_DEBUG_INFO_TESTCASE = True + + CONTINUE_REGEX = re.compile(r"Process \d+ resuming") + + def setUp(self): + # Call super's setUp(). + super(DarwinLogTestBase, self).setUp() + + # Until other systems support this, exit + # early if we're not macOS version 10.12 + # or greater. + version = platform.mac_ver()[0].split('.') + if ((int(version[0]) == 10) and (int(version[1]) < 12) or + (int(version[0]) < 10)): + self.skipTest("DarwinLog tests currently require macOS 10.12+") + return + + self.child = None + self.child_prompt = '(lldb) ' + self.strict_sources = False + self.enable_process_monitor_logging = False + + def run_lldb_to_breakpoint(self, exe, source_file, line, + enable_command=None, settings_commands=None): + + # Set self.child_prompt, which is "(lldb) ". + prompt = self.child_prompt + + # So that the child gets torn down after the test. + self.child = pexpect.spawn('%s %s %s' % (lldbtest_config.lldbExec, + self.lldbOption, exe)) + child = self.child + + # Turn on logging for what the child sends back. + if self.TraceOn(): + child.logfile_read = sys.stdout + + if self.enable_process_monitor_logging: + if platform.system() == 'Darwin': + self.runCmd("settings set target.process.extra-startup-command " + "QSetLogging:bitmask=LOG_DARWIN_LOG;") + self.expect_prompt() + + # Run the enable command if we have one. + if enable_command is not None: + self.runCmd(enable_command) + self.expect_prompt() + + # Disable showing of source lines at our breakpoint. + # This is necessary for the logging tests, because the very + # text we want to match for output from the running inferior + # will show up in the source as well. We don't want the source + # output to erroneously make a match with our expected output. + self.runCmd("settings set stop-line-count-before 0") + self.expect_prompt() + self.runCmd("settings set stop-line-count-after 0") + self.expect_prompt() + + # While we're debugging, turn on packet logging. + self.runCmd("log enable -f /tmp/packets.log gdb-remote packets") + self.expect_prompt() + + # Prevent mirroring of NSLog/os_log content to stderr. We want log + # messages to come exclusively through our log channel. + self.runCmd("settings set target.env-vars IDE_DISABLED_OS_ACTIVITY_DT_MODE=1") + self.expect_prompt() + + # Run any darwin-log settings commands now, before we enable logging. + if settings_commands is not None: + for setting_command in settings_commands: + self.runCmd( + expand_darwinlog_settings_set_command(setting_command)) + self.expect_prompt() + + # Set breakpoint right before the os_log() macros. We don't + # set it on the os_log*() calls because these are a number of + # nested-scoped calls that will cause the debugger to stop + # multiple times on the same line. That is difficult to match + # os_log() content by since it is non-deterministic what the + # ordering between stops and log lines will be. This is why + # we stop before, and then have the process run in a sleep + # afterwards, so we get the log messages while the target + # process is "running" (sleeping). + child.sendline('breakpoint set -f %s -l %d' % (source_file, line)) + child.expect_exact(prompt) + + # Now run to the breakpoint that we just set. + child.sendline('run') + child.expect_exact(prompt) + + # Ensure we stopped at a breakpoint. + self.runCmd("thread list") + self.expect(re.compile(r"stop reason = breakpoint")) + + # Now we're ready to check if DarwinLog is available. + if not self.darwin_log_available(): + self.skipTest("DarwinLog not available") + + def runCmd(self, cmd): + self.child.sendline(cmd) + + def expect_prompt(self, exactly=True): + self.expect(self.child_prompt, exactly=exactly) + + def expect(self, pattern, exactly=False, *args, **kwargs): + if exactly: + return self.child.expect_exact(pattern, *args, **kwargs) + return self.child.expect(pattern, *args, **kwargs) + + def darwin_log_available(self): + self.runCmd("plugin structured-data darwin-log status") + self.expect(re.compile(r"Availability: ([\S]+)")) + return self.child.match is not None and ( + self.child.match.group(1) == "available") + + def do_test(self, enable_options, expect_regexes=None, + settings_commands=None): + """Test that a single fall-through reject rule rejects all logging.""" + self.build(dictionary=self.d) + self.setTearDownCleanup(dictionary=self.d) + + # Build the darwin-log enable command. + enable_cmd = expand_darwinlog_command('enable') + if enable_options is not None and len(enable_options) > 0: + enable_cmd += ' ' + ' '.join(enable_options) + + exe = os.path.join(os.getcwd(), self.exe_name) + self.run_lldb_to_breakpoint(exe, self.source, self.line, + enable_command=enable_cmd, + settings_commands=settings_commands) + self.expect_prompt() + + # Now go. + self.runCmd("process continue") + self.expect(self.CONTINUE_REGEX) + + if expect_regexes is None: + # Expect matching a log line or program exit. + # Test methods determine which ones are valid. + expect_regexes = ( + [re.compile(r"source-log-([^-]+)-(\S+)"), + re.compile(r"exited with status") + ]) + self.expect(expect_regexes) + + +def remove_add_mode_entry(log_entries): + """libtrace creates an "Add Mode:..." message when logging is enabled. + Strip this out of results since our test subjects don't create it.""" + return [entry for entry in log_entries + if "message" in entry and + not entry["message"].startswith("Add Mode:")] + + +class DarwinLogEventBasedTestBase(lldbtest.TestBase): + """Base class for event-based DarwinLog tests.""" + NO_DEBUG_INFO_TESTCASE = True + + class EventListenerThread(threading.Thread): + def __init__(self, listener, process, trace_on, max_entry_count): + super(DarwinLogEventBasedTestBase.EventListenerThread, self).__init__() + self.process = process + self.listener = listener + self.trace_on = trace_on + self.max_entry_count = max_entry_count + self.exception = None + self.structured_data_event_count = 0 + self.wait_seconds = 2 + self.max_timeout_count = 4 + self.log_entries = [] + + def handle_structured_data_event(self, event): + structured_data = SBProcess.GetStructuredDataFromEvent(event) + if not structured_data.IsValid(): + if self.trace_on: + print("invalid structured data") + return + + # Track that we received a valid structured data event. + self.structured_data_event_count += 1 + + # Grab the individual log entries from the JSON. + stream = lldb.SBStream() + structured_data.GetAsJSON(stream) + dict = json.loads(stream.GetData()) + self.log_entries.extend(dict["events"]) + if self.trace_on: + print("Structured data (raw):", stream.GetData()) + + # Print the pretty-printed version. + if self.trace_on: + stream.Clear() + structured_data.PrettyPrint(stream) + print("Structured data (pretty print):", + stream.GetData()) + + def done(self, timeout_count): + """Returns True when we're done listening for events.""" + # See if we should consider the number of events retrieved. + if self.max_entry_count is not None: + if len(self.log_entries) >= self.max_entry_count: + # We've received the max threshold of events expected, + # we can exit here. + if self.trace_on: + print("Event listener thread exiting due to max " + "expected log entry count being reached.") + return True + + # If our event timeout count has exceeded our maximum timeout count, + # we're done. + if timeout_count >= self.max_timeout_count: + if self.trace_on: + print("Event listener thread exiting due to max number of " + "WaitForEvent() timeouts being reached.") + return True + + # If our process is dead, we're done. + if not self.process.is_alive: + if self.trace_on: + print("Event listener thread exiting due to test inferior " + "exiting.") + return True + + # We're not done. + return False + + def run(self): + event = lldb.SBEvent() + try: + timeout_count = 0 + + # Wait up to 4 times for the event to arrive. + while not self.done(timeout_count): + if self.trace_on: + print("Calling wait for event...") + if self.listener.WaitForEvent(self.wait_seconds, event): + while event.IsValid(): + # Check if it's a process event. + if SBProcess.EventIsStructuredDataEvent(event): + self.handle_structured_data_event(event) + else: + if self.trace_on: + print("ignoring unexpected event:", + lldbutil.get_description(event)) + # Grab the next event, if there is one. + event.Clear() + if not self.listener.GetNextEvent(event): + if self.trace_on: + print("listener has no more events " + "available at this time") + else: + if self.trace_on: + print("timeout occurred waiting for event...") + timeout_count += 1 + self.listener.Clear() + except Exception as e: + self.exception = e + + def setUp(self): + # Call super's setUp(). + super(DarwinLogEventBasedTestBase, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + # Enable debugserver logging of the darwin log collection + # mechanism. + self.runCmd("settings set target.process.extra-startup-command " + "QSetLogging:bitmask=LOG_DARWIN_LOG;") + + def do_test(self, enable_options, settings_commands=None, + run_enable_after_breakpoint=False, max_entry_count=None): + """Runs the test inferior, returning collected events. + + This method runs the test inferior to the first breakpoint hit. + It then adds a listener for structured data events, and collects + all events from that point forward until end of execution of the + test inferior. It then returns those events. + + @return + A list of structured data events received, in the order they + were received. + """ + self.build(dictionary=self.d) + self.setTearDownCleanup(dictionary=self.d) + + exe = os.path.join(os.getcwd(), self.exe_name) + + # Create a target by the debugger. + target = self.dbg.CreateTarget(exe) + self.assertTrue(target, lldbtest.VALID_TARGET) + + # Run the darwin-log settings commands. + if settings_commands is not None: + for setting_command in settings_commands: + self.runCmd( + expand_darwinlog_settings_set_command(setting_command)) + + # Build the darwin-log enable command. + enable_cmd = expand_darwinlog_command("enable") + if enable_options is not None and len(enable_options) > 0: + enable_cmd += ' ' + ' '.join(enable_options) + + # Run the darwin-log enable command now if we are not supposed + # to do it at the first breakpoint. This tests the start-up + # code, which has the benefit of being able to set os_log-related + # environment variables. + if not run_enable_after_breakpoint: + self.runCmd(enable_cmd) + + # Create the breakpoint. + breakpoint = target.BreakpointCreateByLocation(self.source, self.line) + self.assertIsNotNone(breakpoint) + self.assertTrue(breakpoint.IsValid()) + self.assertEqual(1, breakpoint.GetNumLocations(), + "Should have found one breakpoint") + + # Enable packet logging. + # self.runCmd("log enable -f /tmp/packets.log gdb-remote packets") + # self.runCmd("log enable lldb process") + + # Launch the process - doesn't stop at entry. + process = target.LaunchSimple(None, None, os.getcwd()) + self.assertIsNotNone(process, lldbtest.PROCESS_IS_VALID) + + # Keep track of whether we're tracing output. + trace_on = self.TraceOn() + + # Get the next thread that stops. + from lldbsuite.test.lldbutil import get_stopped_thread + thread = get_stopped_thread(process, lldb.eStopReasonBreakpoint) + + self.assertIsNotNone(thread, "There should be a thread stopped " + "due to breakpoint") + + # The process should be stopped at this point. + self.expect("process status", lldbtest.PROCESS_STOPPED, + patterns=['Process .* stopped']) + + # The stop reason of the thread should be breakpoint. + self.expect("thread list", lldbtest.STOPPED_DUE_TO_BREAKPOINT, + substrs=['stopped', 'stop reason = breakpoint']) + + # And our one and only breakpoint should have been hit. + self.assertEquals(breakpoint.GetHitCount(), 1) + + # Now setup the structured data listener. + # + # Grab the broadcaster for the process. We'll be attaching our + # listener to it. + broadcaster = process.GetBroadcaster() + self.assertIsNotNone(broadcaster) + + listener = lldb.SBListener("SBStructuredData listener") + self.assertIsNotNone(listener) + + rc = broadcaster.AddListener(listener, + lldb.SBProcess.eBroadcastBitStructuredData) + self.assertTrue(rc, "Successfully add listener to process broadcaster") + + # Start the listening thread to retrieve the events. + # Bump up max entry count for the potentially included Add Mode: + # entry. + if max_entry_count is not None: + max_entry_count += 1 + event_thread = self.EventListenerThread(listener, process, trace_on, + max_entry_count) + event_thread.start() + + # Continue the test inferior. We should get any events after this. + process.Continue() + + # Wait until the event thread terminates. + # print("main thread now waiting for event thread to receive events.") + event_thread.join() + + # If the process is still alive, we kill it here. + if process.is_alive: + process.Kill() + + # Fail on any exceptions that occurred during event execution. + if event_thread.exception is not None: + # Re-raise it here so it shows up as a test error. + raise event_thread + + # Return the collected logging events. + return remove_add_mode_entry(event_thread.log_entries) diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/Makefile new file mode 100644 index 00000000000..b09a579159d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/TestDarwinLogBasic.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/TestDarwinLogBasic.py new file mode 100644 index 00000000000..5b18647e3fc --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/TestDarwinLogBasic.py @@ -0,0 +1,34 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +# System imports +from __future__ import print_function + +# LLDB imports +from lldbsuite.test import darwin_log +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest + + +class TestDarwinLogBasic(darwin_log.DarwinLogEventBasedTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + @decorators.add_test_categories(['pyapi']) + @decorators.skipUnlessDarwin + def test_SBStructuredData_gets_broadcasted(self): + """Exercise SBStructuredData API.""" + + # Run the test. + log_entries = self.do_test(None, max_entry_count=2) + + # Validate that we received our two log entries. + self.assertEqual(len(log_entries), 1, + "Expected one log entry to arrive via events.") + self.assertEqual(log_entries[0]['message'], "Hello, world", + "Log message should match expected content.") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/main.c new file mode 100644 index 00000000000..e6554564411 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/main.c @@ -0,0 +1,32 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/log.h> +#include <stdio.h> + +#include "../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger = os_log_create("org.llvm.lldb.test", "basic-test"); + if (!logger) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_log(logger, "Hello, world"); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/common/darwin_log_common.h b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/common/darwin_log_common.h new file mode 100644 index 00000000000..de923b94911 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/common/darwin_log_common.h @@ -0,0 +1,6 @@ +// The number of seconds to wait at the end of the test inferior before +// exiting. This delay is needed to ensure the logging infrastructure +// has flushed out the message. If we finished before all messages were +// flushed, then the test will never see the unflushed messages, causing +// some test logic to fail. +#define FINAL_WAIT_SECONDS 5 diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/TestDarwinLogFilterMatchActivityChain.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/TestDarwinLogFilterMatchActivityChain.py new file mode 100644 index 00000000000..fca56dd93a8 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/TestDarwinLogFilterMatchActivityChain.py @@ -0,0 +1,117 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterMatchActivityChain(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterMatchActivityChain, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterMatchActivityChain, self).tearDown() + + # ========================================================================== + # activity-chain filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_chain_match(self): + """Test that fall-through reject, accept full-match activity chain works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity-chain match " + "parent-activity:child-activity\""]) + + # We should only see the second log message as we only accept + # that activity. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_reject_activity_chain_partial_match(self): + """Test that fall-through reject, doesn't accept only partial match of activity-chain.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity-chain match parent-activity:child-activity\"", # Match the second fully. + "--filter \"accept activity-chain match parent-ac\""]) # Only partially match the first. + + # We should only see the second log message as we only accept + # that activity. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_reject_activity_chain_full_match(self): + """Test that fall-through accept, reject match activity-chain works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject activity-chain match parent-activity\""]) + + # We should only see the second log message as we rejected the first + # via activity-chain rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_chain_second_rule(self): + """Test that fall-through reject, accept activity-chain on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity-chain match non-existent\"", + "--filter \"accept activity-chain match parent-activity:child-activity\""]) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the activity-chain of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/main.c new file mode 100644 index 00000000000..c93474eedb0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_log(logger_sub1, "source-log-sub1-cat1"); + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub2, "source-log-sub2-cat2"); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/TestDarwinLogFilterMatchActivity.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/TestDarwinLogFilterMatchActivity.py new file mode 100644 index 00000000000..edb5914bfbf --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/TestDarwinLogFilterMatchActivity.py @@ -0,0 +1,121 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterMatchActivity(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterMatchActivity, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterMatchActivity, self).tearDown() + + # ========================================================================== + # activity filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_match(self): + """Test that fall-through reject, accept match activity works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity match child-activity\""] + ) + + # We should only see the second log message as we only accept + # that activity. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_reject_activity_partial_match(self): + """Test that fall-through reject, accept match activity via partial match does not accept.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity match child-activity\"", # Fully match second message. + "--filter \"accept activity match parent-\""] # Only partially match first message. + ) + + # We should only see the second log message as we only accept + # that activity. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_reject_activity_full_match(self): + """Test that fall-through accept, reject match activity works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject activity match parent-activity\""] + ) + + # We should only see the second log message as we rejected the first + # via activity rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_second_rule(self): + """Test that fall-through reject, accept regex activity on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity match non-existent\"", + "--filter \"accept activity match child-activity\"" + ] + ) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the activity of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/main.c new file mode 100644 index 00000000000..c93474eedb0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_log(logger_sub1, "source-log-sub1-cat1"); + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub2, "source-log-sub2-cat2"); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/TestDarwinLogFilterMatchCategory.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/TestDarwinLogFilterMatchCategory.py new file mode 100644 index 00000000000..21d8bfb9d6a --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/TestDarwinLogFilterMatchCategory.py @@ -0,0 +1,118 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterMatchCategory(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterMatchCategory, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterMatchCategory, self).tearDown() + + # ========================================================================== + # category filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_filter_accept_category_full_match(self): + """Test that fall-through reject, accept match single category works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept category match cat2\""] + ) + + # We should only see the second log message as we only accept + # that category. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_category_partial_match(self): + """Test that fall-through reject, accept regex category via partial match works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept category match cat2\"", # Fully match the second message. + "--filter \"accept category match at1\""] # Only partially match first message. Should not show up. + ) + + # We should only see the second log message as we only accept + # that category. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_category_full_match(self): + """Test that fall-through accept, reject match category works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject category match cat1\""] + ) + + # We should only see the second log message as we rejected the first + # via category rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_accept_category_second_rule(self): + """Test that fall-through reject, accept match category on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept category match non-existent\"", + "--filter \"accept category match cat2\"" + ] + ) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the category of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/main.c new file mode 100644 index 00000000000..c93474eedb0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_log(logger_sub1, "source-log-sub1-cat1"); + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub2, "source-log-sub2-cat2"); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/TestDarwinLogFilterMatchMessage.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/TestDarwinLogFilterMatchMessage.py new file mode 100644 index 00000000000..c9b05184e36 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/TestDarwinLogFilterMatchMessage.py @@ -0,0 +1,132 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterMatchMessage(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterMatchMessage, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + self.strict_sources = True + + # Turn on process monitor logging while we work out issues. + self.enable_process_monitor_logging = True + + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterMatchMessage, self).tearDown() + + # ========================================================================== + # category filter tests + # ========================================================================== + + EXPECT_REGEXES = [ + re.compile(r"log message ([^-]+)-(\S+)"), + re.compile(r"exited with status") + ] + + @decorators.skipUnlessDarwin + def test_filter_accept_message_full_match(self): + """Test that fall-through reject, accept match whole message works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept message match log message sub2-cat2\""], + expect_regexes=self.EXPECT_REGEXES + ) + + # We should only see the second log message as we only accept + # that message contents. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_no_accept_message_partial_match(self): + """Test that fall-through reject, match message via partial content match doesn't accept.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept message match log message sub2-cat2\"", + "--filter \"accept message match sub1-cat1\""], + expect_regexes=self.EXPECT_REGEXES + ) + + # We should only see the second log message as the partial match on + # the first message should not pass. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_category_full_match(self): + """Test that fall-through accept, reject match message works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject message match log message sub1-cat1\""], + expect_regexes=self.EXPECT_REGEXES + ) + + # We should only see the second log message as we rejected the first + # via message contents rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_accept_category_second_rule(self): + """Test that fall-through reject, accept match category on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept message match non-existent\"", + "--filter \"accept message match log message sub2-cat2\""], + expect_regexes=self.EXPECT_REGEXES + ) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the category of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/main.c new file mode 100644 index 00000000000..f851e23d880 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/main.c @@ -0,0 +1,35 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_log(logger_sub1, "log message sub%d-cat%d", 1, 1); + os_log(logger_sub2, "log message sub%d-cat%d", 2, 2); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(1); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/TestDarwinLogFilterMatchSubsystem.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/TestDarwinLogFilterMatchSubsystem.py new file mode 100644 index 00000000000..e9cfa7def13 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/TestDarwinLogFilterMatchSubsystem.py @@ -0,0 +1,118 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterMatchSubsystem(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterMatchSubsystem, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterMatchSubsystem, self).tearDown() + + # ========================================================================== + # subsystem filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_filter_accept_subsystem_full_match(self): + """Test that fall-through reject, accept match single subsystem works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept subsystem match org.llvm.lldb.test.sub2\""] + ) + + # We should only see the second log message as we only accept + # that subsystem. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_subsystem_partial_match(self): + """Test that fall-through reject, doesn't accept match subsystem via partial-match.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept subsystem match org.llvm.lldb.test.sub2\"", # Fully match second message subsystem. + "--filter \"accept subsystem match sub1\""] # Only partially match first subsystem. + ) + + # We should only see the second log message as we only accept + # that subsystem. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_subsystem_full_match(self): + """Test that fall-through accept, reject match subsystem works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject subsystem match org.llvm.lldb.test.sub1\""] + ) + + # We should only see the second log message as we rejected the first + # via subsystem rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_accept_subsystem_second_rule(self): + """Test that fall-through reject, accept match subsystem on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept subsystem match non-existent\"", + "--filter \"accept subsystem match org.llvm.lldb.test.sub2\"" + ] + ) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the subsystem of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/main.c new file mode 100644 index 00000000000..c93474eedb0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_log(logger_sub1, "source-log-sub1-cat1"); + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub2, "source-log-sub2-cat2"); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/TestDarwinLogFilterRegexActivityChain.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/TestDarwinLogFilterRegexActivityChain.py new file mode 100644 index 00000000000..a2f5abf1a54 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/TestDarwinLogFilterRegexActivityChain.py @@ -0,0 +1,132 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterRegexActivityChain(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterRegexActivityChain, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterRegexActivityChain, self).tearDown() + + # ========================================================================== + # activity-chain filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_chain_full_match(self): + """Test that fall-through reject, accept full-match activity chain works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity-chain regex " + "parent-activity:child-activity\""]) + + # We should only see the second log message as we only accept + # that activity. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_chain_partial_match(self): + """Test that fall-through reject, accept activity-chain via partial match works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity-chain regex :child-activity\""]) + + # We should only see the second log message as we only accept + # that activity. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_reject_activity_chain_full_match(self): + """Test that fall-through accept, reject activity-chain works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject activity-chain regex parent-activity:child-..tivity\""]) + + # We should only see the second log message as we rejected the first + # via activity-chain rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat1"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_reject_activity_chain_partial_match(self): + """Test that fall-through accept, reject activity-chain by partial match works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject activity-chain regex ^p[^:]+$\""]) + + # We should only see the second log message as we rejected the first + # via activity-chain rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_chain_second_rule(self): + """Test that fall-through reject, accept activity-chain on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity-chain regex non-existent\"", + "--filter \"accept activity-chain regex child-activity\""]) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the activity-chain of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/main.c new file mode 100644 index 00000000000..c93474eedb0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_log(logger_sub1, "source-log-sub1-cat1"); + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub2, "source-log-sub2-cat2"); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/TestDarwinLogFilterRegexActivity.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/TestDarwinLogFilterRegexActivity.py new file mode 100644 index 00000000000..286ad72953b --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/TestDarwinLogFilterRegexActivity.py @@ -0,0 +1,137 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterRegexActivity(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterRegexActivity, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterRegexActivity, self).tearDown() + + # ========================================================================== + # activity filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_full_match(self): + """Test that fall-through reject, accept regex full-match activity works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity regex child-activity\""] + ) + + # We should only see the second log message as we only accept + # that activity. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_partial_match(self): + """Test that fall-through reject, regex accept activity via partial match works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity regex child-.*\""] + ) + + # We should only see the second log message as we only accept + # that activity. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_reject_activity_full_match(self): + """Test that fall-through accept, reject regex activity works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject activity regex parent-activity\""] + ) + + # We should only see the second log message as we rejected the first + # via activity rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_reject_activity_partial_match(self): + """Test that fall-through accept, reject regex activity by partial match works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject activity regex p.+-activity\""] + ) + + # We should only see the second log message as we rejected the first + # via activity rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + + @decorators.skipUnlessDarwin + def test_filter_accept_activity_second_rule(self): + """Test that fall-through reject, accept regex activity on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept activity regex non-existent\"", + "--filter \"accept activity regex child-activity\"" + ] + ) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the activity of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/main.c new file mode 100644 index 00000000000..c93474eedb0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_log(logger_sub1, "source-log-sub1-cat1"); + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub2, "source-log-sub2-cat2"); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/TestDarwinLogFilterRegexCategory.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/TestDarwinLogFilterRegexCategory.py new file mode 100644 index 00000000000..0389f624e61 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/TestDarwinLogFilterRegexCategory.py @@ -0,0 +1,133 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterRegexCategory(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterRegexCategory, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterRegexCategory, self).tearDown() + + # ========================================================================== + # category filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_filter_accept_category_full_match(self): + """Test that fall-through reject, accept regex single category works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept category regex cat2\""] + ) + + # We should only see the second log message as we only accept + # that category. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_accept_category_partial_match(self): + """Test that fall-through reject, accept regex category via partial match works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept category regex .+2\""] + ) + + # We should only see the second log message as we only accept + # that category. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_category_full_match(self): + """Test that fall-through accept, reject regex category works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject category regex cat1\""] + ) + + # We should only see the second log message as we rejected the first + # via category rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_category_partial_match(self): + """Test that fall-through accept, reject regex category by partial match works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject category regex t1\""] + ) + + # We should only see the second log message as we rejected the first + # via category rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_accept_category_second_rule(self): + """Test that fall-through reject, accept regex category on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept category regex non-existent\"", + "--filter \"accept category regex cat2\"" + ] + ) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the category of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/main.c new file mode 100644 index 00000000000..c93474eedb0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_log(logger_sub1, "source-log-sub1-cat1"); + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub2, "source-log-sub2-cat2"); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/TestDarwinLogFilterRegexMessage.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/TestDarwinLogFilterRegexMessage.py new file mode 100644 index 00000000000..e25834a4003 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/TestDarwinLogFilterRegexMessage.py @@ -0,0 +1,118 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +# System imports +from __future__ import print_function + +import re + +# LLDB imports +import lldb + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterRegexMessage(darwin_log.DarwinLogEventBasedTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + @decorators.skipUnlessDarwin + def test_filter_accept_message_full_match(self): + """Test that fall-through reject, accept regex whole message works.""" + log_entries = self.do_test( + ["--no-match-accepts false", + # Note below, the four '\' characters are to get us two + # backslashes over on the gdb-remote side, which then + # becomes one as the cstr interprets it as an escape + # sequence. This needs to be rationalized. Initially I + # supported std::regex ECMAScript, which has the + # [[:digit:]] character classes and such. That was much + # more tenable. The backslashes have to travel through + # so many layers of escaping. (And note if you take + # off the Python raw string marker here, you need to put + # in 8 backslashes to go to two on the remote side.) + r'--filter "accept message regex log message sub2-cat\\\\d+"']) + + # We should have received at least one log entry. + self.assertIsNotNone(log_entries, + "Log entry list should not be None.") + self.assertEqual(len(log_entries), 1, + "Should receive one log entry.") + self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2", + "First os_log call should have been skipped.") + + @decorators.skipUnlessDarwin + def test_filter_accept_message_partial_match(self): + """Test that fall-through reject, accept regex message via partial + match works.""" + log_entries = self.do_test( + ["--no-match-accepts false", + "--filter \"accept message regex [^-]+2\""]) + + # We should only see the second log message as we only accept + # that message contents. + self.assertIsNotNone(log_entries, + "Log entry list should not be None.") + self.assertEqual(len(log_entries), 1, + "Should receive one log entry.") + self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2", + "First os_log call should have been skipped.") + + @decorators.skipUnlessDarwin + def test_filter_reject_message_full_match(self): + """Test that fall-through accept, reject regex message works.""" + log_entries = self.do_test( + ["--no-match-accepts true", + "--filter \"reject message regex log message sub1-cat1\""]) + + # We should only see the second log message as we rejected the first + # via message contents rejection. + self.assertIsNotNone(log_entries, + "Log entry list should not be None.") + self.assertEqual(len(log_entries), 1, + "Should receive one log entry.") + self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2", + "First os_log call should have been skipped.") + + @decorators.skipUnlessDarwin + def test_filter_reject_message_partial_match(self): + """Test that fall-through accept, reject regex message by partial + match works.""" + log_entries = self.do_test( + ["--no-match-accepts true", + "--filter \"reject message regex t1\""]) + + # We should only see the second log message as we rejected the first + # via partial message contents rejection. + self.assertIsNotNone(log_entries, + "Log entry list should not be None.") + self.assertEqual(len(log_entries), 1, + "Should receive one log entry.") + self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2", + "First os_log call should have been skipped.") + + @decorators.skipUnlessDarwin + def test_filter_accept_message_second_rule(self): + """Test that fall-through reject, accept regex message on second rule + works.""" + log_entries = self.do_test( + ["--no-match-accepts false", + "--filter \"accept message regex non-existent\"", + "--filter \"accept message regex cat2\""]) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the message of the second log message. + self.assertIsNotNone(log_entries, + "Log entry list should not be None.") + self.assertEqual(len(log_entries), 1, + "Should receive one log entry.") + self.assertRegexpMatches(log_entries[0]["message"], r"sub2-cat2", + "First os_log call should have been skipped.") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/main.c new file mode 100644 index 00000000000..5648ddae74b --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/main.c @@ -0,0 +1,35 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_log(logger_sub1, "log message sub%d-cat%d", 1, 1); + os_log(logger_sub2, "log message sub%d-cat%d", 2, 2); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/Makefile new file mode 100644 index 00000000000..4f4176f23f3 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/TestDarwinLogFilterRegexSubsystem.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/TestDarwinLogFilterRegexSubsystem.py new file mode 100644 index 00000000000..2134977aa94 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/TestDarwinLogFilterRegexSubsystem.py @@ -0,0 +1,150 @@ +""" +Test basic DarwinLog functionality provided by the StructuredDataDarwinLog +plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogFilterRegexSubsystem(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogFilterRegexSubsystem, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogFilterRegexSubsystem, self).tearDown() + + # ========================================================================== + # basic filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_fallthrough_reject(self): + """Test that a single fall-through reject regex rule rejects all logging.""" + self.do_test( + ["--no-match-accepts false"] + ) + + # We should not match any log lines. + self.assertIsNotNone(self.child.match) + self.assertFalse((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) in ["sub1", "sub2"]), + "log line should not have been received") + + # ========================================================================== + # subsystem filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_filter_accept_subsystem_full_match(self): + """Test that fall-through reject, accept regex single subsystem works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept subsystem regex org.llvm.lldb.test.sub2\""] + ) + + # We should only see the second log message as we only accept + # that subsystem. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_accept_subsystem_partial_match(self): + """Test that fall-through reject, accept regex subsystem via partial-match works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept subsystem regex org.llvm.+.sub2\""] + ) + + # We should only see the second log message as we only accept + # that subsystem. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_subsystem_full_match(self): + """Test that fall-through accept, reject regex subsystem works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject subsystem regex org.llvm.lldb.test.sub1\""] + ) + + # We should only see the second log message as we rejected the first + # via subsystem rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_reject_subsystem_partial_match(self): + """Test that fall-through accept, reject regex subsystem by partial match works.""" + self.do_test( + ["--no-match-accepts true", + "--filter \"reject subsystem regex org.*sub1\""] + ) + + # We should only see the second log message as we rejected the first + # via subsystem rejection. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_filter_accept_subsystem_second_rule(self): + """Test that fall-through reject, accept regex subsystem on second rule works.""" + self.do_test( + ["--no-match-accepts false", + "--filter \"accept subsystem regex non-existent\"", + "--filter \"accept subsystem regex org.llvm.lldb.test.sub2\"" + ] + ) + + # We should only see the second message since we reject by default, + # the first filter doesn't match any, and the second filter matches + # the subsystem of the second log message. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) == "sub2"), + "first log line should not be present, second log line " + "should be") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/main.c new file mode 100644 index 00000000000..c93474eedb0 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/main.c @@ -0,0 +1,43 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_log(logger_sub1, "source-log-sub1-cat1"); + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub2, "source-log-sub2-cat2"); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/Makefile new file mode 100644 index 00000000000..b09a579159d --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/TestDarwinLogMessageFormat.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/TestDarwinLogMessageFormat.py new file mode 100644 index 00000000000..c5d98ae208e --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/TestDarwinLogMessageFormat.py @@ -0,0 +1,189 @@ +""" +Test DarwinLog log message formatting options provided by the +StructuredDataDarwinLog plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogMessageFormat(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogMessageFormat, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogMessageFormat, self).tearDown() + + # ========================================================================== + # Test settings around log message formatting + # ========================================================================== + + REGEXES = [ + re.compile(r"\[([^]]+)\] This is the log message."), # Match log + # with header. + re.compile(r"This is the log message."), # Match no-header content. + re.compile(r"exited with status") # Fallback if no log emitted. + ] + + @decorators.skipUnlessDarwin + def test_display_without_header_works(self): + """Test that turning off log message headers works as advertised.""" + self.do_test([], expect_regexes=self.REGEXES) + + # We should not match the first pattern as we shouldn't have header + # content. + self.assertIsNotNone(self.child.match) + self.assertFalse((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) != ""), + "we should not have seen a header") + + + @decorators.skipUnlessDarwin + def test_display_with_header_works(self): + """Test that displaying any header works.""" + self.do_test( + ["--timestamp-relative", "--subsystem", "--category", + "--activity-chain"], + expect_regexes=self.REGEXES, + settings_commands=[ + "display-header true" + ]) + + # We should match the first pattern as we should have header + # content. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) != ""), + "we should have printed a header") + + def assert_header_contains_timestamp(self, header): + fields = header.split(',') + self.assertGreater(len(fields), 0, + "there should have been header content present") + self.assertRegexpMatches(fields[0], + r"^\d+:\d{2}:\d{2}.\d{9}$", + "time field should match expected format") + + @decorators.skipUnlessDarwin + def test_header_timefield_only_works(self): + """Test that displaying a header with only the timestamp works.""" + self.do_test(["--timestamp-relative"], expect_regexes=self.REGEXES) + + # We should match the first pattern as we should have header + # content. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) != ""), + "we should have printed a header") + header = self.child.match.group(1) + self.assertEqual(len(header.split(',')), 1, + "there should only be one header field") + self.assert_header_contains_timestamp(header) + + @decorators.skipUnlessDarwin + def test_header_subsystem_only_works(self): + """Test that displaying a header with only the subsystem works.""" + self.do_test(["--subsystem"], expect_regexes=self.REGEXES) + + # We should match the first pattern as we should have header + # content. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) != ""), + "we should have printed a header") + header = self.child.match.group(1) + self.assertEqual(len(header.split(',')), 1, + "there should only be one header field") + self.assertEquals(header, + "subsystem=org.llvm.lldb.test.sub1") + + @decorators.skipUnlessDarwin + def test_header_category_only_works(self): + """Test that displaying a header with only the category works.""" + self.do_test(["--category"], expect_regexes=self.REGEXES) + + # We should match the first pattern as we should have header + # content. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) != ""), + "we should have printed a header") + header = self.child.match.group(1) + self.assertEqual(len(header.split(',')), 1, + "there should only be one header field") + self.assertEquals(header, + "category=cat1") + + @decorators.skipUnlessDarwin + def test_header_activity_chain_only_works(self): + """Test that displaying a header with only the activity chain works.""" + self.do_test(["--activity-chain"], expect_regexes=self.REGEXES) + + # We should match the first pattern as we should have header + # content. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 0) and + (self.child.match.group(1) != ""), + "we should have printed a header") + header = self.child.match.group(1) + self.assertEqual(len(header.split(',')), 1, + "there should only be one header field") + self.assertEquals(header, + "activity-chain=parent-activity:child-activity") + + # @decorators.skipUnlessDarwin + # def test_header_activity_no_chain_only_works(self): + # """Test that displaying a header with only the activity works.""" + # self.do_test( + # [], + # expect_regexes=self.REGEXES, + # settings_commands=[ + # "display-header true", + # "format-include-timestamp false", + # "format-include-activity true", + # "format-include-category false", + # "format-include-subsystem false", + # "display-activity-chain false" + # ]) + + # # We should match the first pattern as we should have header + # # content. + # self.assertIsNotNone(self.child.match) + # self.assertTrue((len(self.child.match.groups()) > 0) and + # (self.child.match.group(1) != ""), + # "we should have printed a header") + # header = self.child.match.group(1) + # self.assertEqual(len(header.split(',')), 1, + # "there should only be one header field") + # self.assertEquals(header, + # "activity=child-activity") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/main.c new file mode 100644 index 00000000000..e371a547438 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/main.c @@ -0,0 +1,41 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/activity.h> +#include <os/log.h> +#include <stdio.h> + +#include "../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + if (!logger_sub1) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_activity_t parent_activity = os_activity_create("parent-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(parent_activity, ^{ + os_activity_t child_activity = os_activity_create("child-activity", + OS_ACTIVITY_CURRENT, OS_ACTIVITY_FLAG_DEFAULT); + os_activity_apply(child_activity, ^{ + os_log(logger_sub1, "This is the log message."); + }); + }); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/Makefile new file mode 100644 index 00000000000..214cedd96f1 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/TestDarwinLogSourceDebug.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/TestDarwinLogSourceDebug.py new file mode 100644 index 00000000000..d44437cd14b --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/TestDarwinLogSourceDebug.py @@ -0,0 +1,79 @@ +""" +Test DarwinLog "source include debug-level" functionality provided by the +StructuredDataDarwinLog plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogSourceDebug(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogSourceDebug, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + # Indicate we want strict-sources behavior. + self.strict_sources = True + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogSourceDebug, self).tearDown() + + # ========================================================================== + # source include/exclude debug filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + def test_source_default_exclude_debug(self): + """Test that default excluding of debug-level log messages works.""" + self.do_test([]) + + # We should only see the second log message as the first is a + # debug-level message and we're not including debug-level messages. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_source_explicitly_include_debug(self): + """Test that explicitly including debug-level log messages works.""" + self.do_test(["--debug"]) + + # We should only see the second log message as the first is a + # debug-level message and we're not including debug-level messages. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat1"), + "first log line should be present since we're " + "including debug-level log messages") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/main.c new file mode 100644 index 00000000000..1f5cd1aa6c7 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/main.c @@ -0,0 +1,34 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/log.h> +#include <stdio.h> + +#include "../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_log_debug(logger_sub1, "source-log-sub1-cat1"); + os_log(logger_sub2, "source-log-sub2-cat2"); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/Makefile b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/Makefile new file mode 100644 index 00000000000..214cedd96f1 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/Makefile @@ -0,0 +1,5 @@ +LEVEL = ../../../../make + +C_SOURCES := main.c + +include $(LEVEL)/Makefile.rules diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/TestDarwinLogSourceInfo.py b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/TestDarwinLogSourceInfo.py new file mode 100644 index 00000000000..d47d85a27fd --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/TestDarwinLogSourceInfo.py @@ -0,0 +1,82 @@ +""" +Test DarwinLog "source include info-level" functionality provided by the +StructuredDataDarwinLog plugin. + +These tests are currently only supported when running against Darwin +targets. +""" + +from __future__ import print_function + +import lldb +import os +import re + +from lldbsuite.test import decorators +from lldbsuite.test import lldbtest +from lldbsuite.test import darwin_log + + +class TestDarwinLogSourceInfo(darwin_log.DarwinLogTestBase): + + mydir = lldbtest.TestBase.compute_mydir(__file__) + + def setUp(self): + # Call super's setUp(). + super(TestDarwinLogSourceInfo, self).setUp() + + # Source filename. + self.source = 'main.c' + + # Output filename. + self.exe_name = 'a.out' + self.d = {'C_SOURCES': self.source, 'EXE': self.exe_name} + + # Locate breakpoint. + self.line = lldbtest.line_number(self.source, '// break here') + + # Indicate we want strict-sources behavior. + self.strict_sources = True + + def tearDown(self): + # Shut down the process if it's still running. + if self.child: + self.runCmd('process kill') + self.expect_prompt() + self.runCmd('quit') + + # Let parent clean up + super(TestDarwinLogSourceInfo, self).tearDown() + + # ========================================================================== + # source include/exclude debug filter tests + # ========================================================================== + + @decorators.skipUnlessDarwin + @decorators.expectedFailureAll(bugnumber="rdar://27316264") + def test_source_exclude_info_level(self): + """Test that default excluding of info-level log messages works.""" + self.do_test([]) + + # We should only see the second log message as the first is an + # info-level message and we're not including debug-level messages. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat2"), + "first log line should not be present, second log line " + "should be") + + @decorators.skipUnlessDarwin + def test_source_include_info_level(self): + """Test that explicitly including info-level log messages works.""" + self.do_test( + ["--info"] + ) + + # We should only see the second log message as the first is a + # debug-level message and we're not including debug-level messages. + self.assertIsNotNone(self.child.match) + self.assertTrue((len(self.child.match.groups()) > 1) and + (self.child.match.group(2) == "cat1"), + "first log line should be present since we're " + "including info-level log messages") diff --git a/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/main.c b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/main.c new file mode 100644 index 00000000000..5ab6f39c007 --- /dev/null +++ b/lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/main.c @@ -0,0 +1,34 @@ +//===-- main.c --------------------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include <os/log.h> +#include <stdio.h> + +#include "../../common/darwin_log_common.h" + +int main(int argc, char** argv) +{ + os_log_t logger_sub1 = os_log_create("org.llvm.lldb.test.sub1", "cat1"); + os_log_t logger_sub2 = os_log_create("org.llvm.lldb.test.sub2", "cat2"); + if (!logger_sub1 || !logger_sub2) + return 1; + + // Note we cannot use the os_log() line as the breakpoint because, as of + // the initial writing of this test, we get multiple breakpoints for that + // line, which confuses the pexpect test logic. + printf("About to log\n"); // break here + os_log_info(logger_sub1, "source-log-sub1-cat1"); + os_log(logger_sub2, "source-log-sub2-cat2"); + + // Sleep, as the darwin log reporting doesn't always happen until a bit + // later. We need the message to come out before the process terminates. + sleep(FINAL_WAIT_SECONDS); + + return 0; +} |