diff --git a/src/etaoin/proc.clj b/src/etaoin/proc.clj index c598bd76..1f5986a0 100644 --- a/src/etaoin/proc.clj +++ b/src/etaoin/proc.clj @@ -1,24 +1,22 @@ (ns etaoin.proc (:require [clojure.java.io :as io] - [clojure.string :as str]) - (:import java.lang.IllegalThreadStateException - java.io.IOException)) + [clojure.string :as str])) (def windows? (str/starts-with? (System/getProperty "os.name") "Windows")) -(defn get-null-file ^java.io.File +(defn- get-null-file ^java.io.File [] (if windows? (io/file "NUL") (io/file "/dev/null"))) -(defn get-log-file ^java.io.File +(defn- get-log-file ^java.io.File [file-path] (if file-path (io/file file-path) (get-null-file))) -(defn java-params ^"[Ljava.lang.String;" [params] +(defn- java-params ^"[Ljava.lang.String;" [params] (->> params (map str) (into-array String))) @@ -44,27 +42,6 @@ Please ensure you have the driver installed and specify the path to it. For driver installation, check out the official readme file from Etaoin: %s" binary readme-link) {:args args} e))))))) -;; todo store those streams - -(defn alive? [^Process proc] - (.isAlive proc)) - -(defn exit-code [^Process proc] - (try - (.exitValue proc) - (catch IllegalThreadStateException _))) - (defn kill [^Process proc] - (.destroy proc)) - -;; todo refactor those - -(defn read-out [^Process proc] - (try - (-> proc .getInputStream slurp) - (catch IOException _))) - -(defn read-err [^Process proc] - (try - (-> proc .getErrorStream slurp) - (catch IOException _))) + (.destroy proc) + (.waitFor proc)) diff --git a/test/etaoin/proc_test.clj b/test/etaoin/proc_test.clj index 293d8980..34c2ba35 100644 --- a/test/etaoin/proc_test.clj +++ b/test/etaoin/proc_test.clj @@ -4,46 +4,61 @@ [clojure.test :refer :all] [etaoin.proc :as proc] [etaoin.test-report] + [clojure.pprint :as pprint] [clojure.string :as str])) (defn get-count-chromedriver-instances [] (if proc/windows? - (->> (sh "powershell" "-command" "(Get-Process chromedriver -ErrorAction SilentlyContinue).Path") - :out - str/split-lines - (remove #(str/includes? % "\\scoop\\shims\\")) ;; for the scoop users, exclude the shim process - (filter #(str/includes? % "chromedriver")) - count) + (let [instance-report (-> (sh "powershell" "-command" "(Get-Process chromedriver -ErrorAction SilentlyContinue).Path") + :out + str/split-lines)] + ;; more flakiness diagnosis + (println "windows chromedriver instance report:" instance-report) + (println "windows full list of running processes:") + ;; use Get-CimInstance, because Get-Process, does not have commandline available + (pprint/pprint (-> (sh "powershell" "-command" "Get-CimInstance Win32_Process | select name, commandline") + :out + str/split-lines)) + (->> instance-report + (remove #(str/includes? % "\\scoop\\shims\\")) ;; for the scoop users, exclude the shim process + (filter #(str/includes? % "chromedriver")) + count)) (->> (sh "sh" "-c" "ps aux") :out str/split-lines (filter #(str/includes? % "chromedriver")) count))) -(deftest test-prevent-process-fork - (testing "certain driver port" - (let [port 9999 - process (proc/run ["chromedriver" (format "--port=%d" port)]) - _ (wait-running {:port port :host "localhost"})] - (is (= 1 (get-count-chromedriver-instances))) - (is (thrown-with-msg? - clojure.lang.ExceptionInfo - #"already in use" - (chrome {:port port}))) - (proc/kill process))) - (testing "random driver port" - (let [port 9999 - process (proc/run ["chromedriver" (format "--port=%d" port)]) - _ (wait-running {:port port :host "localhost"})] - (with-chrome {:args ["--no-sandbox"]} driver - (is (= 2 (get-count-chromedriver-instances))) - (proc/kill process)))) - (testing "connect to driver" - (let [port 9999 - process (proc/run ["chromedriver" (format "--port=%d" port)]) - _ (wait-running {:port port :host "localhost"}) - driver (chrome {:host "localhost" :port port :args ["--no-sandbox"]})] - (is (= 1 (get-count-chromedriver-instances))) - (quit driver) - (proc/kill process)))) +(deftest test-process-forking-port-specified + (let [port 9997 + process (proc/run ["chromedriver" (format "--port=%d" port)]) + _ (wait-running {:port port :host "localhost"})] + (is (= 1 (get-count-chromedriver-instances))) + (is (thrown-with-msg? + clojure.lang.ExceptionInfo + #"already in use" + (chrome {:port port}))) + (proc/kill process))) + +(deftest test-process-forking-port-random + (let [port 9998 + process (proc/run ["chromedriver" (format "--port=%d" port)]) + _ (wait-running {:port port :host "localhost"})] + (with-chrome {:args ["--no-sandbox"]} driver + ;; added to diagnose flakyness on windows on CI + (println "automatically chosen port->" (:port driver)) + ;; added to diagnose flakyness on windows on CI + (wait-running driver) + (is (= 2 (get-count-chromedriver-instances)))) + (proc/kill process))) + +(deftest test-process-forking-connect-existing + (let [port 9999 + process (proc/run ["chromedriver" (format "--port=%d" port)]) + _ (wait-running {:port port :host "localhost"}) + driver (chrome {:host "localhost" :port port :args ["--no-sandbox"]})] + (wait-running driver) + (is (= 1 (get-count-chromedriver-instances))) + (quit driver) + (proc/kill process)))