Skip to content

Add end-to-end bridge tests for DHCP and HTTP GET - #12

Merged
JC-000 merged 10 commits into
masterfrom
replay/pr-12-head
May 6, 2026
Merged

Add end-to-end bridge tests for DHCP and HTTP GET#12
JC-000 merged 10 commits into
masterfrom
replay/pr-12-head

Conversation

@JC-000

Copy link
Copy Markdown
Owner

Summary

  • Vendor bridge networking scripts from c64-test-harness, extended with dnsmasq (DHCP pool 10.0.65.50-150, DNS overrides for zimmers.net/apple.com → 10.0.65.1)
  • Robust 6-step cleanup script matching upstream harness pattern (handles orphaned VICE, stale dnsmasq, legacy tap-c64, vicerc files)
  • Reusable tools/https_e2e/ library with public API: BridgeEnv, launch_vice_on_bridge(), press_key(), wait_for_screen_text(), start_http_listener()
  • Phase 1 test: boot c64-https in VICE on RR-Net bridge, DHCP succeeds
  • Phase 2 test: DHCP + plain HTTP GET to local Python listener, response body verified on C64 screen
  • Both tests pass at normal VICE speed with generous timeouts (~90-120s)

Test plan

  • Phase 1 (DHCP): sudo PYTHONPATH=tools python3 tests/test_phase1_dhcp.py — PASS
  • Phase 2 (HTTP GET): sudo PYTHONPATH=tools python3 tests/test_phase2_http.py — PASS
  • Cleanup script idempotent on clean system
  • Phase 3 (HTTPS GET) planned as follow-up

🤖 Generated with Claude Code


Originally posted by @JC-000 on 2026-04-12

