/test/lobos/test.clj

http://github.com/budu/lobos · Clojure · 152 lines · 116 code · 26 blank · 10 comment · 6 complexity · 9fb65bd63795ed270ad421e84aa130f6 MD5 · raw file

  1. ;; Copyright (c) Nicolas Buduroi. All rights reserved.
  2. ;; The use and distribution terms for this software are covered by the
  3. ;; Eclipse Public License 1.0 which can be found in the file
  4. ;; epl-v10.html at the root of this distribution. By using this software
  5. ;; in any fashion, you are agreeing to be bound by the terms of this
  6. ;; license.
  7. ;; You must not remove this notice, or any other, from this software.
  8. (ns lobos.test
  9. (:refer-clojure :exclude [alter defonce drop])
  10. (:use clojure.test
  11. (clojure.java [io :only [delete-file file]])
  12. (lobos analyzer connectivity core utils)
  13. (lobos [schema :only [schema]]))
  14. (:import (java.lang UnsupportedOperationException)))
  15. ;;;; DB connection specifications
  16. (def h2-spec
  17. {:classname "org.h2.Driver"
  18. :subprotocol "h2"
  19. :subname "./lobos.h2"
  20. :unsafe true})
  21. (def mysql-spec
  22. {:classname "com.mysql.jdbc.Driver"
  23. :subprotocol "mysql"
  24. :user "lobos"
  25. :password "lobos"
  26. :subname "//localhost:3306/"
  27. :unsafe true})
  28. (def postgresql-spec
  29. {:classname "org.postgresql.Driver"
  30. :subprotocol "postgresql"
  31. :user "lobos"
  32. :password "lobos"
  33. :subname "//localhost:5432/lobos"
  34. :unsafe true})
  35. (def sqlite-spec
  36. {:classname "org.sqlite.JDBC"
  37. :subprotocol "sqlite"
  38. :subname "./lobos.sqlite3"
  39. :create true
  40. :unsafe true})
  41. (def sqlserver-spec
  42. {:classname "com.microsoft.sqlserver.jdbc.SQLServerDriver"
  43. :subprotocol "sqlserver"
  44. :user "lobos"
  45. :password "lobos"
  46. :subname "//localhost:1433"
  47. :databaseName "lobos"
  48. :unsafe true})
  49. (def db-specs [h2-spec
  50. mysql-spec
  51. postgresql-spec
  52. sqlite-spec
  53. sqlserver-spec])
  54. (defn driver-available?
  55. [{:keys [classname]}]
  56. (try
  57. (clojure.lang.RT/classForName classname)
  58. true
  59. (catch Exception e false)))
  60. (def available-specs (filter driver-available? db-specs))
  61. (defn available-global-cnx []
  62. (keys @global-connections))
  63. (defn test-db-name [db-spec]
  64. (keyword (:subprotocol db-spec)))
  65. (def ^{:dynamic true} *db* nil)
  66. ;;;; Helpers
  67. (defn first-non-runtime-cause [e]
  68. (if (isa? (type e) RuntimeException)
  69. (if-let [c (.getCause e)]
  70. (first-non-runtime-cause c)
  71. e)
  72. e))
  73. (defmacro when-supported [action & body]
  74. `(try ~action
  75. ~@body
  76. (catch Exception e#
  77. (when-not (isa? (type (first-non-runtime-cause e#))
  78. UnsupportedOperationException)
  79. (throw e#)))))
  80. (defmacro def-db-test [name & body]
  81. `(do ~@(for [db-spec available-specs]
  82. (let [db (test-db-name db-spec)]
  83. `(deftest ~(symbol (str name "-" (:subprotocol db-spec)))
  84. (when ((set (available-global-cnx)) ~db)
  85. (binding [*db* ~db]
  86. ~@body)))))))
  87. (defmacro with-schema [[var-name sname] & body]
  88. `(let [db-spec# (get-db-spec *db*)]
  89. (try
  90. (let [~var-name (schema ~sname {:db-spec db-spec#})]
  91. (create db-spec# ~var-name)
  92. ~@body)
  93. (finally (try (drop db-spec# (schema ~sname) :cascade)
  94. (catch Exception _#))))))
  95. (defmacro inspect-schema [& keys]
  96. `(-> (analyze-schema *db* :lobos) ~@keys))
  97. (defn open-global-connections []
  98. (doseq [db-spec available-specs]
  99. (try
  100. (open-global (test-db-name db-spec) db-spec)
  101. (catch Exception _
  102. (println "WARNING: Failed to connect to" (:subprotocol db-spec))))))
  103. (defn close-global-connections []
  104. (doseq [db (available-global-cnx)]
  105. (close-global db)))
  106. ;;;; Fixtures
  107. (def tmp-files-ext '(db sqlite3))
  108. (defn remove-tmp-files []
  109. (let [current-dir (file-seq (file "."))
  110. p (str ".*\\." (apply join "|" tmp-files-ext))
  111. tmp? #(re-find (re-pattern p) (str %))]
  112. (doseq [tmp-file (filter tmp? current-dir)]
  113. (delete-file tmp-file true))))
  114. (defn remove-tmp-files-fixture [f]
  115. (remove-tmp-files)
  116. (f)
  117. (remove-tmp-files))
  118. (defn open-global-connections-fixture [f]
  119. (doseq [db-spec db-specs]
  120. (when-not (driver-available? db-spec)
  121. (println (format "WARNING: Driver for %s isn't available: %s missing"
  122. (:subprotocol db-spec)
  123. (:classname db-spec)))))
  124. (open-global-connections)
  125. (f)
  126. (close-global-connections))