feat: add auto update
This commit is contained in:
@ -2,6 +2,7 @@ package api
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"context"
|
||||
"encoding/json"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@ -801,3 +802,246 @@ func TestContainerAction_Success(t *testing.T) {
|
||||
t.Error("expected command_id in response")
|
||||
}
|
||||
}
|
||||
|
||||
// newCancelledRequest creates a request with an already-cancelled context.
|
||||
func newCancelledRequest(method, target string, body *bytes.Reader) *http.Request {
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
cancel()
|
||||
var req *http.Request
|
||||
if body != nil {
|
||||
req = httptest.NewRequest(method, target, body)
|
||||
} else {
|
||||
req = httptest.NewRequest(method, target, nil)
|
||||
}
|
||||
return req.WithContext(ctx)
|
||||
}
|
||||
|
||||
// ── FsList ────────────────────────────────────────────────────────────────────
|
||||
|
||||
func TestFsList_AgentNotFound(t *testing.T) {
|
||||
h, _, _, _ := newTestHandler(t)
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Get("/api/v1/agents/{agentID}/fs/list", h.FsList)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/agents/ghost/fs/list?path=/tmp", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Errorf("expected 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFsList_Timeout(t *testing.T) {
|
||||
h, _, reg, _ := newTestHandler(t)
|
||||
reg.Register("a1", "h", "a", "ip", "arch", "os")
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Get("/api/v1/agents/{agentID}/fs/list", h.FsList)
|
||||
|
||||
// Use cancelled context to force immediate timeout on the agent wait.
|
||||
req := newCancelledRequest(http.MethodGet, "/api/v1/agents/a1/fs/list?path=/tmp", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
// Either 504 (timeout) or 404 (send failed because channel was full/cancelled).
|
||||
if w.Code != http.StatusGatewayTimeout && w.Code != http.StatusNotFound {
|
||||
t.Errorf("expected 504 or 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
func TestFsList_MissingPath(t *testing.T) {
|
||||
h, _, reg, _ := newTestHandler(t)
|
||||
reg.Register("a1", "h", "a", "ip", "arch", "os")
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Get("/api/v1/agents/{agentID}/fs/list", h.FsList)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/agents/a1/fs/list", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected 400, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// ── FsRead ────────────────────────────────────────────────────────────────────
|
||||
|
||||
func TestFsRead_AgentNotFound(t *testing.T) {
|
||||
h, _, _, _ := newTestHandler(t)
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Get("/api/v1/agents/{agentID}/fs/read", h.FsRead)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/agents/ghost/fs/read?path=/etc/hosts", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Errorf("expected 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFsRead_MissingPath(t *testing.T) {
|
||||
h, _, reg, _ := newTestHandler(t)
|
||||
reg.Register("a1", "h", "a", "ip", "arch", "os")
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Get("/api/v1/agents/{agentID}/fs/read", h.FsRead)
|
||||
|
||||
req := httptest.NewRequest(http.MethodGet, "/api/v1/agents/a1/fs/read", nil)
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected 400, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// ── FsWrite ───────────────────────────────────────────────────────────────────
|
||||
|
||||
func TestFsWrite_AgentNotFound(t *testing.T) {
|
||||
h, _, _, _ := newTestHandler(t)
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Post("/api/v1/agents/{agentID}/fs/write", h.FsWrite)
|
||||
|
||||
body, _ := json.Marshal(map[string]string{"path": "/tmp/test.txt", "content": "hello"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/agents/ghost/fs/write", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Errorf("expected 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFsWrite_MissingPath(t *testing.T) {
|
||||
h, _, reg, _ := newTestHandler(t)
|
||||
reg.Register("a1", "h", "a", "ip", "arch", "os")
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Post("/api/v1/agents/{agentID}/fs/write", h.FsWrite)
|
||||
|
||||
body, _ := json.Marshal(map[string]string{"content": "hello"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/agents/a1/fs/write", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected 400, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// ── FsMkdir ───────────────────────────────────────────────────────────────────
|
||||
|
||||
func TestFsMkdir_AgentNotFound(t *testing.T) {
|
||||
h, _, _, _ := newTestHandler(t)
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Post("/api/v1/agents/{agentID}/fs/mkdir", h.FsMkdir)
|
||||
|
||||
body, _ := json.Marshal(map[string]string{"path": "/opt/stacks/nouveau-dossier"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/agents/ghost/fs/mkdir", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Errorf("expected 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestFsMkdir_InvalidBody(t *testing.T) {
|
||||
h, _, reg, _ := newTestHandler(t)
|
||||
reg.Register("a1", "h", "a", "ip", "arch", "os")
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Post("/api/v1/agents/{agentID}/fs/mkdir", h.FsMkdir)
|
||||
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/agents/a1/fs/mkdir", bytes.NewReader([]byte("not-json")))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected 400, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
// ── ComposeAction ─────────────────────────────────────────────────────────────
|
||||
|
||||
func TestComposeAction_AgentNotFound(t *testing.T) {
|
||||
h, _, _, _ := newTestHandler(t)
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Post("/api/v1/agents/{agentID}/compose", h.ComposeAction)
|
||||
|
||||
body, _ := json.Marshal(map[string]string{"path": "/opt/stack", "action": "up"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/agents/ghost/compose", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusNotFound {
|
||||
t.Errorf("expected 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComposeAction_InvalidAction(t *testing.T) {
|
||||
h, _, reg, _ := newTestHandler(t)
|
||||
reg.Register("a1", "h", "a", "ip", "arch", "os")
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Post("/api/v1/agents/{agentID}/compose", h.ComposeAction)
|
||||
|
||||
body, _ := json.Marshal(map[string]string{"path": "/opt/stack", "action": "restart"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/agents/a1/compose", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected 400, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComposeAction_MissingFields(t *testing.T) {
|
||||
h, _, _, _ := newTestHandler(t)
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Post("/api/v1/agents/{agentID}/compose", h.ComposeAction)
|
||||
|
||||
body, _ := json.Marshal(map[string]string{"action": "up"})
|
||||
req := httptest.NewRequest(http.MethodPost, "/api/v1/agents/ghost/compose", bytes.NewReader(body))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusBadRequest {
|
||||
t.Errorf("expected 400, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
func TestComposeAction_Timeout(t *testing.T) {
|
||||
h, _, reg, _ := newTestHandler(t)
|
||||
reg.Register("a1", "h", "a", "ip", "arch", "os")
|
||||
|
||||
router := chi.NewRouter()
|
||||
router.Post("/api/v1/agents/{agentID}/compose", h.ComposeAction)
|
||||
|
||||
bodyBytes, _ := json.Marshal(map[string]string{"path": "/opt/stack", "action": "up"})
|
||||
req := newCancelledRequest(http.MethodPost, "/api/v1/agents/a1/compose", bytes.NewReader(bodyBytes))
|
||||
req.Header.Set("Content-Type", "application/json")
|
||||
w := httptest.NewRecorder()
|
||||
router.ServeHTTP(w, req)
|
||||
|
||||
if w.Code != http.StatusGatewayTimeout && w.Code != http.StatusNotFound {
|
||||
t.Errorf("expected 504 or 404, got %d", w.Code)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user