(python, blocking, method, tmpdir)
| 106 | |
| 107 | @all_pystack_combinations() |
| 108 | def test_multiple_thread_stack(python, blocking, method, tmpdir): |
| 109 | # GIVEN |
| 110 | |
| 111 | _, python_executable = python |
| 112 | |
| 113 | # WHEN |
| 114 | |
| 115 | with spawn_child_process( |
| 116 | python_executable, TEST_MULTIPLE_THREADS_FILE, tmpdir |
| 117 | ) as child_process: |
| 118 | with xfail_on_expected_exceptions(method): |
| 119 | threads = list( |
| 120 | get_process_threads( |
| 121 | child_process.pid, stop_process=blocking, method=method |
| 122 | ) |
| 123 | ) |
| 124 | |
| 125 | # THEN |
| 126 | |
| 127 | assert len(threads) == 4 |
| 128 | main_thread = [ |
| 129 | thread |
| 130 | for thread in threads |
| 131 | if "threading" not in thread.first_frame.code.filename |
| 132 | ][0] |
| 133 | other_threads = [thread for thread in threads if thread != main_thread] |
| 134 | |
| 135 | frames = list(main_thread.frames) |
| 136 | assert (len(frames)) == 4 |
| 137 | |
| 138 | filenames = {frame.code.filename for frame in frames} |
| 139 | assert filenames == {str(TEST_MULTIPLE_THREADS_FILE)} |
| 140 | |
| 141 | functions = [frame.code.scope for frame in frames] |
| 142 | assert functions == ["<module>", "first_func", "second_func", "third_func"] |
| 143 | |
| 144 | *line_numbers, last_line = [frame.code.location.lineno for frame in frames] |
| 145 | assert line_numbers == [42, 23, 27] |
| 146 | assert last_line in {38, 39} |
| 147 | |
| 148 | assert not main_thread.native_frames |
| 149 | |
| 150 | for thread in other_threads: |
| 151 | frames = [ |
| 152 | frame for frame in thread.frames if "threading" not in frame.code.filename |
| 153 | ] |
| 154 | assert (len(frames)) == 3 |
| 155 | |
| 156 | filenames = {frame.code.filename for frame in frames} |
| 157 | assert str(TEST_MULTIPLE_THREADS_FILE) in filenames |
| 158 | |
| 159 | functions = [frame.code.scope for frame in frames] |
| 160 | assert functions == ["thread_func_1", "thread_func_2", "thread_func_3"] |
| 161 | |
| 162 | *line_numbers, last_line = [frame.code.location.lineno for frame in frames] |
| 163 | assert line_numbers == [9, 13] |
| 164 | assert last_line in {18, 19} |
| 165 |
nothing calls this directly
no test coverage detected