Files
gost/tests/e2e/PLAN.md
T
ginuerzh 69b561f944 feat: add comprehensive HTTP e2e tests covering connector, TLS, probeResist, idleTimeout, and UDP relay
Adds 12 new HTTP handler test scenarios: HTTP connector (no-auth, auth, TLS
upstream), CONNECT tunnel (no-sniffing, bypass-403), probeResist (host, web,
file, knock), idleTimeout, and UDP relay over HTTP. Introduces
RunGostContainerWithFiles helper for mounting extra files into test containers.
2026-06-26 22:00:35 +08:00

7.0 KiB

Plan: Expand E2E Test Suite

Context

The e2e test framework (tests/e2e/) currently covers only 2 protocols (Shadowsocks, parallel selector) out of ~30+ registered protocols in gost. This plan systematically adds test coverage for all major protocols, following the existing Docker-based testcontainers pattern exactly.

Key insight: gost auto-generates self-signed TLS certs when none are provided (x/config/parsing/tls.goBuildDefaultTLSConfig), and clients with default config skip cert verification. This means TLS-based protocols (ws→wss, h2c→h2, quic, etc.) can be tested without mounting cert files.


Step 0: Refactor utils.go — Add Reusable Test Helpers

File: tests/e2e/utils.go

Extract the repeated patterns from shadowsocks_test.go into reusable helpers:

  1. RunTCPCase(t, ctx, networkName, echoIP, name, serverConfig, clientConfig string) — Full lifecycle: start server → render client config → start client → curl assertion → cleanup. Extracts the logic from ShadowsocksSuite.runTCPCase.

  2. RunUDPCase(t, ctx, networkName, name, serverConfig, clientConfig string) — Same for UDP: start server → render client → start client → dial UDP → retry loop → assertion → cleanup. Extracts from runUDPCase.

These eliminate ~40 lines of boilerplate per suite. Each suite's test methods become one-liners:

func (s *SOCKS5Suite) TestSOCKS5TCP() {
    RunTCPCase(s.T(), s.ctx, SharedNetworkName, s.echoIP, "socks5-tcp",
        "testdata/socks5/tcp_server.yaml", "testdata/socks5/tcp_client.yaml")
}

Step 1: Tier 1 — Core Protocols (Plain TCP, No Special Infrastructure)

Each suite follows the exact pattern: suite struct → SetupSuite (echo containers) → TearDownSuite → test methods calling RunTCPCase/RunUDPCasesuite.Run() entry point.

1A. HTTP Proxy Suite

  • Files: http_test.go, testdata/http/ (2 configs)
  • Configs: server.yaml (handler http, listener tcp), server_auth.yaml (+ basic auth)
  • Tests: TestHTTPProxy, TestHTTPProxyAuth (curl with --proxy-user)
  • Note: Simplest test — single gost container acts as HTTP proxy

1B. SOCKS5 Suite

  • Files: socks5_test.go, testdata/socks5/ (4 configs)
  • Configs: tcp_server.yaml (handler socks5), tcp_client.yaml (connector socks5, dialer tcp), + auth variants
  • Tests: TestSOCKS5TCP, TestSOCKS5TCPAuth

1C. SOCKS4 Suite

  • Files: socks4_test.go, testdata/socks4/ (4 configs)
  • Configs: tcp_server.yaml (handler socks4), tcp_client.yaml (connector socks4), + socks4a variants
  • Tests: TestSOCKS4TCP, TestSOCKS4aTCP

1D. HTTP2 Cleartext Suite

  • Files: http2_test.go, testdata/http2/ (2 configs)
  • Configs: tcp_server.yaml (handler http2, listener http2), tcp_client.yaml (connector http2, dialer http2)
  • Tests: TestHTTP2TCP

1E. Relay Suite

  • Files: relay_test.go, testdata/relay/ (4 configs)
  • Configs: tcp_server.yaml (handler relay, listener tcp), tcp_client.yaml (connector relay, dialer tcp), + auth variants
  • Tests: TestRelayTCP, TestRelayTCPAuth

Step 2: Tier 2 — TLS/Transport Protocols

Same pattern but using TLS listeners/dialers. No explicit cert files needed — gost auto-generates them.

