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) 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 }