178 lines
4.8 KiB
Go
178 lines
4.8 KiB
Go
package receiver
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
|
|
"edp.buildth.ing/DevFW-CICD/forgejo-runner-optimiser/internal/summary"
|
|
)
|
|
|
|
func TestNewStore(t *testing.T) {
|
|
dbPath := filepath.Join(t.TempDir(), "test.db")
|
|
|
|
store, err := NewStore(dbPath)
|
|
if err != nil {
|
|
t.Fatalf("NewStore() error = %v", err)
|
|
}
|
|
defer func() { _ = store.Close() }()
|
|
|
|
if _, err := os.Stat(dbPath); os.IsNotExist(err) {
|
|
t.Error("database file was not created")
|
|
}
|
|
}
|
|
|
|
func TestStore_SaveMetric(t *testing.T) {
|
|
store := newTestStore(t)
|
|
defer func() { _ = store.Close() }()
|
|
|
|
payload := &MetricsPayload{
|
|
Execution: ExecutionContext{
|
|
Organization: "test-org",
|
|
Repository: "test-repo",
|
|
Workflow: "ci.yml",
|
|
Job: "build",
|
|
RunID: "run-123",
|
|
},
|
|
Summary: summary.RunSummary{
|
|
StartTime: time.Now().Add(-time.Minute),
|
|
EndTime: time.Now(),
|
|
DurationSeconds: 60.0,
|
|
SampleCount: 12,
|
|
CPUTotal: summary.StatSummary{Peak: 80.5, Avg: 45.2, P95: 75.0},
|
|
MemUsedBytes: summary.StatSummary{Peak: 1024000, Avg: 512000, P95: 900000},
|
|
MemUsedPercent: summary.StatSummary{Peak: 50.0, Avg: 25.0, P95: 45.0},
|
|
},
|
|
}
|
|
|
|
id, err := store.SaveMetric(payload)
|
|
if err != nil {
|
|
t.Fatalf("SaveMetric() error = %v", err)
|
|
}
|
|
if id == 0 {
|
|
t.Error("SaveMetric() returned id = 0, want non-zero")
|
|
}
|
|
}
|
|
|
|
func TestStore_GetMetricsByWorkflowJob(t *testing.T) {
|
|
store := newTestStore(t)
|
|
defer func() { _ = store.Close() }()
|
|
|
|
// Save metrics for different workflow/job combinations
|
|
payloads := []struct {
|
|
org string
|
|
repo string
|
|
workflow string
|
|
job string
|
|
}{
|
|
{"org-a", "repo-1", "ci.yml", "build"},
|
|
{"org-a", "repo-1", "ci.yml", "build"},
|
|
{"org-a", "repo-1", "ci.yml", "test"},
|
|
{"org-a", "repo-1", "deploy.yml", "build"},
|
|
}
|
|
|
|
for i, p := range payloads {
|
|
payload := &MetricsPayload{
|
|
Execution: ExecutionContext{
|
|
Organization: p.org,
|
|
Repository: p.repo,
|
|
Workflow: p.workflow,
|
|
Job: p.job,
|
|
RunID: "run-" + string(rune('a'+i)),
|
|
},
|
|
Summary: summary.RunSummary{},
|
|
}
|
|
if _, err := store.SaveMetric(payload); err != nil {
|
|
t.Fatalf("SaveMetric() error = %v", err)
|
|
}
|
|
}
|
|
|
|
metrics, err := store.GetMetricsByWorkflowJob("org-a", "repo-1", "ci.yml", "build")
|
|
if err != nil {
|
|
t.Fatalf("GetMetricsByWorkflowJob() error = %v", err)
|
|
}
|
|
if len(metrics) != 2 {
|
|
t.Errorf("GetMetricsByWorkflowJob() returned %d metrics, want 2", len(metrics))
|
|
}
|
|
|
|
for _, m := range metrics {
|
|
if m.Organization != "org-a" || m.Repository != "repo-1" || m.Workflow != "ci.yml" || m.Job != "build" {
|
|
t.Errorf("GetMetricsByWorkflowJob() returned metric with org=%q repo=%q workflow=%q job=%q, want org-a/repo-1/ci.yml/build",
|
|
m.Organization, m.Repository, m.Workflow, m.Job)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestStore_GetMetricsByWorkflowJob_NotFound(t *testing.T) {
|
|
store := newTestStore(t)
|
|
defer func() { _ = store.Close() }()
|
|
|
|
metrics, err := store.GetMetricsByWorkflowJob("nonexistent", "repo", "workflow", "job")
|
|
if err != nil {
|
|
t.Fatalf("GetMetricsByWorkflowJob() error = %v", err)
|
|
}
|
|
if len(metrics) != 0 {
|
|
t.Errorf("GetMetricsByWorkflowJob() returned %d metrics, want 0", len(metrics))
|
|
}
|
|
}
|
|
|
|
func TestStore_SaveMetric_PreservesPayload(t *testing.T) {
|
|
store := newTestStore(t)
|
|
defer func() { _ = store.Close() }()
|
|
|
|
original := &MetricsPayload{
|
|
Execution: ExecutionContext{
|
|
Organization: "test-org",
|
|
Repository: "test-repo",
|
|
Workflow: "build.yml",
|
|
Job: "test",
|
|
RunID: "run-preserve",
|
|
},
|
|
Summary: summary.RunSummary{
|
|
DurationSeconds: 123.45,
|
|
SampleCount: 50,
|
|
CPUTotal: summary.StatSummary{Peak: 99.9, Avg: 55.5, P95: 88.8},
|
|
},
|
|
}
|
|
|
|
_, err := store.SaveMetric(original)
|
|
if err != nil {
|
|
t.Fatalf("SaveMetric() error = %v", err)
|
|
}
|
|
|
|
metrics, err := store.GetMetricsByWorkflowJob("test-org", "test-repo", "build.yml", "test")
|
|
if err != nil {
|
|
t.Fatalf("GetMetricsByWorkflowJob() error = %v", err)
|
|
}
|
|
if len(metrics) != 1 {
|
|
t.Fatalf("GetMetricsByWorkflowJob() returned %d metrics, want 1", len(metrics))
|
|
}
|
|
|
|
m := metrics[0]
|
|
if m.Organization != original.Execution.Organization {
|
|
t.Errorf("Organization = %q, want %q", m.Organization, original.Execution.Organization)
|
|
}
|
|
if m.Repository != original.Execution.Repository {
|
|
t.Errorf("Repository = %q, want %q", m.Repository, original.Execution.Repository)
|
|
}
|
|
if m.Workflow != original.Execution.Workflow {
|
|
t.Errorf("Workflow = %q, want %q", m.Workflow, original.Execution.Workflow)
|
|
}
|
|
if m.Job != original.Execution.Job {
|
|
t.Errorf("Job = %q, want %q", m.Job, original.Execution.Job)
|
|
}
|
|
if m.Payload == "" {
|
|
t.Error("Payload is empty")
|
|
}
|
|
}
|
|
|
|
func newTestStore(t *testing.T) *Store {
|
|
t.Helper()
|
|
dbPath := filepath.Join(t.TempDir(), "test.db")
|
|
store, err := NewStore(dbPath)
|
|
if err != nil {
|
|
t.Fatalf("NewStore() error = %v", err)
|
|
}
|
|
return store
|
|
}
|