Example #1
0
    def test_create_treemap_csv_different_stack_lengths(self):
        """
        Again, tests multidigit weights, now with bigger input

        """
        # The expected output
        expected = self.tmap.data_options.weight_units + ";" + \
                   ';'.join([str(i) for i in
                             range(1, self.tmap.display_options.depth + 1)]) + \
                   '\n' + \
                   "1;pname;call1;call2;call3\n" \
                   "2;pname;call1\n" \
                   "3;pname;call1;call2\n"

        data = iter(("00000" + consts.field_separator
                     + "pname;call1;call2;call3;call4;call5\n",
                     "000000000" + consts.field_separator + "pname;call1;call2\n",
                     "000" + consts.field_separator + "pname;call1;call2;call3"))
        datum_generator = (
            data_io.StackDatum(1, ('pname', 'call1', 'call2', 'call3')),
            data_io.StackDatum(2, ('pname', 'call1')),
            data_io.StackDatum(3, ('pname', 'call1', 'call2'))
        )

        data = data_io.StackData(datum_generator, None, None, None, None)

        out = self._get_output(data)

        # Check that we got the desired output
        self.assertEqual(expected, out)
Example #2
0
    def test_create_treemap_csv_multidigit(self):
        """
        Tests multidigit weight values

        """
        # The expected output
        expected = self.tmap.data_options.weight_units + ";" + \
                   ';'.join([str(i) for i in
                             range(1, self.tmap.display_options.depth + 1)]) + \
                   '\n' + \
                   "1;pname;call1;call2\n" \
                   "2;pname;call3;call4\n"

        # Get the output from a collapsed stack (first line in inpt is the
        # empty header
        datum_generator = (
            data_io.StackDatum(1, ('pname', 'call1', 'call2')),
            data_io.StackDatum(2, ('pname', 'call3', 'call4'))
        )

        data = data_io.StackData(datum_generator, None, None, None, None)

        outpt = self._get_output(data)

        # Check that we got the desired output
        self.assertEqual(expected, outpt)
Example #3
0
    def stack_collapse(self):
        """
        Goes through input line by line to fold the stacks.

        Calls the appropriate function to parse each line.
        Returns a generator to get single stacks lazily.

        :return:
            An iterable of tuples that contain information about stacks.

        """
        for line in self.data:
            # If end of stack, save cached data.
            if self._line_is_empty(line):
                # Matches empty line
                stack_folded = self._make_stack()
                if stack_folded:
                    # @@@ TODO: generalise to allow different weights
                    yield data_io.StackDatum(weight=1, stack=stack_folded)
            # event record start
            elif self._line_is_baseline(line):
                # Matches "perf script" output, first line of a stack
                self._parse_baseline(line)

            # stack line
            elif self._line_is_stackline(line):
                # Matches the other lines of a stack above the baseline
                self._parse_stackline(line)

            # if nothing matches, log an error
            else:
                logger.error("Unrecognized line: %s", line)
Example #4
0
 def test_to_string(self):
     """Test datapoints are correctly converted to strings."""
     sd = data_io.StackDatum(0, ('A', 'B'))
     expected = self.standard_field
     actual = str(sd)
     self.assertEqual(expected, actual, msg='Expected {}, got {}'
                      .format(expected, actual))
Example #5
0
    async def test_basic_collect(self):
        """
        Basic test case where everything should work as expected

        """
        mock_return_popen_stdout = str.encode(consts.field_separator.join(
            ["123123", "proc1", "func1", "func2"]) + "\n") + \
                                   str.encode(consts.field_separator.join(
            ["321321", "proc2", "func1", "func2", "func3"]) + "\n")

        expected = [
            data_io.StackDatum(123123, ("proc1", "func1", "func2")),
            data_io.StackDatum(321321, ("proc2", "func1", "func2", "func3"))
        ]

        output = await self.mock(mock_return_popen_stdout)
        self.assertEqual(expected, output)
Example #6
0
    async def test_strange_symbols(self):
        """
        Basic test case where everything should work as expected

        """
        mock_return_popen_stdout = b"123123" + \
                                   str.encode(consts.field_separator) +\
                                   b"1   []#'" + \
                                   str.encode(consts.field_separator) + \
                                   b"[]-=1   2=\n"

        expected = [data_io.StackDatum(123123, ("1   []#'", "[]-=1   2="))]

        output = await self.mock(mock_return_popen_stdout)
        self.assertEqual(output, expected)
Example #7
0
class _FlamegraphBaseTest(unittest.TestCase):
    """ Base class for flamegraph tests """
    coloring = 'test_color'
    weight_units = "kb"

    datum_generator = (
        data_io.StackDatum(1, ('2', '3', '4', '5'))
    )
    data = data_io.StackData(datum_generator, None, None, None, data_io.StackData.DataOptions("kb"))

    outfile = mock.MagicMock()
    outfilename = "test_output"
    outfile.__str__.return_value = outfilename
    file_mock = StringIO("")

    # Set up blank flamegraph
    fg = object.__new__(flamegraph.Flamegraph)

    fg.display_options = flamegraph.Flamegraph.DisplayOptions(coloring)
    fg.data_options = data_io.StackData.DataOptions("kb")
    fg.data = data