JC-000and others added 10 commits March 23, 2026 15:39
…erged
The harness wait_for_text() now calls transport.resume() between polls
internally, so the inline polling loops are no longer needed. This
replaces 13 copies of the same ~10-line loop with single wait_for_text()
calls, reducing total code by 120 lines.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…r reuse
The parallel runner had two bugs: (1) as_completed() didn't see futures added
mid-iteration, so only the first N suites were collected, and (2) reusing VICE
instances across suites caused state contamination (HKDF 0/12 on reused workers).
Fix: allocate a fresh VICE instance per suite via run_suite_in_own_instance().
Add all 10 suites (was 5). Add --skip-slow and --seed flags. 193/193 pass.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Fix parallel test runner: all 10 suites, instance-per-suite.
… tests
net_dns_resolve and net_set_tcp_dest both passed A/X parameters through
net_save_zp, which uses X as a loop counter and clobbers both registers.
This caused DNS resolution and TCP destination setup to receive garbage
pointers instead of the caller's intended addresses. Fixed by pushing
A/X to the stack before the ZP save and restoring after.
Added test_dns.py (4 tests) exercising net_dns_resolve over TAP with
dnsmasq, and test_http_integration.py (5 tests) for end-to-end plain
HTTP GET (DNS → TCP → request → response). Both use ViceInstanceManager
with ethernet_mode="rrnet" and run unprivileged (only dnsmasq via sudo).
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
…ion-tests
Fix A/X register clobbering in net.asm, add DNS + HTTP integration tests
Replace baseline fe25519/x25519 with optimized versions from the c64-x25519
performance tuning project, achieving ~30% speedup (12,782 jiffies / 3.6 min
per key generation vs 18,005 baseline).
Optimizations imported:
- REU DMA multiplication tables (128KB REU, 4 cyc/product vs mul_8x8)
- mult66 indirect-indexed quarter-square multiply for fe_sqr
- Self-modifying accumulation addresses in fe_mul/fe_sqr inner loops
- 4x unrolled constant-time fe_cswap (38 cyc/byte vs 49)
- Shift-before-accumulate for fe_sqr cross terms
- mul_by_38 lookup tables for fe_reduce_wide
Key integration fixes:
- Optimization tables (mul_dma, sqtab2, mul38) placed early in data.asm to
stay below $A000 and avoid BASIC ROM shadow region
- BASIC ROM banked out at boot and kept off during runtime (data buffers at
$A000+ need direct RAM access)
- VICE launched with -reu -reusize 512 for all test suites
- Zero page lmul0/lmul1 pointers time-shared with ChaCha20 vars
New files:
- tools/test_x25519.py: 71 unit tests (fe25519 field ops + x25519_clamp +
optional --slow RFC 7748 scalarmult vectors)
- tools/bench_x25519.py: key generation benchmark with jiffy clock timing
and Python X25519 verification
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Import optimized X25519 (~30% faster key generation)
Introduces tools/net_test_env.py with NetworkTestEnv context manager
that handles TAP interface, dnsmasq, and optional HTTPS server lifecycle.
Replaces duplicated inline setup/teardown code across network test files
and guarantees cleanup via __exit__, signal handlers, and atexit.
Migrates test_dns.py as proof-of-concept. Includes 14 unit tests.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Add consolidated network test environment
Vendor the c64-test-harness bridge networking scripts (setup + cleanup)
and extend them with dnsmasq (DHCP + DNS overrides). Build a reusable
tools/https_e2e/ library with BridgeEnv context manager, single-VICE
launcher, boot menu helpers, and HTTP listener. Two passing e2e tests
drive the real c64-https binary in VICE over RR-Net at normal speed:
Phase 1 verifies DHCP, Phase 2 verifies plain HTTP GET to a local
listener. HTTPS (Phase 3) to follow.
Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@JC-000
JC-000 merged commit 6772458 into masterMay 6, 2026
@JC-000
JC-000 deleted the replay/pr-12-head branch May 6, 2026 19:03
JC-000 added a commit that referenced this pull request Jul 20, 2026
…te (#56)
CLAUDE.md was partially updated during the session that produced
PRs #51-#55; several sections survived with pre-bump claims that no
longer match reality. This commit refreshes them in one pass:
- Crypto ABI: bump x25519 sibling pin v0.4.0 -> v0.6.0; mark P-256
as c64-lib-contract SPEC-aligned with the make -C libs/<X>
lib-VARIANT integration pattern.
- MEMORY requirements: rename CRYPTO -> CRYPTO_HOT (UCI) /
CRYPTO_RESIDENT (ip65) per the W1 hot/cold split; cross-link
c64-lib-contract repo + docs/library-ingestion-architecture.md.
- Build vars: document USE_X25519_SIBLING + EMBED_P256_OVERLAY.
- UCI Memory layout: collapse to a pointer at the post-W1 table
below.
- Known issues: rewrite the X25519 sibling block for v0.6.0 + the
post-W1 split; replace MemoryPolicy note with the centralized
VICE helper (tools/_vice_helpers.py::default_vice_config).
- ECDSA P-256 wall-clock: update to 82.1 s under v0.3.0 (was 86.7 s
under v0.2.0); drop the v0.2.0-era defensive-init footnote.
- Memory layout: replace pre-W1 monolithic CRYPTO table with the
full UCI + ip65 post-W1 layout; document the ip65 CRYPTO_COLD_SHADOW
1,662 B overflow tracked at c64-nist-curves#54.
docs/library-ingestion-architecture.md gets a "Status as of 2026-05-23"
appendix snapshotting which §3 library-side issues and §4 c64-https-side
work items landed via PRs #51-#55 vs. are still in-flight (Task #12 /
P-384 wall-clock / CI bot).
No source / cfg / integration script / submodule changes.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
JC-000 added a commit that referenced this pull request Jul 20, 2026
…te (#57)
CLAUDE.md was partially updated during the session that produced
PRs #51-#55; several sections survived with pre-bump claims that no
longer match reality. This commit refreshes them in one pass:
- Crypto ABI: bump x25519 sibling pin v0.4.0 -> v0.6.0; mark P-256
as c64-lib-contract SPEC-aligned with the make -C libs/<X>
lib-VARIANT integration pattern.
- MEMORY requirements: rename CRYPTO -> CRYPTO_HOT (UCI) /
CRYPTO_RESIDENT (ip65) per the W1 hot/cold split; cross-link
c64-lib-contract repo + docs/library-ingestion-architecture.md.
- Build vars: document USE_X25519_SIBLING + EMBED_P256_OVERLAY.
- UCI Memory layout: collapse to a pointer at the post-W1 table
below.
- Known issues: rewrite the X25519 sibling block for v0.6.0 + the
post-W1 split; replace MemoryPolicy note with the centralized
VICE helper (tools/_vice_helpers.py::default_vice_config).
- ECDSA P-256 wall-clock: update to 82.1 s under v0.3.0 (was 86.7 s
under v0.2.0); drop the v0.2.0-era defensive-init footnote.
- Memory layout: replace pre-W1 monolithic CRYPTO table with the
full UCI + ip65 post-W1 layout; document the ip65 CRYPTO_COLD_SHADOW
1,662 B overflow tracked at c64-nist-curves#54.
docs/library-ingestion-architecture.md gets a "Status as of 2026-05-23"
appendix snapshotting which §3 library-side issues and §4 c64-https-side
work items landed via PRs #51-#55 vs. are still in-flight (Task #12 /
P-384 wall-clock / CI bot).
No source / cfg / integration script / submodule changes.
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
JC-000 added a commit that referenced this pull request Jul 20, 2026
* docs: refresh CLAUDE.md + ingestion plan for PR #46/#51-55 merged state
CLAUDE.md was partially updated during the session that produced
PRs #51-#55; several sections survived with pre-bump claims that no
longer match reality. This commit refreshes them in one pass:
- Crypto ABI: bump x25519 sibling pin v0.4.0 -> v0.6.0; mark P-256
as c64-lib-contract SPEC-aligned with the make -C libs/<X>
lib-VARIANT integration pattern.
- MEMORY requirements: rename CRYPTO -> CRYPTO_HOT (UCI) /
CRYPTO_RESIDENT (ip65) per the W1 hot/cold split; cross-link
c64-lib-contract repo + docs/library-ingestion-architecture.md.
- Build vars: document USE_X25519_SIBLING + EMBED_P256_OVERLAY.
- UCI Memory layout: collapse to a pointer at the post-W1 table
below.
- Known issues: rewrite the X25519 sibling block for v0.6.0 + the
post-W1 split; replace MemoryPolicy note with the centralized
VICE helper (tools/_vice_helpers.py::default_vice_config).
- ECDSA P-256 wall-clock: update to 82.1 s under v0.3.0 (was 86.7 s
under v0.2.0); drop the v0.2.0-era defensive-init footnote.
- Memory layout: replace pre-W1 monolithic CRYPTO table with the
full UCI + ip65 post-W1 layout; document the ip65 CRYPTO_COLD_SHADOW
1,662 B overflow tracked at c64-nist-curves#54.
docs/library-ingestion-architecture.md gets a "Status as of 2026-05-23"
appendix snapshotting which §3 library-side issues and §4 c64-https-side
work items landed via PRs #51-#55 vs. are still in-flight (Task #12 /
P-384 wall-clock / CI bot).
No source / cfg / integration script / submodule changes.
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
* feat(uci): C64 Ultimate support — 64 MHz e2e + WiFi DHCP + fence retune (#58)
* fix(uci): widen uci_fence to keep 35% margin at 64 MHz
The C64 Ultimate tops out at 64 MHz, where the old 2525-cycle fence
(INNER=100, tuned for 48 MHz) shrinks to ~39.5 us — only ~4% over the
FPGA's ~38 us floor. Bump UCI_FENCE_INNER to 131 (~3300 cycles):
51.6 us at 64 MHz (35.7% margin), 68.8 us at 48 MHz, ~3.3 ms at
1 MHz. Still negligible for networking at every speed.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UZmMaxyyykvYbCvJAc4QVW
* feat(uci): interface-fallback DHCP acquire for C64 Ultimate WiFi
The C64 Ultimate has Ethernet AND WiFi; GET_IPADDR(iface=0) returns
0.0.0.0 when the box is on WiFi, which the old single-shot
net_dhcp_acquire surfaced as DHCP FAILED (UCI_ERR_NO_IP). Probe
interface indices 0..3 and take the first non-zero lease; clean up
(drain + ack) after a CMD_FAILED probe so the next one starts from
idle. Clear net_last_error on success so no-lease residue from
earlier probes doesn't sit next to a good acquire.
Costs ~38 B in NET_CODE — boundary with NET_BSS_TAIL shifted by $40
($1B26 -> $1B66); NET_BSS_TAIL occupancy is $625 so $75 slack
remains. Verified on C64 Ultimate firmware 1.1.0 (WiFi): phase2_check
PASS, IP acquired on iface 1.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UZmMaxyyykvYbCvJAc4QVW
* fix(uci): retune uci_fence for C64 Ultimate burst floor
The C64U (firmware 1.1.0, core 1.49) needs more inter-access time
than the U64E's empirical ~38 us, and only under sustained CMD_DATA
bursts: at 51.6 us spacing (INNER=131 @ 64 MHz) GET_IPADDR works but
TCP_CONNECT's ~15-byte hostname push is silently lost
(UCI_ERR_NO_SOCKET, no SYN ever leaves the box). Floor bracketed at
64 MHz: 51.6 us FAIL / 62.9 us PASS / 100 us PASS. Ship INNER=217
(5450 cycles = 85.2 us @ 64 MHz) for 35% margin over the worst-case
floor; 113.5 us @ 48 MHz, ~5.5 ms @ 1 MHz — negligible for
networking on both devices.
E2e verified on C64U: 64 MHz PASS (64.7 s), 48 MHz PASS (73.0 s).
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UZmMaxyyykvYbCvJAc4QVW
* test(uci): set turbo before boot — C64U runtime-switch quirk
On the C64 Ultimate, a REST config CPU-speed change while the PRG is
running can glitch the UCI bridge so the next pushed command is
silently lost — reproduced 2x as UCI_ERR_NO_SOCKET on the first
TCP_CONNECT after a 1->64 MHz switch, even with a 100 us fence
(1->48 happened to survive). Move set_turbo_mhz before
reset/run_prg so the machine boots at target speed and never
switches mid-session; also makes boot speed deterministic instead
of inheriting the previous run's config.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UZmMaxyyykvYbCvJAc4QVW
* docs: C64 Ultimate notes + 48/64 MHz benchmarks
New bench device: C64 Ultimate Starlight (10.53.21.158, fw 1.1.0,
core 1.49, NTSC, WiFi). Documents the 64 MHz speed enum, the
runtime speed-switch quirk, the wider fence floor, multi-interface
GET_IPADDR, REU-disabled default + set_reu() incompatibility, and
the new P-256 e2e numbers: 73.0 s @ 48 MHz, 64.7 s @ 64 MHz.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UZmMaxyyykvYbCvJAc4QVW
* bench+docs: 48/64 MHz verify scaling analysis — REU DMA is the wall
bench_ecdsa_u64e.py: the post-W1 MemoryPolicy blocks the bench's DMA
writes of vector inputs into CRYPTO_BSS (now in CRYPTO_COLD_SHADOW);
pass override= with a reason instead of widening the policy.
Measured on C64U: ecdsa_verify_256 53.8 s @ 48 MHz / 47.4 s @ 64 MHz.
T(f) = D + C/f fits both e2e and verify pairs to 0.1 s:
verify D = 28.4 s speed-invariant vs C = 1.22 Gcycles CPU-scaled.
D matches fp_mul's REU row-fetch volume (~27 MB/verify) at the
stock ~1 MB/s DMA rate that turbo does not scale (consistent with
the 16 ms overlay-swap datapoint). e2e adds ~11.4 s of UCI/network
D. Conclusion documented in CLAUDE.md: >48 MHz clocks are mostly
wasted on this fp_mul; the fix is library-side.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01UZmMaxyyykvYbCvJAc4QVW
---------
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant

@JC-000