|
12 | 12 | [control :as c]
|
13 | 13 | [independent :as independent]
|
14 | 14 | [generator :as gen]
|
15 |
| - [nemesis :as nemesis] |
16 | 15 | [tests :as tests]
|
17 | 16 | [util :refer [timeout meh]]]
|
18 | 17 | [jepsen.checker.timeline :as timeline]
|
19 | 18 | ;[knossos.model :as model]
|
20 | 19 | [jepsen.os.ubuntu :as ubuntu]
|
21 | 20 | [tarantool [db :as db]
|
22 | 21 | [errcode :as err]
|
| 22 | + [nemesis :as nemesis] |
23 | 23 | [register :as register]
|
24 | 24 | [sets :as sets]
|
25 | 25 | [counter :as counter]]))
|
|
74 | 74 | ;:pages {:serialized-indices [true false]}
|
75 | 75 | :register {}})
|
76 | 76 |
|
| 77 | +(def nemeses |
| 78 | + "Types of faults a nemesis can create." |
| 79 | + #{:pause :kill :partition :clock}) |
| 80 | + |
| 81 | +(def standard-nemeses |
| 82 | + "Combinations of nemeses for tests." |
| 83 | + [[] |
| 84 | + [:pause] |
| 85 | + [:kill] |
| 86 | + [:partition] |
| 87 | + [:pause :kill :partition :clock]]) |
| 88 | + |
| 89 | +(def special-nemeses |
| 90 | + "A map of special nemesis names to collections of faults." |
| 91 | + {:none [] |
| 92 | + :standard [:pause :kill :partition :clock] |
| 93 | + :all [:pause :kill :partition :clock]}) |
| 94 | + |
| 95 | +(defn parse-nemesis-spec |
| 96 | + "Takes a comma-separated nemesis string and |
| 97 | + returns a collection of keyword faults." |
| 98 | + [spec] |
| 99 | + (->> (str/split spec #",") |
| 100 | + (map keyword) |
| 101 | + (mapcat #(get special-nemeses % [%])))) |
| 102 | + |
77 | 103 | (def cli-opts
|
78 | 104 | "Options for test runners."
|
79 | 105 | [["-v" "--version VERSION"
|
|
82 | 108 | [nil "--mvcc"
|
83 | 109 | "Enable MVCC engine"
|
84 | 110 | :default false]
|
| 111 | + [nil "--nemesis FAULTS" "A comma-separated list of nemesis faults to enable" |
| 112 | + :parse-fn parse-nemesis-spec |
| 113 | + :validate [(partial every? (into nemeses (keys special-nemeses))) |
| 114 | + (str "Faults must be one of " nemeses " or " |
| 115 | + (cli/one-of special-nemeses))]] |
| 116 | + [nil "--nemesis-interval SECONDS" "How long to wait between nemesis faults" |
| 117 | + :default 3 |
| 118 | + :parse-fn read-string |
| 119 | + :validate [#(and (number? %) (pos? %)) "must be a positive number"]] |
85 | 120 | ["-e" "--engine NAME"
|
86 | 121 | "What Tarantool data engine should we use?"
|
87 | 122 | :default "memtx"]])
|
|
140 | 175 | (defn tarantool-test
|
141 | 176 | [opts]
|
142 | 177 | (let [workload ((get workloads (:workload opts)) opts)
|
143 |
| - nemesis nemesis/noop |
| 178 | + nemesis (nemesis/nemesis-package |
| 179 | + {:db db/db |
| 180 | + :nodes (:nodes opts) |
| 181 | + :faults (:nemesis opts) |
| 182 | + :partition {:targets [:primaries]} |
| 183 | + :pause {:targets [nil :one :primaries :majority :all]} |
| 184 | + :kill {:targets [nil :one :primaries :majority :all]} |
| 185 | + :interval (:nemesis-interval opts)}) |
| 186 | + _ (info (pr-str nemesis)) |
144 | 187 | gen (->> (:generator workload)
|
145 | 188 | (gen/nemesis (:generator nemesis))
|
146 | 189 | (gen/time-limit (:time-limit opts)))
|
|
154 | 197 | (merge tests/noop-test
|
155 | 198 | opts
|
156 | 199 | {:client (:client workload)
|
157 |
| - :nemesis nemesis |
| 200 | + :nemesis (:nemesis nemesis) |
158 | 201 | :name (str "tarantool-" (:version opts))
|
159 | 202 | :os ubuntu/os
|
160 | 203 | :db (db/db (:version opts))
|
161 | 204 | :engine (:engine opts)
|
162 | 205 | :mvcc (:mvcc opts)
|
163 | 206 | :pure-generators true
|
164 | 207 | :generator gen
|
165 |
| - :checker (checker/compose {:perf (checker/perf) |
| 208 | + :checker (checker/compose {:perf (checker/perf {:nemeses (:perf nemesis)}) |
166 | 209 | :clock-skew (checker/clock-plot)
|
167 | 210 | :crash (crash-checker)
|
168 | 211 | :timeline (timeline/html)
|
|
171 | 214 | :workload (:checker workload)})})))
|
172 | 215 |
|
173 | 216 | (defn all-test-options
|
174 |
| - "Takes base cli options, a collection of workloads, and a test count, |
| 217 | + "Takes base cli options, a collection of nemeses, workloads, and a test count, |
175 | 218 | and constructs a sequence of test options."
|
176 |
| - [cli workloads] |
177 |
| - (for [w workloads, i (range (:test-count cli))] |
| 219 | + [cli nemeses workloads] |
| 220 | + (for [n nemeses, w workloads, i (range (:test-count cli))] |
178 | 221 | (assoc cli
|
| 222 | + :nemesis n |
179 | 223 | :workload w)))
|
180 | 224 |
|
181 | 225 | (defn all-tests
|
182 | 226 | "Takes parsed CLI options and constructs a sequence of test options, by
|
183 |
| - combining all workloads." |
184 |
| - [test-fn opts] |
185 |
| - (let [workloads (if-let [w (:workload opts)] [w] |
186 |
| - (if (:only-workloads-expected-to-pass opts) |
| 227 | + combining all workloads and nemeses." |
| 228 | + [test-fn cli] |
| 229 | + (let [nemeses (if-let [n (:nemesis cli)] [n] standard-nemeses) |
| 230 | + workloads (if-let [w (:workload cli)] [w] |
| 231 | + (if (:only-workloads-expected-to-pass cli) |
187 | 232 | workloads-expected-to-pass
|
188 | 233 | standard-workloads))]
|
189 |
| - (->> (all-test-options opts workloads) |
| 234 | + (->> (all-test-options cli nemeses workloads) |
190 | 235 | (map test-fn))))
|
191 | 236 |
|
192 | 237 | (defn -main
|
|
0 commit comments