Skip to content

Commit

Permalink
Tests: Armor
Browse files Browse the repository at this point in the history
In particular:
* Test Runner: Profile sleep() imprecision while running tests
* Bump timeouts in many locations.
* Fix many soft timeout warnings to point to test code rather than to infrastructure.

Also:
* Shell: Fix race condition where shell might start accepting commands before foreground thread created
  • Loading branch information
davidfstr committed Jan 10, 2024
2 parents dcd7071 + a81a56a commit c739a70
Show file tree
Hide file tree
Showing 11 changed files with 212 additions and 89 deletions.
15 changes: 8 additions & 7 deletions src/crystal/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -189,13 +189,6 @@ def _main(args: List[str]) -> None:
install_to_linux_desktop_environment()
sys.exit()

# Start shell if requested
if parsed_args.shell:
from crystal.shell import Shell
shell = Shell()
else:
shell = None

# Start GUI subsystem
import wx
import wx.xml # required by wx.richtext; use explicit import as hint to py2app
Expand Down Expand Up @@ -293,8 +286,16 @@ def _finish_launch(self, filepath: Optional[str]=None) -> None:
from crystal.util.xthreading import is_quitting, set_foreground_thread
set_foreground_thread(threading.current_thread())
try:
# (Don't insert anything between set_foreground_thread() and MyApp())
app = MyApp(redirect=False)

# Start shell if requested
if parsed_args.shell:
from crystal.shell import Shell
shell = Shell()
else:
shell = None

# Starts tests if requested
if parsed_args.test is not None:
from crystal.util.xthreading import bg_call_later, fg_call_later, has_foreground_thread
Expand Down
1 change: 1 addition & 0 deletions src/crystal/model.py
Original file line number Diff line number Diff line change
Expand Up @@ -173,6 +173,7 @@ class Project(ListenableMixin):

# === Load ===

@fg_affinity
def __init__(self,
path: str,
progress_listener: Optional[OpenProjectProgressListener]=None,
Expand Down
3 changes: 3 additions & 0 deletions src/crystal/shell.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,9 @@

class Shell:
def __init__(self) -> None:
if not has_foreground_thread():
raise ValueError('Expected there to be a foreground thread when starting a Shell')

# Setup proxy variables for shell
_Proxy._patch_help()
self._project_proxy = _Proxy(f'<unset {Project.__module__}.{Project.__name__} proxy>')
Expand Down
3 changes: 2 additions & 1 deletion src/crystal/tests/index.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
from crystal.tests.util.runner import run_test
from crystal.tests.util.subtests import SubtestFailed
from crystal.util.xthreading import bg_affinity
from crystal.util.xtime import sleep_profiled
from functools import wraps
import gc
import os
Expand Down Expand Up @@ -100,7 +101,7 @@ def run_tests(test_names: List[str]) -> bool:
The format of the summary report is designed to be similar
to that used by Python's unittest module.
"""
with delay_between_downloads_minimized():
with delay_between_downloads_minimized(), sleep_profiled():
return _run_tests(test_names)


Expand Down
19 changes: 14 additions & 5 deletions src/crystal/tests/test_addgroup.py
Original file line number Diff line number Diff line change
Expand Up @@ -331,15 +331,19 @@ async def test_given_node_is_selected_in_entity_tree_when_press_new_group_button
home_rrn__feed_glrn__rss_feed_lrn, home_url, url_prefix)

# Children of LinkedResourceNode (a kind of _ResourceNode) that is inside RootResourceNode
await _expand_node(home_rrn__archive_lrn, mw, will_download=True)
# HACK: Relies on Crystal's "Not in Archive" page to provide a
# link to the original URL (which is offsite)
await _expand_node(home_rrn__archive_lrn, mw) # not in archive
home_rrn__archive_lrn__offsite_cn = _find_child_by_title(
home_rrn__archive_lrn, 'Offsite')

# Children of LinkedResourceNode (a kind of _ResourceNode) that is inside ClusterNode
await _expand_node(home_rrn__offsite_cn__twitter_lrn, mw, will_download=True)
# HACK: Relies on Crystal's "Not in Archive" page to provide a
# link to the original URL (which is offsite)
await _expand_node(home_rrn__offsite_cn__twitter_lrn, mw) # not in archive
home_rrn__offsite_cn__twitter_lrn__offsite_cn = _find_child_by_title(
home_rrn__offsite_cn__twitter_lrn, 'Offsite')
await _expand_node(home_rrn__embedded_cn__stylesheet_lrn)
await _expand_node(home_rrn__embedded_cn__stylesheet_lrn) # already downloaded
home_rrn__embedded_cn__stylesheet_lrn__embedded_cn = _find_child_by_title(
home_rrn__embedded_cn__stylesheet_lrn, 'Embedded')

Expand Down Expand Up @@ -396,8 +400,13 @@ async def _expand_node(node_ti: TreeItem, mw: Optional[MainWindow]=None, *, will
if will_download:
if mw is None:
raise ValueError('Need mw parameter when will_download=True')
await wait_for_download_to_start_and_finish(mw.task_tree)
await wait_for(first_child_of_tree_item_is_not_loading_condition(node_ti))
await wait_for_download_to_start_and_finish(
mw.task_tree,
stacklevel_extra=1)
await wait_for(
first_child_of_tree_item_is_not_loading_condition(node_ti),
timeout=3.0, # took 2.2s on Windows CI
stacklevel_extra=1)


async def _source_name_for_node(node_ti: TreeItem, mw: MainWindow) -> Optional[str]:
Expand Down
Loading

0 comments on commit c739a70

Please sign in to comment.