                (and (not= status exp-status)
                     (str "status " status " not equal to expected " exp-status))
                (some (fn [[header value]]
-                        (if (not= value (headers header))
-                          (str "header " header " was " (headers header) " expected " value))) exp-headers)
-               (if-let [diff (and (not-empty exp-body) (first (data/diff exp-body body*)))]
+                       (if (not= value (headers header))
+                         (str "header " header " was " (headers header) " expected " value))) exp-headers)
+               (if-let [diff (and (not-empty exp-body) (first (diff* exp-body body*)))]
                  (->> diff json/generate-string (str "expected body missing:" ))))]
     (if error [error resp])))
 
 (defn test-all [suites]
-  (for [{:keys[suite tests]} suites
-        :let [results (doall (map #(future [(% :test)
-                                            (verify-response (mk-request %) %)]) tests))]]
-    {:suite suite
-     :results results
-     :total (count results)
-     :failures (count (filter #(second @%) results))}))
+  (-> (for [{:keys[suite tests]} suites
+         :let [results (doall (map #(future [(% :test)
+                                             (verify-response (mk-request %) %)]) tests))]]
+     {:suite suite
+      :results results
+      :count (count results)
+      :failures (count (filter #(second @%) results))})
+      (#(hash-map :suites %
+                  :total (reduce + (map :count %))
+                  :total-failures (reduce + (map :failures %))))))
 
-(defn print-test-results [suites]
-  (let [total (reduce + (map :total suites))
-        fail-count (reduce + (map :failures suites))]
-    (println "=============================================================")
-    (println "Test cases:" total ", failed:" fail-count)
-    (doseq [{:keys [suite results]} suites]
-      (println suite)
-      (doseq [result results :let [[test result] @result]][]
-        (print (if result "\u001B[31m [x] " "\u001B[32m [v] "))
-        (println test "\t" (or (first result) :OK) "\u001B[0m")))))
+(defn print-test-results [{:keys[suites total total-failures]}]
+  (flush)
+  (println "=============================================================")
+  (println "Test cases:" total ", failed:" total-failures)
+  (doseq [{:keys [suite results]} suites]
+    (println suite)
+    (doseq [result results :let [[test result] @result]][]
+           (print (if result "\u001B[31m [x] " "\u001B[32m [v] "))
+           (println test "\t" (or (first result) :OK) "\u001B[0m"))))
 
 (defn -main
   "Give me a CSV with API rest cases and I will verify them"
   [& args]
-  (let [opts (apply hash-map (map-indexed #(if (even? %1) (subs %2 1) %2) (rest args)))]
-    (println "running with arguments:" opts)
+  (let [opts (apply hash-map (map-indexed #(if (even? %1) (subs %2 1) %2) (rest args)))
+        _ (println "running with arguments:" opts)
+        results (test-all (load-tests-from (first args) opts))]
     (try
-      (print-test-results (test-all (tests-from (first args) opts)))
+      (print-test-results results)
+      (System/exit (:total-failures results))
       (finally
         (shutdown-agents)))))

   (if-not (str/blank? s)
     (->> (str/split s #"\s*,\s*") (map #(let [[k v] (str/split % sep 2)]
                                           [k (replace-opts v opts)])) (into {})))))

(defn tests-from [file opts]
  (with-open [in-file (io/reader file)]
    (reduce
     (fn[suites [suite test url verb headers payload params exp-status exp-body exp-headers]]
       (let [test-case {:test test :url (replace-opts url opts) :verb verb
                        :headers (str->map headers #":" opts)
                        :params (str->map params #"\s*=\s*" opts)

            [clj-http.client :as client]
            [clojure
             [data :as data]
             [string :as str]
             [test :refer [deftest is run-tests testing]]]
            [clojure.data.csv :as csv]
            [clojure.java.io :as io]
            [clojure.tools.logging :as log])
