Add recon UX backend: scan history, export, and streaming tests.
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Some checks failed
CI Docker Mining Proof / Linux agent hashrate proof (push) Has been cancelled
Persist recon scans in SQLite with history diff and export routes; wire WebSocket streaming test coverage and relay path_tracer_hints in fleet reports.
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"encoding/base64"
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
@@ -13,6 +14,7 @@ import (
|
||||
"crypto-miner-server/internal/db"
|
||||
"crypto-miner-server/internal/models"
|
||||
"crypto-miner-server/internal/pool"
|
||||
"crypto-miner-server/internal/recon"
|
||||
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
@@ -1295,3 +1297,49 @@ func TestStatsBatchCoalescesManyAgents(t *testing.T) {
|
||||
// no second batch within coalesce window — good
|
||||
}
|
||||
}
|
||||
|
||||
func TestWSReconStreamingEventTypes(t *testing.T) {
|
||||
recon.SetPortDialHook(func(host string, port int, _ time.Duration) bool { return port == 80 })
|
||||
t.Cleanup(func() { recon.SetPortDialHook(nil) })
|
||||
recon.SetFetchPageHook(func(rawURL string) (int, string, error) {
|
||||
return 200, `<html><form enctype="multipart/form-data"><input type="file" name="payload"></form></html>`, nil
|
||||
})
|
||||
t.Cleanup(func() { recon.SetFetchPageHook(nil) })
|
||||
|
||||
database, err := db.New(t.TempDir())
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
t.Cleanup(func() { _ = database.Close() })
|
||||
|
||||
hub := NewWSHub(database)
|
||||
conn := connectTestDashboard(t, hub)
|
||||
h := NewReconHandler(database, hub)
|
||||
|
||||
body, _ := json.Marshal(map[string]interface{}{"host": "ws-recon.lab", "port": 80, "scheme": "http", "profile": "quick"})
|
||||
go func() {
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/recon/scan", bytes.NewReader(body))
|
||||
w := httptest.NewRecorder()
|
||||
h.Scan(w, req)
|
||||
}()
|
||||
|
||||
seen := map[string]bool{}
|
||||
deadline := time.Now().Add(5 * time.Second)
|
||||
for time.Now().Before(deadline) {
|
||||
var msg Message
|
||||
if err := conn.ReadJSON(&msg); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
switch msg.Type {
|
||||
case "recon_port", "recon_page", "recon_finding":
|
||||
seen[msg.Type] = true
|
||||
case "recon_complete":
|
||||
seen[msg.Type] = true
|
||||
if !seen["recon_port"] {
|
||||
t.Fatalf("recon_complete before recon_port; seen=%v", seen)
|
||||
}
|
||||
return
|
||||
}
|
||||
}
|
||||
t.Fatalf("missing recon events; seen=%v", seen)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user