aboutsummaryrefslogtreecommitdiffstats
path: root/tests/test_scenarios.py
diff options
context:
space:
mode:
authorblasty <blasty@local>2026-08-06 23:25:23 +0200
committerblasty <blasty@local>2026-08-06 23:25:23 +0200
commit9622e957cdd9602a2f2230ed7d4c90b06688a217 (patch)
treed81a9c2761da67f2929d6fe852090a3f418038b1 /tests/test_scenarios.py
parentsplit: stop the resync loop that spun the worker forever (diff)
downloadida-tui-9622e957cdd9602a2f2230ed7d4c90b06688a217.tar.gz
ida-tui-9622e957cdd9602a2f2230ed7d4c90b06688a217.tar.xz
ida-tui-9622e957cdd9602a2f2230ed7d4c90b06688a217.zip
tests: wait for the thing, don't sleep and hope
test_trace_ui spent 18.8 of its 35.2 seconds in flat pilot.pause() calls placed to let an async seek land. Two loops were most of it: 6 iterations at 0.5s and 28 at 0.3s, 11.4s of sleeping to check that a step moves the cursor. They are condition waits now. The questions are unchanged -- does the listing cursor reach the pc, does the pseudocode cursor follow -- but they cost what they cost instead of a fixed budget. The second loop settles on something that does NOT presuppose the answer (the listing cursor arriving, and the trail map belonging to the loaded function): waiting on 'is this pc mapped' would have burned the timeout on every unmapped instruction, about half of them, and come out slower than the sleep it replaced. 35.2s -> 20.9s, 39 checks, stable over repeated runs. tests/_fixtures.py collects the staging both this suite and test_scenarios need -- scratch copy, seeded from a golden .i64 nothing writes back to -- which was private to test_scenarios. Worth saying plainly: on targets/echo the seeding is worth 0.19s, not the analysis time I assumed when I went looking. It is shared for the deduplication and for whatever gets pointed at a bigger binary.
Diffstat (limited to 'tests/test_scenarios.py')
-rw-r--r--tests/test_scenarios.py34
1 files changed, 4 insertions, 30 deletions
diff --git a/tests/test_scenarios.py b/tests/test_scenarios.py
index 68ebfa3..0dbb0bd 100644
--- a/tests/test_scenarios.py
+++ b/tests/test_scenarios.py
@@ -24,12 +24,12 @@ import asyncio
import fnmatch
import os
import re
-import shutil
import sys
-import tempfile
import traceback
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
+sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
+from _fixtures import staged # noqa: E402
from idatui.app import ( # noqa: E402
ConfirmScreen, DecompView, FunctionsPanel, GraphView, HexView, IdaTui,
HelpScreen, ListingView, QuitScreen, StringsPalette, StructEditor,
@@ -3137,25 +3137,6 @@ async def s_graph_sticky(c: Ctx):
# --------------------------------------------------------------------------- #
# Runner
# --------------------------------------------------------------------------- #
-async def _build_pristine(binary, cache):
- """Analyse ``binary`` once and keep the resulting database as a golden copy.
-
- Costs one full analysis, then every later run starts from it instead of
- re-analysing.
- """
- print(f" (building pristine database for {os.path.basename(binary)}\u2026)")
- app = IdaTui(open_path=binary, keepalive=False)
- async with app.run_test(size=(140, 44)) as pilot:
- for _ in range(6000):
- await pilot.pause(0.05)
- if app._func_index is not None and app._func_index.complete:
- break
- app.program.client.call("idb_save", timeout=600.0)
- db = binary + ".i64"
- if os.path.exists(db):
- shutil.copy2(db, cache)
-
-
async def run(binary, only=None):
# The suite EDITS the database — it defines code, undefines items, renames
# and comments — and IDA saves those edits. Run that against the tracked
@@ -3167,15 +3148,8 @@ async def run(binary, only=None):
#
# So: work on a scratch copy, seeded from a golden database that nothing
# ever writes back to.
- with tempfile.TemporaryDirectory(prefix="idatui-pilot-") as scratch:
- target = os.path.join(scratch, os.path.basename(binary))
- shutil.copy2(binary, target)
- cache = binary + ".pristine.i64"
- if not (os.path.exists(cache)
- and os.path.getmtime(cache) >= os.path.getmtime(binary)):
- await _build_pristine(target, cache)
- if os.path.exists(cache):
- shutil.copy2(cache, target + ".i64")
+ async with staged(binary, lambda p: IdaTui(open_path=p, keepalive=False),
+ prefix="idatui-pilot-") as target:
await _run_on(target, only)