Files
bzzz/internal/common/runtime/runtime_test.go
anthonyrawlins be761cfe20 Enhance deployment system with retry functionality and improved UX
Major Improvements:
- Added retry deployment buttons in machine list for failed deployments
- Added retry button in SSH console modal footer for enhanced UX
- Enhanced deployment process with comprehensive cleanup of existing services
- Improved binary installation with password-based sudo authentication
- Updated configuration generation to include all required sections (agent, ai, network, security)
- Fixed deployment verification and error handling

Security Enhancements:
- Enhanced verifiedStopExistingServices with thorough cleanup process
- Improved binary copying with proper sudo authentication
- Added comprehensive configuration validation

UX Improvements:
- Users can retry deployments without re-running machine discovery
- Retry buttons available from both machine list and console modal
- Real-time deployment progress with detailed console output
- Clear error states with actionable retry options

Technical Changes:
- Modified ServiceDeployment.tsx with retry button components
- Enhanced api/setup_manager.go with improved deployment functions
- Updated main.go with command line argument support (--config, --setup)
- Added comprehensive zero-trust security validation system

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-08-31 10:23:27 +10:00

198 lines
4.7 KiB
Go

package runtime
import (
"context"
"testing"
"time"
)
// MockLogger implements logging.Logger interface for testing
type MockLogger struct {
messages []string
}
func (m *MockLogger) Info(format string, args ...interface{}) {
m.messages = append(m.messages, "INFO")
}
func (m *MockLogger) Warn(format string, args ...interface{}) {
m.messages = append(m.messages, "WARN")
}
func (m *MockLogger) Error(format string, args ...interface{}) {
m.messages = append(m.messages, "ERROR")
}
func TestRuntimeTypes(t *testing.T) {
// Test BinaryType enum
agent := BinaryTypeAgent
hap := BinaryTypeHAP
if agent.String() != "agent" {
t.Errorf("Expected 'agent', got %s", agent.String())
}
if hap.String() != "hap" {
t.Errorf("Expected 'hap', got %s", hap.String())
}
// Test RuntimeError
err := NewRuntimeError(ErrConfigInvalid, "test", BinaryTypeAgent, "test error", nil)
if err.Code != ErrConfigInvalid {
t.Errorf("Expected ErrConfigInvalid, got %v", err.Code)
}
if err.BinaryType != BinaryTypeAgent {
t.Errorf("Expected BinaryTypeAgent, got %v", err.BinaryType)
}
if err.Error() != "test error" {
t.Errorf("Expected 'test error', got %s", err.Error())
}
}
func TestRuntimeInterface(t *testing.T) {
// Test that we can create a runtime instance
logger := &MockLogger{}
runtime := NewRuntime(logger)
if runtime == nil {
t.Fatal("Expected non-nil runtime")
}
// Test that the runtime implements the Runtime interface
var _ Runtime = runtime
}
func TestConfigValidator(t *testing.T) {
// Test config validator creation
validator := NewConfigValidator(BinaryTypeAgent)
if validator == nil {
t.Fatal("Expected non-nil validator")
}
if validator.binaryType != BinaryTypeAgent {
t.Errorf("Expected BinaryTypeAgent, got %v", validator.binaryType)
}
}
func TestTaskTracker(t *testing.T) {
// Test task tracker creation and basic operations
tracker := NewTaskTracker(5, "test-node", nil).(*TaskTracker)
if tracker.GetMaxTasks() != 5 {
t.Errorf("Expected max tasks 5, got %d", tracker.GetMaxTasks())
}
// Test task operations
tracker.AddTask("task1")
tasks := tracker.GetActiveTasks()
if len(tasks) != 1 {
t.Errorf("Expected 1 active task, got %d", len(tasks))
}
if !tracker.IsAvailable() {
t.Error("Expected tracker to be available")
}
status := tracker.GetStatus()
if status != "working" {
t.Errorf("Expected status 'working', got %s", status)
}
// Remove task
tracker.RemoveTask("task1")
tasks = tracker.GetActiveTasks()
if len(tasks) != 0 {
t.Errorf("Expected 0 active tasks, got %d", len(tasks))
}
status = tracker.GetStatus()
if status != "ready" {
t.Errorf("Expected status 'ready', got %s", status)
}
}
func TestCapabilityAnnouncer(t *testing.T) {
// Test capability announcer creation
announcer := NewCapabilityAnnouncer(nil, "test-node")
if announcer == nil {
t.Fatal("Expected non-nil announcer")
}
if announcer.nodeID != "test-node" {
t.Errorf("Expected node ID 'test-node', got %s", announcer.nodeID)
}
}
func TestStatusReporter(t *testing.T) {
// Test status reporter creation
reporter := NewStatusReporter(nil)
if reporter == nil {
t.Fatal("Expected non-nil reporter")
}
}
// Test that our architecture properly separates concerns
func TestArchitectureSeparation(t *testing.T) {
// Test that we can create runtime components independently
logger := &MockLogger{}
// Runtime
runtime := NewRuntime(logger)
if runtime == nil {
t.Fatal("Failed to create runtime")
}
// Config validator
agentValidator := NewConfigValidator(BinaryTypeAgent)
hapValidator := NewConfigValidator(BinaryTypeHAP)
if agentValidator.binaryType == hapValidator.binaryType {
t.Error("Expected different binary types for validators")
}
// Task tracker
tracker := NewTaskTracker(3, "test", nil)
if tracker.GetMaxTasks() != 3 {
t.Error("Task tracker not properly initialized")
}
// Capability announcer
announcer := NewCapabilityAnnouncer(nil, "test")
if announcer.nodeID != "test" {
t.Error("Announcer not properly initialized")
}
t.Log("✅ All runtime components can be created independently")
}
// Benchmark basic operations
func BenchmarkTaskTrackerOperations(b *testing.B) {
tracker := NewTaskTracker(100, "bench-node", nil).(*TaskTracker)
b.Run("AddTask", func(b *testing.B) {
for i := 0; i < b.N; i++ {
taskID := "task-" + string(rune(i))
tracker.AddTask(taskID)
}
})
b.Run("GetActiveTasks", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = tracker.GetActiveTasks()
}
})
b.Run("GetStatus", func(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = tracker.GetStatus()
}
})
}
func BenchmarkRuntimeErrorCreation(b *testing.B) {
for i := 0; i < b.N; i++ {
_ = NewRuntimeError(ErrConfigInvalid, "test", BinaryTypeAgent, "error", nil)
}
}