Mining/pkg/database/interface_test.go
snider 34f860309f refactor: Add reliability fixes and architecture improvements
Reliability fixes:
- Fix HTTP response body drainage in xmrig, ttminer, miner
- Fix database init race condition (nil before close)
- Fix empty minerType bug in P2P StartMinerPayload
- Add context timeout to InsertHashratePoint (5s default)

Architecture improvements:
- Extract HashrateStore interface with DefaultStore/NopStore
- Create ServiceContainer for centralized initialization
- Extract protocol response handler (ValidateResponse, ParseResponse)
- Create generic FileRepository[T] with atomic writes

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2025-12-31 12:43:46 +00:00

135 lines
3.5 KiB
Go

package database
import (
"context"
"testing"
"time"
)
func TestDefaultStore(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
store := DefaultStore()
// Test InsertHashratePoint
point := HashratePoint{
Timestamp: time.Now(),
Hashrate: 1500,
}
if err := store.InsertHashratePoint(nil, "interface-test", "xmrig", point, ResolutionHigh); err != nil {
t.Fatalf("InsertHashratePoint failed: %v", err)
}
// Test GetHashrateHistory
history, err := store.GetHashrateHistory("interface-test", ResolutionHigh, time.Now().Add(-time.Hour), time.Now().Add(time.Hour))
if err != nil {
t.Fatalf("GetHashrateHistory failed: %v", err)
}
if len(history) != 1 {
t.Errorf("Expected 1 point, got %d", len(history))
}
// Test GetHashrateStats
stats, err := store.GetHashrateStats("interface-test")
if err != nil {
t.Fatalf("GetHashrateStats failed: %v", err)
}
if stats == nil {
t.Fatal("Expected non-nil stats")
}
if stats.TotalPoints != 1 {
t.Errorf("Expected 1 total point, got %d", stats.TotalPoints)
}
// Test GetAllMinerStats
allStats, err := store.GetAllMinerStats()
if err != nil {
t.Fatalf("GetAllMinerStats failed: %v", err)
}
if len(allStats) != 1 {
t.Errorf("Expected 1 miner in stats, got %d", len(allStats))
}
// Test Cleanup
if err := store.Cleanup(30); err != nil {
t.Fatalf("Cleanup failed: %v", err)
}
}
func TestDefaultStore_WithContext(t *testing.T) {
cleanup := setupTestDB(t)
defer cleanup()
store := DefaultStore()
ctx := context.Background()
point := HashratePoint{
Timestamp: time.Now(),
Hashrate: 2000,
}
if err := store.InsertHashratePoint(ctx, "ctx-test", "xmrig", point, ResolutionHigh); err != nil {
t.Fatalf("InsertHashratePoint with context failed: %v", err)
}
history, err := store.GetHashrateHistory("ctx-test", ResolutionHigh, time.Now().Add(-time.Hour), time.Now().Add(time.Hour))
if err != nil {
t.Fatalf("GetHashrateHistory failed: %v", err)
}
if len(history) != 1 {
t.Errorf("Expected 1 point, got %d", len(history))
}
}
func TestNopStore(t *testing.T) {
store := NopStore()
// All operations should succeed without error
point := HashratePoint{
Timestamp: time.Now(),
Hashrate: 1000,
}
if err := store.InsertHashratePoint(nil, "test", "xmrig", point, ResolutionHigh); err != nil {
t.Errorf("NopStore InsertHashratePoint should not error: %v", err)
}
history, err := store.GetHashrateHistory("test", ResolutionHigh, time.Now().Add(-time.Hour), time.Now())
if err != nil {
t.Errorf("NopStore GetHashrateHistory should not error: %v", err)
}
if history != nil {
t.Errorf("NopStore GetHashrateHistory should return nil, got %v", history)
}
stats, err := store.GetHashrateStats("test")
if err != nil {
t.Errorf("NopStore GetHashrateStats should not error: %v", err)
}
if stats != nil {
t.Errorf("NopStore GetHashrateStats should return nil, got %v", stats)
}
allStats, err := store.GetAllMinerStats()
if err != nil {
t.Errorf("NopStore GetAllMinerStats should not error: %v", err)
}
if allStats != nil {
t.Errorf("NopStore GetAllMinerStats should return nil, got %v", allStats)
}
if err := store.Cleanup(30); err != nil {
t.Errorf("NopStore Cleanup should not error: %v", err)
}
if err := store.Close(); err != nil {
t.Errorf("NopStore Close should not error: %v", err)
}
}
// TestInterfaceCompatibility ensures all implementations satisfy HashrateStore
func TestInterfaceCompatibility(t *testing.T) {
var _ HashrateStore = DefaultStore()
var _ HashrateStore = NopStore()
var _ HashrateStore = &defaultStore{}
var _ HashrateStore = &nopStore{}
}