test(rtc): launch two clients at the same time

This commit is contained in:
rcmerci
2024-08-29 20:14:32 +08:00
parent fa43327eff
commit 50fb730c43
10 changed files with 187 additions and 149 deletions

3
bb.edn
View File

@@ -146,6 +146,9 @@
dev:lint-and-test
logseq.tasks.dev/lint-and-test
dev:rtc-e2e-test
logseq.tasks.dev/rtc-e2e-test
dev:gen-malli-kondo-config
logseq.tasks.dev/gen-malli-kondo-config

View File

@@ -12,7 +12,8 @@ module.exports = function (config) {
client: {
args: ["shadow.test.karma.init"],
singleRun: true,
testvar: config.testvar
testvar: config.testvar,
seed: config.seed
}
})
};

View File

@@ -9,7 +9,8 @@
[clojure.java.io :as io]
[clojure.pprint :as pp]
[clojure.edn :as edn]
[clojure.data :as data]))
[clojure.data :as data]
[clojure.core.async :as async]))
(defn test
"Run tests. Pass args through to cmd 'yarn cljs:run-test'"
@@ -24,6 +25,14 @@
(dev-lint/dev)
(test "-e" "long" "-e" "fix-me"))
(defn rtc-e2e-test
"Run karma rtc-e2e-test"
[]
(let [seed (hash (rand))
c1 (async/go (shell (str "npx karma start --testvar=client1 --single-run --seed=" seed)))
c2 (async/go (shell (str "npx karma start --testvar=client2 --single-run --seed=" seed)))]
(prn :exit-code :client1 (:exit (async/<!! c1)) :client2 (:exit (async/<!! c2)))))
(defn gen-malli-kondo-config
"Generate clj-kondo type-mismatch config from malli schema
.clj-kondo/metosin/malli-types/config.edn"

View File

@@ -92,6 +92,7 @@
:rtc-e2e-test {:target :karma
:closure-defines {frontend.worker.rtc.const/RTC-E2E-TEST* true}
:output-to "static/rtc-e2e-test/main.js"
:devtools {:enabled true}
:compiler-options {:source-map true
:warnings {:fn-deprecated false
:redef false}}}

View File

@@ -1,93 +1,31 @@
(ns basic-edits-test
(:require [cljs.test :as t :refer [deftest is testing]]
(:require [client1-edits]
[cljs.test :as t :refer [deftest testing]]
[const]
[datascript.core :as d]
[fixture]
[frontend.worker.rtc.client-op :as client-op]
[frontend.worker.rtc.core :as rtc-core]
[frontend.worker.rtc.log-and-state :as rtc-log-and-state]
[helper]
[logseq.outliner.batch-tx :as batch-tx]
[meander.epsilon :as me]
[missionary.core :as m]))
(when (exists? js/__karma__)
(prn :config.testvar js/__karma__.config.testvar))
(t/use-fixtures :once
fixture/install-some-consts
fixture/install-example-db-fixture
fixture/clear-test-remote-graphs-fixture
fixture/build-two-conns-by-download-example-graph-fixture)
(defn- simplify-client-op
[client-op]
#_:clj-kondo/ignore
(me/find
client-op
[?op-type _ {:block-uuid ?block-uuid :av-coll [[!a !v _ !add] ...]}]
[?op-type ?block-uuid (map vector !a !v !add)]
[?op-type _ {:block-uuid ?block-uuid}]
[?op-type ?block-uuid]))
(def ^:private page-uuid1 (random-uuid))
(def ^:private block-uuid1 (random-uuid))
(def ^:private tx-data-map
{:create-page
[{:db/id "page"
:block/name "basic-edits-test"
:block/title "basic-edits-test"
:block/uuid page-uuid1
:block/created-at 1724836490809
:block/updated-at 1724836490809
:block/type "page"
:block/format :markdown}
{:block/uuid block-uuid1
:block/updated-at 1724836490810
:block/created-at 1724836490810
:block/format :markdown
:block/title "block1"
:block/parent "page"
:block/order "a0"
:block/page "page"}]})
fixture/upload-example-graph-fixture
fixture/build-conn-by-download-example-graph-fixture)
(deftest basic-edits-test
(let [conn1 (helper/get-downloaded-test-conn)]
(t/async
done
(js/Promise.
(t/async
done
(js/Promise.
(if const/is-client1?
(m/sp
(testing "create page first"
(let [tx-data (tx-data-map :create-page)]
(batch-tx/with-batch-tx-mode conn1 {:e2e-test const/downloaded-test-repo}
(d/transact! conn1 tx-data))
(is (=
#{[:update-page page-uuid1]
[:update page-uuid1
[[:block/title "[\"~#'\",\"basic-edits-test\"]" true]
[:block/created-at "[\"~#'\",1724836490809]" true]
[:block/updated-at "[\"~#'\",1724836490809]" true]
[:block/type "[\"~#'\",\"page\"]" true]]]
[:move block-uuid1]
[:update block-uuid1
[[:block/updated-at "[\"~#'\",1724836490810]" true]
[:block/created-at "[\"~#'\",1724836490810]" true]
[:block/title "[\"~#'\",\"block1\"]" true]]]}
(set (map simplify-client-op (client-op/get-all-ops const/downloaded-test-repo)))))))
(client1-edits/step1--create-page))
(testing "start rtc on repo"
(let [r (m/? (rtc-core/new-task--rtc-start const/downloaded-test-repo const/test-token))]
(is (nil? r))))
(m/? (client1-edits/step2--task-start-rtc)))
(testing "waiting for :create-page synced"
(let [r (m/? (m/timeout
(m/reduce (fn [_ v]
(when (= :rtc.log/push-local-update (:type v))
(reduced v)))
rtc-log-and-state/rtc-log-flow)
6000 :timeout))]
(is (not= :timeout r))))
(m/? (client1-edits/step3--task-wait-:create-page-synced)))
(done))
(m/sp
(testing "TODO: client2 cases")
(done))))))

