♻️ Reimplement GC mechanism for penpot database objects.

This commit is contained in:
Andrey Antukh
2021-06-07 16:51:09 +02:00
committed by Andrés Moya
parent 71c4145ea2
commit 860e0227af
20 changed files with 437 additions and 104 deletions

View File

@@ -11,6 +11,7 @@
[app.http :as http]
[app.storage :as sto]
[app.test-helpers :as th]
[app.util.time :as dt]
[clojure.test :as t]
[datoteka.core :as fs]))
@@ -337,3 +338,69 @@
(t/is (th/ex-info? error))
(t/is (th/ex-of-type? error :not-found))))
(t/deftest deletion-test
(let [task (:app.tasks.objects-gc/handler th/*system*)
profile1 (th/create-profile* 1)
file (th/create-file* 1 {:project-id (:default-project-id profile1)
:profile-id (:id profile1)})]
;; file is not deleted because it does not meet all
;; conditions to be deleted.
(let [result (task {:max-age (dt/duration 0)})]
(t/is (nil? result)))
;; query the list of files
(let [data {::th/type :project-files
:project-id (:default-project-id profile1)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 1 (count result)))))
;; Request file to be deleted
(let [params {::th/type :delete-file
:id (:id file)
:profile-id (:id profile1)}
out (th/mutation! params)]
(t/is (nil? (:error out))))
;; query the list of files after soft deletion
(let [data {::th/type :project-files
:project-id (:default-project-id profile1)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 0 (count result)))))
;; run permanent deletion (should be noop)
(let [result (task {:max-age (dt/duration {:minutes 1})})]
(t/is (nil? result)))
;; query the list of file libraries of a after hard deletion
(let [data {::th/type :file-libraries
:file-id (:id file)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 0 (count result)))))
;; run permanent deletion
(let [result (task {:max-age (dt/duration 0)})]
(t/is (nil? result)))
;; query the list of file libraries of a after hard deletion
(let [data {::th/type :file-libraries
:file-id (:id file)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(let [error (:error out)
error-data (ex-data error)]
(t/is (th/ex-info? error))
(t/is (= (:type error-data) :not-found))))
))

View File

@@ -9,6 +9,7 @@
[app.db :as db]
[app.rpc.mutations.profile :as profile]
[app.test-helpers :as th]
[app.util.time :as dt]
[clojure.java.io :as io]
[clojure.test :as t]
[cuerdas.core :as str]
@@ -117,7 +118,7 @@
))
(t/deftest profile-deletion-simple
(let [task (:app.tasks.delete-profile/handler th/*system*)
(let [task (:app.tasks.objects-gc/handler th/*system*)
prof (th/create-profile* 1)
file (th/create-file* 1 {:profile-id (:id prof)
:project-id (:default-project-id prof)
@@ -125,23 +126,14 @@
;; profile is not deleted because it does not meet all
;; conditions to be deleted.
(let [result (task {:props {:profile-id (:id prof)}})]
(let [result (task {:max-age (dt/duration 0)})]
(t/is (nil? result)))
;; Request profile to be deleted
(with-mocks [mock {:target 'app.worker/submit! :return nil}]
(let [params {::th/type :delete-profile
:profile-id (:id prof)}
out (th/mutation! params)]
(t/is (nil? (:error out)))
;; check the mock
(let [mock (deref mock)
mock-params (first (:call-args mock))]
(t/is (:called? mock))
(t/is (= 1 (:call-count mock)))
(t/is (= :delete-profile (:app.worker/task mock-params)))
(t/is (= (:id prof) (:profile-id mock-params))))))
(let [params {::th/type :delete-profile
:profile-id (:id prof)}
out (th/mutation! params)]
(t/is (nil? (:error out))))
;; query files after profile soft deletion
(let [params {::th/type :files
@@ -153,8 +145,8 @@
(t/is (= 1 (count (:result out)))))
;; execute permanent deletion task
(let [result (task {:props {:profile-id (:id prof)}})]
(t/is (true? result)))
(let [result (task {:max-age (dt/duration "-1m")})]
(t/is (nil? result)))
;; query profile after delete
(let [params {::th/type :profile
@@ -165,17 +157,6 @@
error-data (ex-data error)]
(t/is (th/ex-info? error))
(t/is (= (:type error-data) :not-found))))
;; query files after profile soft deletion
(let [params {::th/type :files
:project-id (:default-project-id prof)
:profile-id (:id prof)}
out (th/query! params)]
;; (th/print-result! out)
(let [error (:error out)
error-data (ex-data error)]
(t/is (th/ex-info? error))
(t/is (= (:type error-data) :not-found))))
))
(t/deftest registration-domain-whitelist

View File

@@ -10,8 +10,8 @@
[app.db :as db]
[app.http :as http]
[app.test-helpers :as th]
[clojure.test :as t]
[promesa.core :as p]))
[app.util.time :as dt]
[clojure.test :as t]))
(t/use-fixtures :once th/state-init)
(t/use-fixtures :each th/database-reset)
@@ -170,3 +170,71 @@
(t/is (th/ex-info? error))
(t/is (th/ex-of-type? error :not-found))))
(t/deftest test-deletion
(let [task (:app.tasks.objects-gc/handler th/*system*)
profile1 (th/create-profile* 1)
project (th/create-project* 1 {:team-id (:default-team-id profile1)
:profile-id (:id profile1)})]
;; project is not deleted because it does not meet all
;; conditions to be deleted.
(let [result (task {:max-age (dt/duration 0)})]
(t/is (nil? result)))
;; query the list of projects
(let [data {::th/type :projects
:team-id (:default-team-id profile1)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 2 (count result)))))
;; Request project to be deleted
(let [params {::th/type :delete-project
:id (:id project)
:profile-id (:id profile1)}
out (th/mutation! params)]
(t/is (nil? (:error out))))
;; query the list of projects after soft deletion
(let [data {::th/type :projects
:team-id (:default-team-id profile1)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 1 (count result)))))
;; run permanent deletion (should be noop)
(let [result (task {:max-age (dt/duration {:minutes 1})})]
(t/is (nil? result)))
;; query the list of files of a after soft deletion
(let [data {::th/type :project-files
:project-id (:id project)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 0 (count result)))))
;; run permanent deletion
(let [result (task {:max-age (dt/duration 0)})]
(t/is (nil? result)))
;; query the list of files of a after hard deletion
(let [data {::th/type :project-files
:project-id (:id project)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(let [error (:error out)
error-data (ex-data error)]
(t/is (th/ex-info? error))
(t/is (= (:type error-data) :not-found))))
))

View File

@@ -11,6 +11,7 @@
[app.http :as http]
[app.storage :as sto]
[app.test-helpers :as th]
[app.util.time :as dt]
[clojure.test :as t]
[datoteka.core :as fs]
[mockery.core :refer [with-mocks]]))
@@ -80,6 +81,80 @@
)))
(t/deftest test-deletion
(let [task (:app.tasks.objects-gc/handler th/*system*)
profile1 (th/create-profile* 1 {:is-active true})
team (th/create-team* 1 {:profile-id (:id profile1)})
pool (:app.db/pool th/*system*)
data {::th/type :delete-team
:team-id (:id team)
:profile-id (:id profile1)}]
;; team is not deleted because it does not meet all
;; conditions to be deleted.
(let [result (task {:max-age (dt/duration 0)})]
(t/is (nil? result)))
;; query the list of teams
(let [data {::th/type :teams
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 2 (count result)))
(t/is (= (:id team) (get-in result [1 :id])))
(t/is (= (:default-team-id profile1) (get-in result [0 :id])))))
;; Request team to be deleted
(let [params {::th/type :delete-team
:id (:id team)
:profile-id (:id profile1)}
out (th/mutation! params)]
(t/is (nil? (:error out))))
;; query the list of teams after soft deletion
(let [data {::th/type :teams
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 1 (count result)))
(t/is (= (:default-team-id profile1) (get-in result [0 :id])))))
;; run permanent deletion (should be noop)
(let [result (task {:max-age (dt/duration {:minutes 1})})]
(t/is (nil? result)))
;; query the list of projects of a after hard deletion
(let [data {::th/type :projects
:team-id (:id team)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(t/is (nil? (:error out)))
(let [result (:result out)]
(t/is (= 0 (count result)))))
;; run permanent deletion
(let [result (task {:max-age (dt/duration 0)})]
(t/is (nil? result)))
;; query the list of projects of a after hard deletion
(let [data {::th/type :projects
:team-id (:id team)
:profile-id (:id profile1)}
out (th/query! data)]
;; (th/print-result! out)
(let [error (:error out)
error-data (ex-data error)]
(t/is (th/ex-info? error))
(t/is (= (:type error-data) :not-found))))
))