Skip to content

Amiga port test status

Simon Dick edited this page Jun 21, 2026 · 14 revisions

Amiga port — test status

At-a-glance status of every test that covers the AmigaOS port. The full runbook (how to run each path, setup, gotchas) is on Amiga port testing; the per-phase design log is on Amiga port design. Snapshot date: 2026-06-21 (standard variant unless noted).

Legend: ✅ passes · ◐ runs and passes, but part of the surface is gated/stubbed on this host so full coverage needs the other path · ✗ fails · — not applicable.

Port-local smoke tests (tests/ports/amiga/)

34 targeted smoke tests. All pass under vamos on the standard variant; the ◐ rows run cleanly but only fully exercise their live surface on Amiberry / real hardware (the test files accept either the vamos-stub or live-success path, so the same file is portable to the Amiberry rig).

Native / viper emitter

Test Covers vamos Amiberry
test_native_nlr_smoke.py Phase 12a — try/except/with in native mode (register NLR)
test_native_nested_smoke.py Phase 12b — nested def / closure / generator (big-endian prelude index)
test_viper_shift_smoke.py Phase 12c — viper long shifts (LSL.L/LSR.L/ASR.L)
test_native_emitter_smoke.py MOVEQ destination-register regression (asm68k.h)

Core runtime / port internals

Test Covers vamos Amiberry
test_floatconv_smoke.py floatconv.c libgcc / libm wraps + NaN comparison
test_mem_smoke.py alloc_vec/free_vec, peek_*/poke_*, big-endian order, MEMF_*
test_library_proxy_smoke.py Phase 17 — amiga.Library + .fd trampoline (lib_open/lib_call/lib_close)
test_vfs_smoke.py VfsAmiga file I/O (open/read/write/seek/listdir/stat/rename/mkdir/chdir/errors)
test_stdio_smoke.py sys.stdin/stdout/stderr — fd numbers, write guards, TextIOWrapper
test_json_smoke.py Port-local modjson — primitives/composites/escapes/round-trip
test_history_smoke.py Phase 24 — REPL history ring (readline_history/readline_push_history)
test_mpy_load_smoke.py .mpy bytecode loading (MICROPY_PERSISTENT_CODE_LOAD) — import reaches the .mpy loader (garbage .mpy → ValueError, not ImportError)
test_time_monotonic_smoke.py time.ticks_* / ticks_add / ticks_diff / sleep_ms / sleep_us
test_amiga_introspection_smoke.py os_version/heap_info/exists/volumes/assigns/disk_info/match/imatch
test_signal_smoke.py Phase 25 — signal/wait_signal + SIGBREAKF_CTRL_*
test_amiga_execute_smoke.py amiga.execute (dos.library SystemTagList())
test_workbench_smoke.py Phase 19 — launched_from_workbench/wb_selected_files/tooltype

test_signal_smoke ◐: vamos doesn't deliver Signal/Wait to the same task. test_amiga_execute_smoke ◐ / test_workbench_smoke ◐: vamos has no live SystemTagList command run / no icon.library + Workbench state.

AmigaOS API wrappers

Test Covers vamos Amiberry
test_intuition_smoke.py Phase 30 — intuition requesters (arg-shape; modal dialog needs a screen)
test_asl_smoke.py Phase 31 — asl.file_request (arg-shape + multi+save guard; dialog needs HW)
test_rexx_polish.py Phase 32 — rexx_exists/rexx_list/RexxClient (live host needs a peer)
test_platform_smoke.py Phase 33 — platform.* + amiga.* accessors (chipset/amiga_info need graphics.library)
test_os_smoke.py Phase 34 — frozen os.py/_ospath.py, chmod/getprotect/makedirs/walk
test_os_envvar_smoke.py Phase 20 — os.getenv/putenv/unsetenvENV: + chmod round-trip
test_icon_smoke.py Phase 35 — _icon registration, WB*, error paths, new→write→read round trip
test_catalog_smoke.py Phase 36 — _catalog registration, language(), error paths, lookup round trip

