aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorblasty <blasty@local>2026-08-06 23:41:11 +0200
committerblasty <blasty@local>2026-08-06 23:41:11 +0200
commit77db4042fbc913cedd44e63d8eced50b5702794f (patch)
tree5e3760994dead3ce892b6d8c1b1e3874d3c8ecf9
parenttests: wait for the thing, don't sleep and hope (diff)
downloadida-tui-77db4042fbc913cedd44e63d8eced50b5702794f.tar.gz
ida-tui-77db4042fbc913cedd44e63d8eced50b5702794f.tar.xz
ida-tui-77db4042fbc913cedd44e63d8eced50b5702794f.zip
tests: deterministic fixtures, and a correction
all_funcs() forced a full load of the function index only when it was EMPTY, so a partially streamed index -- non-empty but incomplete, which is exactly the state during boot and after any bump_items() -- came back truncated. Every fixture picked through find_func/biggest therefore depended on how far streaming had got by the time a scenario asked. That is the graph_minimap flake: on an unlucky run find_func(size > 0x300) picked a much larger function than usual, whose graph never finished inside the scenario's own 60s wait. Three failures and 65 seconds, one run in several, with no code change to blame. Three consecutive clean runs at 1.7s since. CORRECTION to f898350, which said a range cache for function_of 'broke graph_minimap'. It did not. The failure happened in the run after I added the cache and I attributed it without checking; it recurred with the cache long gone. The cache is still not here, but for the honest reason: with the resync loop fixed, function_of is down to 340 calls and 1.4s across the whole suite, so caching it is not worth the invalidation surface. Suite 195.7s -> 138.4s, 732 checks.
-rw-r--r--tests/test_scenarios.py18
1 files changed, 16 insertions, 2 deletions
diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py
index 0dbb0bd..a1ffaad 100644
--- a/tests/test_scenarios.py
+++ b/tests/test_scenarios.py
@@ -132,9 +132,23 @@ class Ctx:
# -- discovery -------------------------------------------------------- #
def all_funcs(self):
+ """Every function, always -- never the prefix that happens to be loaded.
+
+ This used to load_all() only when the index was EMPTY, so a partially
+ streamed index (non-empty but incomplete: exactly the state during boot,
+ and after any bump_items()) came back truncated. Every fixture chosen
+ through find_func/biggest then depended on how far streaming had got,
+ which is a race.
+
+ It bit graph_minimap: on an unlucky run `find_func(size > 0x300)` picked
+ a far larger function than usual, whose graph never finished inside the
+ scenario's 60s wait -- 3 failures and 65s, one run in several, with no
+ code change to blame. Deterministic fixtures or deterministic flakes,
+ pick one.
+ """
idx = self.prog.functions()
- if len(idx) == 0 and not idx.complete:
- idx.load_all() # a prior bump_items() cleared the index cache
+ if not idx.complete:
+ idx.load_all() # boot streaming, or a prior bump_items()
return idx.all_loaded()
def find_func(self, pred, limit=400):