mirror of
https://github.com/penpot/penpot.git
synced 2026-11-09 03:20:57 +00:00
203 lines
8.8 KiB
Clojure
203 lines
8.8 KiB
Clojure
;; This Source Code Form is subject to the terms of the Mozilla Public
|
|
;; License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
;; file, You can obtain one at http://mozilla.org/MPL/2.0/.
|
|
;;
|
|
;; Copyright (c) KALEIDOS SUBSIDIARY SL
|
|
|
|
(ns performance-tests.render-wasm.merge-test
|
|
(:require
|
|
[benches.render-wasm.result :as result]
|
|
[cljs.test :as t :include-macros true]))
|
|
|
|
(defn- metric
|
|
[value]
|
|
(result/metric {:value value
|
|
:unit :ms
|
|
:semantics :elapsed
|
|
:basis {:kind :attempt-total}
|
|
:zero-policy :positive}))
|
|
|
|
(defn- case-definition
|
|
[case-id]
|
|
{:id case-id
|
|
:scene :case
|
|
:scene-description "merge scene"
|
|
:scene-seed 7
|
|
:params {:count 10}
|
|
:view {:scale 1 :x 0 :y 0}
|
|
:context :fresh
|
|
:completion :render-full
|
|
:batch-size 1
|
|
:preparation {}})
|
|
|
|
(defn- preparation
|
|
[preparation-id case-id]
|
|
{:preparation-id preparation-id
|
|
:case-id case-id
|
|
:fingerprint {:algorithm :sha-256
|
|
:digest (apply str (repeat 64 "a"))}
|
|
:effective-graphics {:webgl2 true}
|
|
:diagnostics {}})
|
|
|
|
(defn- attempt
|
|
[case-id preparation-id warmup?]
|
|
{:case-id case-id
|
|
:preparation-id preparation-id
|
|
:warmup? warmup?
|
|
:outcome :completed
|
|
:metrics {:elapsed (metric 1.0)}
|
|
:trace {}})
|
|
|
|
(defn- make-run
|
|
[{:keys [run-id cases warmups repetitions git-sha build environment analysis
|
|
timeout-ms started-at ended-at termination preparations]
|
|
:or {git-sha "same-sha"
|
|
build {:mode :release}
|
|
environment {:node "v24"}
|
|
timeout-ms 30000
|
|
started-at "2026-10-26T00:00:00.000Z"
|
|
ended-at "2026-10-26T00:01:00.000Z"
|
|
termination {:reason :completed}}}]
|
|
(let [run (result/create-run
|
|
{:run-id run-id
|
|
:started-at started-at
|
|
:plan {:cases (mapv case-definition cases)
|
|
:warmups warmups
|
|
:repetitions repetitions
|
|
:timeout-policy {:attempt-ms timeout-ms}}
|
|
:metadata {:git {:sha git-sha :dirty false}
|
|
:build {:functional build}
|
|
:environment environment
|
|
:scored? true}
|
|
:analysis analysis})
|
|
run (reduce
|
|
(fn [run case-id]
|
|
(let [options (get preparations case-id)
|
|
warmup-id (or (:warmup options)
|
|
(str run-id "-" (name case-id)))
|
|
measured-id (or (:measured options) warmup-id)]
|
|
(-> run
|
|
(result/record-preparation (preparation warmup-id case-id))
|
|
(cond-> (not= warmup-id measured-id)
|
|
(result/record-preparation (preparation measured-id case-id)))
|
|
(as-> run
|
|
(reduce (fn [run _]
|
|
(result/record-attempt
|
|
run (attempt case-id warmup-id true)))
|
|
run (range warmups))
|
|
(reduce (fn [run _]
|
|
(result/record-attempt
|
|
run (attempt case-id measured-id false)))
|
|
run (range repetitions))))))
|
|
run cases)]
|
|
(result/finish-run run ended-at termination)))
|
|
|
|
(t/deftest merges-measured-attempts-and-updates-the-plan
|
|
(let [base (make-run {:run-id "base"
|
|
:cases [:case/load :case/pan]
|
|
:warmups 1
|
|
:repetitions 2
|
|
:started-at "2026-10-26T00:00:00.000Z"
|
|
:ended-at "2026-10-26T00:01:00.000Z"})
|
|
additional (make-run {:run-id "additional"
|
|
:cases [:case/load :case/pan]
|
|
:warmups 1
|
|
:repetitions 3
|
|
:started-at "2026-10-26T00:02:00.000Z"
|
|
:ended-at "2026-10-26T00:03:00.000Z"})
|
|
merged (result/merge-runs base additional {:run-id "merged"})]
|
|
(t/is (= "merged" (:run-id merged)))
|
|
(t/is (= 1 (get-in merged [:plan :warmups])))
|
|
(t/is (= 5 (get-in merged [:plan :repetitions])))
|
|
(t/is (= 12 (count (:attempts merged))))
|
|
(t/is (= (range 12) (map :ordinal (:attempts merged))))
|
|
(t/is (= [true false false true false false false false false false false false]
|
|
(map :warmup? (:attempts merged))))
|
|
(t/is (every? #(every? zero? (vals %)) (vals (:remaining merged))))
|
|
(t/is (= "2026-10-26T00:03:00.000Z" (:ended-at merged)))
|
|
(t/is (= 2 (get-in merged [:metadata :diagnostics :merge
|
|
:additional-warmups-excluded])))
|
|
(t/is (= merged (result/check-run merged)))
|
|
(t/is (= (:attempts merged)
|
|
(:attempts (result/decode (result/encode merged)))))))
|
|
|
|
(t/deftest excludes-additional-warmup-only-preparations
|
|
(let [base (make-run {:run-id "base"
|
|
:cases [:case/load]
|
|
:warmups 1
|
|
:repetitions 1})
|
|
additional (make-run {:run-id "additional"
|
|
:cases [:case/load]
|
|
:warmups 1
|
|
:repetitions 1
|
|
:preparations
|
|
{:case/load {:warmup "warm-prep"
|
|
:measured "measured-prep"}}})
|
|
merged (result/merge-runs base additional {:run-id "merged"})
|
|
preparation-ids (map :preparation-id (:preparations merged))]
|
|
(t/is (some #{"base-load"} preparation-ids))
|
|
(t/is (some #{"measured-prep"} preparation-ids))
|
|
(t/is (not (some #{"warm-prep"} preparation-ids)))
|
|
(t/is (= 3 (count (:attempts merged))))
|
|
(t/is (= "measured-prep" (:preparation-id (last (:attempts merged)))))))
|
|
|
|
(t/deftest rejects-incompatible-runs
|
|
(let [base (make-run {:run-id "base"
|
|
:cases [:case/load]
|
|
:warmups 1
|
|
:repetitions 1})]
|
|
(doseq [[label options message]
|
|
[["case" {:cases [:case/pan]} #"different case definitions"]
|
|
["timeout" {:timeout-ms 1000} #"different timeout policy"]
|
|
["warmups" {:warmups 0} #"different warmup count"]
|
|
["analysis" {:analysis {:draws 1000}} #"different analysis settings"]
|
|
["git" {:git-sha "other"} #"different git provenance"]
|
|
["build" {:build {:mode :debug}} #"different build facts"]
|
|
["environment" {:environment {:node "v25"}}
|
|
#"different runtime environment"]]]
|
|
(t/testing label
|
|
(let [additional (make-run (merge {:run-id "additional"
|
|
:cases [:case/load]
|
|
:warmups 1
|
|
:repetitions 1}
|
|
options))]
|
|
(t/is (thrown-with-msg? js/Error message
|
|
(result/merge-runs base additional
|
|
{:run-id "merged"}))))))))
|
|
|
|
(t/deftest rejects-non-completed-runs
|
|
(let [completed (make-run {:run-id "base"
|
|
:cases [:case/load]
|
|
:warmups 1
|
|
:repetitions 1})
|
|
interrupted (make-run {:run-id "additional"
|
|
:cases [:case/load]
|
|
:warmups 1
|
|
:repetitions 1
|
|
:termination {:reason :interrupted}})]
|
|
(t/is (thrown-with-msg? js/Error #"only completed runs can be merged"
|
|
(result/merge-runs completed interrupted
|
|
{:run-id "merged"})))
|
|
(t/is (thrown-with-msg? js/Error #"only completed runs can be merged"
|
|
(result/merge-runs interrupted completed
|
|
{:run-id "merged"})))))
|
|
|
|
(t/deftest rejects-duplicate-preparation-ids
|
|
(let [base (make-run {:run-id "base"
|
|
:cases [:case/load]
|
|
:warmups 1
|
|
:repetitions 1
|
|
:preparations
|
|
{:case/load {:warmup "shared"
|
|
:measured "shared"}}})
|
|
additional (make-run {:run-id "additional"
|
|
:cases [:case/load]
|
|
:warmups 1
|
|
:repetitions 1
|
|
:preparations
|
|
{:case/load {:warmup "shared"
|
|
:measured "shared"}}})]
|
|
(t/is (thrown-with-msg? js/Error #"duplicate preparation ids"
|
|
(result/merge-runs base additional
|
|
{:run-id "merged"})))))
|