here: vamos stubs intuition/asl (no real screen), lacks graphics.library, partially stubs SetProtection, and has no real icon.library / locale.library so the round-trip blocks soft-pass.

Networking & TLS

Test Covers vamos Amiberry
test_socket_smoke.py socket surface (constants; live I/O needs bsdsocket.library)
test_select_smoke.py select.poll() surface + live WaitSelect-backed readiness / POLLNVAL over a socket
test_ssl_smoke.py ssl.SSLContext surface (constants; live handshake needs AmiSSL)
test_urequests_smoke.py Frozen urequests_parse_url/_quote/_urlencode/verbs/Response (live fetch needs HW)
test_asyncio_smoke.py asyncio event loop — tasks/sleep/gather/Event/Lock/wait_for (vamos has no advancing clock, so the loop only runs live)

extmod opt-ins (Phase 39)

Test Covers vamos Amiberry
test_time_wallclock_smoke.py Step 1 — time.time/time_ns/gmtime/localtime/mktime (vamos: static surface only, no GetSysTime)
test_hashlib_smoke.py Step 2 — hashlib.md5/sha1/sha256 against canonical vectors
test_deflate_compress_smoke.py Step 3 — deflate.DeflateIO compress (RAW/ZLIB/GZIP round trip)
test_btree_smoke.py Step 4 — btree persistent K/V over a stream

One Amiga surface still lacks a targeted smoke test: Ctrl+C interrupt polling (amiga_check_ctrl_c, VM hook every 1024 bytecodes) — vamos doesn't deliver a signal to the same task, so it can only be verified on Amiberry / real hardware. It's exercised implicitly by every long-running test.

Upstream suite (vamos, standard)

Per-directory snapshot, driven through run-tests.py with MICROPY_MICROPYTHON=tools/amiga-vamos-run.sh. Full re-run 2026-06-21 after MICROPY_LONGINT_IMPL_MPZ (arbitrary-precision ints) plus the asyncio / select / ssl work landed (cmdline/ not re-run — Unix-only):

Directory Files Pass Self-skip Fail Failing tests are…
basics/ 574 534 38 2 struct1.py (m68k ABI); sys_path.py
float/ 68 63 2 3 long-double soft-float precision
io/ 16 14 1 1 argv.py
import/ 30 29 0 1 import_file.py
micropython/ 108 92 10 6 5× viper ptr16/ptr32 boundary (big-endian); ringio_async
extmod/ 206 81 79 45 asyncio ×32 / ssl ×7 / socket ×3 / time ×2 / select ×1 ‡
misc/ 14 6 8 0
cmdline/ 27 9 2 14 Unix-port-specific (not re-run)
stress/ 13 12 0 1 bytecode_limit.py (parser memory)

Re-run dirs (excl. cmdline/): 831 pass / 59 fail / 138 self-skip.

The MPZ win: arbitrary-precision ints moved ~60 int_big-dependent tests from self-skip to pass — basics/ +44 pass (490→534), float/ +9 (54→63), micropython/ +7 (85→92).

