package templates import ( "os" "path/filepath" "testing" "github.com/stretchr/testify/assert" ) func createTestTemplate() *WorkflowTemplate { return &WorkflowTemplate{ Name: "golang-project", Version: "1.0.0", Description: "Template for Go projects", Author: "test-author", Orchestrator: OrchestratorConfig{ PlannerURL: "http://planner:8000", JudgeURL: "http://judge:8000", ImplementerURL: "http://implementer:8000", TimeoutSeconds: 300, RetryPolicy: "exponential", MaxConcurrency: 10, }, Tasks: []TaskConfig{ { ID: "T0.1", Title: "Analyze Requirements", Description: "Analyze project requirements", Type: "feature", Priority: "high", }, { ID: "T0.2", Title: "Implement Solution", Description: "Implement the solution", Type: "feature", Priority: "high", DependsOn: []string{"T0.1"}, }, }, } } func TestNewWorkflowTemplateManager(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) assert.NotNil(t, manager) assert.Equal(t, tmpDir, manager.templatePath) } func TestSaveTemplate(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() err := manager.SaveTemplate(template) assert.NoError(t, err) // Check file was created filePath := filepath.Join(tmpDir, "golang-project.yaml") _, err = os.Stat(filePath) assert.NoError(t, err) } func TestSaveTemplateNil(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) err := manager.SaveTemplate(nil) assert.Error(t, err) } func TestLoadTemplate(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) loaded, err := manager.LoadTemplate("golang-project") assert.NoError(t, err) assert.NotNil(t, loaded) assert.Equal(t, "golang-project", loaded.Name) } func TestLoadTemplateNotFound(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) _, err := manager.LoadTemplate("nonexistent") assert.Error(t, err) } func TestGetTemplate(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) retrieved, exists := manager.GetTemplate("golang-project") assert.True(t, exists) assert.Equal(t, "golang-project", retrieved.Name) } func TestGetTemplateNotFound(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) _, exists := manager.GetTemplate("nonexistent") assert.False(t, exists) } func TestListTemplates(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) for i := 0; i < 3; i++ { template := createTestTemplate() template.Name = "template-" + string(rune(48+i)) manager.SaveTemplate(template) } templates := manager.ListTemplates() assert.Equal(t, 3, len(templates)) } func TestDeleteTemplate(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) err := manager.DeleteTemplate("golang-project") assert.NoError(t, err) _, exists := manager.GetTemplate("golang-project") assert.False(t, exists) } func TestDeleteTemplateNotFound(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) err := manager.DeleteTemplate("nonexistent") assert.Error(t, err) } func TestValidateTemplateValid(t *testing.T) { template := createTestTemplate() err := NewWorkflowTemplateManager("/tmp").ValidateTemplate(template) assert.NoError(t, err) } func TestValidateTemplateEmptyName(t *testing.T) { template := createTestTemplate() template.Name = "" err := NewWorkflowTemplateManager("/tmp").ValidateTemplate(template) assert.Error(t, err) } func TestValidateTemplateNoTasks(t *testing.T) { template := createTestTemplate() template.Tasks = make([]TaskConfig, 0) err := NewWorkflowTemplateManager("/tmp").ValidateTemplate(template) assert.Error(t, err) } func TestValidateTemplateInvalidDependency(t *testing.T) { template := createTestTemplate() template.Tasks[1].DependsOn = []string{"nonexistent"} err := NewWorkflowTemplateManager("/tmp").ValidateTemplate(template) assert.Error(t, err) } func TestExportTemplateJSON(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) json, err := manager.ExportTemplateJSON("golang-project") assert.NoError(t, err) assert.NotEmpty(t, json) assert.Contains(t, json, "golang-project") } func TestExportTemplateJSONNotFound(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) _, err := manager.ExportTemplateJSON("nonexistent") assert.Error(t, err) } func TestRecordUsage(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) err := manager.RecordUsage("golang-project") assert.NoError(t, err) stats := manager.GetStats() assert.Equal(t, 1, stats.ExecutedTemplates) } func TestRecordUsageNotFound(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) err := manager.RecordUsage("nonexistent") assert.Error(t, err) } func TestTemplateGetStats(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) stats := manager.GetStats() assert.Equal(t, 1, stats.TotalTemplates) assert.Equal(t, 1, stats.LoadedTemplates) } func TestLoadTemplateDirectory(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) for i := 0; i < 3; i++ { template := createTestTemplate() template.Name = "template-" + string(rune(48+i)) manager.SaveTemplate(template) } manager.ClearCache() err := manager.LoadTemplateDirectory() assert.NoError(t, err) templates := manager.ListTemplates() assert.Equal(t, 3, len(templates)) } func TestClearCache(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) assert.Equal(t, 1, len(manager.ListTemplates())) manager.ClearCache() assert.Equal(t, 0, len(manager.ListTemplates())) } func TestTemplateTimestamps(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) retrieved, _ := manager.GetTemplate("golang-project") assert.False(t, retrieved.CreatedAt.IsZero()) assert.False(t, retrieved.UpdatedAt.IsZero()) assert.True(t, retrieved.UpdatedAt.After(retrieved.CreatedAt) || retrieved.UpdatedAt.Equal(retrieved.CreatedAt)) } func TestTemplateWithDefaults(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() template.Defaults = map[string]interface{}{ "language": "go", "version": "1.20", } manager.SaveTemplate(template) retrieved, _ := manager.GetTemplate("golang-project") assert.NotNil(t, retrieved.Defaults) assert.Equal(t, "go", retrieved.Defaults["language"]) } func TestTemplateWithTags(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() template.Tags = map[string]string{ "environment": "production", "team": "backend", } manager.SaveTemplate(template) retrieved, _ := manager.GetTemplate("golang-project") assert.NotNil(t, retrieved.Tags) assert.Equal(t, "production", retrieved.Tags["environment"]) } func TestMultipleTemplates(t *testing.T) { tmpDir := t.TempDir() manager := NewWorkflowTemplateManager(tmpDir) for i := 0; i < 5; i++ { template := createTestTemplate() template.Name = "template-" + string(rune(48+i)) manager.SaveTemplate(template) } templates := manager.ListTemplates() assert.Equal(t, 5, len(templates)) for i := 0; i < 5; i++ { name := "template-" + string(rune(48+i)) manager.RecordUsage(name) } stats := manager.GetStats() assert.Equal(t, 5, stats.ExecutedTemplates) } func BenchmarkSaveTemplate(b *testing.B) { tmpDir := b.TempDir() manager := NewWorkflowTemplateManager(tmpDir) for i := 0; i < b.N; i++ { template := createTestTemplate() template.Name = "template-" + string(rune(48+i%100)) manager.SaveTemplate(template) } } func BenchmarkLoadTemplate(b *testing.B) { tmpDir := b.TempDir() manager := NewWorkflowTemplateManager(tmpDir) template := createTestTemplate() manager.SaveTemplate(template) b.ResetTimer() for i := 0; i < b.N; i++ { manager.LoadTemplate("golang-project") } }