1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134
|
(ns puppetlabs.trapperkeeper.config-test
(:import (java.io FileNotFoundException))
(:require [clojure.test :refer :all]
[puppetlabs.trapperkeeper.testutils.bootstrap :refer [bootstrap-services-with-cli-data with-app-with-cli-data]]
[puppetlabs.trapperkeeper.app :refer [get-service]]
[puppetlabs.trapperkeeper.services :refer [defservice]]
[puppetlabs.trapperkeeper.config :refer [load-config]]
[schema.test :as schema-test]))
(use-fixtures :once schema-test/validate-schemas)
(defprotocol ConfigTestService
(test-fn [this ks])
(test-fn2 [this])
(get-in-config [this ks] [this ks default]))
(defservice test-service
ConfigTestService
[[:ConfigService get-in-config get-config]]
(test-fn [this ks] (get-in-config ks))
(test-fn2 [this] (get-config))
(get-in-config [this ks] (get-in-config ks))
(get-in-config [this ks default] (get-in-config ks default)))
(deftest test-config-service
(testing "Fails if config path doesn't exist"
(is (thrown-with-msg?
FileNotFoundException
#"Configuration path './foo/bar/baz' must exist and must be readable."
(bootstrap-services-with-cli-data [test-service] {:config "./foo/bar/baz"}))))
(testing "Can read values from a single .ini file"
(with-app-with-cli-data app [test-service] {:config "./dev-resources/config/file/config.ini"}
(let [test-svc (get-service app :ConfigTestService)]
(is (= (test-fn test-svc [:foo :setting1]) "foo1"))
(is (= (test-fn test-svc [:foo :setting2]) "foo2"))
(is (= (test-fn test-svc [:bar :setting1]) "bar1"))
(testing "`get-config` function"
(is (= (test-fn2 test-svc) {:foo {:setting2 "foo2"
:setting1 "foo1"}
:bar {:setting1 "bar1"}
:debug false}))))))
(testing "Can read values from a single .edn file"
(with-app-with-cli-data app [test-service] {:config "./dev-resources/config/file/config.edn"}
(let [test-svc (get-service app :ConfigTestService)]
(testing "`get-config` function"
(is (= {:debug false
:foo {:bar "barbar"
:baz "bazbaz"
:bam 42
:bap {:boozle "boozleboozle"
:bip [1 2 {:hi "there"} 3]}}}
(test-fn2 test-svc)))))))
(testing "Can parse comma-separated configs"
(with-app-with-cli-data app [test-service]
{:config (str "./dev-resources/config/mixeddir/baz.ini,"
"./dev-resources/config/mixeddir/bar.conf")}
(let [test-svc (get-service app :ConfigTestService)]
(is (= {:debug false, :baz {:setting1 "baz1", :setting2 "baz2"}
:bar {:junk "thingz"
:nesty {:mappy {:hi "there" :stuff [1 2 {:how "areyou"} 3]}}}}
(test-fn2 test-svc))))))
(testing "Conflicting comma-separated configs fail with error"
(is (thrown-with-msg?
IllegalArgumentException
#"Duplicate configuration entry: \[:foo :baz\]"
(bootstrap-services-with-cli-data [test-service]
{:config (str "./dev-resources/config/conflictdir1/config.ini,"
"./dev-resources/config/conflictdir1/config.conf")}))))
(testing "Error results when second of two comma-separated configs is malformed"
(is (thrown-with-msg?
FileNotFoundException
#"Configuration path 'blob.conf' must exist and must be readable."
(bootstrap-services-with-cli-data [test-service]
{:config (str "./dev-resources/config/conflictdir1/config.ini,"
"blob.conf")}))))
;; NOTE: other individual file formats are tested in `typesafe-test`
(testing "Can read values from a directory of .ini files"
(with-app-with-cli-data app [test-service] {:config "./dev-resources/config/inidir"}
(let [test-svc (get-service app :ConfigTestService)]
(is (= (test-fn test-svc [:baz :setting1]) "baz1"))
(is (= (test-fn test-svc [:baz :setting2]) "baz2"))
(is (= (test-fn test-svc [:bam :setting1]) "bam1")))))
(testing "A proper default value is returned if a key can't be found"
(with-app-with-cli-data app [test-service] {:config "./dev-resources/config/inidir"}
(let [test-svc (get-service app :ConfigTestService)]
(is (= (get-in-config test-svc [:doesnt :exist] "foo") "foo")))))
(testing "Can read values from a directory of mixed config files"
(with-app-with-cli-data app [test-service] {:config "./dev-resources/config/mixeddir"}
(let [test-svc (get-service app :ConfigTestService)
cfg (test-fn2 test-svc)]
(is (= {:debug false
:taco {:burrito [1, 2]
:nacho "cheese"}
:foo {:bar "barbar"
:baz "bazbaz"
:meaningoflife 42}
:baz {:setting1 "baz1"
:setting2 "baz2"}
:bar {:nesty {:mappy {:hi "there"
:stuff [1 2 {:how "areyou"} 3]}}
:junk "thingz"}}
cfg)))))
(testing "An error is thrown if duplicate settings exist"
(doseq [invalid-config-dir ["./dev-resources/config/conflictdir1"
"./dev-resources/config/conflictdir2"
"./dev-resources/config/conflictdir3"]]
(is (thrown-with-msg?
IllegalArgumentException
#"Duplicate configuration entry: \[:foo :baz\]"
(bootstrap-services-with-cli-data [test-service] {:config invalid-config-dir})))))
(testing "Can call load-config directly"
(is (= {:taco {:burrito [1, 2]
:nacho "cheese"}
:foo {:bar "barbar"
:baz "bazbaz"
:meaningoflife 42}
:baz {:setting1 "baz1"
:setting2 "baz2"}
:bar {:nesty {:mappy {:hi "there"
:stuff [1 2 {:how "areyou"} 3]}}
:junk "thingz"}}
(load-config "./dev-resources/config/mixeddir")))))
|