(defn -main
"Handles command line arguments. Can either run a test, or a web server for
browsing results."
[& args]
(cli/run! (merge (cli/single-test-cmd {:test-fn etcd-test
:opt-spec cli-opts})
(cli/serve-cmd))
args)
如果我们再次通过lein run test -q ...运行我们的测试,我们将在我们的测试map中看到一个新的:quorum选项。
10:02:42.532 [main] INFO jepsen.cli - Test options:
{:concurrency 10,
:test-count 1,
:time-limit 30,
:quorum true,
...
(case (:f op)
:read (let [value (-> conn
(v/get k {:quorum? (:quorum test)})
parse-long)]
(assoc op :type :ok, :value (independent/tuple k value)))
让我们尝试携带-q和不携带 -q 参数执行lein run,然后看看能否再次观察到脏读bug。
$ lein run test -q ...
...
$ lein run test ...
...
clojure.lang.ExceptionInfo: throw+: {:errorCode 209, :message "Invalid field", :cause "invalid value for \"quorum\"", :index 0, :status 400}
...
(defn etcd-test
"Given an options map from the command line runner (e.g. :nodes, :ssh,
:concurrency ...), constructs a test map. Special options:
:quorum Whether to use quorum reads"
[opts]
(let [quorum (boolean (:quorum opts))]
(merge tests/noop-test
opts
{:pure-generators true
:name (str "etcd q=" quorum)
:quorum quorum
...
(def cli-opts
"Additional command line options."
[["-q" "--quorum" "Use quorum reads, instead of reading from any primary."]
["-r" "--rate HZ" "Approximate number of requests per second, per thread."
:default 10
:parse-fn read-string
:validate [#(and (number? %) (pos? %)) "Must be a positive number"]]
[nil "--ops-per-key NUM" "Maximum number of operations on any given key."
:default 100
:parse-fn parse-long
:validate [pos? "Must be a positive integer."]]])