View File

@@ -0,0 +1,47 @@
(ns client1-edits
(:require [cljs.test :as t :refer [is]]
[const]
[datascript.core :as d]
[frontend.worker.rtc.client-op :as client-op]
[frontend.worker.rtc.core :as rtc-core]
[frontend.worker.rtc.log-and-state :as rtc-log-and-state]
[helper]
[logseq.outliner.batch-tx :as batch-tx]
[missionary.core :as m]))
(defn step1--create-page
[]
(let [conn (helper/get-downloaded-test-conn)
tx-data (const/tx-data-map :create-page)]
(batch-tx/with-batch-tx-mode conn {:e2e-test const/downloaded-test-repo}
(d/transact! conn tx-data))
(is (=
#{[:update-page const/page-uuid1]
[:update const/page-uuid1
[[:block/title "[\"~#'\",\"basic-edits-test\"]" true]
[:block/created-at "[\"~#'\",1724836490809]" true]
[:block/updated-at "[\"~#'\",1724836490809]" true]
[:block/type "[\"~#'\",\"page\"]" true]]]
[:move const/block-uuid1]
[:update const/block-uuid1
[[:block/updated-at "[\"~#'\",1724836490810]" true]
[:block/created-at "[\"~#'\",1724836490810]" true]
[:block/title "[\"~#'\",\"block1\"]" true]]]}
(set (map helper/simplify-client-op (client-op/get-all-ops const/downloaded-test-repo)))))))
(defn step2--task-start-rtc
[]
(m/sp
(let [r (m/? (rtc-core/new-task--rtc-start const/downloaded-test-repo const/test-token))]
(is (nil? r)))))
(defn step3--task-wait-:create-page-synced
[]
(m/sp
(let [r (m/? (m/timeout
(m/reduce (fn [_ v]
(when (= :rtc.log/push-local-update (:type v))
(reduced v)))
rtc-log-and-state/rtc-log-flow)
6000 :timeout))]
(is (not= :timeout r)))))

View File

