Files
poimen-workflows/internal/routing/knowledge_base_test.go
T

372 lines
8.2 KiB
Go
Raw Normal View History

package routing
import (
"os"
"testing"
)
func getKBPath() string {
// Try direct name (when running from this directory)
if _, err := os.Stat("activity_knowledge_base.json"); err == nil {
return "activity_knowledge_base.json"
}
// Try relative path
if _, err := os.Stat("./internal/routing/activity_knowledge_base.json"); err == nil {
return "./internal/routing/activity_knowledge_base.json"
}
return ""
}
func TestLoadKnowledgeBase(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
if kb == nil {
t.Error("Knowledge base is nil")
}
if kb.Version == "" {
t.Error("Knowledge base version is empty")
}
if len(kb.Activities) == 0 {
t.Error("Knowledge base has no activities")
}
if len(kb.byName) != len(kb.Activities) {
t.Errorf("Index size (%d) doesn't match activities (%d)", len(kb.byName), len(kb.Activities))
}
}
func TestGetActivity(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
activity := kb.GetActivity("CloneRepoActivity")
if activity == nil {
t.Error("CloneRepoActivity not found")
} else {
if activity.Name != "CloneRepoActivity" {
t.Errorf("Activity name mismatch: %s", activity.Name)
}
if activity.Description == "" {
t.Error("Activity description is empty")
}
}
missing := kb.GetActivity("NonExistentActivity")
if missing != nil {
t.Error("NonExistentActivity should be nil")
}
}
func TestHasActivity(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
if !kb.HasActivity("CloneRepoActivity") {
t.Error("CloneRepoActivity should exist")
}
if kb.HasActivity("NonExistentActivity") {
t.Error("NonExistentActivity should not exist")
}
}
func TestListActivities(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
activities := kb.ListActivities()
if len(activities) == 0 {
t.Error("ListActivities returned empty list")
}
for _, activity := range activities {
if activity.Name == "" {
t.Error("Activity name is empty")
}
}
}
func TestListActivitiesByCategory(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
repoActivities := kb.ListActivitiesByCategory("repository")
if len(repoActivities) == 0 {
t.Error("No repository activities found")
}
for _, activity := range repoActivities {
if activity.Category != "repository" {
t.Errorf("Activity %s has wrong category: %s", activity.Name, activity.Category)
}
}
unknown := kb.ListActivitiesByCategory("unknown")
if len(unknown) != 0 {
t.Error("Unknown category should return empty list")
}
}
func TestGetActivityNames(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
names := kb.GetActivityNames()
if len(names) == 0 {
t.Error("GetActivityNames returned empty list")
}
found := false
for _, name := range names {
if name == "CloneRepoActivity" {
found = true
break
}
}
if !found {
t.Error("CloneRepoActivity not found in activity names")
}
}
func TestGetDependencies(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
deps := kb.GetDependencies("AnalyzeCodeActivity")
if len(deps) == 0 {
t.Error("AnalyzeCodeActivity should have dependencies")
}
found := false
for _, dep := range deps {
if dep == "CloneRepoActivity" {
found = true
break
}
}
if !found {
t.Error("CloneRepoActivity should be a dependency of AnalyzeCodeActivity")
}
noDeps := kb.GetDependencies("CloneRepoActivity")
if len(noDeps) != 0 {
t.Error("CloneRepoActivity should have no dependencies")
}
}
func TestGetTimeout(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
timeout := kb.GetTimeoutForActivity("CloneRepoActivity")
if timeout == "" {
t.Error("Timeout should not be empty")
}
defaultTimeout := kb.GetTimeoutForActivity("NonExistent")
if defaultTimeout != "5m" {
t.Errorf("Default timeout should be 5m, got %s", defaultTimeout)
}
}
func TestGetRetryPolicy(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
policy := kb.GetRetryPolicyForActivity("AnalyzeCodeActivity")
if policy == nil {
t.Error("Retry policy should not be nil")
} else {
if policy.MaxAttempts < 2 {
t.Errorf("Flaky activity should have multiple retries, got %d", policy.MaxAttempts)
}
if policy.BackoffRate == 0 {
t.Error("Backoff rate should be set")
}
}
stablePolicy := kb.GetRetryPolicyForActivity("CloneRepoActivity")
if stablePolicy == nil {
t.Error("Retry policy should not be nil")
}
}
func TestIsFlaky(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
if !kb.IsFlaky("AnalyzeCodeActivity") {
t.Error("AnalyzeCodeActivity should be marked as flaky")
}
if kb.IsFlaky("CloneRepoActivity") {
t.Error("CloneRepoActivity should not be marked as flaky")
}
}
func TestGetNotes(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
notes := kb.GetNotes("AnalyzeCodeActivity")
if notes == "" {
t.Error("Notes should not be empty")
}
missingNotes := kb.GetNotes("NonExistent")
if missingNotes != "" {
t.Error("Non-existent activity should have empty notes")
}
}
func TestValidate(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
if err := kb.Validate(); err != nil {
t.Fatalf("Knowledge base validation failed: %v", err)
}
}
func TestString(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
str := kb.String()
if str == "" {
t.Error("String() returned empty string")
}
if !contains(str, "KnowledgeBase") {
t.Error("String should contain 'KnowledgeBase'")
}
}
func TestPrintSummary(t *testing.T) {
kbPath := getKBPath()
if kbPath == "" {
t.Skip("Knowledge base file not found, skipping test")
}
kb, err := LoadKnowledgeBase(kbPath)
if err != nil {
t.Fatalf("Failed to load knowledge base: %v", err)
}
summary := kb.PrintSummary()
if summary == "" {
t.Error("PrintSummary() returned empty string")
}
if !contains(summary, "Activity Knowledge Base") {
t.Error("Summary should contain 'Activity Knowledge Base'")
}
if !contains(summary, "CloneRepoActivity") {
t.Error("Summary should list activities")
}
}
func contains(str, substr string) bool {
for i := 0; i < len(str)-len(substr)+1; i++ {
if str[i:i+len(substr)] == substr {
return true
}
}
return false
}