first commit
This commit is contained in:
commit
1751544440
28 changed files with 6994 additions and 0 deletions
234
internal/e2e/workflow_test.go
Normal file
234
internal/e2e/workflow_test.go
Normal file
|
|
@ -0,0 +1,234 @@
|
|||
package e2e
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/debian/deb-orchestrator/internal/database"
|
||||
"github.com/debian/deb-orchestrator/internal/models"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
// TestCompleteBuildWorkflow tests the complete build workflow
|
||||
func TestCompleteBuildWorkflow(t *testing.T) {
|
||||
service := database.NewMockService()
|
||||
require.NotNil(t, service)
|
||||
|
||||
// Step 1: Register a build host
|
||||
hostReq := models.HostRequest{
|
||||
Name: "e2e-build-host",
|
||||
Arch: "amd64",
|
||||
Channel: "stable",
|
||||
Capacity: 5,
|
||||
Hostname: "192.168.1.200",
|
||||
Port: 22,
|
||||
Capabilities: map[string]interface{}{"build": true},
|
||||
}
|
||||
host := models.NewHost(hostReq)
|
||||
err := service.CreateHost(host)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Step 2: Create a build task
|
||||
taskReq := models.TaskRequest{
|
||||
Method: "build",
|
||||
Args: []string{"test-package"},
|
||||
Priority: 1,
|
||||
Arch: "amd64",
|
||||
Channel: "stable",
|
||||
}
|
||||
task := models.NewTask(taskReq)
|
||||
err = service.CreateTask(task)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Step 3: Complete the workflow
|
||||
err = service.AssignTask(task.ID, host.ID)
|
||||
require.NoError(t, err)
|
||||
err = service.StartTask(task.ID)
|
||||
require.NoError(t, err)
|
||||
err = service.CompleteTask(task.ID, "Build completed successfully")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify final state
|
||||
retrievedTask, err := service.GetTaskByID(task.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, models.TaskStateCompleted, retrievedTask.State)
|
||||
assert.Equal(t, host.ID, retrievedTask.HostID)
|
||||
}
|
||||
|
||||
// TestHostFailoverWorkflow tests the failover and recovery workflow
|
||||
func TestHostFailoverWorkflow(t *testing.T) {
|
||||
service := database.NewMockService()
|
||||
require.NotNil(t, service)
|
||||
|
||||
t.Run("Host Failure and Task Recovery", func(t *testing.T) {
|
||||
// Create two hosts
|
||||
host1 := models.NewHost(models.HostRequest{
|
||||
Name: "primary-host",
|
||||
Arch: "amd64",
|
||||
Channel: "stable",
|
||||
Capacity: 3,
|
||||
Hostname: "192.168.1.100",
|
||||
Port: 22,
|
||||
Capabilities: map[string]interface{}{"build": true},
|
||||
})
|
||||
err := service.CreateHost(host1)
|
||||
require.NoError(t, err)
|
||||
|
||||
host2 := models.NewHost(models.HostRequest{
|
||||
Name: "backup-host",
|
||||
Arch: "amd64",
|
||||
Channel: "stable",
|
||||
Capacity: 3,
|
||||
Hostname: "192.168.1.101",
|
||||
Port: 22,
|
||||
Capabilities: map[string]interface{}{"build": true},
|
||||
})
|
||||
err = service.CreateHost(host2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Create and assign tasks to primary host
|
||||
task1 := models.NewTask(models.TaskRequest{
|
||||
Method: "build",
|
||||
Args: []string{"package1"},
|
||||
Priority: 1,
|
||||
Arch: "amd64",
|
||||
Channel: "stable",
|
||||
})
|
||||
err = service.CreateTask(task1)
|
||||
require.NoError(t, err)
|
||||
|
||||
task2 := models.NewTask(models.TaskRequest{
|
||||
Method: "build",
|
||||
Args: []string{"package2"},
|
||||
Priority: 1,
|
||||
Arch: "amd64",
|
||||
Channel: "stable",
|
||||
})
|
||||
err = service.CreateTask(task2)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assign tasks to primary host
|
||||
err = service.AssignTask(task1.ID, host1.ID)
|
||||
require.NoError(t, err)
|
||||
err = service.AssignTask(task2.ID, host1.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Start tasks
|
||||
err = service.StartTask(task1.ID)
|
||||
require.NoError(t, err)
|
||||
err = service.StartTask(task2.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Simulate primary host failure by marking it as offline
|
||||
err = service.UpdateHostState(host1.ID, models.HostStateOffline)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify tasks are in running state but host is offline
|
||||
retrievedTask1, err := service.GetTaskByID(task1.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, models.TaskStateRunning, retrievedTask1.State)
|
||||
|
||||
retrievedHost1, err := service.GetHostByID(host1.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, models.HostStateOffline, retrievedHost1.State)
|
||||
|
||||
// Simulate task recovery by reassigning to backup host
|
||||
err = service.AssignTask(task1.ID, host2.ID)
|
||||
require.NoError(t, err)
|
||||
err = service.AssignTask(task2.ID, host2.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Complete tasks on backup host
|
||||
err = service.CompleteTask(task1.ID, "Build completed on backup host")
|
||||
require.NoError(t, err)
|
||||
err = service.CompleteTask(task2.ID, "Build completed on backup host")
|
||||
require.NoError(t, err)
|
||||
|
||||
// Verify tasks completed successfully
|
||||
finalTask1, err := service.GetTaskByID(task1.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, models.TaskStateCompleted, finalTask1.State)
|
||||
assert.Equal(t, host2.ID, finalTask1.HostID)
|
||||
|
||||
finalTask2, err := service.GetTaskByID(task2.ID)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, models.TaskStateCompleted, finalTask2.State)
|
||||
assert.Equal(t, host2.ID, finalTask2.HostID)
|
||||
})
|
||||
}
|
||||
|
||||
// TestSystemStability tests system stability under load
|
||||
func TestSystemStability(t *testing.T) {
|
||||
service := database.NewMockService()
|
||||
require.NotNil(t, service)
|
||||
|
||||
t.Run("High Load Stability", func(t *testing.T) {
|
||||
const numOperations = 100
|
||||
|
||||
// Create hosts
|
||||
hosts := make([]*models.Host, 5)
|
||||
for i := 0; i < 5; i++ {
|
||||
hostReq := models.HostRequest{
|
||||
Name: fmt.Sprintf("stability-host-%d", i),
|
||||
Arch: "amd64",
|
||||
Channel: "stable",
|
||||
Capacity: 10,
|
||||
Hostname: fmt.Sprintf("192.168.1.%d", 300+i),
|
||||
Port: 22,
|
||||
Capabilities: map[string]interface{}{"build": true},
|
||||
}
|
||||
host := models.NewHost(hostReq)
|
||||
err := service.CreateHost(host)
|
||||
require.NoError(t, err)
|
||||
hosts[i] = host
|
||||
}
|
||||
|
||||
// Create and process many tasks
|
||||
start := time.Now()
|
||||
for i := 0; i < numOperations; i++ {
|
||||
taskReq := models.TaskRequest{
|
||||
Method: "build",
|
||||
Args: []string{fmt.Sprintf("stability-package-%d", i)},
|
||||
Priority: i % 3,
|
||||
Arch: "amd64",
|
||||
Channel: "stable",
|
||||
}
|
||||
task := models.NewTask(taskReq)
|
||||
err := service.CreateTask(task)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Assign to random host
|
||||
hostIndex := i % len(hosts)
|
||||
err = service.AssignTask(task.ID, hosts[hostIndex].ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
// Start and complete immediately
|
||||
err = service.StartTask(task.ID)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = service.CompleteTask(task.ID, "Stability test completed")
|
||||
require.NoError(t, err)
|
||||
}
|
||||
duration := time.Since(start)
|
||||
|
||||
// Performance assertions
|
||||
assert.Less(t, duration, 5*time.Second, "High load operations should complete within 5 seconds")
|
||||
avgTime := duration / numOperations
|
||||
assert.Less(t, avgTime, 50*time.Millisecond, "Average operation time should be under 50ms")
|
||||
|
||||
t.Logf("Processed %d operations in %v (avg: %v per operation)",
|
||||
numOperations, duration, avgTime)
|
||||
|
||||
// Verify system integrity
|
||||
stats, err := service.GetTaskStats()
|
||||
require.NoError(t, err)
|
||||
assert.GreaterOrEqual(t, stats.(map[string]int)["total_tasks"], numOperations)
|
||||
|
||||
// Verify all hosts are available
|
||||
for _, host := range hosts {
|
||||
retrievedHost, err := service.GetHostByID(host.ID)
|
||||
require.NoError(t, err)
|
||||
assert.True(t, retrievedHost.IsAvailable())
|
||||
}
|
||||
})
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue