Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enable all tests on MS-Windows and run them during CI #62

Merged
merged 2 commits into from
Oct 10, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions appveyor.yml
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ build_script:

call script/compile.bat

test_script:
- cmd: >-
call script/exe_test.bat

artifacts:
- path: deps.clj-*-windows-amd64.zip
name: deps.exe
30 changes: 17 additions & 13 deletions src/borkdude/deps.clj
Original file line number Diff line number Diff line change
Expand Up @@ -430,21 +430,25 @@ For more info, see:

(def java-exe (if windows? "java.exe" "java"))

(defn- get-java-cmd
"Returns the path to java executable to invoke commands on."
[]
(or (*getenv-fn* "JAVA_CMD")
(let [java-cmd (which java-exe)]
(if (str/blank? java-cmd)
(let [java-home (*getenv-fn* "JAVA_HOME")]
(if-not (str/blank? java-home)
(let [f (io/file java-home "bin" java-exe)]
(if (and (.exists f)
(.canExecute f))
(.getCanonicalPath f)
(throw (Exception. "Couldn't find 'java'. Please set JAVA_HOME."))))
(throw (Exception. "Couldn't find 'java'. Please set JAVA_HOME."))))
java-cmd))))

(defn -main [& command-line-args]
(let [opts (parse-args command-line-args)
java-cmd
(or (*getenv-fn* "JAVA_CMD")
(let [java-cmd (which java-exe)]
(if (str/blank? java-cmd)
(let [java-home (*getenv-fn* "JAVA_HOME")]
(if-not (str/blank? java-home)
(let [f (io/file java-home "bin" java-exe)]
(if (and (.exists f)
(.canExecute f))
(.getCanonicalPath f)
(throw (Exception. "Couldn't find 'java'. Please set JAVA_HOME."))))
(throw (Exception. "Couldn't find 'java'. Please set JAVA_HOME."))))
java-cmd)))
java-cmd (get-java-cmd)
env-tools-dir (or
;; legacy name
(*getenv-fn* "CLOJURE_TOOLS_DIR")
Expand Down
140 changes: 93 additions & 47 deletions test/borkdude/deps_test.clj
Original file line number Diff line number Diff line change
@@ -1,24 +1,36 @@
(ns borkdude.deps-test
(:require
[babashka.fs :as fs]
[babashka.process :refer [process]]
[babashka.process :refer [check process]]
[borkdude.deps :as deps]
[clojure.edn :as edn]
[clojure.java.io :as io]
[clojure.string :as str]
[clojure.test :as t :refer [deftest is testing]]))

(def invoke-deps-cmd
"Returns the command to invoke `borkdude.deps` on the current system,
based on the value of env variable `DEPS_CLJ_TEST_ENV`."
(case (System/getenv "DEPS_CLJ_TEST_ENV")
(defn invoke-deps-cmd
"Returns the command string that can be used to invoke the
`borkdude.deps/-main` fn with the given ARGS from the command line.

The tool to use for invoking the fn is selected based on the value
of the `DEPS_CLJ_TEST_ENV` env variable, which can be one
of (defaults to `clojure`):

`babashka`: Use `bb`.
`clojure`: Use the `clojure` cli tool.
`native`: Use the `deps` native binary."
[& args]

(case (or (System/getenv "DEPS_CLJ_TEST_ENV") "clojure")
"babashka" (let [classpath (str/join deps/path-separator ["src" "test" "resources"])]
(str "bb -cp " classpath " -m borkdude.deps "))
"native" "./deps "
(cond->>
"clojure -M -m borkdude.deps "
deps/windows?
(str "powershell -NoProfile -Command "))))
(apply str "bb -cp " classpath " -m borkdude.deps " args))
"native" (apply str "./deps " args)
"clojure" (cond->>
(apply str "clojure -M -m borkdude.deps " args)
deps/windows?
;; the `exit` command is a workaround for
;; https://ask.clojure.org/index.php/12290/clojuretools-commands-windows-properly-exit-code-failure
(format "powershell -NoProfile -Command %s; exit $LASTEXITCODE"))))

(deftest parse-args-test
(is (= {:mode :repl, :jvm-opts ["-Dfoo=bar" "-Dbaz=quuz"]}
Expand Down Expand Up @@ -51,27 +63,62 @@
(is (do (deps/-main "-X" "clojure.core/prn" ":foo" "1")
::success)))

(when (not deps/windows?)
(deftest whitespace-test
(testing "jvm opts"
(let [temp-dir (fs/create-temp-dir)
temp-file (fs/create-file (fs/path temp-dir "temp.txt"))
temp-file-path (str temp-file)
_ (deps/-main "-Sdeps" "{:aliases {:space {:jvm-opts [\"-Dfoo=\\\"foo bar\\\"\"]}}}" "-M:space" "-e"
(format "(spit \"%s\" (System/getProperty \"foo\"))"
temp-file-path))
out (slurp temp-file-path)]
(is (= "\"foo bar\"" out))))
(testing "main opts"
(let [temp-dir (fs/create-temp-dir)
temp-file (fs/create-file (fs/path temp-dir "temp.txt"))
temp-file-path (str temp-file)
_ (deps/-main "-Sdeps"
(format "{:aliases {:space {:main-opts [\"-e\" \"(spit \\\"%s\\\" (+ 1 2 3))\"]}}}"
temp-file-path)
"-M:space")
out (slurp temp-file-path)]
(is (= "6" out))))))
(defmacro deps-main-throw
"Same as `babashka.deps/-main`, but throws an exception on error
instead of exiting the process.

The exception's additional data map keys are:

:exit-code The process's exit code.

:msg The process's error messsage (if any)."
[& command-line-args]
`(binding [deps/*exit-fn*
(fn
([exit-code#] (when-not (= exit-code# 0)
(throw (ex-info (str ::deps-main-throw) {:exit-code exit-code#}))))
([exit-code# msg#] (throw (ex-info (str ::deps-main-throw)
{:exit-code exit-code# :msg msg#}))))]
(deps/-main ~@command-line-args)))

(defn java-major-version-get
"Returns the major version number of the java executable used to run
the java command at run time."
[]
(-> (process [(#'deps/get-java-cmd) "-version"] {:err :string})
check
:err
(->> (re-find #"version \"(\d+)"))
second
Integer/parseInt))

(deftest whitespace-test
(testing "jvm opts"
(let [temp-dir (fs/create-temp-dir)
temp-file (fs/create-file (fs/path temp-dir "temp.txt"))
temp-file-path (str temp-file)
_ (deps-main-throw "-Sdeps" "{:aliases {:space {:jvm-opts [\"-Dfoo=foo bar\"]}}}" "-M:space" "-e"
(format "(spit \"%s\" (System/getProperty \"foo\"))"
(.toURI (fs/file temp-file-path))))
out (slurp temp-file-path)]
(is (= "foo bar" out))))
(testing "main opts"
(let [java-major-version (java-major-version-get)
temp-dir (fs/create-temp-dir)
temp-file (fs/create-file (fs/path temp-dir "temp.txt"))
temp-file-path (str temp-file)
_ (deps-main-throw "-Sdeps"
(format
(if-not deps/windows?
"{:aliases {:space {:main-opts [\"-e\" \"(spit \\\"%s\\\" (+ 1 2 3))\"]}}}"

(if (< java-major-version 17)
"{:aliases {:space {:main-opts [\"-e\" \"(spit \\\\\"%s\\\\\" (+ 1 2 3))\"]}}}"
"{:aliases {:space {:main-opts [\"-e\" \"(spit \\\"\\\\\"%s\\\"\\\\\" (+ 1 2 3))\"]}}}"))
(.toURI (fs/file temp-file-path)))
"-M:space")
out (slurp temp-file-path)]
(is (= "6" out)))))

(deftest jvm-proxy-settings-test
(is (= {:host "aHost" :port "1234"} (deps/parse-proxy-info "http://aHost:1234")))
Expand All @@ -80,22 +127,21 @@
(is (= {:host "aHost" :port "1234"} (deps/parse-proxy-info "https://user:pw@aHost:1234")))
(is (nil? (deps/parse-proxy-info "http://aHost:abc"))))

(when (not deps/windows?)
(deftest jvm-opts-test
(let [temp-dir (fs/create-temp-dir)
temp-file (fs/create-file (fs/path temp-dir "temp.txt"))
temp-file-path (str temp-file)]
(deps/-main "-J-Dfoo=bar" "-J-Dbaz=quux"
"-M" "-e" (format "
(deftest jvm-opts-test
(let [temp-dir (fs/create-temp-dir)
temp-file (fs/create-file (fs/path temp-dir "temp.txt"))
temp-file-path (str temp-file)]
(deps-main-throw "-J-Dfoo=bar" "-J-Dbaz=quux"
"-M" "-e" (format "
(spit \"%s\" (pr-str [(System/getProperty \"foo\") (System/getProperty \"baz\")]))"
temp-file-path))
(is (= ["bar" "quux"] (edn/read-string (slurp temp-file-path)))))))
(.toURI (fs/file temp-file-path))))
(is (= ["bar" "quux"] (edn/read-string (slurp temp-file-path))))))

(deftest tools-dir-env-test
(fs/delete-tree "tools-dir")
(try
(let [[out err exit]
(-> (process (str invoke-deps-cmd "-Sdescribe")
(-> (process (invoke-deps-cmd "-Sdescribe")
{:out :string
:err :string
:extra-env {"DEPS_CLJ_TOOLS_VERSION" "1.10.3.899"
Expand All @@ -122,7 +168,7 @@
(let [{:keys [out exit]}
; use bogus deps-file to force using CLJ_CONFIG instead of current directory,
; meaning that the cache directory will be empty
(-> (process (str invoke-deps-cmd "-Sdeps-file force_clj_config/missing.edn " option)
(-> (process (invoke-deps-cmd "-Sdeps-file force_clj_config/missing.edn " option)
{:out :string
:err :string
:extra-env {"CLJ_CONFIG" "missing_config"}})
Expand All @@ -139,9 +185,9 @@
(deps/-main "-Ttools" "list"))

(defmacro get-shell-command-args
"Executes BODY with the given ENV'ironment variables added to the
`babashka.deps` scope, presumbably to indirectly invoke
`babashka.deps/shell-command` whose invocation ARGS captures and
"Executes BODY with the given extra ENV-VARS environment variables
added to the `babashka.deps` scope, presumbably to indirectly invoke
`babashka.deps/shell-command` whose invocation ARGS it captures and
returns with this call.

It overrides `baabashka.deps/*exit-fn*` so as to never exit the
Expand All @@ -166,7 +212,7 @@
([exit-code# msg#] (throw (ex-info "mock-shell-failed"
{:exit-code exit-code# :msg msg#}))))
deps/*getenv-fn* #(or (get ~env-vars %)
(System/getenv %))]
(System/getenv %))]
(with-redefs [deps/shell-command sh-mock#]
~@body
(or (deref ret*# 500 false) (ex-info "No shell-command invoked in body." {:body ~body-str})))))))
Expand Down