Exemple #1
0
    def test_insert_first_child_calls_memory_counter(self):
        mock_memory_counter = _mock_memory_counter()
        call_graph_node = CallGraphNode("foo", class_name=None, file_path=None, line_no=None,
                                        memory_counter=mock_memory_counter)

        call_graph_node.update_current_node_and_get_child(Frame("new_child_frame"))

        mock_memory_counter.count_first_child.assert_called_once()
        mock_memory_counter.count_add_child.assert_not_called()
Exemple #2
0
    def __init__(self, profiling_group_name, sampling_interval_seconds, host_weight, start, agent_debug_info, clock=time.time):
        """
        A profile holds the root node of the call graph and the metadata related to the profile
        """
        self.memory_counter = MemoryCounter()

        self.profiling_group_name = profiling_group_name
        self.callgraph = CallGraphNode(ROOT_NODE_NAME, class_name=None, file_path=None, line_no=None,
                                       memory_counter=self.memory_counter)
        self._validate_positive_number(start)
        self.start = start
        self.last_resume = start
        self.last_pause = None
        self._paused_ms = 0
        self._clock = clock
        self._end = None
        self.cpu_time_seconds = None
        self.total_attempted_sample_threads_count = 0
        self.total_seen_threads_count = 0
        self.total_sample_count = 0
        self.sampling_interval_ms = int(sampling_interval_seconds * 1000)
        self.host_weight = int(host_weight)
        self._start_process_time = time.process_time()  # provides process time in fractional seconds as float.
        self.overhead_ms = 0
        self.agent_debug_info = agent_debug_info
Exemple #3
0
        def test_it_matches_the_expected_size(self):
            node = CallGraphNode(frame_name=None,
                                 class_name=None,
                                 file_path=None,
                                 line_no=None)
            node.update_current_node_and_get_child(frame=Frame(None))

            recursive_node_storage_size = asizeof.asizeof(node.children)
            child_node_size = asizeof.asizeof(
                CallGraphNode(frame_name=None,
                              class_name=None,
                              file_path=None,
                              line_no=None))

            assert (MemoryCounter.base_storage_size_bytes == (
                recursive_node_storage_size - child_node_size))
Exemple #4
0
    def test_memory_count_called(self):
        mock_memory_counter = _mock_memory_counter()
        CallGraphNode("foo", class_name=None, file_path=None, line_no=None, memory_counter=mock_memory_counter)

        mock_memory_counter.count_create_node.assert_called_once()
        mock_memory_counter.count_first_child.assert_not_called()
        mock_memory_counter.count_add_child.assert_not_called()
Exemple #5
0
        def test_it_matches_the_expected_size(self):
            dummy_frame_name = None

            node = CallGraphNode(frame_name=dummy_frame_name,
                                 class_name=None,
                                 file_path=None,
                                 line_no=None)
            node.increase_runnable_count()

            full_recursive_size_of_node = asizeof.asizeof(node)

            frame_name_size = sys.getsizeof(dummy_frame_name)
            empty_children_tuple_size = sys.getsizeof(())

            assert (MemoryCounter.empty_node_size_bytes == \
                (full_recursive_size_of_node \
                    # The empty size should not include the frame name, so we subtract it

                    - frame_name_size
                    # The empty tuple is always reused by Python, so we also subtract it
                    - empty_children_tuple_size))
Exemple #6
0
    def test_insert_already_exist_child_does_not_call_memory_counter(self):
        mock_memory_counter = _mock_memory_counter()
        call_graph_node = CallGraphNode("foo", class_name=None, file_path=None, line_no=None,
                                        memory_counter=mock_memory_counter)
        call_graph_node.update_current_node_and_get_child(Frame("new_child_frame"))
        mock_memory_counter.reset_mock()

        call_graph_node.update_current_node_and_get_child(Frame("new_child_frame"))

        mock_memory_counter.assert_not_called()
Exemple #7
0
        def test_it_matches_the_expected_size(self):
            node = CallGraphNode(frame_name=None,
                                 class_name=None,
                                 file_path=None,
                                 line_no=None)

            node.update_current_node_and_get_child(Frame("child1"))
            one_child_storage_size = asizeof.asizeof(node.children, limit=0)

            node.update_current_node_and_get_child(Frame("child2"))
            two_children_storage_size = asizeof.asizeof(node.children, limit=0)

            assert (MemoryCounter.storage_increment_size_bytes == (
                two_children_storage_size - one_child_storage_size))
Exemple #8
0
class MemoryCounter:

    empty_node = CallGraphNode(frame_name="empty_node",
                               class_name=None,
                               file_path=None,
                               line_no=None)
    python_int_size = getsizeof(2**40)
    runnable_counter_size = python_int_size
    # As we store the min and max of line number for each frame, we would need to add these to our memory
    # estimation twice.
    line_no_size = 2 * python_int_size

    empty_node_size_bytes = getsizeof(empty_node) + runnable_counter_size
    base_storage_size_bytes = getsizeof((empty_node, ))
    storage_increment_size_bytes = getsizeof(
        (empty_node, empty_node)) - base_storage_size_bytes

    def __init__(self):
        self.memory_usage_bytes = 0

    def get_memory_usage_bytes(self):
        return self.memory_usage_bytes

    def count_create_node(self, frame, file_path, class_name):
        self.memory_usage_bytes += MemoryCounter.empty_node_size_bytes
        self.memory_usage_bytes += getsizeof(frame)
        self.memory_usage_bytes += getsizeof(file_path)
        self.memory_usage_bytes += getsizeof(class_name)
        # For simplicity, we assume all nodes contain line_no and we only expect root node and
        # duration metric node not to have line_no.
        self.memory_usage_bytes += MemoryCounter.line_no_size

    def count_first_child(self):
        self.memory_usage_bytes += MemoryCounter.base_storage_size_bytes

    def count_add_child(self):
        self.memory_usage_bytes += MemoryCounter.storage_increment_size_bytes
Exemple #9
0
 def before(self):
     self.subject = CallGraphNode("dummy_frame", None, file_path="file_path/file.py", line_no=123)
Exemple #10
0
 def test_when_a_custom_value_to_add_is_used_it_raises_a_value_error(self):
     subject = CallGraphNode("dummy_frame", class_name=None, file_path=None, line_no=None)
     with pytest.raises(ValueError):
         subject.increase_runnable_count(value_to_add=-1)
Exemple #11
0
    def test_when_a_custom_value_to_add_is_used_it_increases_the_runnable_count_by_the_value_to_add(self):
        subject = CallGraphNode("dummy_frame", class_name=None, file_path=None, line_no=None)
        subject.increase_runnable_count(value_to_add=2)

        assert (subject.runnable_count == 2)
Exemple #12
0
    def test_it_increases_the_runnable_count_by_one(self):
        subject = CallGraphNode("dummy_frame", class_name=None, file_path=None, line_no=None)
        subject.increase_runnable_count()

        assert (subject.runnable_count == 1)