菜单

开发与测试

相关源文件

本页面为 frp 项目的贡献者提供必要信息,重点介绍开发工作流程和测试基础设施。它解释了如何设置开发环境、理解测试框架以及运行测试来验证您的更改。有关具体的贡献指南,请参阅贡献指南

开发环境设置

要为 frp 做贡献,您需要设置一个包含以下组件的本地开发环境:

  1. Go 编程语言 (1.20+ 版本)
  2. Git 用于版本控制
  3. Make 用于运行构建目标
  4. Ginkgo 用于运行端到端测试

该项目使用 Go modules 进行依赖管理,因此不需要额外的包管理器。

来源: hack/run-e2e.sh6-10

测试框架架构

frp 项目采用了一个全面的端到端测试框架来验证跨不同组件的功能。该框架旨在启动完整的 frp 环境(服务器和客户端),并具有各种配置来测试不同的场景。

测试框架架构

来源: test/e2e/framework/framework.go18-64 test/e2e/framework/framework.go86-164

关键组件

测试框架包含几个关键组件:

  1. Framework:协调测试执行、资源分配和清理的中心结构
  2. PortAllocator:管理端口分配,以避免并行测试执行中的冲突
  3. MockServers:提供模拟服务器,用于测试各种代理场景
  4. ProcessRunner:处理 frps 和 frpc 进程的启动和停止

框架

Framework 结构体是管理测试生命周期的核心组件。它负责:

  • 创建临时目录用于存放测试文件
  • 为 frp 服务器和客户端分配端口
  • 运行 frps 和 frpc 进程
  • 测试后清理资源
  • 渲染模板配置文件

来源: test/e2e/framework/framework.go26-62

端口分配器

PortAllocator 负责管理端口分配,以避免在并行测试时发生冲突。主要功能:

  • 为测试保留端口范围
  • 根据并行执行的测试节点索引分配端口
  • 分配前验证端口可用性
  • 测试后妥善释放端口

来源: test/e2e/pkg/port/port.go12-86 test/e2e/framework/framework.go237-246

测试进程执行

测试框架通过结构化的方法执行 frp 进程并管理它们的生命周期。

进程执行流程

来源: test/e2e/framework/process.go13-69

运行测试

端到端测试

该项目包含一个端到端测试脚本,可以自动化测试执行过程。该脚本位于 hack/run-e2e.sh,可以从项目根目录执行。

# Run all end-to-end tests
./hack/run-e2e.sh

# Run with debug output
DEBUG=true ./hack/run-e2e.sh

# Specify log level
LOG_LEVEL=info ./hack/run-e2e.sh

# Specify frpc/frps paths (for testing custom builds)
FRPC_PATH=/path/to/frpc FRPS_PATH=/path/to/frps ./hack/run-e2e.sh

# Adjust concurrency
CONCURRENCY=8 ./hack/run-e2e.sh

该脚本会在找不到 Ginkgo 的情况下自动安装它,然后设置环境并使用适当的参数运行测试。

来源: hack/run-e2e.sh1-34

测试配置

测试通过全局 TestContext 结构体进行配置,该结构体包含:

参数描述默认
FRPClientPathfrpc 二进制文件的路径./bin/frpc
FRPServerPathfrps 二进制文件的路径./bin/frps
LogLevel测试的日志级别debug
调试启用调试输出false
并发并行测试数量16

来源: hack/run-e2e.sh12-32

测试用例开发

编写新测试

新测试应使用 Ginkgo 测试框架编写。典型的测试结构:

  1. test/e2e/ 下创建一个带有描述性名称的新文件
  2. 使用框架设置服务器和客户端配置
  3. 执行测试场景
  4. 验证预期行为

示例测试工作流程

  1. 获取框架实例
  2. 为 frps 和 frpc 创建配置文件模板
  3. 使用这些模板运行进程
  4. 执行测试断言
  5. 让框架处理清理工作

测试模板

框架使用 Go 模板生成 frp 配置文件。模板可以包含端口占位符,这些占位符将被分配的端口替换。

[common]
bind_port = {{ .PortServerName }}

[test_tcp]
type = tcp
local_port = {{ .PortLocalService }}
remote_port = {{ .PortRemoteService }}

来源: test/e2e/framework/framework.go174-231

最佳实践

在为 frp 项目贡献时,请遵循以下测试最佳实践:

  1. 为新功能编写测试:确保所有新功能都有适当的测试覆盖
  2. 在本地运行所有测试:在提交更改之前,请验证所有测试是否通过
  3. 隔离测试资源:使用框架妥善隔离测试资源
  4. 妥善清理:确保所有进程和资源都得到妥善清理
  5. 使用描述性的测试名称:使测试名称清晰并准确描述正在测试的内容
  6. 有条理地组织测试:使用 Ginkgo 的 BDD 风格语法有条理地组织测试

来源: test/e2e/framework/framework.go111-164