Example #8
0
    def test_StackParser_complete(self):

        # Example of a single stack from perf extracted stack data
        sample_stack = \
            "swapper     0 [003] 687886.672908:  108724462 cycles:ppp:\n" \
            "ffffffffa099768b intel_idle ([kernel.kallsyms])\n" \
            "ffffffffa07e5ce4 cpuidle_enter_state ([kernel.kallsyms])\n" \
            "ffffffffa07e5f97 cpuidle_enter ([kernel.kallsyms])\n" \
            "ffffffffa00d299c do_idle ([kernel.kallsyms])\n" \
            "ffffffffa00d2723 call_cpuidle ([kernel.kallsyms])\n" \
            "ffffffffa00d2be3 cpu_startup_entry ([kernel.kallsyms])\n" \
            "ffffffffa00581cb start_secondary ([kernel.kallsyms])\n" \
            "ffffffffa00000d5 secondary_startup_64 ([kernel.kallsyms])\n" \
            "\n"

        # Expected output data
        expected = [
            data_io.StackDatum(
                weight=1,
                stack=("swapper", "secondary_startup_64", "start_secondary",
                       "cpu_startup_entry", "call_cpuidle", "do_idle",
                       "cpuidle_enter", "cpuidle_enter_state", "intel_idle"))
        ]

        # # Mock a file with sample data
        # file_mock = StringIO("")
        # file_mock.writelines(sample_stack)
        # context_mock =  open_mock.return_value
        # context_mock.__enter__.return_value = file_mock

        self.stack_parser.data = StringIO(sample_stack)
        self.stack_parser.event_filter = ""

        # Run the whole stack_collapse function
        events = list(self.stack_parser.stack_collapse())

        self.assertEqual(expected, events)
Example #9
0
class MakeTest(_FlamegraphBaseTest):
    """ Test the flamegraph creation """

    # Set up test data and expected values
    test_stack_datums = [
        data_io.StackDatum(1, ('A1', 'A2', 'A3')),
        data_io.StackDatum(2, ('B1', 'B2', 'B3', 'B4')),
        data_io.StackDatum(3, ('A1', 'A2', 'A3'))
    ]

    test_stack_data = data_io.StackData(test_stack_datums, None, None, None,
                                        data_io.StackData.DataOptions("kb"))

    expected = collections.Counter({('A1', 'A2', 'A3'): 4,
                                    ('B1', 'B2', 'B3', 'B4'): 2})

    expected_temp_file = "A1;A2;A3 4\n" \
                         "B1;B2;B3;B4 2\n"

    @mock.patch('marple.display.interface.flamegraph.file')
    @mock.patch('builtins.open')
    @mock.patch('marple.display.interface.flamegraph.subprocess')
    def test_no_options(self, subproc_mock, open_mock, temp_file_mock):
        """ Test without display options """
        temp_file_mock.TempFileName.return_value.__str__.return_value = \
            "test_temp_file"

        fg = flamegraph.Flamegraph(self.test_stack_data)

        context_mock1, context_mock2 = mock.MagicMock(), mock.MagicMock()
        file_mock1, file_mock2 = StringIO(""), StringIO("")
        open_mock.side_effect = [context_mock1, context_mock2]
        context_mock1.__enter__.return_value = file_mock1
        context_mock2.__enter__.return_value = file_mock2

        actual = fg._make()

        temp_file_mock.TempFileName.return_value.__str__.\
            assert_has_calls((mock.call(), mock.call()))
        open_mock.assert_has_calls([
            mock.call("test_temp_file", "w"),
            mock.call("test_temp_file", "w")
        ])
        self.assertEqual(file_mock1.getvalue(), self.expected_temp_file)

        subproc_mock.Popen.assert_called_once_with(
            [flamegraph.FLAMEGRAPH_DIR, "--color=hot", "--countname=kb",
             "test_temp_file"],
            stdout=file_mock2
        )
        self.assertEqual(self.expected, actual)

    @mock.patch('marple.display.interface.flamegraph.file')
    @mock.patch('builtins.open')
    @mock.patch('marple.display.interface.flamegraph.subprocess')
    def test_with_coloring(self, subproc_mock, open_mock, temp_file_mock):
        """ Test with a options """
        temp_file_mock.TempFileName.return_value.__str__.return_value = \
            "test_temp_file"

        fg = flamegraph.Flamegraph(self.test_stack_data)

        context_mock1, context_mock2 = mock.MagicMock(), mock.MagicMock()
        file_mock1, file_mock2 = StringIO(""), StringIO("")
        open_mock.side_effect = [context_mock1, context_mock2]
        context_mock1.__enter__.return_value = file_mock1
        context_mock2.__enter__.return_value = file_mock2

        actual = fg._make()

        temp_file_mock.TempFileName.return_value.__str__.\
            assert_has_calls((mock.call(), mock.call()))
        open_mock.assert_has_calls([
            mock.call("test_temp_file", "w"),
            mock.call("test_temp_file", "w")
        ])
        self.assertEqual(file_mock1.getvalue(), self.expected_temp_file)
        subproc_mock.Popen.assert_called_once_with(
            [flamegraph.FLAMEGRAPH_DIR, '--color=hot', '--countname=kb',
             'test_temp_file'], stdout=file_mock2
        )
        self.assertEqual(self.expected, actual)
Example #10
0
 def test_without_newline(self):
     """Ensure from_string works without newlines"""
     expected = data_io.StackDatum(0, ('A', 'B'))
     self.check_from_str(self.standard_field, expected)
Example #11
0
 def test_with_newline_rn(self):
     """Ensure from_string copes with newlines"""
     expected = data_io.StackDatum(0, ('A', 'B'))
     self.check_from_str(self.standard_field + '\r\n', expected)