Skip to content

Commit

Permalink
Merge pull request #17234 from impact27/test_stall
Browse files Browse the repository at this point in the history
PR: Do not test for leaks on Windows to avoid tests stall
  • Loading branch information
ccordoba12 committed Jan 24, 2022
2 parents 24b8ca1 + 8ff6ef6 commit ebc7e48
Show file tree
Hide file tree
Showing 2 changed files with 98 additions and 81 deletions.
87 changes: 42 additions & 45 deletions spyder/app/tests/test_mainwindow.py
Original file line number Diff line number Diff line change
Expand Up @@ -328,17 +328,15 @@ def main_window(request, tmpdir, qtbot):
qtbot.waitUntil(lambda: shell._prompt_html is not None,
timeout=SHELL_TIMEOUT)

# _DummyThread are created if current_thread() is called from them.
# They will always leak (From python doc) so we ignore them.
init_threads = [
thread for thread in threading.enumerate()
if not isinstance(thread, threading._DummyThread)]
window._initial_number_threads = len(init_threads)
proc = psutil.Process()
window._initial_number_files = len(proc.open_files())
init_files = [repr(f) for f in proc.open_files()]
init_subprocesses = [repr(f) for f in proc.children()]
number_subprocesses = len(init_subprocesses)
if os.name != 'nt':
# _DummyThread are created if current_thread() is called from them.
# They will always leak (From python doc) so we ignore them.
init_threads = [
repr(thread) for thread in threading.enumerate()
if not isinstance(thread, threading._DummyThread)]
proc = psutil.Process()
init_files = [repr(f) for f in proc.open_files()]
init_subprocesses = [repr(f) for f in proc.children()]

yield window

Expand Down Expand Up @@ -378,67 +376,66 @@ def main_window(request, tmpdir, qtbot):
if spyder_boilerplate is not None:
window.unregister_plugin(spyder_boilerplate)

if os.name == 'nt':
# Do not test leaks on windows
return

known_leak = request.node.get_closest_marker(
'known_leak')
if known_leak:
# This test has a known leak
return

def show_diff(init_list, now_list, name):
sys.stderr.write(f"Extra {name} before test:\n")
for item in init_list:
if item in now_list:
now_list.remove(item)
else:
sys.stderr.write(item + "\n")
sys.stderr.write(f"Extra {name} after test:\n")
for item in now_list:
sys.stderr.write(item + "\n")

# The test is not allowed to open new files or threads.
try:
def threads_condition():
threads = [
thread for thread in threading.enumerate()
if not isinstance(thread, threading._DummyThread)]
return (window._initial_number_threads
>= len(threads))
return (len(init_threads) >= len(threads))

qtbot.waitUntil(threads_condition, timeout=SHELL_TIMEOUT)
except Exception:
# print for debug purposes
sys.stderr.write("Initial threads:\n")
for thread in init_threads:
sys.stderr.write(repr(thread) + "\n")
sys.stderr.write("Running threads:" + "\n")
for thread in threading.enumerate():
if not isinstance(thread, threading._DummyThread):
sys.stderr.write(repr(thread) + "\n")
now_threads = [
thread for thread in threading.enumerate()
if not isinstance(thread, threading._DummyThread)]
threads = [repr(t) for t in now_threads]
show_diff(init_threads, threads, "thread")
sys.stderr.write("Running Threads stacks:\n")
now_thread_ids = [t.ident for t in now_threads]
for threadId, frame in sys._current_frames().items():
sys.stderr.write("\nThread " + str(threadId) + ":\n")
traceback.print_stack(frame)
if threadId in now_thread_ids:
sys.stderr.write("\nThread " + str(threads) + ":\n")
traceback.print_stack(frame)
raise

try:
qtbot.waitUntil(lambda: (number_subprocesses >=
len(proc.children())),
timeout=SHELL_TIMEOUT)
qtbot.waitUntil(lambda: (
len(init_subprocesses) >= len(proc.children())),
timeout=SHELL_TIMEOUT)
except Exception:
# print for debug purposes
sys.stderr.write("Initially open processes:" + "\n")
for process in init_subprocesses:
sys.stderr.write(repr(process) + "\n")
sys.stderr.write("Open processes:" + "\n")
for process in proc.children():
sys.stderr.write(repr(process) + "\n")
subprocesses = [repr(f) for f in proc.children()]
show_diff(init_subprocesses, subprocesses, "processes")
raise

if os.name == 'nt':
# kernel stderr file leaks on windows
return
try:
qtbot.waitUntil(
lambda: (window._initial_number_files
>= len(proc.open_files())),
lambda: (len(init_files) >= len(proc.open_files())),
timeout=SHELL_TIMEOUT)
except Exception:
# print for debug purposes
sys.stderr.write("Initially open files:" + "\n")
for file in init_files:
sys.stderr.write(repr(file) + "\n")
sys.stderr.write("Open files:" + "\n")
for file in proc.open_files():
sys.stderr.write(repr(file) + "\n")
files = [repr(f) for f in proc.open_files()]
show_diff(init_files, files, "files")
raise