The fail count rose 40→59, but every new failure is a vamos limitation or a harness artifact, not a port regression — confirmed individually:

  • ‡ Now-enabled features that need a real Amiga. Enabling asyncio, ssl, and select means those tests now run under vamos (they used to self-skip because the features were off) but can't complete there: the asyncio event loop needs an advancing ticks_ms (vamos's E-clock is static), ssl needs AmiSSL, socket/select need bsdsocket, and the time_* tests need a real clock. Re-run on Amiberry (2026-06-21): 43 of these 46 tests pass — all ssl ×7, socket ×3, select ×1, time ×2, ringio_async, and 29 of 32 asyncio tests. The 3 that fail (asyncio_gather_notimpl, asyncio_wait_for, asyncio_fair) are an execution-speed artifact, investigated and understood (not a port bug). All three pass on the unix reference port. modasyncio.c stamps a new task's ph_key = ticks_ms() at create time, and these tests assume the surrounding bookkeeping is instantaneous relative to their short (10–100 ms) sleeps — true on a fast host, false on a 68k. On the emulated 68020 the per-asyncio-iteration overhead is ~12–50 ms (it's directly measurable: asyncio_fair expects t2 to fire 5× in 0.45 s at a 0.1 s period and we get 4×, i.e. an effective period ~0.11–0.15 s), so e.g. creating three tasks takes longer than a 10 ms sleep and a later task's ph_key lands after an earlier task's reschedule, reordering the output. The asyncio functionality is correct (gather raises, wait_for cancels, scheduling is fair); only the event interleaving/count shifts. It is not a timing-precision issue — a throwaway µs-precise busy-wait WFE left all three unchanged — it's raw 68k speed, and would ease on faster hardware. asyncio_fair also has no .exp (diffed against CPython, a different scheduler).
  • run-tests.py harness / vamos-path artifacts. argv.py, import_file.py, sys_path.py depend on sys.argv / __file__ / cwd matching the host invocation, which the vamos wrapper doesn't reproduce; they pass when run directly.

