From 6616d1d4527d4c49232ab23d60c9489417b02d6b Mon Sep 17 00:00:00 2001 From: Gijs Stuurman Date: Mon, 9 Jul 2012 16:57:47 +0200 Subject: [PATCH] add test project --- test/.gitignore | 11 +++++++ test/README.md | 24 ++++++++++++++ test/project.clj | 3 ++ test/src/test/actors.clj | 67 ++++++++++++++++++++++++++++++++++++++++ test/src/test/core.clj | 46 +++++++++++++++++++++++++++ 5 files changed, 151 insertions(+) create mode 100644 test/.gitignore create mode 100644 test/README.md create mode 100644 test/project.clj create mode 100644 test/src/test/actors.clj create mode 100644 test/src/test/core.clj diff --git a/test/.gitignore b/test/.gitignore new file mode 100644 index 0000000..8236a2e --- /dev/null +++ b/test/.gitignore @@ -0,0 +1,11 @@ +/target +/lib +/classes +/checkouts +pom.xml +*.jar +*.class +.lein-deps-sum +.lein-failures +.lein-plugins +notes diff --git a/test/README.md b/test/README.md new file mode 100644 index 0000000..072cfd2 --- /dev/null +++ b/test/README.md @@ -0,0 +1,24 @@ +# test + +Beginnings of a test suite for [clj-browserchannel][1]. Uses the +[clj-webdriver][2] Selenium wrapper to launch and interact with +browsers. Actors send messages through the demo chat application and +may introduce connection failures. The test checks whether all messages +were still received. + +[1]:https://github.com/thegeez/clj-browserchannel +[2]:https://github.com/semperos/clj-webdriver/ + +## About + +Written by: +Gijs Stuurman / [@thegeez][twt] / [Blog][blog] / [GitHub][github] + +[twt]: http://twitter.com/thegeez +[blog]: http://thegeez.github.com +[github]: https://github.com/thegeez + +### License + +Copyright (c) 2012 Gijs Stuurman and released under an MIT license. + diff --git a/test/project.clj b/test/project.clj new file mode 100644 index 0000000..f95ef8c --- /dev/null +++ b/test/project.clj @@ -0,0 +1,3 @@ +(defproject test "0.0.1-SNAPSHOT" + :dependencies [[org.clojure/clojure "1.4.0"] + [clj-webdriver "0.6.0-alpha8"]]) diff --git a/test/src/test/actors.clj b/test/src/test/actors.clj new file mode 100644 index 0000000..03bda78 --- /dev/null +++ b/test/src/test/actors.clj @@ -0,0 +1,67 @@ +(ns test.actors + (require [clj-webdriver.core :as w] + [clj-webdriver.wait :as wait])) + +(defmulti web-action (fn [driver action] + (:type action))) + +(defmethod web-action :default [& args] nil) + +(defmethod web-action :say [driver {:keys [msg]}] + (w/input-text (w/find-element driver {:id "msg-input"}) msg) + (w/click (w/find-element driver {:id "send-button"}))) + +(defmethod web-action :kill-get [driver action] + (w/execute-script driver "try{ bc.core.channel.backChannelRequest_.xmlHttp_.xhr_.abort(); } catch (err) {return true;}; return true;" )) + +(defmethod web-action :wait [driver {:keys [time]}] + ;; uhm ja, want to use Thread/sleep but this is handled by the driver + (try (wait/wait-until driver (constantly false) time time) + (catch Exception e ;; should be TimeOutException + true))) + +(defn play-actors [actors] + (let [agents (map (fn [act] + (-> act + (assoc :to-do (:actions act)) + (assoc :driver (w/new-driver (select-keys [:browser] act))) + agent)) actors) + ;; broken down clojure.core/await, because we can't know when + ;; all the sends will be done as they are not all done in this thread + done-talking-latch (java.util.concurrent.CountDownLatch. (count actors))] + ;; launch web-drivers + (doseq [ag agents] + (send ag (fn [{:keys [driver url] :as a}] + (w/to driver url) + a))) + ;; can't use await here, the send are fired from separate threads + ;;(apply await actors) + (println "All launched") + (doseq [ag agents] + (send ag (fn send-msg [a] + (let [{:keys [driver name to-do]} a] + (if-let [action (first to-do)] + (do + (web-action driver action) + (send *agent* send-msg)) + (.countDown done-talking-latch))) + (update-in a [:to-do] rest))) + ) + (.await done-talking-latch) + (println "All done talking") + (Thread/sleep 10000) + (doseq [ag agents] + (send ag (fn [a] + (let [{:keys [driver name]} a] + ;;(w/execute-script driver "alert(\"LOLOLO\");") + (let [seen-msgs (doall (map w/text (w/find-elements driver [{:id "room"} {:tag :div}])))] + (assoc a :seen-msgs seen-msgs)))))) + (apply await agents) + (Thread/sleep 10000) + (doseq [ag agents] + (send ag (fn [a] + (let [{:keys [driver name]} a] + (w/quit driver))))) + (println "All quit") + (doall (map #(dissoc (deref %) :to-do :driver) agents)))) + diff --git a/test/src/test/core.clj b/test/src/test/core.clj new file mode 100644 index 0000000..7ba2bd3 --- /dev/null +++ b/test/src/test/core.clj @@ -0,0 +1,46 @@ +(ns test.core + (require [test.actors :as actors])) + +(def url "http://localhost:8080/index-dev.html") + +(defn -main [& args] + (let [mario {:name "MARIO" + :actions (for [i (range 10)] + {:type :say :msg (str "MARIO says Hello world! " i)}) + :url url + :browser :firefox} + luigi {:name "LUIGI" + :actions (concat (interleave (for [i (range 5)] + {:type :say :msg (str "LUIGI says Hello world! " i)}) + (repeat {:type :kill-get})) + [{:type :kill-get}] + [{:type :wait :time 30000}] + (interleave (for [i (range 5 10)] + {:type :say :msg (str "LUIGI says Hello world! " i)}) + (repeat {:type :kill-get})) + ) + :url url + :browser :firefox} + actors [mario luigi] + done-actors (actors/play-actors actors)] + (doseq [act1 done-actors + act2 done-actors + :when (not= act1 act2)] + ;; check if every msgs for act1 sort of appears in what act2 + ;; recv and is in the correct order + (loop [act1-said (->> act1 + :actions + (filter (comp #{:say} :type)) + (map :msg)) + act2-recv (:seen-msgs act2)] + (let [a1 (first act1-said)] + (if (nil? a1) + (println "All messages accounted for" (:name act1) " to " (:name act2)) + (let [[match & others] (drop-while #(not (re-find (re-pattern a1) %)) act2-recv)] + (if match + (do #_(println "act1 said: " a1 " recv by act2 as: " match) + (recur (rest act1-said) others)) + (println "Msg from act1 " (:name act1) " not recv by act2" (:name act2) a1))))))))) + + +