diff --git a/pkg/node/worker_test.go b/pkg/node/worker_test.go index 34b0adc..036721c 100644 --- a/pkg/node/worker_test.go +++ b/pkg/node/worker_test.go @@ -506,6 +506,280 @@ func TestWorker_HandleGetLogs_Bad(t *testing.T) { } } +func TestWorker_HandleStartMiner_Good(t *testing.T) { + cleanup := setupTestEnv(t) + defer cleanup() + + nodeManager, err := NewNodeManager() + if err != nil { + t.Fatalf("failed to create node manager: %v", err) + } + if err := nodeManager.GenerateIdentity("test-worker", RoleWorker); err != nil { + t.Fatalf("failed to generate identity: %v", err) + } + + peerRegistry, err := NewPeerRegistryWithPath(t.TempDir() + "/peers.json") + if err != nil { + t.Fatalf("failed to create peer registry: %v", err) + } + + transport := NewTransport(nodeManager, peerRegistry, DefaultTransportConfig()) + worker := NewWorker(nodeManager, transport) + worker.SetMinerManager(&mockMinerManager{}) + worker.SetProfileManager(&mockProfileManager{}) + + identity := nodeManager.GetIdentity() + if identity == nil { + t.Fatal("expected identity to be generated") + } + + // worker.handleStartMiner(msg) — starts miner via profile manager config + payload := StartMinerPayload{MinerType: "xmrig", ProfileID: "pool-main"} + msg, err := NewMessage(MsgStartMiner, "sender-id", identity.ID, payload) + if err != nil { + t.Fatalf("failed to create start_miner message: %v", err) + } + + response, err := worker.handleStartMiner(msg) + if err != nil { + t.Fatalf("handleStartMiner returned unexpected error: %v", err) + } + if response == nil { + t.Fatal("handleStartMiner returned nil response") + } + if response.Type != MsgMinerAck { + t.Errorf("expected response type %s, got %s", MsgMinerAck, response.Type) + } +} + +func TestWorker_HandleStartMiner_Ugly(t *testing.T) { + cleanup := setupTestEnv(t) + defer cleanup() + + nodeManager, err := NewNodeManager() + if err != nil { + t.Fatalf("failed to create node manager: %v", err) + } + if err := nodeManager.GenerateIdentity("test-worker", RoleWorker); err != nil { + t.Fatalf("failed to generate identity: %v", err) + } + + peerRegistry, err := NewPeerRegistryWithPath(t.TempDir() + "/peers.json") + if err != nil { + t.Fatalf("failed to create peer registry: %v", err) + } + + transport := NewTransport(nodeManager, peerRegistry, DefaultTransportConfig()) + worker := NewWorker(nodeManager, transport) + worker.SetMinerManager(&mockMinerManager{}) + + identity := nodeManager.GetIdentity() + if identity == nil { + t.Fatal("expected identity to be generated") + } + + // worker.handleStartMiner(msg) — empty miner type triggers validation error + payload := StartMinerPayload{MinerType: ""} + msg, err := NewMessage(MsgStartMiner, "sender-id", identity.ID, payload) + if err != nil { + t.Fatalf("failed to create start_miner message: %v", err) + } + + _, err = worker.handleStartMiner(msg) + if err == nil { + t.Error("expected error for empty miner type") + } +} + +func TestWorker_HandleStopMiner_Good(t *testing.T) { + cleanup := setupTestEnv(t) + defer cleanup() + + nodeManager, err := NewNodeManager() + if err != nil { + t.Fatalf("failed to create node manager: %v", err) + } + if err := nodeManager.GenerateIdentity("test-worker", RoleWorker); err != nil { + t.Fatalf("failed to generate identity: %v", err) + } + + peerRegistry, err := NewPeerRegistryWithPath(t.TempDir() + "/peers.json") + if err != nil { + t.Fatalf("failed to create peer registry: %v", err) + } + + transport := NewTransport(nodeManager, peerRegistry, DefaultTransportConfig()) + worker := NewWorker(nodeManager, transport) + worker.SetMinerManager(&mockMinerManager{}) + + identity := nodeManager.GetIdentity() + if identity == nil { + t.Fatal("expected identity to be generated") + } + + // worker.handleStopMiner(msg) — stops named miner, returns MinerAck with success + payload := StopMinerPayload{MinerName: "xmrig"} + msg, err := NewMessage(MsgStopMiner, "sender-id", identity.ID, payload) + if err != nil { + t.Fatalf("failed to create stop_miner message: %v", err) + } + + response, err := worker.handleStopMiner(msg) + if err != nil { + t.Fatalf("handleStopMiner returned unexpected error: %v", err) + } + if response == nil { + t.Fatal("handleStopMiner returned nil response") + } + if response.Type != MsgMinerAck { + t.Errorf("expected response type %s, got %s", MsgMinerAck, response.Type) + } + + var ack MinerAckPayload + if err := response.ParsePayload(&ack); err != nil { + t.Fatalf("failed to parse ack payload: %v", err) + } + if !ack.Success { + t.Errorf("expected success=true, got false: %s", ack.Error) + } +} + +func TestWorker_HandleStopMiner_Ugly(t *testing.T) { + cleanup := setupTestEnv(t) + defer cleanup() + + nodeManager, err := NewNodeManager() + if err != nil { + t.Fatalf("failed to create node manager: %v", err) + } + if err := nodeManager.GenerateIdentity("test-worker", RoleWorker); err != nil { + t.Fatalf("failed to generate identity: %v", err) + } + + peerRegistry, err := NewPeerRegistryWithPath(t.TempDir() + "/peers.json") + if err != nil { + t.Fatalf("failed to create peer registry: %v", err) + } + + transport := NewTransport(nodeManager, peerRegistry, DefaultTransportConfig()) + worker := NewWorker(nodeManager, transport) + worker.SetMinerManager(&mockMinerManager{}) + + identity := nodeManager.GetIdentity() + if identity == nil { + t.Fatal("expected identity to be generated") + } + + // worker.handleStopMiner(msg) — corrupted JSON payload triggers parse error + msg := &Message{ + ID: "test-id", + Type: MsgStopMiner, + From: "sender-id", + To: identity.ID, + Payload: []byte(`{invalid json`), + } + + _, err = worker.handleStopMiner(msg) + if err == nil { + t.Error("expected error for malformed stop_miner payload") + } +} + +func TestWorker_HandleGetLogs_Good(t *testing.T) { + cleanup := setupTestEnv(t) + defer cleanup() + + nodeManager, err := NewNodeManager() + if err != nil { + t.Fatalf("failed to create node manager: %v", err) + } + if err := nodeManager.GenerateIdentity("test-worker", RoleWorker); err != nil { + t.Fatalf("failed to generate identity: %v", err) + } + + peerRegistry, err := NewPeerRegistryWithPath(t.TempDir() + "/peers.json") + if err != nil { + t.Fatalf("failed to create peer registry: %v", err) + } + + transport := NewTransport(nodeManager, peerRegistry, DefaultTransportConfig()) + worker := NewWorker(nodeManager, transport) + minerInstance := &mockMinerInstance{name: "xmrig", minerType: "xmrig"} + worker.SetMinerManager(&mockMinerManager{miners: []MinerInstance{minerInstance}}) + + identity := nodeManager.GetIdentity() + if identity == nil { + t.Fatal("expected identity to be generated") + } + + // worker.handleGetLogs(msg) — fetches console history for a running miner + payload := GetLogsPayload{MinerName: "xmrig", Lines: 50} + msg, err := NewMessage(MsgGetLogs, "sender-id", identity.ID, payload) + if err != nil { + t.Fatalf("failed to create get_logs message: %v", err) + } + + response, err := worker.handleGetLogs(msg) + if err != nil { + t.Fatalf("handleGetLogs returned unexpected error: %v", err) + } + if response == nil { + t.Fatal("handleGetLogs returned nil response") + } + if response.Type != MsgLogs { + t.Errorf("expected response type %s, got %s", MsgLogs, response.Type) + } + + var logs LogsPayload + if err := response.ParsePayload(&logs); err != nil { + t.Fatalf("failed to parse logs payload: %v", err) + } + if logs.MinerName != "xmrig" { + t.Errorf("expected miner name xmrig, got %s", logs.MinerName) + } +} + +func TestWorker_HandleGetLogs_Ugly(t *testing.T) { + cleanup := setupTestEnv(t) + defer cleanup() + + nodeManager, err := NewNodeManager() + if err != nil { + t.Fatalf("failed to create node manager: %v", err) + } + if err := nodeManager.GenerateIdentity("test-worker", RoleWorker); err != nil { + t.Fatalf("failed to generate identity: %v", err) + } + + peerRegistry, err := NewPeerRegistryWithPath(t.TempDir() + "/peers.json") + if err != nil { + t.Fatalf("failed to create peer registry: %v", err) + } + + transport := NewTransport(nodeManager, peerRegistry, DefaultTransportConfig()) + worker := NewWorker(nodeManager, transport) + worker.SetMinerManager(&mockMinerManager{}) + + identity := nodeManager.GetIdentity() + if identity == nil { + t.Fatal("expected identity to be generated") + } + + // worker.handleGetLogs(msg) — corrupted JSON payload triggers parse error + msg := &Message{ + ID: "test-id", + Type: MsgGetLogs, + From: "sender-id", + To: identity.ID, + Payload: []byte(`{invalid json`), + } + + _, err = worker.handleGetLogs(msg) + if err == nil { + t.Error("expected error for malformed get_logs payload") + } +} + func TestWorker_HandleDeploy_Bad(t *testing.T) { cleanup := setupTestEnv(t) defer cleanup() @@ -641,7 +915,7 @@ type mockMinerManager struct { } func (m *mockMinerManager) StartMiner(minerType string, config interface{}) (MinerInstance, error) { - return nil, nil + return &mockMinerInstance{name: minerType, minerType: minerType}, nil } func (m *mockMinerManager) StopMiner(name string) error {