2A. TLS Suite

  • Files: tls_test.go, testdata/tls/ (4 configs)
  • Tests: TestTLSHTTPProxy (handler http + listener tls), TestTLSSOCKS5 (handler socks5 + listener tls)

2B. WebSocket Suite

  • Files: ws_test.go, testdata/ws/ (4 configs)
  • Tests: TestWSSOCKS5 (dialer ws), TestWSSSOCKS5 (dialer wss)

2C. gRPC Suite

  • Files: grpc_test.go, testdata/grpc/ (2 configs)
  • Tests: TestGRPCSOCKS5 (listener grpc, metadata insecure: true)

2D. HTTP/2 TLS (h2) Suite

  • Files: h2_test.go, testdata/h2/ (2 configs)
  • Tests: TestH2HTTP2Proxy (listener h2, dialer h2)

2E. QUIC Suite

  • Files: quic_test.go, testdata/quic/ (2 configs)
  • Tests: TestQUICHTTP (listener quic, handler http — uses UDP ports)

2F. KCP Suite

  • Files: kcp_test.go, testdata/kcp/ (2 configs)
  • Tests: TestKCPSOCKS5 (listener kcp, handler socks5 — uses UDP)

2G. Multiplex Variants (mws/mwss/mtls/mtcp)

  • Files: mux_test.go, testdata/mux/ (6 configs)
  • Tests: TestMWSSOCKS5, TestMWSSSOCKS5, TestMtlSSOCKS5, TestMtcpSOCKS5

2H. Obfuscation (ohttp/otls)

  • Files: obfs_test.go, testdata/obfs/ (4 configs)
  • Tests: TestOHTTP, TestOTLS

2I. PHT (HTTP Pipe)

  • Files: pht_test.go, testdata/pht/ (4 configs)
  • Tests: TestPHT, TestPHTS

Step 3: Tier 3 — Special Infrastructure (Deferred)

These require Docker capabilities (NET_ADMIN, NET_RAW), SSH key generation, or iptables setup. Implemented after Tiers 1-2 are stable.

Protocol Challenge Approach
SSH/sshd Host key generation Generate SSH key at test time, mount into container
HTTP/3/WebTransport QUIC+UDP, TLS Uses UDP like QUIC suite; auto certs work
TUN/TAP CAP_NET_ADMIN, /dev/net/tun Privileged container + routing setup
Tungo/MASQUE Same as TUN Same approach
ICMP CAP_NET_RAW, raw sockets Privileged container
Redirect (red/redu) iptables rules Privileged + iptables setup in container
DTLS UDP + TLS Auto certs; UDP port mapping

Files to Create/Modify

New files (per suite):

  • tests/e2e/<protocol>_test.go — Suite struct + test methods
  • tests/e2e/testdata/<protocol>/ — Server + client YAML configs

Modified files:

  • tests/e2e/utils.go — Add RunTCPCase, RunUDPCase helpers
  • tests/e2e/shadowsocks_test.go — Refactor to use new helpers (optional, reduces duplication)
  • tests/e2e/README.md — Document new suites

Reference files (read-only):

  • tests/e2e/shadowsocks_test.go — Pattern template for all suites
  • tests/e2e/testdata/shadowsocks/tcp_server_aes256gcm.yaml — Server config template
  • tests/e2e/testdata/shadowsocks/tcp_client_aes256gcm.yaml — Client config template

Config Pattern Reference

Server (all protocols):

services:
- name: <proto>-server
  addr: :<port>
  handler:
    type: <handler-type>
  listener:
    type: <listener-type>

Client (all protocols):

services:
- name: http-proxy
  addr: :8080
  handler:
    type: http
    chain: <proto>-chain
  listener:
    type: tcp
chains:
- name: <proto>-chain
  hops:
  - name: <proto>-hop
    nodes:
    - name: <proto>-node
      addr: {{.ServerAddr}}
      connector:
        type: <connector-type>
      dialer:
        type: <dialer-type>

Verification

After each suite is implemented:

  1. cd gost && go build ./... — Ensure compilation
  2. go vet ./tests/e2e/ — Static analysis
  3. go test ./tests/e2e/ -v -run TestXxxSuite -timeout 5m — Run individual suite
  4. go test ./tests/e2e/ -v -timeout 10m — Run all suites together