80 lines
2.7 KiB
Go
80 lines
2.7 KiB
Go
package api
|
|
|
|
import (
|
|
"encoding/json"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
"vpn-platform/backend/internal/core"
|
|
"vpn-platform/backend/internal/model"
|
|
"vpn-platform/backend/internal/store"
|
|
)
|
|
|
|
type stateTestProtocol struct{}
|
|
|
|
func (stateTestProtocol) Name() string { return "state-test" }
|
|
func (stateTestProtocol) DisplayName() string { return "state-test" }
|
|
func (stateTestProtocol) Validate(cfg map[string]interface{}) (map[string]interface{}, error) {
|
|
return cfg, nil
|
|
}
|
|
func (stateTestProtocol) Create(*model.Tunnel) error { return nil }
|
|
func (stateTestProtocol) Start(*model.Tunnel) error { return nil }
|
|
func (stateTestProtocol) Stop(*model.Tunnel) error { return nil }
|
|
func (stateTestProtocol) Status(*model.Tunnel) (core.Status, error) { return core.Status{}, nil }
|
|
func (stateTestProtocol) GenerateClientConfig(*model.Tunnel) (string, error) { return "", nil }
|
|
func (stateTestProtocol) Delete(*model.Tunnel) error { return nil }
|
|
func (stateTestProtocol) Available() (bool, string) { return true, "" }
|
|
|
|
func TestStartStopDropsStaleRuntimeSnapshot(t *testing.T) {
|
|
oldDB := store.DB
|
|
t.Cleanup(func() { store.DB = oldDB })
|
|
if err := store.Init(t.TempDir()); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
line := model.Tunnel{Name: "snapshot", Protocol: "state-test", State: "running", Config: "{}"}
|
|
if err := store.DB.Create(&line).Error; err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
mgr := core.NewManager()
|
|
mgr.Register(stateTestProtocol{})
|
|
s := NewServer(mgr)
|
|
for _, tc := range []struct{ operation, oldState, wantState string }{
|
|
{"stop", "running", "stopped"},
|
|
{"start", "stopped", "running"},
|
|
} {
|
|
mgr.SetStatus(line.ID, core.Status{State: tc.oldState})
|
|
w := httptest.NewRecorder()
|
|
c, _ := gin.CreateTestContext(w)
|
|
c.Params = gin.Params{{Key: "id", Value: strconv.FormatUint(uint64(line.ID), 10)}}
|
|
if tc.operation == "stop" {
|
|
s.stopTunnel(c)
|
|
} else {
|
|
s.startTunnel(c)
|
|
}
|
|
if w.Code != http.StatusOK {
|
|
t.Fatalf("%s returned %d: %s", tc.operation, w.Code, w.Body.String())
|
|
}
|
|
if _, ok := mgr.GetStatus(line.ID); ok {
|
|
t.Fatalf("%s left the old runtime status cached", tc.operation)
|
|
}
|
|
|
|
listResponse := httptest.NewRecorder()
|
|
listContext, _ := gin.CreateTestContext(listResponse)
|
|
s.listTunnels(listContext)
|
|
var rows []struct {
|
|
State string `json:"state"`
|
|
Runtime *core.Status `json:"runtime"`
|
|
}
|
|
if err := json.Unmarshal(listResponse.Body.Bytes(), &rows); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(rows) != 1 || rows[0].State != tc.wantState || rows[0].Runtime != nil {
|
|
t.Fatalf("%s list returned stale state: %+v", tc.operation, rows)
|
|
}
|
|
}
|
|
}
|