summaryrefslogtreecommitdiffstats
path: root/lldb/packages/Python/lldbsuite/test
diff options
context:
space:
mode:
Diffstat (limited to 'lldb/packages/Python/lldbsuite/test')
-rw-r--r--lldb/packages/Python/lldbsuite/test/darwin_log.py430
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/TestDarwinLogBasic.py34
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/main.c32
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/common/darwin_log_common.h6
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/TestDarwinLogFilterMatchActivityChain.py117
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/main.c43
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/TestDarwinLogFilterMatchActivity.py121
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/main.c43
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/TestDarwinLogFilterMatchCategory.py118
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/main.c43
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/TestDarwinLogFilterMatchMessage.py132
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/main.c35
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/TestDarwinLogFilterMatchSubsystem.py118
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/main.c43
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/TestDarwinLogFilterRegexActivityChain.py132
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/main.c43
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/TestDarwinLogFilterRegexActivity.py137
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/main.c43
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/TestDarwinLogFilterRegexCategory.py133
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/main.c43
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/TestDarwinLogFilterRegexMessage.py118
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/main.c35
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/TestDarwinLogFilterRegexSubsystem.py150
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/main.c43
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/TestDarwinLogMessageFormat.py189
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/format/main.c41
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/TestDarwinLogSourceDebug.py79
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/main.c34
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/Makefile5
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/TestDarwinLogSourceInfo.py82
-rw-r--r--lldb/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/main.c34
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;
+}
OpenPOWER on IntegriCloud