Files
vps-commander/internal/api/api_test.go
T

91 lines
2.4 KiB
Go

package api
import (
"net/http/httptest"
"path/filepath"
"strings"
"sync"
"testing"
"github.com/wjyhk/vps-commander/internal/executor"
"github.com/wjyhk/vps-commander/internal/storage"
)
func TestExecConcurrent100AuditsPersisted(t *testing.T) {
store, err := storage.Open(filepath.Join(t.TempDir(), "commander.db"))
if err != nil {
t.Fatal(err)
}
defer store.DB.Close()
if err := store.SetGlobalSecurityMode("high"); err != nil {
t.Fatal(err)
}
s := &Server{Exec: executor.Local{MaxOutput: 1024 * 1024}, Store: store, LocalName: "local"}
const n = 100
var wg sync.WaitGroup
statuses := make(chan int, n)
wg.Add(n)
for i := 0; i < n; i++ {
go func() {
defer wg.Done()
req := httptest.NewRequest("POST", "/api/v1/exec", strings.NewReader("{\"device\":\"local\",\"command\":\"true\",\"timeout\":10}"))
rec := httptest.NewRecorder()
s.exec(rec, req)
statuses <- rec.Code
}()
}
wg.Wait()
close(statuses)
for status := range statuses {
if status != 200 {
t.Fatalf("unexpected HTTP status: %d", status)
}
}
logs, err := store.RecentAudits(500)
if err != nil {
t.Fatal(err)
}
if len(logs) != n {
t.Fatalf("audit loss: got %d rows, want %d", len(logs), n)
}
}
func TestSecurityEffectiveModeAndExecGate(t *testing.T) {
store, err := storage.Open(filepath.Join(t.TempDir(), "commander.db"))
if err != nil {
t.Fatal(err)
}
defer store.DB.Close()
s := &Server{Exec: executor.Local{MaxOutput: 1024 * 1024}, Store: store, LocalName: "local"}
if got := s.GetEffectiveSecurityMode("node-a"); got != "medium" {
t.Fatalf("default mode=%s", got)
}
if err := store.SetNodeSecurityMode("node-a", "high"); err != nil {
t.Fatal(err)
}
if got := s.GetEffectiveSecurityMode("node-a"); got != "high" {
t.Fatalf("override=%s", got)
}
if err := store.SetNodeSecurityMode("node-a", "inherit"); err != nil {
t.Fatal(err)
}
if err := store.SetGlobalSecurityMode("low"); err != nil {
t.Fatal(err)
}
if got := s.GetEffectiveSecurityMode("node-a"); got != "low" {
t.Fatalf("inherit=%s", got)
}
req := httptest.NewRequest("POST", "/api/v1/exec", strings.NewReader(`{"device":"node-a","command":"true"}`))
rec := httptest.NewRecorder()
s.exec(rec, req)
if rec.Code != 403 {
t.Fatalf("low exec status=%d", rec.Code)
}
logs, _ := store.RecentAudits(10)
if len(logs) == 0 || logs[0].Action != "security_denied" {
t.Fatalf("missing denial audit: %+v", logs)
}
}