Skip to content

Commit

Permalink
road to bb: http-client-lite & tests
Browse files Browse the repository at this point in the history
When running babashka, we now use the compatible http-client-lite.
(Thanks borkdude your etaoin pod work was a very useful reference!)

Reader conditionals select the existing http-client when running on from
the JVM.

Reader conditionals mean .cljc, which often means Clojure and
ClojureScript, but in our case it means JVM Clojure and Babashka
Clojure. Update configs for cljdoc and clj-kondo to let them know
that this is not a ClojureScript project.

Facility to test our bb implementation added via a new --platform option
on our `bb test` task. I'm not sure of the best way to run babashka
tests, but my first stab generates a runner.clj with appropriate
namespaces and classpath then runs that.

Etaoin does have some debug logging, so Babashka's log level is adjusted
from the default of debug to info in the generated test runner.

Finally adjusted our CI matrix to include the bb platform.

Contributes to clj-commons#380
  • Loading branch information
lread committed May 23, 2022
1 parent 8de9110 commit d5f15b3
Show file tree
Hide file tree
Showing 11 changed files with 196 additions and 67 deletions.
2 changes: 1 addition & 1 deletion .clj-kondo/config.edn
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{:config-paths ^:replace [] ;; don't adopt any user preferences

:cljc {:features [:clj]}
:hooks
;; for now we'll use the simple macroexpand, can move to hooks for finer grained errors later
{:macroexpand
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: Test

on:
push:
branches: ['master']
branches: ['lread-*']
pull_request:

jobs:
Expand Down
5 changes: 0 additions & 5 deletions Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
;; TODO: lread move to bb tasks

.PHONY: kill
kill:
pkill chromedriver || true
Expand All @@ -9,7 +7,6 @@ kill:

IMAGE := etaoin

;; TODO: lread: have never tried, test, fix if necessary
.PHONY: docker-build
docker-build:
docker build --no-cache -t ${IMAGE}:latest .
Expand All @@ -20,7 +17,6 @@ check-host:
$(error The HOST variable is not set, please do `export HOST=$$HOST` first)
endif

;; TODO: lread: have never tried, test, fix if necessary
# works only on mac + quartz
.PHONY: docker-test-display
docker-test-display: check-host
Expand All @@ -32,7 +28,6 @@ docker-test-display: check-host
bb test all || \
xhost -

;; TODO: lread: have never tried, test, fix if necessary
.PHONY: docker-test
docker-test:
docker run --rm \
Expand Down
12 changes: 9 additions & 3 deletions deps.edn
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
{:paths ["src"]
:deps {org.clojure/clojure {:mvn/version "1.9.0"} ;; min clojure version
babashka/fs {:mvn/version "0.1.6"}
clj-http/clj-http {:mvn/version "3.10.1"}
clj-http/clj-http {:mvn/version "3.10.1"} ;; for jvm use
org.clj-commons/clj-http-lite {:mvn/version "0.4.392"} ;; for babashka use
cheshire/cheshire {:mvn/version "5.9.0"}
org.clojure/tools.cli {:mvn/version "1.0.194"}
org.clojure/tools.logging {:mvn/version "0.3.1"}}
Expand All @@ -10,5 +11,10 @@
:debug {:extra-paths ["env/dev/resources"]}
:test {:extra-paths ["test" "env/test/resources"]
:extra-deps {io.github.cognitect-labs/test-runner {:git/tag "v0.5.1" :git/sha "dfb30dd"}
ch.qos.logback/logback-classic {:mvn/version "1.3.0-alpha16"}}
:main-opts ["-m" "cognitect.test-runner"]}}}
ch.qos.logback/logback-classic {:mvn/version "1.3.0-alpha16"}
;; for http-client which uses apache http client 4.x which uses commons logging
org.slf4j/jcl-over-slf4j {:mvn/version "2.0.0-alpha7"}}
:main-opts ["-m" "cognitect.test-runner"]}
;; for babashka testing, needed for eatoin.ide
:bb-spec {:extra-deps {org.babashka/spec.alpha {:git/url "https://github.com/babashka/spec.alpha"
:sha "644a7fc216e43d5da87b07471b0f87d874107d1a"}}}}}
4 changes: 4 additions & 0 deletions doc/cljdoc.edn
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{:cljdoc.doc/tree
[["Readme" {:file "README.adoc"}]
["Changelog" {:file "CHANGELOG.adoc"}]]
:cljdoc/languages ["clj"]}
5 changes: 5 additions & 0 deletions env/dev/resources/logback.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@
</encoder>
</appender>

