Skip to content

[codex] Show tunnel IPs for each enabled server protocol#281

Merged
NLipatov merged 4 commits into
mainfrom
issue/280
Apr 5, 2026
Merged

[codex] Show tunnel IPs for each enabled server protocol#281
NLipatov merged 4 commits into
mainfrom
issue/280

Conversation

@NLipatov

@NLipatov NLipatov commented Apr 5, 2026

Copy link
Copy Markdown
Owner

Summary

  • add protocol-tagged tunnel address collection to runtime address info
  • render all active server tunnel IPs per enabled protocol in the runtime dashboard
  • cover runtime address aggregation, backend forwarding, and dashboard rendering with tests

Why

The server runtime dashboard previously collapsed multiple enabled protocol interfaces into a single Tunnel IP pair, which made the dataplane view incomplete when TCP, UDP, and WS were enabled together.

Impact

Server-mode TUI now shows the active tunnel addresses per protocol instead of implying that one address pair represents the full dataplane.

Root cause

RuntimeAddressInfoFromServerConfiguration(...) only kept the first valid tunnel IPv4/IPv6 pair, and the dashboard options/model only carried one tunnel pair through to the UI.

Validation

  • GOCACHE=/tmp/tungo-go-build-cache go test ./...

Closes #280

Summary by CodeRabbit

  • Improvements
    • Enhanced the runtime dashboard to display per-protocol server and tunnel IP addresses
    • When different protocols use different server or tunnel addresses, the dashboard now shows them individually with clear protocol labels (TCP, UDP, WS)
    • Improved internal handling of network address information for better reliability

@coderabbitai

coderabbitai Bot commented Apr 5, 2026

Copy link
Copy Markdown
📝 Walkthrough

Walkthrough

The runtime address model is refactored from flat IPv4/IPv6 fields into a protocol-aware structure. RuntimeAddressInfo now stores ProtocolAddresses []RuntimeProtocolAddress, where each entry binds a protocol with server and tunnel address pairs. Client and server configuration constructors adapted accordingly; dashboard rendering updated to display per-protocol addresses with conditional multi-line presentation.

Changes

Cohort / File(s) Summary
Core Address Model Refactoring
src/presentation/runners/common/runtime_address_info.go
New types RuntimeAddressPair (IPv4+IPv6) and RuntimeProtocolAddress (protocol + address pairs); restructured RuntimeAddressInfo to use ProtocolAddresses[] instead of flat fields; updated client constructor to build single entry via protocol fallback; server constructor now iterates enabled protocols with validation gating.
Core Address Model Tests
src/presentation/runners/common/runtime_address_info_test.go
Refactored assertions to validate per-protocol entries in ProtocolAddresses[]; added coverage for multi-protocol server scenarios, invalid pair handling, and protocol-specific address retention.
Dashboard UI Rendering
src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard.go, src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard_test.go
Updated RuntimeDashboardOptions to accept ProtocolAddresses[]; replaced scalar IP display with serverAddressLines()/tunnelIPLines() helpers for conditional single/multi-line rendering per protocol; added formatting helpers and shared-address detection logic; extended test coverage for per-protocol display scenarios.
Backend Integration & Tests
src/presentation/ui/tui/runtime_backend_bubbletea.go, src/presentation/ui/tui/runtime_backend_bubbletea_test.go, src/presentation/ui/tui/runtime_ui_test.go
Updated dashboard options initialization to forward ProtocolAddresses[] from options.Address; adjusted test assertions to validate per-protocol entries and nested address fields.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Possibly related PRs

Poem

🐰 A protocol-aware refactor hops,
From flat fields to nested, it stops,
Each protocol now gets its pair,
Server and tunnel with proper care,
The dashboard renders with flair! 🌟

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title '[codex] Show tunnel IPs for each enabled server protocol' directly and clearly describes the main change: displaying tunnel IP addresses per protocol instead of a single address pair.
Linked Issues check ✅ Passed The PR fully addresses issue #280 by refactoring RuntimeAddressInfo to store protocol-addressed pairs, updating dashboard rendering to show per-protocol tunnel addresses, and removing reliance on a single pair.
Out of Scope Changes check ✅ Passed All changes are directly scoped to the linked issue: refactoring address structures, updating dashboard rendering, and adding comprehensive test coverage for the new protocol-specific address model.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch issue/280

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@codecov

codecov Bot commented Apr 5, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

