plp-test/internal/testcase/testcase.go

202 lines
4.7 KiB
Go

package testcase
import (
"context"
"sync"
"time"
"plp-test/internal/config"
"plp-test/internal/model"
"plp-test/pkg/opencastools"
"github.com/sirupsen/logrus"
)
// TestCaseStatus 表示测试用例状态
type TestCaseStatus string
const (
StatusReady TestCaseStatus = "ready"
StatusRunning TestCaseStatus = "running"
StatusCompleted TestCaseStatus = "completed"
StatusFailed TestCaseStatus = "failed"
StatusAborted TestCaseStatus = "aborted"
)
// TestCase 定义测试用例接口
type TestCase interface {
// Name 返回测试用例名称
Name() string
// Description 返回测试用例描述
Description() string
// Setup 设置测试环境
Setup(ctx context.Context, recovery bool) error
// Run 运行测试
Run(ctx context.Context) (*model.TestResult, error)
// Cleanup 清理测试环境
Cleanup(ctx context.Context) error
// Status 获取测试状态
Status() *model.TestStatus
}
// BaseTestCase 基础测试用例实现
type BaseTestCase struct {
name string
description string
status TestCaseStatus
statusMu sync.RWMutex
config *config.Config
logger *logrus.Logger
casManager *opencastools.OpenCASManager
progress float64
message string
startTime time.Time
testID string
}
// NewBaseTestCase 创建基础测试用例
func NewBaseTestCase(name, description string, cfg *config.Config, logger *logrus.Logger) *BaseTestCase {
return &BaseTestCase{
name: name,
description: description,
status: StatusReady,
config: cfg,
logger: logger,
casManager: opencastools.NewOpenCASManager(logger),
testID: name + "-" + time.Now().Format("20060102-150405"),
}
}
// Name 返回测试用例名称
func (b *BaseTestCase) Name() string {
return b.name
}
// Description 返回测试用例描述
func (b *BaseTestCase) Description() string {
return b.description
}
// Setup 设置测试环境
func (b *BaseTestCase) Setup(ctx context.Context) error {
b.setStatus(StatusRunning)
b.setProgress(0)
b.setMessage("设置测试环境")
b.startTime = time.Now()
return nil
}
// Run 运行测试
func (b *BaseTestCase) Run(ctx context.Context) (*model.TestResult, error) {
// 由子类实现
return nil, nil
}
// Cleanup 清理测试环境
func (b *BaseTestCase) Cleanup(ctx context.Context) error {
b.setMessage("清理测试环境")
return nil
}
// Status 获取测试状态
func (b *BaseTestCase) Status() *model.TestStatus {
b.statusMu.RLock()
defer b.statusMu.RUnlock()
return &model.TestStatus{
TestID: b.testID,
TestType: b.name,
Status: string(b.status),
Progress: b.progress,
StartTime: b.startTime,
CurrentPhase: b.message,
}
}
// setStatus 设置测试状态
func (b *BaseTestCase) setStatus(status TestCaseStatus) {
b.statusMu.Lock()
defer b.statusMu.Unlock()
b.status = status
}
// setProgress 设置测试进度
func (b *BaseTestCase) setProgress(progress float64) {
b.statusMu.Lock()
defer b.statusMu.Unlock()
b.progress = progress
}
// setMessage 设置测试消息
func (b *BaseTestCase) setMessage(message string) {
b.statusMu.Lock()
defer b.statusMu.Unlock()
b.message = message
b.logger.Info(message)
}
// getTestResult 获取测试结果的基本信息
func (b *BaseTestCase) getTestResult() *model.TestResult {
return &model.TestResult{
ID: b.testID,
TestName: b.name,
StartTime: b.startTime,
EndTime: time.Now(),
Duration: time.Since(b.startTime).Seconds(),
Success: b.status == StatusCompleted,
}
}
// TestCaseFactory 测试用例工厂,用于创建所有测试用例
type TestCaseFactory struct {
config *config.Config
logger *logrus.Logger
}
// NewTestCaseFactory 创建测试用例工厂
func NewTestCaseFactory(cfg *config.Config, logger *logrus.Logger) *TestCaseFactory {
return &TestCaseFactory{
config: cfg,
logger: logger,
}
}
// CreateTestCase 根据名称创建测试用例
func (f *TestCaseFactory) CreateTestCase(name string) (TestCase, error) {
switch name {
case "sequential":
return NewSequentialWriteTest(f.config, f.logger), nil
case "random":
return NewRandomWriteTest(f.config, f.logger), nil
case "mixed":
return NewMixedReadWriteTest(f.config, f.logger), nil
case "concurrent":
return NewConcurrentWriteTest(f.config, f.logger), nil
case "power_loss":
return NewPowerLossTest(f.config, f.logger), nil
case "stability":
return NewStabilityTest(f.config, f.logger), nil
default:
return nil, nil
}
}
// CreateAllEnabledTestCases 创建所有启用的测试用例
func (f *TestCaseFactory) CreateAllEnabledTestCases() []TestCase {
var testCases []TestCase
for _, name := range f.config.Test.EnabledTests {
testCase, err := f.CreateTestCase(name)
if err == nil && testCase != nil {
testCases = append(testCases, testCase)
}
}
return testCases
}