128 lines
5.7 KiB
Go
128 lines
5.7 KiB
Go
package workflows
|
|
|
|
// workflows 包定义了 Temporal 工作流的实现
|
|
import (
|
|
"beacon/pkg/pb"
|
|
"fmt"
|
|
"go.temporal.io/sdk/temporal"
|
|
"go.temporal.io/sdk/workflow"
|
|
"time"
|
|
)
|
|
|
|
// TestRunWorkflow 定义了整个测试执行的工作流
|
|
// 该工作流负责协调和执行 API 测试和 UI 测试的整个流程
|
|
// 参数:
|
|
// - ctx: Temporal 工作流上下文,用于控制工作流的执行
|
|
// - input: 测试运行的输入参数,包含运行配置和标识
|
|
//
|
|
// 返回值:
|
|
// - *pb.TestRunOutput: 测试运行的结果输出
|
|
// - error: 执行过程中的错误信息
|
|
func TestRunWorkflow(ctx workflow.Context, input *pb.TestRunInput) (*pb.TestRunOutput, error) {
|
|
// 获取工作流日志记录器,用于记录执行过程中的关键信息
|
|
logger := workflow.GetLogger(ctx)
|
|
logger.Info("TestRunWorkflow started", "runID", input.RunId)
|
|
|
|
// 配置 Activity 的执行选项,包括超时时间和重试策略
|
|
ctx = workflow.WithActivityOptions(ctx, workflow.ActivityOptions{
|
|
StartToCloseTimeout: 10 * time.Minute, // Activity 从开始到完成的最大允许时间
|
|
HeartbeatTimeout: 30 * time.Second, // Heartbeat 超时时间,防止 Worker 假死
|
|
RetryPolicy: &temporal.RetryPolicy{ // Activity 级别的重试策略配置
|
|
InitialInterval: time.Second, // 首次重试前的等待时间
|
|
BackoffCoefficient: 2.0, // 重试间隔的递增系数
|
|
MaximumInterval: time.Minute, // 重试间隔的最大值
|
|
MaximumAttempts: 3, // 最大重试次数
|
|
NonRetryableErrorTypes: []string{"NonRetryableErrorType"}, // 自定义不可重试的错误类型
|
|
},
|
|
})
|
|
|
|
// 初始化变量用于存储测试结果和状态
|
|
var (
|
|
apiResults []*pb.ApiTestResult // 存储所有 API 测试的结果
|
|
uiResults []*pb.UiTestResult // 存储所有 UI 测试的结果
|
|
overallSuccess = true // 整体测试是否成功的标志
|
|
completionMessage = "Test run completed successfully." // 完成时的状态消息
|
|
)
|
|
|
|
// 条件执行 API 测试 Activity
|
|
// 只有当输入配置中指定需要运行 API 测试时才执行
|
|
if input.RunApiTests {
|
|
// 构造 API 测试的请求参数
|
|
// 这里使用硬编码的示例数据,实际应用中应该从配置或输入中获取
|
|
apiTestInput := &pb.ApiTestRequest{
|
|
TestCaseId: "api-example-1", // 测试用例唯一标识
|
|
Endpoint: "/api/v1/data", // 要测试的 API 端点
|
|
HttpMethod: "GET", // HTTP 请求方法
|
|
Headers: map[string]string{"Authorization": "Bearer token123"}, // 请求头信息
|
|
ExpectedStatusCode: 200, // 预期的 HTTP 状态码
|
|
}
|
|
|
|
// 声明变量用于接收 API 测试的结果
|
|
var apiRes pb.ApiTestResult
|
|
|
|
// 执行 API 测试 Activity 并等待结果
|
|
// "run_api_test" 是注册的 Activity 名称
|
|
err := workflow.ExecuteActivity(ctx, "run_api_test", apiTestInput).Get(ctx, &apiRes)
|
|
if err != nil {
|
|
// API 测试执行失败时的错误处理
|
|
logger.Error("API test activity failed", "error", err)
|
|
// 标记整体测试为失败,但继续执行后续测试
|
|
overallSuccess = false
|
|
// 设置测试结果的失败状态和错误信息
|
|
apiRes.BaseResult.Success = false
|
|
apiRes.BaseResult.Message = fmt.Sprintf("API Test Failed: %v", err)
|
|
}
|
|
// 将 API 测试结果添加到结果集合中
|
|
apiResults = append(apiResults, &apiRes)
|
|
}
|
|
|
|
// 条件执行 UI 测试 Activity
|
|
// 只有当输入配置中指定需要运行 UI 测试时才执行
|
|
if input.RunUiTests {
|
|
// 构造 UI 测试的请求参数
|
|
// 包含浏览器配置和测试页面信息
|
|
uiTestInput := &pb.UiTestRequest{
|
|
TestCaseId: "ui-example-1", // UI 测试用例标识
|
|
UrlPath: "/dashboard", // 要测试的页面路径
|
|
BrowserType: "chromium", // 使用的浏览器类型
|
|
Headless: true, // 是否使用无头模式运行浏览器
|
|
UserData: map[string]string{"user": "test", "pass": "password"}, // 测试用的用户数据
|
|
}
|
|
|
|
// 声明变量用于接收 UI 测试的结果
|
|
var uiRes pb.UiTestResult
|
|
|
|
// 执行 UI 测试 Activity 并等待结果
|
|
// "run_ui_test" 是注册的 Activity 名称
|
|
err := workflow.ExecuteActivity(ctx, "run_ui_test", uiTestInput).Get(ctx, &uiRes)
|
|
if err != nil {
|
|
// UI 测试执行失败时的错误处理
|
|
logger.Error("UI test activity failed", "error", err)
|
|
// 标记整体测试为失败
|
|
overallSuccess = false
|
|
// 设置测试结果的失败状态和错误信息
|
|
uiRes.BaseResult.Success = false
|
|
uiRes.BaseResult.Message = fmt.Sprintf("UI Test Failed: %v", err)
|
|
}
|
|
// 将 UI 测试结果添加到结果集合中
|
|
uiResults = append(uiResults, &uiRes)
|
|
}
|
|
|
|
// 根据整体测试结果更新完成消息
|
|
if !overallSuccess {
|
|
completionMessage = "Test run completed with failures."
|
|
}
|
|
|
|
// 记录工作流完成的日志信息
|
|
logger.Info("TestRunWorkflow completed", "overallSuccess", overallSuccess)
|
|
|
|
// 构造并返回测试运行的完整结果
|
|
return &pb.TestRunOutput{
|
|
RunId: input.RunId, // 测试运行的唯一标识
|
|
OverallSuccess: overallSuccess, // 整体测试是否成功
|
|
CompletionMessage: completionMessage, // 完成状态消息
|
|
ApiResults: apiResults, // 所有 API 测试结果
|
|
UiResults: uiResults, // 所有 UI 测试结果
|
|
}, nil
|
|
}
|