Flag Coverage Δ
unittests 95.29% <100.00%> (+0.02%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

Files with missing lines Coverage Δ
...resentation/runners/common/runtime_address_info.go 100.00% <100.00%> (ø)
...on/ui/tui/internal/bubble_tea/runtime_dashboard.go 100.00% <100.00%> (ø)
...c/presentation/ui/tui/runtime_backend_bubbletea.go 100.00% <100.00%> (ø)
🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@NLipatov NLipatov marked this pull request as ready for review April 5, 2026 16:43

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
src/presentation/runners/common/runtime_address_info_test.go (1)

81-122: Add a WSS/UNKNOWN fallback case to this test coverage.

protocolOrFallback(...) is now what preserves WSSettings.Protocol = settings.WSS and the UNKNOWN -> WS fallback, but these assertions only cover matching TCP/UDP/WS inputs. A small extra case here would lock down the remaining protocol-tagging edge.

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/presentation/runners/common/runtime_address_info_test.go` around lines 81
- 122, Extend
TestRuntimeAddressInfoFromServerConfiguration_CollectsAllEnabledTunnelAddresses
to also assert handling of WSS and UNKNOWN fallbacks: add a
serverConfiguration.Configuration variant where WSSettings.Protocol is set to
settings.WSS and another where a non-WS protocol triggers the UNKNOWN->WS
fallback via protocolOrFallback, then call
RuntimeAddressInfoFromServerConfiguration and assert that the resulting
TunnelAddresses entry for the WS slot preserves settings.WSS for the first case
and maps UNKNOWN to settings.WS for the fallback case; reference
WSSettings.Protocol, protocolOrFallback, and
RuntimeAddressInfoFromServerConfiguration when locating where to add these
assertions.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@src/presentation/runners/common/runtime_address_info.go`:
- Around line 35-36: The code flattens per-protocol server hosts into a single
ServerAddress (RuntimeAddressPair) via MergeMissing, which can hide differences
across protocols; update the code that constructs ServerAddress (and similarly
TunnelAddresses handling) to either (A) validate that all enabled protocols in
serverConfiguration.Configuration have identical Server hosts before merging and
abort/log an error if they differ, or (B) change the model to keep server
addresses per protocol (e.g., map protocol->RuntimeAddressPair) instead of a
single ServerAddress and update consumers accordingly; identify usages of
ServerAddress, RuntimeAddressPair, MergeMissing, and
serverConfiguration.Configuration to implement the chosen approach and ensure
TunnelAddresses (lines 57-59) follow the same rule.

---

Nitpick comments:
In `@src/presentation/runners/common/runtime_address_info_test.go`:
- Around line 81-122: Extend
TestRuntimeAddressInfoFromServerConfiguration_CollectsAllEnabledTunnelAddresses
to also assert handling of WSS and UNKNOWN fallbacks: add a
serverConfiguration.Configuration variant where WSSettings.Protocol is set to
settings.WSS and another where a non-WS protocol triggers the UNKNOWN->WS
fallback via protocolOrFallback, then call
RuntimeAddressInfoFromServerConfiguration and assert that the resulting
TunnelAddresses entry for the WS slot preserves settings.WSS for the first case
and maps UNKNOWN to settings.WS for the fallback case; reference
WSSettings.Protocol, protocolOrFallback, and
RuntimeAddressInfoFromServerConfiguration when locating where to add these
assertions.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 1c9cb4f4-8457-48e6-afaa-448e2139d584

📥 Commits

Reviewing files that changed from the base of the PR and between 6c92c41 and 9815fcd.

📒 Files selected for processing (7)
  • src/presentation/runners/common/runtime_address_info.go
  • src/presentation/runners/common/runtime_address_info_test.go
  • src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard.go
  • src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard_test.go
  • src/presentation/ui/tui/runtime_backend_bubbletea.go
  • src/presentation/ui/tui/runtime_backend_bubbletea_test.go
  • src/presentation/ui/tui/runtime_ui_test.go

Comment thread src/presentation/runners/common/runtime_address_info.go Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🧹 Nitpick comments (2)
src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard_test.go (1)

690-704: Add an explicit guard against legacy single-line tunnel output.

The test checks for the new grouped section, but it should also assert that legacy Tunnel IP: is absent in multi-protocol server mode.

Suggested assertion
 	if !strings.Contains(view, "WS: IPv4 10.0.2.1 | IPv6 fd00::3") {
 		t.Fatalf("expected WS tunnel line in server main view, got %q", view)
 	}
+	if strings.Contains(view, "Tunnel IP: ") {
+		t.Fatalf("unexpected legacy single tunnel IP line in multi-protocol server view, got %q", view)
+	}
 }
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard_test.go` around
lines 690 - 704, The test currently asserts presence of the new grouped tunnel
section by checking substrings in the view variable but does not guard against
the old single-line legacy output; update the test in runtime_dashboard_test.go
(the assertions that check view for "Tunnel IPs:", "Server IP: IPv4
198.51.100.10", "TCP: IPv4 10.0.0.1 | IPv6 fd00::1", "UDP: IPv4 10.0.1.1 | IPv6
fd00::2", "WS: IPv4 10.0.2.1 | IPv6 fd00::3") to also assert that the legacy
string "Tunnel IP:" is not present (e.g., add a t.Fatalf when
strings.Contains(view, "Tunnel IP:") is true) so the test fails if the old
single-line output appears in multi-protocol server mode.
src/presentation/ui/tui/runtime_backend_bubbletea_test.go (1)

75-83: Consider adding a multi-protocol forwarding assertion.

This fixture only exercises a single entry, so a future regression that drops additional protocols could still pass.

Suggested test hardening
-       if len(options.ProtocolAddresses) != 1 {
-           t.Fatalf("expected one protocol address entry forwarded, got %d", len(options.ProtocolAddresses))
+       if len(options.ProtocolAddresses) != 2 {
+           t.Fatalf("expected two protocol address entries forwarded, got %d", len(options.ProtocolAddresses))
        }
+       if options.ProtocolAddresses[1].Protocol != settings.UDP {
+           t.Fatalf("expected second protocol address protocol UDP, got %v", options.ProtocolAddresses[1].Protocol)
+       }

        ...
-       Address: runnerCommon.RuntimeAddressInfo{
-           ProtocolAddresses: []runnerCommon.RuntimeProtocolAddress{{
+       Address: runnerCommon.RuntimeAddressInfo{
+           ProtocolAddresses: []runnerCommon.RuntimeProtocolAddress{{
                Protocol: settings.TCP,
                ServerAddress: runnerCommon.RuntimeAddressPair{
                    IPv4: netip.MustParseAddr("198.51.100.10"),
                },
                TunnelAddress: runnerCommon.RuntimeAddressPair{
                    IPv4: netip.MustParseAddr("10.0.0.2"),
                },
-           }},
+           }, {
+               Protocol: settings.UDP,
+               ServerAddress: runnerCommon.RuntimeAddressPair{
+                   IPv4: netip.MustParseAddr("198.51.100.11"),
+               },
+               TunnelAddress: runnerCommon.RuntimeAddressPair{
+                   IPv4: netip.MustParseAddr("10.0.1.2"),
+               },
+           }},
        },
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/presentation/ui/tui/runtime_backend_bubbletea_test.go` around lines 75 -
83, The test fixture only includes a single ProtocolAddresses entry
(runnerCommon.RuntimeProtocolAddress with Protocol settings.TCP), which won't
catch regressions that drop support for other protocols; update the test in
runtime_backend_bubbletea_test.go to include at least one additional
ProtocolAddresses entry (e.g., a second runnerCommon.RuntimeProtocolAddress with
Protocol settings.UDP and appropriate ServerAddress/TunnelAddress pairs) and add
assertions that the component under test handles both entries (check that
forwarding/translation logic for ProtocolAddresses and RuntimeProtocolAddress
processes both TCP and UDP entries).
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Nitpick comments:
In `@src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard_test.go`:
- Around line 690-704: The test currently asserts presence of the new grouped
tunnel section by checking substrings in the view variable but does not guard
against the old single-line legacy output; update the test in
runtime_dashboard_test.go (the assertions that check view for "Tunnel IPs:",
"Server IP: IPv4 198.51.100.10", "TCP: IPv4 10.0.0.1 | IPv6 fd00::1", "UDP: IPv4
10.0.1.1 | IPv6 fd00::2", "WS: IPv4 10.0.2.1 | IPv6 fd00::3") to also assert
that the legacy string "Tunnel IP:" is not present (e.g., add a t.Fatalf when
strings.Contains(view, "Tunnel IP:") is true) so the test fails if the old
single-line output appears in multi-protocol server mode.

In `@src/presentation/ui/tui/runtime_backend_bubbletea_test.go`:
- Around line 75-83: The test fixture only includes a single ProtocolAddresses
entry (runnerCommon.RuntimeProtocolAddress with Protocol settings.TCP), which
won't catch regressions that drop support for other protocols; update the test
in runtime_backend_bubbletea_test.go to include at least one additional
ProtocolAddresses entry (e.g., a second runnerCommon.RuntimeProtocolAddress with
Protocol settings.UDP and appropriate ServerAddress/TunnelAddress pairs) and add
assertions that the component under test handles both entries (check that
forwarding/translation logic for ProtocolAddresses and RuntimeProtocolAddress
processes both TCP and UDP entries).

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 6e293aec-bc37-4934-9356-3cda1e06fdfd

📥 Commits

Reviewing files that changed from the base of the PR and between 9815fcd and dc2e81a.

📒 Files selected for processing (7)
  • src/presentation/runners/common/runtime_address_info.go
  • src/presentation/runners/common/runtime_address_info_test.go
  • src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard.go
  • src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard_test.go
  • src/presentation/ui/tui/runtime_backend_bubbletea.go
  • src/presentation/ui/tui/runtime_backend_bubbletea_test.go
  • src/presentation/ui/tui/runtime_ui_test.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/presentation/ui/tui/runtime_ui_test.go
  • src/presentation/runners/common/runtime_address_info_test.go
  • src/presentation/runners/common/runtime_address_info.go
  • src/presentation/ui/tui/internal/bubble_tea/runtime_dashboard.go
  • src/presentation/ui/tui/runtime_backend_bubbletea.go

@NLipatov NLipatov merged commit 35442f1 into main Apr 5, 2026
10 checks passed
Sign up for free to 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.

Server runtime dashboard shows tunnel IP for only one enabled protocol

1 participant