<!-- uncomment org.apache.http for more details when using clj-http -->
<!--logger name="org.apache.http" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
</logger -->

<logger name="etaoin" level="debug" additivity="false">
<appender-ref ref="STDOUT"/>
</logger>
Expand Down
60 changes: 60 additions & 0 deletions script/bb_test_runner.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
(ns bb-test-runner
(:require [babashka.fs :as fs]
[clojure.string :as string]
[babashka.tasks :as tasks]
[helper.main :as main]))

(def id->nses {:ide ['etaoin.ide-test]
:api ['etaoin.api-test]
:unit (->> "test/etaoin/unit"
fs/list-dir
(map #(fs/relativize "test" %))
(map #(string/replace % #"\.clj$" ""))
(map #(string/replace % fs/file-separator "."))
(map #(string/replace % "_" "-"))
sort)})

(def args-usage "Valid args:
(unit|api|ide|all)
--help
Commands:
unit Run only unit tests
api Run only api tests
ide Run only ide tests
all Run all tests
Options:
--help Show this help
Intended to be called from test.clj where setup for such things as browser
web browser selection and virtual displays occur")

(defn -main [& args]
(when-let [opts (main/doc-arg-opt args-usage args)]
(let [;; we only need bb-spec for ide and unit tests tests, so explicitly otherwise test without it
cp-aliases (if (or (get opts "all") (get opts "ide") (get opts "unit"))
":test:bb-spec"
":test")
nses (cond
(get opts "ide") (:ide id->nses)
(get opts "api") (:api id->nses)
(get opts "unit") (:unit id->nses)
(get opts "all") (mapcat second id->nses))
runner (-> "script/bb_test_runner_template.clj"
slurp
(string/replace "{{cp-aliases}}" cp-aliases)
(string/replace "{{nses}}" (->> nses
(map #(str "'" %))
(string/join " "))))
test-runner-file (-> (fs/create-temp-file {:prefix "bb-test-runner"
:suffix ".clj"})
fs/file)]
(spit test-runner-file runner)
(tasks/shell "bb" test-runner-file)
(try
(finally
(fs/delete-if-exists test-runner-file))))))

(main/when-invoked-as-script
(apply -main *command-line-args*))
15 changes: 15 additions & 0 deletions script/bb_test_runner_template.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
(require '[babashka.classpath :as cp]
'[babashka.tasks :as tasks]
'[clojure.test :as t]
'[taoensso.timbre :as timbre])

;; bb log level by default is debug, let's set it to info
;; TODO: maybe there is some different abstraction for this?
(alter-var-root #'timbre/*config* #(assoc %1 :min-level :info))

(cp/add-classpath (with-out-str (tasks/clojure "-A{{cp-aliases}} -Spath")))

(require {{nses}})

(let [test-results (t/run-tests {{nses}})]
(System/exit (+ (:fail test-results) (:error test-results))))
121 changes: 76 additions & 45 deletions script/test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,37 @@
[helper.shell :as shell]
[lread.status-line :as status]))

(defn- test-def [os id browser]
(defn- test-def [os id platform browser]
{:os os
:cmd (->> ["bb test" id
(str "--platform=" platform)
(when browser (str "--browser=" browser))
(when (= "ubuntu" os) "--launch-virtual-display")]
(remove nil?)
(string/join " "))
:desc (->> [id os browser]
:desc (->> [platform id os browser]
(remove nil?)
(string/join " "))})

(defn- github-actions-matrix []
(let [oses ["macos" "ubuntu" "windows"]
ide-browsers ["chrome" "firefox"]
api-browsers ["chrome" "firefox" "edge" "safari"]]
api-browsers ["chrome" "firefox" "edge" "safari"]
platforms ["jvm" "bb"]]
(->> (concat
(for [os oses]
(test-def os "unit" nil))
(for [os oses
platform platforms]
(test-def os "unit" platform nil))
(for [os oses
platform platforms
browser ide-browsers]
(test-def os "ide" browser))
(test-def os "ide" platform browser))
(for [os oses
platform platforms
browser api-browsers
:when (not (or (and (= "ubuntu" os) (some #{browser} ["edge" "safari"]))
(and (= "windows" os) (= "safari" browser))))]
(test-def os "api" browser)))
(test-def os "api" platform browser)))
(sort-by :desc)
(into []))))

Expand All @@ -57,62 +62,88 @@
(Thread/sleep 500)
(recur))))))))

(def args-usage "Valid args:
(api|ide) [--browser=<edge|safari|firefox|chrome>]... [--launch-virtual-display]
(unit|all) [--launch-virtual-display]
(def valid-browsers ["chrome" "firefox" "edge" "safari"])
(def valid-platforms ["jvm" "bb"])

(defn valid-opts [opts]
(format "<%s>" (string/join "|" opts)))

(def args-usage (-> "Valid args:
(api|ide) [--browser=BROWSER]... [--launch-virtual-display] [--platform=PLATFORM]
(unit|all) [--launch-virtual-display] [--platform=PLATFORM]
matrix-for-ci [--format=json]
--help
Commands:
unit Run only unit tests
api Run only api tests, optionally specifying browsers to override defaults
ide Run only ide tests, optionally specifying browsers to override defaults
unit Run unit tests
api Run api tests
ide Run ide tests
all Run all tests using browser defaults
matrix-for-ci Return text matrix for GitHub Actions
Options:
--launch-virtual-display Launch a virtual display for browsers (use on linux only)
--browser=BROWSER {{valid-browsers}} overrides defaults
--platform=PLATFORM {{valid-platforms}} [default: jvm]
--launch-virtual-display Launch a virtual display for browsers
--help Show this help
Notes:
- ide tests default to firefox and chrome only.
- api tests default browsers based on OS on which they are run.
- launching a virtual display is necessary for GitHub Actions but not so for CircleCI")
- launching a virtual display is necessary for GitHub Actions but not for CircleCI"
(string/replace "{{valid-browsers}}" (valid-opts valid-browsers))
(string/replace "{{valid-platforms}}" (valid-opts valid-platforms))))

(defn -main [& args]
(when-let [opts (main/doc-arg-opt args-usage args)]
(cond
(get opts "matrix-for-ci")
(if (= "json" (get opts "--format"))
(status/line :detail (-> (github-actions-matrix)
(json/generate-string #_{:pretty true})))
(status/line :detail (->> (github-actions-matrix)
(doric/table [:os :cmd :desc]))))
(let [browsers (->> (get opts "--browser") (keep identity))
platform (get opts "--platform")]
(when (or (not-every? (set valid-browsers) browsers)
(and platform (not (some #{platform} valid-platforms))))
(status/die 1 args-usage))
(cond
(get opts "matrix-for-ci")
(if (= "json" (get opts "--format"))
(status/line :detail (-> (github-actions-matrix)
(json/generate-string #_{:pretty true})))
(status/line :detail (->> (github-actions-matrix)
(doric/table [:os :cmd :desc]))))

:else
(let [clojure-args (cond
(get opts "api") "-M:test --namespace etaoin.api-test"
(get opts "ide") "-M:test --namespace etaoin.ide-test"
(get opts "unit") "-M:test --namespace-regex '.*unit.*-test$'"
:else "-M:test")
browsers (->> (get opts "--browser") (keep identity))
env (cond-> {}
(seq browsers)
(assoc (if (get opts "api")
"ETAOIN_TEST_DRIVERS"
"ETAOIN_IDE_TEST_DRIVERS")
(mapv keyword browsers))
:else
(let [env (cond-> {}
(seq browsers)
(assoc (if (get opts "api")
"ETAOIN_TEST_DRIVERS"
"ETAOIN_IDE_TEST_DRIVERS")
(mapv keyword browsers))

(get opts "--launch-virtual-display")
(assoc "DISPLAY" ":99.0"))
shell-opts (if (seq env)
{:extra-env env}
{})]
(when (get opts "--launch-virtual-display")
(status/line :head "Launching virtual display")
(launch-xvfb))
(status/line :head "Running tests")
(shell/clojure shell-opts clojure-args)))))
(get opts "--launch-virtual-display")
(assoc "DISPLAY" ":99.0"))
shell-opts (if (seq env)
{:extra-env env}
{})
test-id (cond
(get opts "api") "api"
(get opts "ide") "ide"
(get opts "unit") "unit"
:else "all")]
(when (get opts "--launch-virtual-display")
(status/line :head "Launching virtual display")
(launch-xvfb))
(status/line :head "Running %s tests on %s%s"
test-id
platform
(if (seq browsers)
(str " against browsers: " (string/join ", " browsers))
""))
(if (= "jvm" platform)
(shell/clojure shell-opts
(case test-id
"api" "-M:test --namespace etaoin.api-test"
"ide" "-M:test --namespace etaoin.ide-test"
"unit" "-M:test --namespace-regex '.*unit.*-test$'"
"all" "-M:test"))
(shell/command shell-opts "bb" "script/bb_test_runner.clj" test-id)))))))

(main/when-invoked-as-script
(apply -main *command-line-args*))
Expand Down
Loading

0 comments on commit d5f15b3

Please sign in to comment.