Genuine platform differences (unchanged, won't-fix): struct1.py (m68k 2-byte int alignment), float/ ×3 (80-bit soft-float ULP), the five viper ptr16/ptr32 boundary tests (big-endian), and stress/bytecode_limit.py (parser memory).

The native + viper emitter is functionally complete (Phase 12a/12b/12c

  • the MOVEQ fix): every native_* / viper_* test passes except the five viper ptr16/ptr32 boundary tests, which are big-endian vs little-endian-.exp differences.

Remaining real-hardware failures

Verified on Amiberry 2026-06-20 — these still fail against real Kickstart (not vamos artifacts):

Genuine port gaps (TODO)

None outstanding in the per-directory suite — the last one (extmod/vfs_userfs.py) is now fixed (see below). Remaining feature work is the Phase 39 menu (marshal, websocket/webrepl) and the low-priority Phase 37 (amiga.datatypes).

Environmental / not a port bug

Test(s) Cause
extmod/socket_tcp_basic.py Needs a routable TCP path from the Amiga to the host test server; neither the serial bridge nor vamos provides one (passes against a reachable server)
stress/bytecode_limit.py Parser memory pressure at the bytecode-size edge

Platform differences (won't fix)

Both sides are correct; the .exp expects CPython-on-x86 / full-precision IEEE rather than the AmigaOS m68k ABI + bebbo soft-float.

Test(s) Cause
basics/struct1.py struct.calcsize("97sI") = 102 (m68k 2-byte int alignment) vs 104 (x86)
float/float_parse*.py, float_format_accuracy.py, inf_nan_arith.py bebbo 80-bit long-double soft-float loses 1–2 ULP; repr round-trip ~72%; a nan/inf sign quirk in min/max
micropython/viper_ptr16_load*.py, viper_ptr16_store_boundary.py, viper_ptr32_load_boundary.py, viper_ptr32_store_boundary.py Raw ptr16/ptr32 access uses native byte order — m68k big-endian vs little-endian .exp

Recently fixed (2026-06-21)

The full upstream extmod/ssl_* suite now passes on real Amiberry (AmiSSL v5). See Phase 28 follow-ups.

Was failing Fix
extmod/ssl_basic.py, ssl_ioctl.py, ssl_keycert.py Module-level ssl.wrap_socket(...), load_cert_chain, server_side, and a memory-BIO stream transport in modssl.c
extmod/ssl_cadata.py In-memory cadata loading (load_verify_locations)
extmod/ssl_poll.py Non-blocking, poll-driven BIO-pair stream path (poll_mask/last_error/SSL_pending); single-write flights; SSL_write flush; security level 0 for the 1024-bit test key
extmod/ssl_sslcontext_verify_mode2.py Exposed ssl.OPENSSL_VERSION so the test runs instead of skipping
extmod/ssl_keycert_pkcs8.py Now skips cleanly (mbedTLS-only PKCS#8 gate)
extmod/select_poll_basic.py, select_ipoll.py select.poll()/select() over bsdsocket: socket MP_STREAM_POLL ioctl backed by a zero-timeout WaitSelect() (modsocket.c); MICROPY_INTERNAL_WFE sleeps in short slices so idle poll-waits don't busy-spin (mphalport.c)
extmod/platform_basic.py The frozen platform.py (which shadows the C platform module) lacked python_compiler() / libc_ver(); added both (str / (lib, ver) tuple, matching CPython's types). Not a sys.platform issue as earlier noted.
extmod/vfs_userfs.py Not a VFS-mount collision (it mounts at /userfs, which works) — the test imports a .mpy, and the port had MICROPY_PERSISTENT_CODE_LOAD off, so import never searched for .mpy and failed at usermod4. Enabled it (the .mpy reader is already linked for frozen modules; native-code .mpy stays off). Matches .exp under vamos.
basics/int_big_* (~23 tests) Switched MICROPY_LONGINT_IMPL from LONGLONG (64-bit) to MPZ (arbitrary precision), so the int_big suite runs instead of self-skipping. Two-line change (config + the Makefile MPY_TOOL_FLAGS so frozen big-int constants are encoded as mpz); needs a clean build. Verified on vamos and Amiberry: all 38 basics/int* tests pass (incl. big arithmetic and big-endian to_bytes/from_bytes), the 34-test smoke suite still passes; +11 KB binary. mpz is correct on big-endian m68k.
asyncio (was disabled) Enabled MICROPY_PY_ASYNCIO + MICROPY_ENABLE_SCHEDULER, froze the asyncio package. Event loop runs off time.ticks_* + select.poll().ipoll(). Verified live on Amiberry: core loop (test_asyncio_smoke) and asyncio.open_connection plain-TCP HTTP GET (HTTP/1.1 200 OK).
asyncio over TLS SSLContext.wrap_socket(do_handshake_on_connect=False) now routes non-blocking clients through the memory-BIO stream path (poll-aware) instead of the fd path, so a TLS SSLSocket is pollable. Verified live: asyncio.open_connection(host, 443, ssl=True) HTTPS GET to www.python.org (52 KB) and example.com (HTTP/1.1 200 OK).
urequests HTTPS hardened Removed the SSL_set_fd fd path — every TLS socket uses the one BIO stream transport. urequests reuses one module-level SSLContext and closes the socket on failure. modssl.c now calls ERR_clear_error() before each SSL op, so a failed connection no longer poisons the next (stale OpenSSL error queue made SSL_get_error() misreport). CERT_REQUIRED GETs to www.python.org are reliable, and a good request recovers cleanly after a server that resets mid-exchange (3/3 good→bad→good rounds). The only residual failure is the resetting server itself, in isolation — AmiSSL notes.

Recently fixed (2026-06-20)

Was failing Fix
micropython/native_try/native_try_deep/native_with Phase 12a register NLR (nlr68k.S)
micropython/native_const/native_closure/native_gen Phase 12b big-endian prelude-index byte-swap (emitnative.c)
micropython/viper_binop_arith + 5 more Phase 12c long-size shift opcodes (asm68k.h)
extmod/time_res.py FPU FPCR rounding-precision reset at startup (amiga_fpu_fix_rounding() in main.c)
import/import_file.py Keep sys.path[0] relative ("") for a basename script
extmod/socket_*, ssl_sslcontext*, time_ms_us, time_time_ns Were vamos artifacts — pass on real Amiberry

Clone this wiki locally