add more backchannel tests. add various test helper functions

This commit is contained in:
Gered 2016-05-12 16:44:40 -04:00
parent ae6fa268cc
commit b0463fbbd7
2 changed files with 172 additions and 17 deletions

View file

@ -1,4 +1,7 @@
(ns net.thegeez.browserchannel.common)
(ns net.thegeez.browserchannel.common
(:require
[clojure.string :as string]
[cheshire.core :as json]))
(defn ->queue
[& x]
@ -18,3 +21,31 @@
(= (get m k) v)))
(remove true?)
(empty?)))
;; each chunk of arrays that the server sends out looks like this:
;;
;; length_of_following_array\n
;; [[array_id, array],
;; [array_id, array],
;; [array_id, array]]
;;
;; there may be 1 or more arrays. this splits each chunk up based on
;; the "length_of_following_array\n" part, and returns all the actual
;; arrays of data as one vector (all chunks together)
(defn get-response-arrays
[body]
(if (string? body)
(as-> body x
(string/split x #"\d+\n")
(remove string/blank? x)
(mapv json/parse-string x))))
;; HACK: sleep for an arbitrary period that is based off me throwing in a
;; random "feels good" number in there... i think this says it all, really
(defn wait-for-agent-send-offs
[]
(Thread/sleep 500))
(defn wait-for-heartbeat-interval
[secs]
(Thread/sleep (+ 1000 (* 1000 secs))))

View file

@ -5,6 +5,7 @@
net.thegeez.browserchannel.server
net.thegeez.browserchannel.test-async-adapter)
(:require
[clojure.edn :as edn]
[clojure.string :as string]
[cheshire.core :as json]
[ring.util.response :as response]
@ -15,19 +16,13 @@
(reset! sessions {})
(f)
(doseq [[_ session-agent] @sessions]
(send-off session-agent close nil "reset-sessions-fixture")))
(send-off session-agent close nil "reset-sessions-fixture"))
;; send-off dispatches on another thread, so we need to wait a small bit
;; before returning (otherwise the next test might start while a previous
;; test's session is still closing)
(wait-for-agent-send-offs))
(use-fixtures :each async-output-fixture reset-sessions-fixture)
(defn parse-channel-response
[body]
(if-not (string/blank? body)
(let [[len arrays] (string/split body #"\n" 2)
arrays (if-not (string/blank? arrays)
(json/parse-string arrays)
arrays)]
[len arrays])
body))
(use-fixtures :each reset-sessions-fixture async-output-fixture)
(defn app
[request & [options]]
@ -51,13 +46,142 @@
"zx" (random-string)
"t" 1}))
options)]
(wait-for-agent-send-offs)
(is (= 200 (:status resp)))
(is (contains-all-of? (:headers resp) (:headers options)))
(let [[len arrays] (parse-channel-response (:body resp))
[[id [c session-id host-prefix version]]] arrays]
(is (= "57" len))
(let [arrays (get-response-arrays (:body resp))
[[id [c session-id host-prefix version]]] (first arrays)]
(is (= "c" c))
(is (and (string? session-id)
(not (string/blank? session-id))))
(is (nil? host-prefix))
(is (= 8 version)))))
(is (= 8 version))
(is (get @sessions session-id))
(is (connected? session-id)))))
(deftest backchannel-request-with-no-session-test
(let [resp (app (-> (mock/request
:get "/channel/bind")
(mock/query-string
{"VER" 8
"RID" "rpc"
"CVER" 8
"CI" 0
"AID" 0
"TYPE" "xmlhttp"
"zx" (random-string)
"t" 1})))]
(is (= 400 (:status resp)))
(is (empty? @sessions))))
(deftest backchannel-request-with-invalid-sid-test
(let [resp (app (-> (mock/request
:get "/channel/bind")
(mock/query-string
{"VER" 8
"RID" "rpc"
"SID" "foobar"
"CVER" 8
"CI" 0
"AID" 0
"TYPE" "xmlhttp"
"zx" (random-string)
"t" 1})))]
(is (= 400 (:status resp)))
(is (empty? @sessions))))
(defn ->new-session-request
[]
(-> (mock/request
:post "/channel/bind")
(mock/query-string
{"VER" 8
"RID" 1
"CVER" 8
"zx" (random-string)
"t" 1})))
(defn get-session-id
[new-session-response]
(is (= 200 (:status new-session-response)))
(let [arrays (get-response-arrays (:body new-session-response))
[[_ [c session-id _ _]]] (first arrays)]
(is (= "c" c))
(is (and (string? session-id)
(not (string/blank? session-id))))
session-id))
(deftest backchannel-request-test
(let [options (update-in default-options [:headers] dissoc "Content-Type")
create-resp (app (->new-session-request) options)
session-id (get-session-id create-resp)
back-resp (app (-> (mock/request
:get "/channel/bind")
(mock/query-string
{"VER" 8
"RID" "rpc"
"SID" session-id
"CVER" 8
"CI" 0
"AID" 0
"TYPE" "xmlhttp"
"zx" (random-string)
"t" 1})))
async-resp @async-output]
(wait-for-agent-send-offs)
(let [status (get-status session-id)]
(is (= 200 (:status back-resp)))
(is (= 200 (:status async-resp)))
(is (not (:closed? async-resp)))
(is (contains-all-of? (:headers async-resp) (:headers options)))
(is (:connected? status))
(is (:has-back-channel? status)))))
(defn ->new-backchannel-request
[session-id]
(-> (mock/request
:get "/channel/bind")
(mock/query-string
{"VER" 8
"RID" "rpc"
"SID" session-id
"CVER" 8
"CI" 0
"AID" 0
"TYPE" "xmlhttp"
"zx" (random-string)
"t" 1})))
(deftest backchannel-request-send-data-to-client-test
(let [options (update-in default-options [:headers] dissoc "Content-Type")
create-resp (app (->new-session-request) options)
session-id (get-session-id create-resp)
back-resp (app (->new-backchannel-request session-id))]
(send-data session-id {:foo "bar"})
(wait-for-agent-send-offs)
(let [async-resp @async-output
arrays (get-response-arrays (:body async-resp))]
(is (= 200 (:status back-resp)))
(is (= 200 (:status async-resp)))
(is (not (:closed? async-resp)))
(is (contains-all-of? (:headers async-resp) (:headers options)))
(is (= (-> arrays ffirst second (get "__edn") (edn/read-string))
{:foo "bar"})))))
(deftest backchannel-request-heartbeat-test
(let [options (-> default-options
(update-in [:headers] dissoc "Content-Type")
; shortened heartbeat interval for the purposes of this test
(assoc :keep-alive-interval 2))
create-resp (app (->new-session-request) options)
session-id (get-session-id create-resp)
back-resp (app (->new-backchannel-request session-id))]
(wait-for-heartbeat-interval (:keep-alive-interval options))
(let [async-resp @async-output
arrays (get-response-arrays (:body async-resp))]
(is (= 200 (:status back-resp)))
(is (= 200 (:status async-resp)))
(is (not (:closed? async-resp)))
(is (contains-all-of? (:headers async-resp) (:headers options)))
(is (= (-> arrays ffirst second)
["noop"])))))