diff options
Diffstat (limited to 'packages/Python/lldbsuite/test/functionalities/darwin_log')
43 files changed, 2382 insertions, 0 deletions
diff --git a/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/Makefile new file mode 100644 index 000000000000..b09a579159d4 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/TestDarwinLogBasic.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/TestDarwinLogBasic.py new file mode 100644 index 000000000000..85281a97c572 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/TestDarwinLogBasic.py @@ -0,0 +1,35 @@ +""" +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 +    @decorators.expectedFailureAll(archs=["i386"], bugnumber="rdar://28655626") +    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/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/basic/main.c new file mode 100644 index 000000000000..e6554564411f --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/common/darwin_log_common.h b/packages/Python/lldbsuite/test/functionalities/darwin_log/common/darwin_log_common.h new file mode 100644 index 000000000000..de923b949116 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/TestDarwinLogFilterMatchActivityChain.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/TestDarwinLogFilterMatchActivityChain.py new file mode 100644 index 000000000000..f8ce069478fd --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/TestDarwinLogFilterMatchActivityChain.py @@ -0,0 +1,123 @@ +""" +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", +             # Match the second fully. +             "--filter \"accept activity-chain match parent-activity:child-activity\"", +             "--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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity-chain/main.c new file mode 100644 index 000000000000..c93474eedb01 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/TestDarwinLogFilterMatchActivity.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/TestDarwinLogFilterMatchActivity.py new file mode 100644 index 000000000000..12a430295a77 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/TestDarwinLogFilterMatchActivity.py @@ -0,0 +1,127 @@ +""" +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", +             # Fully match second message. +             "--filter \"accept activity match child-activity\"", +             "--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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/activity/main.c new file mode 100644 index 000000000000..c93474eedb01 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/TestDarwinLogFilterMatchCategory.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/TestDarwinLogFilterMatchCategory.py new file mode 100644 index 000000000000..8ce4d4135d18 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/TestDarwinLogFilterMatchCategory.py @@ -0,0 +1,127 @@ +""" +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", +             # Fully match the second message. +             "--filter \"accept category match cat2\"", +             "--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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/category/main.c new file mode 100644 index 000000000000..c93474eedb01 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/TestDarwinLogFilterMatchMessage.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/TestDarwinLogFilterMatchMessage.py new file mode 100644 index 000000000000..b7664ddd8071 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/TestDarwinLogFilterMatchMessage.py @@ -0,0 +1,147 @@ +""" +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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/message/main.c new file mode 100644 index 000000000000..f851e23d8800 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/TestDarwinLogFilterMatchSubsystem.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/TestDarwinLogFilterMatchSubsystem.py new file mode 100644 index 000000000000..5afe649e16a2 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/TestDarwinLogFilterMatchSubsystem.py @@ -0,0 +1,127 @@ +""" +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", +             # Fully match second message subsystem. +             "--filter \"accept subsystem match org.llvm.lldb.test.sub2\"", +             "--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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/exact_match/subsystem/main.c new file mode 100644 index 000000000000..c93474eedb01 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/TestDarwinLogFilterRegexActivityChain.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/TestDarwinLogFilterRegexActivityChain.py new file mode 100644 index 000000000000..74be57aeef85 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/TestDarwinLogFilterRegexActivityChain.py @@ -0,0 +1,138 @@ +""" +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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity-chain/main.c new file mode 100644 index 000000000000..c93474eedb01 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/TestDarwinLogFilterRegexActivity.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/TestDarwinLogFilterRegexActivity.py new file mode 100644 index 000000000000..55f015403d1f --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/TestDarwinLogFilterRegexActivity.py @@ -0,0 +1,143 @@ +""" +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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/activity/main.c new file mode 100644 index 000000000000..c93474eedb01 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/TestDarwinLogFilterRegexCategory.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/TestDarwinLogFilterRegexCategory.py new file mode 100644 index 000000000000..6786d6f009b0 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/TestDarwinLogFilterRegexCategory.py @@ -0,0 +1,143 @@ +""" +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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/category/main.c new file mode 100644 index 000000000000..c93474eedb01 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/TestDarwinLogFilterRegexMessage.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/TestDarwinLogFilterRegexMessage.py new file mode 100644 index 000000000000..eceedce2954e --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/TestDarwinLogFilterRegexMessage.py @@ -0,0 +1,128 @@ +""" +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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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 +    @decorators.expectedFailureAll(oslist=["macosx"], +                                   bugnumber="llvm.org/pr30299") +    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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/message/main.c new file mode 100644 index 000000000000..5648ddae74b8 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/Makefile new file mode 100644 index 000000000000..4f4176f23f3c --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/TestDarwinLogFilterRegexSubsystem.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/TestDarwinLogFilterRegexSubsystem.py new file mode 100644 index 000000000000..28677b54c75d --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/TestDarwinLogFilterRegexSubsystem.py @@ -0,0 +1,160 @@ +""" +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/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/filter/regex/subsystem/main.c new file mode 100644 index 000000000000..c93474eedb01 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/format/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/format/Makefile new file mode 100644 index 000000000000..b09a579159d4 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/format/TestDarwinLogMessageFormat.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/format/TestDarwinLogMessageFormat.py new file mode 100644 index 000000000000..65822cab430a --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/format/TestDarwinLogMessageFormat.py @@ -0,0 +1,188 @@ +""" +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/packages/Python/lldbsuite/test/functionalities/darwin_log/format/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/format/main.c new file mode 100644 index 000000000000..e371a547438a --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/Makefile new file mode 100644 index 000000000000..214cedd96f1a --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/TestDarwinLogSourceDebug.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/TestDarwinLogSourceDebug.py new file mode 100644 index 000000000000..85b8e30f6064 --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/TestDarwinLogSourceDebug.py @@ -0,0 +1,81 @@ +""" +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/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/source/debug/main.c new file mode 100644 index 000000000000..1f5cd1aa6c70 --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/Makefile b/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/Makefile new file mode 100644 index 000000000000..214cedd96f1a --- /dev/null +++ b/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/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/TestDarwinLogSourceInfo.py b/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/TestDarwinLogSourceInfo.py new file mode 100644 index 000000000000..44348374636d --- /dev/null +++ b/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/TestDarwinLogSourceInfo.py @@ -0,0 +1,84 @@ +""" +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/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/main.c b/packages/Python/lldbsuite/test/functionalities/darwin_log/source/info/main.c new file mode 100644 index 000000000000..5ab6f39c0079 --- /dev/null +++ b/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; +}  | 
