mirror of
https://github.com/laoxong/nofx.git
synced 2026-06-04 09:58:22 +08:00
3ca95b294d
* feat: integrate NOFXi agent into dev * Enhance NOFXi agent workflow and diagnostics
128 lines
3.8 KiB
Go
128 lines
3.8 KiB
Go
package agent
|
|
|
|
import (
|
|
"encoding/json"
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
|
|
"nofx/store"
|
|
)
|
|
|
|
func TestReadBackendLogEntriesReturnsRecentErrorLines(t *testing.T) {
|
|
wd, err := os.Getwd()
|
|
if err != nil {
|
|
t.Fatalf("Getwd() error = %v", err)
|
|
}
|
|
tmp := t.TempDir()
|
|
if err := os.Chdir(tmp); err != nil {
|
|
t.Fatalf("Chdir(tmp) error = %v", err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_ = os.Chdir(wd)
|
|
})
|
|
|
|
if err := os.MkdirAll("data", 0o755); err != nil {
|
|
t.Fatalf("MkdirAll(data) error = %v", err)
|
|
}
|
|
logPath := filepath.Join("data", "nofx_2099-01-01.log")
|
|
content := strings.Join([]string{
|
|
"04-19 13:00:00 [INFO] api/server.go:590 API server starting",
|
|
"04-19 13:00:01 [ERRO] api/server.go:600 invalid signature for okx account",
|
|
"04-19 13:00:02 [ERRO] agent/tools.go:123 model update failed: missing api key",
|
|
}, "\n") + "\n"
|
|
if err := os.WriteFile(logPath, []byte(content), 0o644); err != nil {
|
|
t.Fatalf("WriteFile() error = %v", err)
|
|
}
|
|
|
|
path, entries, err := readBackendLogEntries(10, "model", true)
|
|
if err != nil {
|
|
t.Fatalf("readBackendLogEntries() error = %v", err)
|
|
}
|
|
if !strings.Contains(path, "nofx_2099-01-01.log") {
|
|
t.Fatalf("unexpected log path: %s", path)
|
|
}
|
|
if len(entries) != 1 || !strings.Contains(entries[0], "missing api key") {
|
|
t.Fatalf("unexpected filtered entries: %#v", entries)
|
|
}
|
|
}
|
|
|
|
func TestToolGetBackendLogsRequiresOwnedTrader(t *testing.T) {
|
|
wd, err := os.Getwd()
|
|
if err != nil {
|
|
t.Fatalf("Getwd() error = %v", err)
|
|
}
|
|
tmp := t.TempDir()
|
|
if err := os.Chdir(tmp); err != nil {
|
|
t.Fatalf("Chdir(tmp) error = %v", err)
|
|
}
|
|
t.Cleanup(func() {
|
|
_ = os.Chdir(wd)
|
|
})
|
|
|
|
if err := os.MkdirAll("data", 0o755); err != nil {
|
|
t.Fatalf("MkdirAll(data) error = %v", err)
|
|
}
|
|
logPath := filepath.Join("data", "nofx_2099-01-01.log")
|
|
content := strings.Join([]string{
|
|
"04-19 13:00:00 [INFO] api/server.go:590 API server starting",
|
|
"04-19 13:00:01 [ERRO] trader/runtime.go:88 trader_id=trader-owned strategy execution failed",
|
|
"04-19 13:00:02 [ERRO] trader/runtime.go:89 trader_id=trader-other strategy execution failed",
|
|
}, "\n") + "\n"
|
|
if err := os.WriteFile(logPath, []byte(content), 0o644); err != nil {
|
|
t.Fatalf("WriteFile() error = %v", err)
|
|
}
|
|
|
|
a := newTestAgentWithStore(t)
|
|
if err := a.store.Trader().Create(&store.Trader{
|
|
ID: "trader-owned",
|
|
UserID: "user-1",
|
|
Name: "Owned Trader",
|
|
AIModelID: "model-1",
|
|
ExchangeID: "exchange-1",
|
|
StrategyID: "strategy-1",
|
|
InitialBalance: 1000,
|
|
}); err != nil {
|
|
t.Fatalf("create owned trader: %v", err)
|
|
}
|
|
if err := a.store.Trader().Create(&store.Trader{
|
|
ID: "trader-other",
|
|
UserID: "user-2",
|
|
Name: "Other Trader",
|
|
AIModelID: "model-2",
|
|
ExchangeID: "exchange-2",
|
|
StrategyID: "strategy-2",
|
|
InitialBalance: 1000,
|
|
}); err != nil {
|
|
t.Fatalf("create other trader: %v", err)
|
|
}
|
|
|
|
resp := a.toolGetBackendLogs("user-1", `{"trader_id":"trader-owned","limit":5}`)
|
|
var okResult struct {
|
|
TraderID string `json:"trader_id"`
|
|
Entries []string `json:"entries"`
|
|
Count int `json:"count"`
|
|
}
|
|
if err := json.Unmarshal([]byte(resp), &okResult); err != nil {
|
|
t.Fatalf("unmarshal owned response: %v\nraw=%s", err, resp)
|
|
}
|
|
if okResult.TraderID != "trader-owned" || okResult.Count != 1 {
|
|
t.Fatalf("unexpected owned response: %+v", okResult)
|
|
}
|
|
if len(okResult.Entries) != 1 || !strings.Contains(okResult.Entries[0], "trader-owned") {
|
|
t.Fatalf("unexpected owned entries: %#v", okResult.Entries)
|
|
}
|
|
|
|
resp = a.toolGetBackendLogs("user-1", `{"trader_id":"trader-other","limit":5}`)
|
|
var denied struct {
|
|
Error string `json:"error"`
|
|
}
|
|
if err := json.Unmarshal([]byte(resp), &denied); err != nil {
|
|
t.Fatalf("unmarshal denied response: %v\nraw=%s", err, resp)
|
|
}
|
|
if denied.Error != "trader not found for current user" {
|
|
t.Fatalf("unexpected denied response: %+v", denied)
|
|
}
|
|
}
|