@@ -1,11 +1,40 @@
(ns const
"Consts for rtc e2e tests")
(assert (exists? js/__karma__))
(def seed js/__karma__.config.seed)
(def testvar js/__karma__.config.testvar)
(prn :karma-config :seed seed :testvar testvar)
(def is-client1? (= "client1" testvar))
(def test-token "TEST-TOKEN")
(def test-graph-name "TEST-REPO")
(def test-repo "logseq_db_TEST-REPO")
(def test-graph-name (str "TEST-REPO-" seed))
(def test-repo (str "logseq_db_TEST-REPO-" seed))
(def downloaded-test-graph-name "TEST-REPO-downloaded")
(def downloaded-test-repo "logseq_db_TEST-REPO-downloaded")
(def downloaded-test-graph-name2 "TEST-REPO-2-downloaded")
(def downloaded-test-repo2 "logseq_db_TEST-REPO-2-downloaded")
;;; tests data
(def page-uuid1 (random-uuid))
(def block-uuid1 (random-uuid))
(def tx-data-map
{:create-page
[{:db/id "page"
:block/name "basic-edits-test"
:block/title "basic-edits-test"
:block/uuid page-uuid1
:block/created-at 1724836490809
:block/updated-at 1724836490809
:block/type "page"
:block/format :markdown}
{:block/uuid block-uuid1
:block/updated-at 1724836490810
:block/created-at 1724836490810
:block/format :markdown
:block/title "block1"
:block/parent "page"
:block/order "a0"
:block/page "page"}]})

View File

