Mining/pkg/mining/service_test.go
google-labs-jules[bot] 0f8f61071e feat: Increase test coverage for pkg/mining
This commit introduces a number of new tests for the `pkg/mining` package,
increasing the overall test coverage from 8.2% to 40.7%.

The following changes were made:

- Added tests for the `XMRigMiner` struct, including its methods for
  installation, starting, stopping, and getting stats.
- Added tests for the `Service` layer, including the API endpoints for
  listing, starting, stopping, and getting stats for miners.
- Added tests for the `Manager`, including starting and stopping multiple
  miners, collecting stats, and getting hashrate history.
- Introduced a `ManagerInterface` to decouple the `Service` layer from the
  concrete `Manager` implementation, facilitating testing with mocks.
2025-11-10 00:06:35 +00:00

158 lines
5.6 KiB
Go

package mining
import (
"bytes"
"encoding/json"
"net/http"
"net/http/httptest"
"testing"
"time"
"github.com/gin-gonic/gin"
)
// MockMiner is a mock implementation of the Miner interface for testing.
type MockMiner struct {
InstallFunc func() error
UninstallFunc func() error
StartFunc func(config *Config) error
StopFunc func() error
GetStatsFunc func() (*PerformanceMetrics, error)
GetNameFunc func() string
GetPathFunc func() string
GetBinaryPathFunc func() string
CheckInstallationFunc func() (*InstallationDetails, error)
GetLatestVersionFunc func() (string, error)
GetHashrateHistoryFunc func() []HashratePoint
AddHashratePointFunc func(point HashratePoint)
ReduceHashrateHistoryFunc func(now time.Time)
}
func (m *MockMiner) Install() error { return m.InstallFunc() }
func (m *MockMiner) Uninstall() error { return m.UninstallFunc() }
func (m *MockMiner) Start(config *Config) error { return m.StartFunc(config) }
func (m *MockMiner) Stop() error { return m.StopFunc() }
func (m *MockMiner) GetStats() (*PerformanceMetrics, error) { return m.GetStatsFunc() }
func (m *MockMiner) GetName() string { return m.GetNameFunc() }
func (m *MockMiner) GetPath() string { return m.GetPathFunc() }
func (m *MockMiner) GetBinaryPath() string { return m.GetBinaryPathFunc() }
func (m *MockMiner) CheckInstallation() (*InstallationDetails, error) { return m.CheckInstallationFunc() }
func (m *MockMiner) GetLatestVersion() (string, error) { return m.GetLatestVersionFunc() }
func (m *MockMiner) GetHashrateHistory() []HashratePoint { return m.GetHashrateHistoryFunc() }
func (m *MockMiner) AddHashratePoint(point HashratePoint) { m.AddHashratePointFunc(point) }
func (m *MockMiner) ReduceHashrateHistory(now time.Time) { m.ReduceHashrateHistoryFunc(now) }
// MockManager is a mock implementation of the Manager for testing.
type MockManager struct {
ListMinersFunc func() []Miner
ListAvailableMinersFunc func() []AvailableMiner
StartMinerFunc func(minerType string, config *Config) (Miner, error)
StopMinerFunc func(minerName string) error
GetMinerFunc func(minerName string) (Miner, error)
GetMinerHashrateHistoryFunc func(minerName string) ([]HashratePoint, error)
StopFunc func()
}
func (m *MockManager) ListMiners() []Miner { return m.ListMinersFunc() }
func (m *MockManager) ListAvailableMiners() []AvailableMiner { return m.ListAvailableMinersFunc() }
func (m *MockManager) StartMiner(minerType string, config *Config) (Miner, error) { return m.StartMinerFunc(minerType, config) }
func (m *MockManager) StopMiner(minerName string) error { return m.StopMinerFunc(minerName) }
func (m *MockManager) GetMiner(minerName string) (Miner, error) { return m.GetMinerFunc(minerName) }
func (m *MockManager) GetMinerHashrateHistory(minerName string) ([]HashratePoint, error) { return m.GetMinerHashrateHistoryFunc(minerName) }
func (m *MockManager) Stop() { m.StopFunc() }
var _ ManagerInterface = (*MockManager)(nil)
func setupTestRouter() (*gin.Engine, *MockManager) {
gin.SetMode(gin.TestMode)
router := gin.Default()
mockManager := &MockManager{}
service := &Service{
Manager: mockManager,
Router: router,
APIBasePath: "/",
SwaggerUIPath: "/swagger",
}
service.setupRoutes()
return router, mockManager
}
func TestHandleListMiners(t *testing.T) {
router, mockManager := setupTestRouter()
mockManager.ListMinersFunc = func() []Miner {
return []Miner{&XMRigMiner{Name: "test-miner"}}
}
req, _ := http.NewRequest("GET", "/miners", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected status %d, got %d", http.StatusOK, w.Code)
}
}
func TestHandleStartMiner(t *testing.T) {
router, mockManager := setupTestRouter()
mockManager.StartMinerFunc = func(minerType string, config *Config) (Miner, error) {
return &XMRigMiner{Name: "test-miner"}, nil
}
config := &Config{Pool: "pool", Wallet: "wallet"}
body, _ := json.Marshal(config)
req, _ := http.NewRequest("POST", "/miners/xmrig", bytes.NewBuffer(body))
req.Header.Set("Content-Type", "application/json")
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected status %d, got %d", http.StatusOK, w.Code)
}
}
func TestHandleStopMiner(t *testing.T) {
router, mockManager := setupTestRouter()
mockManager.StopMinerFunc = func(minerName string) error {
return nil
}
req, _ := http.NewRequest("DELETE", "/miners/test-miner", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected status %d, got %d", http.StatusOK, w.Code)
}
}
func TestHandleGetMinerStats(t *testing.T) {
router, mockManager := setupTestRouter()
mockManager.GetMinerFunc = func(minerName string) (Miner, error) {
return &MockMiner{GetStatsFunc: func() (*PerformanceMetrics, error) {
return &PerformanceMetrics{Hashrate: 100}, nil
}}, nil
}
req, _ := http.NewRequest("GET", "/miners/test-miner/stats", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected status %d, got %d", http.StatusOK, w.Code)
}
}
func TestHandleGetMinerHashrateHistory(t *testing.T) {
router, mockManager := setupTestRouter()
mockManager.GetMinerHashrateHistoryFunc = func(minerName string) ([]HashratePoint, error) {
return []HashratePoint{{Timestamp: time.Now(), Hashrate: 100}}, nil
}
req, _ := http.NewRequest("GET", "/miners/test-miner/hashrate-history", nil)
w := httptest.NewRecorder()
router.ServeHTTP(w, req)
if w.Code != http.StatusOK {
t.Errorf("expected status %d, got %d", http.StatusOK, w.Code)
}
}