| """ |
| 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 = self.getBuildArtifact("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") |