 ;; limitations under the License.
 ;;
 (ns waiter.websocket-integration-test
-  (:require [clj-time.core :as t]
+  (:require [clj-time.coerce :as tc]
+            [clj-time.core :as t]
             [clojure.core.async :as async]
             [clojure.data.json :as json]
             [clojure.string :as str]

          inter-request-interval-ms (+ metrics-sync-interval-ms 1000)
          auth-cookie-value (auth-cookie waiter-url)
          waiter-headers (assoc (kitchen-request-headers)
                           :x-waiter-metric-group "waiter_ws_test"
                           :x-waiter-name (rand-name))
          _ (make-kitchen-request waiter-url waiter-headers :method :get)

                               (async/close! out)
                               (deliver response-promise :done)))
                           {:middleware (fn [_ ^UpgradeRequest request]
                                          (websocket/add-headers-to-upgrade-request! request request-headers)
                                          (add-auth-cookie request auth-cookie-value))})
              [close-code error] (connection->ctrl-data connection)]
          (is (= :qbits.jet.websocket/close close-code))
          (is (= websocket-1000-normal error))
          (is (= :done (deref response-promise (* 2 num-iterations inter-request-interval-ms) :timed-out)))
          (let [min-metrics-sync-interval-ms 1000] ;; avoid sleeping for toon short a duration
            (-> metrics-sync-interval-ms (* 3) (max min-metrics-sync-interval-ms) (Thread/sleep)))
          (let [connection-duration-ms (- @connect-end-time-ms-atom connect-start-time-ms)
                websocket-duration-ms (* num-iterations inter-request-interval-ms)
                minimum-last-request-time-duration-ms (+ connection-duration-ms websocket-duration-ms)
                minimum-last-request-time (t/plus first-request-time-header (t/millis minimum-last-request-time-duration-ms))
                service-last-request-time (service-id->last-request-time waiter-url service-id)
                assertion-message (str {:durations {:connection-duration-ms connection-duration-ms
                                                    :websocket-duration-ms websocket-duration-ms}
                                        :request-headers request-headers
                                        :service-id service-id
                                        :times {:minimum-last-request-time minimum-last-request-time
                                                :service-last-request-time service-last-request-time
                                                :ws-connect-end-time-ms (tc/from-long @connect-end-time-ms-atom)
                                                :ws-connect-start-time (tc/from-long connect-start-time-ms)}})]
            (is (some? service-last-request-time) assertion-message)
            (is (pos? (.getMillis service-last-request-time)) assertion-message)
            (is (t/after? service-last-request-time minimum-last-request-time) assertion-message)))))))

(deftest ^:parallel ^:integration-fast ^:explicit test-request-socket-timeout
  (testing-using-waiter-url