Expand Down
92 changes: 56 additions & 36 deletions spyder/plugins/ipythonconsole/tests/test_ipythonconsole.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
import tempfile
from textwrap import dedent
import threading
import traceback
from unittest.mock import Mock

# Third party imports
Expand Down Expand Up @@ -214,13 +215,15 @@ def __getattr__(self, attr):
qtbot.waitUntil(lambda: shell._prompt_html is not None,
timeout=SHELL_TIMEOUT)

threads_count = threading.active_count()
init_threads = [repr(t) for t in threading.enumerate()]
proc = psutil.Process()
init_subprocesses = [repr(f) for f in proc.children()]
number_subprocesses = len(init_subprocesses) - 1 # -1 from closed client
number_files = len(proc.open_files())
init_files = [repr(f) for f in proc.open_files()]
if os.name != 'nt':
# _DummyThread are created if current_thread() is called from them.
# They will always leak (From python doc) so we ignore them.
init_threads = [
repr(thread) for thread in threading.enumerate()
if not isinstance(thread, threading._DummyThread)]
proc = psutil.Process()
init_files = [repr(f) for f in proc.open_files()]
init_subprocesses = [repr(f) for f in proc.children()]

yield console

Expand All @@ -242,50 +245,66 @@ def __getattr__(self, attr):
os.environ.pop('IPYCONSOLE_TEST_DIR')
os.environ.pop('IPYCONSOLE_TEST_NO_STDERR')

if os.name == 'nt':
# Do not test for leaks on windows
return

known_leak = request.node.get_closest_marker(
'known_leak')
if known_leak:
return

def show_diff(init_list, now_list, name):
sys.stderr.write(f"Extra {name} before test:\n")
for item in init_list:
if item in now_list:
now_list.remove(item)
else:
sys.stderr.write(item + "\n")
sys.stderr.write(f"Extra {name} after test:\n")
for item in now_list:
sys.stderr.write(item + "\n")

# The test is not allowed to open new files or threads.
try:
qtbot.waitUntil(
lambda: threads_count >= threading.active_count(),
timeout=SHELL_TIMEOUT)
def threads_condition():
threads = [
thread for thread in threading.enumerate()
if not isinstance(thread, threading._DummyThread)]
return (len(init_threads) >= len(threads))

qtbot.waitUntil(threads_condition, timeout=SHELL_TIMEOUT)
except Exception:
# print for debug purposes
sys.stderr.write("Initial threads:" + "\n")
for thread in init_threads:
sys.stderr.write(repr(thread) + "\n")
sys.stderr.write("Running threads:" + "\n")
for thread in threading.enumerate():
sys.stderr.write(repr(thread) + "\n")
now_threads = [
thread for thread in threading.enumerate()
if not isinstance(thread, threading._DummyThread)]
threads = [repr(t) for t in now_threads]
show_diff(init_threads, threads, "thread")
sys.stderr.write("Running Threads stacks:\n")
now_thread_ids = [t.ident for t in now_threads]
for threadId, frame in sys._current_frames().items():
if threadId in now_thread_ids:
sys.stderr.write("\nThread " + str(threads) + ":\n")
traceback.print_stack(frame)
raise

try:
qtbot.waitUntil(lambda: number_files >= len(proc.open_files()),
timeout=SHELL_TIMEOUT)
# -1 from closed client
qtbot.waitUntil(lambda: (
len(init_subprocesses) - 1 >= len(proc.children())),
timeout=SHELL_TIMEOUT)
except Exception:
# print for debug purposes
sys.stderr.write("Initially open files:" + "\n")
for file in init_files:
sys.stderr.write(repr(file) + "\n")
sys.stderr.write("Open files:" + "\n")
for file in proc.open_files():
sys.stderr.write(repr(file) + "\n")
subprocesses = [repr(f) for f in proc.children()]
show_diff(init_subprocesses, subprocesses, "processes")
raise

try:
qtbot.waitUntil(lambda: (number_subprocesses >=
len(proc.children())),
timeout=SHELL_TIMEOUT)
qtbot.waitUntil(
lambda: (len(init_files) >= len(proc.open_files())),
timeout=SHELL_TIMEOUT)
except Exception:
# print for debug purposes
sys.stderr.write("Initially open processes:" + "\n")
for process in init_subprocesses:
sys.stderr.write(repr(process) + "\n")
sys.stderr.write("Open processes" + "\n")
for process in proc.children():
sys.stderr.write(repr(process) + "\n")
files = [repr(f) for f in proc.open_files()]
show_diff(init_files, files, "files")
raise


Expand Down Expand Up @@ -1235,6 +1254,7 @@ def test_sys_argv_clear(ipyconsole, qtbot):


@flaky(max_runs=5)
@pytest.mark.skipif(os.name == 'nt', reason="Fails sometimes on Windows")
def test_set_elapsed_time(ipyconsole, qtbot):
"""Test that the IPython console elapsed timer is set correctly."""
client = ipyconsole.get_current_client()
Expand Down

0 comments on commit ebc7e48

Please sign in to comment.