- Add context.Context to ManagerInterface methods (StartMiner, StopMiner, UninstallMiner) - Add WebSocket state sync on client connect (sends current miner states) - Add EventStateSync event type and SetStateProvider method - Add manager lifecycle tests (idempotent stop, context cancellation, shutdown timeout) - Add database tests (initialization, hashrate storage, stats) - Add EventHub tests (creation, broadcast, client count, state provider) - Update all test files for new context-aware API 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
150 lines
3.1 KiB
Go
150 lines
3.1 KiB
Go
package database
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func setupTestDB(t *testing.T) func() {
|
|
tmpDir := t.TempDir()
|
|
dbPath := filepath.Join(tmpDir, "test.db")
|
|
|
|
cfg := Config{
|
|
Enabled: true,
|
|
Path: dbPath,
|
|
RetentionDays: 7,
|
|
}
|
|
|
|
if err := Initialize(cfg); err != nil {
|
|
t.Fatalf("Failed to initialize database: %v", err)
|
|
}
|
|
|
|
return func() {
|
|
Close()
|
|
os.Remove(dbPath)
|
|
}
|
|
}
|
|
|
|
func TestInitialize(t *testing.T) {
|
|
cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
// Database should be initialized
|
|
dbMu.RLock()
|
|
initialized := db != nil
|
|
dbMu.RUnlock()
|
|
|
|
if !initialized {
|
|
t.Error("Database should be initialized")
|
|
}
|
|
}
|
|
|
|
func TestInitialize_Disabled(t *testing.T) {
|
|
cfg := Config{
|
|
Enabled: false,
|
|
}
|
|
|
|
if err := Initialize(cfg); err != nil {
|
|
t.Errorf("Initialize with disabled should not error: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestClose(t *testing.T) {
|
|
cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
// Close should not error
|
|
if err := Close(); err != nil {
|
|
t.Errorf("Close failed: %v", err)
|
|
}
|
|
}
|
|
|
|
func TestHashrateStorage(t *testing.T) {
|
|
cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
// Store some hashrate data
|
|
minerName := "test-miner"
|
|
minerType := "xmrig"
|
|
now := time.Now()
|
|
|
|
points := []HashratePoint{
|
|
{Timestamp: now.Add(-5 * time.Minute), Hashrate: 1000},
|
|
{Timestamp: now.Add(-4 * time.Minute), Hashrate: 1100},
|
|
{Timestamp: now.Add(-3 * time.Minute), Hashrate: 1200},
|
|
}
|
|
|
|
for _, p := range points {
|
|
if err := InsertHashratePoint(minerName, minerType, p, ResolutionHigh); err != nil {
|
|
t.Fatalf("Failed to store hashrate point: %v", err)
|
|
}
|
|
}
|
|
|
|
// Retrieve the data
|
|
retrieved, err := GetHashrateHistory(minerName, ResolutionHigh, now.Add(-10*time.Minute), now)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get hashrate history: %v", err)
|
|
}
|
|
|
|
if len(retrieved) != 3 {
|
|
t.Errorf("Expected 3 points, got %d", len(retrieved))
|
|
}
|
|
}
|
|
|
|
func TestGetHashrateStats(t *testing.T) {
|
|
cleanup := setupTestDB(t)
|
|
defer cleanup()
|
|
|
|
minerName := "stats-test-miner"
|
|
minerType := "xmrig"
|
|
now := time.Now()
|
|
|
|
// Store some test data
|
|
points := []HashratePoint{
|
|
{Timestamp: now.Add(-2 * time.Minute), Hashrate: 500},
|
|
{Timestamp: now.Add(-1 * time.Minute), Hashrate: 1000},
|
|
{Timestamp: now, Hashrate: 1500},
|
|
}
|
|
|
|
for _, p := range points {
|
|
if err := InsertHashratePoint(minerName, minerType, p, ResolutionHigh); err != nil {
|
|
t.Fatalf("Failed to store point: %v", err)
|
|
}
|
|
}
|
|
|
|
stats, err := GetHashrateStats(minerName)
|
|
if err != nil {
|
|
t.Fatalf("Failed to get stats: %v", err)
|
|
}
|
|
|
|
if stats.TotalPoints != 3 {
|
|
t.Errorf("Expected 3 total points, got %d", stats.TotalPoints)
|
|
}
|
|
|
|
// Average should be (500+1000+1500)/3 = 1000
|
|
if stats.AverageRate != 1000 {
|
|
t.Errorf("Expected average rate 1000, got %d", stats.AverageRate)
|
|
}
|
|
|
|
if stats.MaxRate != 1500 {
|
|
t.Errorf("Expected max rate 1500, got %d", stats.MaxRate)
|
|
}
|
|
|
|
if stats.MinRate != 500 {
|
|
t.Errorf("Expected min rate 500, got %d", stats.MinRate)
|
|
}
|
|
}
|
|
|
|
func TestDefaultConfig(t *testing.T) {
|
|
cfg := defaultConfig()
|
|
|
|
if !cfg.Enabled {
|
|
t.Error("Default config should have Enabled=true")
|
|
}
|
|
|
|
if cfg.RetentionDays != 30 {
|
|
t.Errorf("Expected default retention 30, got %d", cfg.RetentionDays)
|
|
}
|
|
}
|