fix: delete instance data and remove legacy shared workspace support
This commit is contained in:
@@ -0,0 +1,110 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"testing"
|
||||
|
||||
"git.misaka.ren/m1saka/dsh-web/internal/store"
|
||||
)
|
||||
|
||||
func TestInstanceDeleteDataAndRetry(t *testing.T) {
|
||||
for _, blocked := range []bool{false, true} {
|
||||
t.Run(map[bool]string{false: "success", true: "retry"}[blocked], func(t *testing.T) {
|
||||
a, sid := runtimeTestAPI(t, func(w http.ResponseWriter, r *http.Request) {
|
||||
if r.Method == http.MethodDelete {
|
||||
w.WriteHeader(204)
|
||||
} else {
|
||||
w.WriteHeader(404)
|
||||
}
|
||||
})
|
||||
i := store.Instance{ID: "one", UID: "owner", ContainerID: "container"}
|
||||
if err := a.s.AddInstance(i); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
write := func(rel string) {
|
||||
p := filepath.Join(a.root, rel)
|
||||
if err := os.MkdirAll(filepath.Dir(p), 0750); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.WriteFile(p, []byte("keep"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
write("workspaces/owner/instances/one/home/data")
|
||||
write("workspaces/owner/instances/one/pre-restore-test/data")
|
||||
write("workspaces/owner/instances/two/home/data")
|
||||
write("backups/owner/one/archive.dshbak")
|
||||
write("backups/owner/two/archive.dshbak")
|
||||
outside := t.TempDir()
|
||||
sentinel := filepath.Join(outside, "sentinel")
|
||||
if err := os.WriteFile(sentinel, []byte("safe"), 0600); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Symlink(outside, filepath.Join(a.root, "workspaces/owner/instances/one/home/link")); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
backups := filepath.Join(a.root, "backups/owner")
|
||||
if blocked {
|
||||
if err := os.Rename(backups, backups+"-saved"); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Symlink(backups+"-saved", backups); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
remove := func() *httptest.ResponseRecorder {
|
||||
w := httptest.NewRecorder()
|
||||
a.instance(w, runtimeRequest("DELETE", "/api/instances/one", "", sid))
|
||||
return w
|
||||
}
|
||||
w := remove()
|
||||
if blocked {
|
||||
if w.Code != 500 {
|
||||
t.Fatal(w.Code, w.Body.String())
|
||||
}
|
||||
current, err := a.s.GetInstance(i.ID)
|
||||
if err != nil || current.Status != "error" {
|
||||
t.Fatal(current, err)
|
||||
}
|
||||
if err := os.Remove(backups); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
if err := os.Rename(backups+"-saved", backups); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
w = remove()
|
||||
}
|
||||
if w.Code != 200 {
|
||||
t.Fatal(w.Code, w.Body.String())
|
||||
}
|
||||
for _, rel := range []string{"workspaces/owner/instances/one", "backups/owner/one"} {
|
||||
if _, err := os.Lstat(filepath.Join(a.root, rel)); !os.IsNotExist(err) {
|
||||
t.Fatal("data retained", rel, err)
|
||||
}
|
||||
}
|
||||
for _, p := range []string{sentinel, filepath.Join(a.root, "workspaces/owner/instances/two/home/data"), filepath.Join(a.root, "backups/owner/two/archive.dshbak")} {
|
||||
if _, err := os.Stat(p); err != nil {
|
||||
t.Fatal("unrelated data removed", err)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestUsageDoesNotCreateLegacyFiles(t *testing.T) {
|
||||
a, sid := runtimeTestAPI(t, func(w http.ResponseWriter, r *http.Request) { t.Fatal("unexpected Docker request") })
|
||||
w := httptest.NewRecorder()
|
||||
a.workspace(w, runtimeRequest("GET", "/api/ws/usage", "", sid))
|
||||
if w.Code != 200 {
|
||||
t.Fatal(w.Code, w.Body.String())
|
||||
}
|
||||
if _, err := os.Stat(filepath.Join(a.root, "workspaces/owner/files")); !os.IsNotExist(err) {
|
||||
t.Fatal("legacy directory created", err)
|
||||
}
|
||||
if _, err := a.openWorkspace(store.User{ID: "owner"}, ""); err == nil {
|
||||
t.Fatal("shared workspace accepted")
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user