Integrate reviewed topology-free demo readiness diagnostics

Change-source: pulse-maintainer
This commit is contained in:
pulse-triage[bot]
2026-10-01 18:14:16 +01:00
5 changed files with 203 additions and 43 deletions
@@ -2599,8 +2599,8 @@ func TestDemoReachabilityHelperSeparatesTailnetAndSshTransportProof(t *testing.T
`tailscale status --json`,
`tailscale ping --c 3 --timeout 10s "$DEMO_SERVER_HOST"`,
`nc -z -w 5 "$DEMO_SERVER_HOST" "$TCP_PORT"`,
`Runner Tailscale DNS:`,
`Runner Tailscale tags:`,
`Tailscale backend:`,
`Diagnostic mode is local-only`,
`Demo peer is not present in the runner peer map yet.`,
`Verify sshd and the host firewall on tailscale0.`,
} {
@@ -2641,7 +2641,7 @@ exit 1
if err != nil {
t.Fatalf("demo reachability helper failed: %v\n%s", err, output)
}
for _, needle := range []string{"Tailscale backend: Running", "Demo peer state: online=True active=True relay=lhr", "Demo SSH transport is reachable over Tailscale."} {
for _, needle := range []string{"Tailscale backend: Running", "Demo peer state: online=True active=True", "Demo SSH transport is reachable over Tailscale."} {
if !strings.Contains(string(output), needle) {
t.Fatalf("demo reachability output missing %q: %s", needle, output)
}
@@ -0,0 +1,127 @@
package installtests
import (
"encoding/json"
"os"
"os/exec"
"path/filepath"
"strconv"
"strings"
"testing"
)
func TestDemoReachabilityStopsBeforeUnreadyOrFailedTailnetProbes(t *testing.T) {
for _, tc := range []struct {
name, mode, state, rawStatus string
statusExit, pingExit, tcpExit int
wantExit, pings, tcpProbes int
want string
}{
{name: "needs-login", state: "NeedsLogin", wantExit: 1, want: "no demo reachability probes attempted"},
{name: "machine-auth", state: "NeedsMachineAuth", wantExit: 1, want: "no demo reachability probes attempted"},
{name: "stopped", state: "Stopped", wantExit: 1},
{name: "starting", state: "Starting", wantExit: 1},
{name: "unknown-state", state: "private-data-never-log", wantExit: 1, want: "Tailscale backend: unknown"},
{name: "unavailable-status", statusExit: 1, wantExit: 1, want: "status JSON is unavailable"},
{name: "invalid-json", rawStatus: "private-data-never-log", wantExit: 1},
{name: "array-status", rawStatus: "[]", wantExit: 1},
{name: "null-status", rawStatus: "null", wantExit: 1},
{name: "missing-state", rawStatus: "{}", wantExit: 1},
{name: "invalid-state-type", rawStatus: `{"BackendState":[]}`, wantExit: 1},
{name: "diagnose-after-login-failure", mode: "diagnose", state: "NeedsLogin", want: "Diagnostic mode is local-only"},
{name: "diagnose-after-running-setup-failure", mode: "diagnose", state: "Running", want: "installed state remain unverified"},
{name: "diagnose-unavailable-status", mode: "diagnose", statusExit: 1, want: "Diagnostic mode is local-only"},
{name: "failed-tailnet-ping", state: "Running", pingExit: 1, wantExit: 1, pings: 1, want: "Tailscale cannot reach the demo peer"},
{name: "closed-ssh", state: "Running", tcpExit: 1, wantExit: 1, pings: 1, tcpProbes: 2, want: "TCP/22 remained closed"},
{name: "ready", state: "Running", pings: 1, tcpProbes: 1, want: "Demo SSH transport is reachable over Tailscale"},
{name: "malformed-peer-map", rawStatus: `{"BackendState":"Running","Peer":[]}`, pings: 1, tcpProbes: 1},
{name: "malformed-peer", rawStatus: `{"BackendState":"Running","Peer":{"a":null,"b":{"DNSName":[],"TailscaleIPs":3}}}`, pings: 1, tcpProbes: 1},
{name: "invalid-mode", mode: "unsupported", state: "Running", wantExit: 2, want: "Usage:"},
} {
t.Run(tc.name, func(t *testing.T) {
tmp := t.TempDir()
bin := filepath.Join(tmp, "bin")
if err := os.Mkdir(bin, 0o755); err != nil {
t.Fatal(err)
}
status := tc.rawStatus
if status == "" {
data, err := json.Marshal(map[string]any{
"BackendState": tc.state,
"Self": map[string]any{"TailscaleIPs": []string{"100.100.100.1"}, "DNSName": "private-data-never-log.test.", "Tags": []string{"tag:private-data-never-log"}},
"Peer": map[string]any{"demo": map[string]any{"DNSName": "demo.synthetic.test.", "Online": true, "Active": true, "Relay": "private-data-never-log"}},
})
if err != nil {
t.Fatal(err)
}
status = string(data)
}
statusFile := filepath.Join(tmp, "status.json")
if err := os.WriteFile(statusFile, []byte(status), 0o600); err != nil {
t.Fatal(err)
}
callsFile := filepath.Join(tmp, "calls")
for name, script := range map[string]string{
"tailscale": `#!/bin/sh
printf 'tailscale %s\n' "$*" >> "$CALLS_FILE"
case "$1" in
status) cat "$STATUS_FILE"; echo 'private-data-never-log' >&2; exit "$STATUS_EXIT" ;;
ping) echo 'private-data-never-log'; echo 'private-data-never-log' >&2; exit "$PING_EXIT" ;;
*) exit 97 ;;
esac
`,
"nc": `#!/bin/sh
printf 'nc %s\n' "$*" >> "$CALLS_FILE"
echo 'private-data-never-log'
echo 'private-data-never-log' >&2
exit "$TCP_EXIT"
`,
} {
if err := os.WriteFile(filepath.Join(bin, name), []byte(script), 0o755); err != nil {
t.Fatal(err)
}
}
mode := tc.mode
if mode == "" {
mode = "check"
}
cmd := exec.Command("bash", repoFile(".github", "scripts", "check-demo-reachability.sh"), mode)
cmd.Env = append(os.Environ(),
"PATH="+bin+string(os.PathListSeparator)+os.Getenv("PATH"),
"DEMO_SERVER_HOST=demo.synthetic.test", "DEMO_SERVER_PORT=22", "DEMO_TCP_ATTEMPTS=2", "DEMO_TCP_RETRY_SECONDS=0",
"CALLS_FILE="+callsFile, "STATUS_FILE="+statusFile,
"STATUS_EXIT="+strconv.Itoa(tc.statusExit), "PING_EXIT="+strconv.Itoa(tc.pingExit), "TCP_EXIT="+strconv.Itoa(tc.tcpExit),
)
output, err := cmd.CombinedOutput()
if cmd.ProcessState == nil || cmd.ProcessState.ExitCode() != tc.wantExit {
t.Fatalf("helper exit: %v, want %d; output=%s", err, tc.wantExit, output)
}
calls, err := os.ReadFile(callsFile)
if err != nil && !os.IsNotExist(err) {
t.Fatal(err)
}
if got := strings.Count(string(calls), "tailscale ping "); got != tc.pings {
t.Fatalf("tailnet probes=%d, want %d; calls=%s", got, tc.pings, calls)
}
if got := strings.Count(string(calls), "nc "); got != tc.tcpProbes {
t.Fatalf("TCP probes=%d, want %d; calls=%s", got, tc.tcpProbes, calls)
}
if tc.mode == "unsupported" && len(calls) != 0 {
t.Fatalf("invalid mode attempted a diagnostic: %s", calls)
}
if !strings.Contains(string(output), tc.want) {
t.Fatalf("output missing %q: %s", tc.want, output)
}
for _, private := range []string{"private-data-never-log", "100.100.100.1", "demo.synthetic.test", "Traceback"} {
if strings.Contains(string(output), private) {
t.Fatalf("helper exposed private or raw diagnostic content %q: %s", private, output)
}
}
if tc.wantExit != 0 || tc.mode == "diagnose" {
if strings.Contains(string(output), "Demo SSH transport is reachable") {
t.Fatalf("helper claimed connectivity without successful check: %s", output)
}
}
})
}
}