@@ -1,31 +0,0 @@
(ns download-upload-test
"RTC e2e tests for download-graph and upload-graph"
(:require [cljs.test :as t :refer [deftest]]
[const]
[datascript.core :as d]
[example]
[fixture]
[frontend.common.missionary-util :as c.m]
[helper]
[missionary.core :as m]
[frontend.worker.state :as worker-state]))
(t/use-fixtures :once
fixture/install-some-consts
fixture/install-example-db-fixture
fixture/clear-test-remote-graphs-fixture)
(deftest upload-download-graph-test
(t/async
done
(c.m/run-task-throw
(m/sp
(println :example-db-block-count (count (d/datoms @(helper/get-example-test-conn) :avet :block/uuid)))
(let [{:keys [graph-uuid]} (m/? helper/new-task--upload-example-graph)]
(m/? (helper/new-task--wait-creating-graph graph-uuid))
(m/? (helper/new-task--download-graph graph-uuid const/downloaded-test-graph-name))
(let [conn (helper/get-downloaded-test-conn)]
(println :repos (keys @worker-state/*datascript-conns))
(println :block-count (count (d/datoms @conn :avet :block/uuid)))))
(done))
:upload-download-graph-test)))

View File

@@ -18,6 +18,7 @@
(def install-example-db-fixture
{:before
(fn []
(prn :test-repo const/test-repo)
(swap! worker-state/*client-ops-conns assoc const/test-repo (d/create-conn client-op/schema-in-db))
(let [conn (d/conn-from-db example/example-db)]
(swap! worker-state/*datascript-conns assoc const/test-repo conn)))
@@ -28,30 +29,45 @@
(def clear-test-remote-graphs-fixture
{:before
#(t/async
done
(c.m/run-task-throw
(m/sp
(m/? helper/new-task--clear-all-test-remote-graphs)
(done))
:clear-test-remote-graphs))})
#(when const/is-client1?
(t/async
done
(c.m/run-task-throw
(m/sp
(m/? helper/new-task--clear-all-test-remote-graphs)
(done))
:clear-test-remote-graphs)))})
(def build-two-conns-by-download-example-graph-fixture
(def upload-example-graph-fixture
{:before
#(when const/is-client1?
(t/async
done
(c.m/run-task-throw
(m/sp
(swap! worker-state/*datascript-conns dissoc const/downloaded-test-repo)
(swap! worker-state/*client-ops-conns assoc
const/downloaded-test-repo (d/create-conn client-op/schema-in-db))
(let [{:keys [graph-uuid]} (m/? helper/new-task--upload-example-graph)]
(assert (some? graph-uuid))
(m/? (helper/new-task--wait-creating-graph graph-uuid)))
(done))
:upload-example-graph-fixture)))})
(def build-conn-by-download-example-graph-fixture
{:before
#(t/async
done
(c.m/run-task-throw
(m/sp
(swap! worker-state/*datascript-conns dissoc const/downloaded-test-repo const/downloaded-test-repo2)
(swap! worker-state/*datascript-conns dissoc const/downloaded-test-repo)
(swap! worker-state/*client-ops-conns assoc
const/downloaded-test-repo (d/create-conn client-op/schema-in-db)
const/downloaded-test-repo2 (d/create-conn client-op/schema-in-db))
(let [{:keys [graph-uuid]} (m/? helper/new-task--upload-example-graph)]
(m/? (helper/new-task--wait-creating-graph graph-uuid))
(m/? (helper/new-task--download-graph graph-uuid const/downloaded-test-graph-name))
(m/? (helper/new-task--download-graph graph-uuid const/downloaded-test-graph-name2))
(done)))
:build-two-conns-by-download-example-graph-fixture))
const/downloaded-test-repo (d/create-conn client-op/schema-in-db))
(let [graph-uuid (m/? helper/new-task--get-remote-example-graph-uuid)]
(assert (some? graph-uuid))
(m/? (helper/new-task--download-graph graph-uuid const/downloaded-test-graph-name)))
(done))
:build-conn-by-download-example-graph-fixture))
:after
#(do (swap! worker-state/*datascript-conns dissoc const/downloaded-test-repo const/downloaded-test-repo2)
(swap! worker-state/*client-ops-conns dissoc const/downloaded-test-repo const/downloaded-test-repo2))})
#(do (swap! worker-state/*datascript-conns dissoc const/downloaded-test-repo)
(swap! worker-state/*client-ops-conns dissoc const/downloaded-test-repo))})

View File

@@ -3,10 +3,11 @@
[frontend.common.missionary-util :as c.m]
[frontend.worker.rtc.core :as rtc.core]
[missionary.core :as m]
[frontend.worker.state :as worker-state]))
[frontend.worker.state :as worker-state]
[meander.epsilon :as me]))
(def new-task--upload-example-graph
(rtc.core/new-task--upload-graph const/test-token const/test-repo const/test-repo))
(rtc.core/new-task--upload-graph const/test-token const/test-repo const/test-graph-name))
(defn new-task--wait-creating-graph
[graph-uuid]
@@ -31,29 +32,53 @@
(doseq [graph test-graphs]
(m/? (rtc.core/new-task--delete-graph const/test-token (:graph-uuid graph)))))))
(def new-task--get-remote-example-graph-uuid
(c.m/backoff
(take 5 c.m/delays)
(m/sp
(let [graphs (m/? (rtc.core/new-task--get-graphs const/test-token))
graph
(some (fn [graph]
(when (and (= const/test-graph-name (:graph-name graph))
(not= "deleting" (:graph-status graph)))
graph))
graphs)]
(when-not graph
(throw (ex-info "wait remote-example-graph" {:missionary/retry true})))
(when (= "creating" (:graph-status graph))
(throw (ex-info "wait remote-example-graph (creating)" {:missionary/retry true})))
(:graph-uuid graph)))))
(defn new-task--download-graph
[graph-uuid graph-name]
(m/sp
(let [download-info-uuid (m/? (rtc.core/new-task--request-download-graph const/test-token graph-uuid))
result (m/? (rtc.core/new-task--wait-download-info-ready const/test-token download-info-uuid graph-uuid 60000))
{:keys [_download-info-uuid
download-info-s3-url
_download-info-tx-instant
_download-info-t
_download-info-created-at]} result]
(when (= result :timeout)
(throw (ex-info "wait download-info-ready timeout" {})))
(m/? (rtc.core/new-task--download-graph-from-s3
graph-uuid graph-name download-info-s3-url)))))
(let [download-info-uuid (m/? (rtc.core/new-task--request-download-graph const/test-token graph-uuid))
result (m/? (rtc.core/new-task--wait-download-info-ready const/test-token download-info-uuid graph-uuid 60000))
{:keys [_download-info-uuid
download-info-s3-url
_download-info-tx-instant
_download-info-t
_download-info-created-at]} result]
(when (= result :timeout)
(throw (ex-info "wait download-info-ready timeout" {})))
(m/? (rtc.core/new-task--download-graph-from-s3
graph-uuid graph-name download-info-s3-url)))))
(defn get-downloaded-test-conn
[]
(worker-state/get-datascript-conn const/downloaded-test-repo))
(defn get-downloaded-test-conn2
[]
(worker-state/get-datascript-conn const/downloaded-test-repo2))
(defn get-example-test-conn
[]
(worker-state/get-datascript-conn const/test-repo))
(defn simplify-client-op
[client-op]
#_:clj-kondo/ignore
(me/find
client-op
[?op-type _ {:block-uuid ?block-uuid :av-coll [[!a !v _ !add] ...]}]
[?op-type ?block-uuid (map vector !a !v !add)]
[?op-type _ {:block-uuid ?block-uuid}]
[?op-type ?block-uuid]))