This document describes the testing framework infrastructure used in the frp codebase. It covers the Ginkgo/Gomega testing framework, test execution utilities, mock server implementations, and the supporting infrastructure for running end-to-end tests. For information about the actual test scenarios and test coverage, see End-to-End Testing. For code quality enforcement tools, see Code Quality and Linting.
The frp project uses Ginkgo v2 as its primary BDD-style testing framework, paired with Gomega for assertions. This combination provides expressive, readable test specifications and comprehensive matcher support for validating complex proxy behaviors.
Key Components:
Sources: go.mod13-14 go.mod25
Sources: hack/run-e2e.sh1-35 go.mod13-14 go.mod25
Ginkgo is a BDD-style Go testing framework that provides rich test organization capabilities, parallel execution, and expressive test specifications.
Test Suite Organization:
Describe blocks: Group related test casesContext blocks: Describe specific scenariosIt blocks: Individual test specificationsBeforeEach/AfterEach: Setup and teardown hooksBeforeSuite/AfterSuite: Suite-level initializationParallel Execution: The framework supports running tests in parallel with configurable concurrency:
ginkgo -nodes=${concurrency} --poll-progress-after=60s
The default concurrency is 16 nodes, which can be overridden via the CONCURRENCY environment variable.
Progress Reporting:
The --poll-progress-after=60s flag enables progress reporting for long-running tests, printing status updates every 60 seconds to detect hanging tests.
Sources: hack/run-e2e.sh29-34
Sources: hack/run-e2e.sh34
Gomega provides expressive matchers for test assertions, enabling readable and maintainable test code.
Basic Matchers:
Equal(expected): Value equalityBeNil(): Nil checkBeTrue()/BeFalse(): Boolean assertionsHaveLen(length): Collection lengthContainSubstring(substring): String matchingNetwork Matchers:
Async Matchers:
Eventually(func): Retry until success or timeoutConsistently(func): Verify condition remains trueTests typically use Eventually for operations that may take time:
Sources: go.mod14
The hack/run-e2e.sh1-35 script provides a convenient wrapper around the Ginkgo CLI with environment-based configuration.
Environment Variables:
| Variable | Default | Purpose |
|---|---|---|
DEBUG | false | Enable debug mode for verbose output |
LOG_LEVEL | debug | Set log level (trace, debug, info, warn, error) |
FRPC_PATH | ${ROOT}/bin/frpc | Path to frpc binary |
FRPS_PATH | ${ROOT}/bin/frps | Path to frps binary |
CONCURRENCY | 16 | Number of parallel test nodes |
Script Workflow:
ginkgo CLI is available, installs if missingSources: hack/run-e2e.sh6-34
Test utilities manage frpc/frps process lifecycles:
Responsibilities:
To support parallel test execution, the framework includes dynamic port allocation:
Features:
Test utilities generate frpc/frps configuration files dynamically:
Configuration Templates:
Format Support: The configuration generator supports multiple formats (TOML, YAML, JSON, INI) to test configuration loading across all supported formats.
The test framework integrates with frp's logging system via pkg/util/xlog/log_writer.go1-66:
LogWriter Types:
NewTraceWriter(xl): Trace-level output for detailed debuggingNewDebugWriter(xl): Debug-level for test diagnosticsNewInfoWriter(xl): Information-level for test progressNewWarnWriter(xl): Warning-level for non-critical issuesNewErrorWriter(xl): Error-level for failuresThe yamux multiplexer uses NewTraceWriter to minimize log noise during normal test execution while retaining full diagnostics when needed:
Sources: pkg/util/xlog/log_writer.go19-66 client/connector.go118
Mock HTTP servers use gorilla/mux for routing:
Capabilities:
Example Use Cases:
Sources: go.mod10
TCP Mock Server:
UDP Mock Server:
Uses gorilla/websocket for testing WebSocket transport:
Test Scenarios:
Sources: go.mod11
Process Control Interface:
Start(): Launch frpc/frps with configurationStop(): Graceful shutdownKill(): Force terminationWait(): Wait for process exitIsRunning(): Process status checkOutput Capture:
The framework uses the version information from pkg/util/version/version.go15-21 to support backward compatibility testing:
Version Testing:
Sources: pkg/util/version/version.go15-21
Ginkgo distributes tests across multiple nodes (processes):
Coordination:
Resource Management:
Isolation Strategies:
Sources: hack/run-e2e.sh29-34
Enable via DEBUG=true environment variable:
Debug Features:
Log Levels:
Configurable via LOG_LEVEL environment variable:
trace: Maximum verbosity, including protocol-level detailsdebug: Detailed operational informationinfo: General progress informationwarn: Warning messages onlyerror: Error messages onlySources: hack/run-e2e.sh12-19
Failure Information Captured:
Gomega Failure Messages: Gomega provides detailed failure messages including:
The test framework validates all transport protocols supported by the Connector abstraction:
TCP Transport:
WebSocket Transport:
QUIC Transport:
KCP Transport:
Sources: client/connector.go37-227
TLS Configuration Validation:
Custom TLS Features:
Sources: client/connector.go69-104 client/connector.go147-196
The test framework integrates with the CI/CD pipeline documented in Development and Deployment:
CI Execution:
Platform Coverage:
Sources: See CI/CD Pipeline for details
Describe blocksContext to describe different scenariosIt blocks focused on single behaviorsBeforeEach for test setup, not BeforeSuiteAfterEachEventually for asynchronous operationsRefresh this wiki