2021-03-16 08:03:47 +00:00
|
|
|
(ns jepsen.nukeeper.nemesis
|
2021-03-17 07:11:55 +00:00
|
|
|
(:require
|
2021-03-17 11:35:37 +00:00
|
|
|
[clojure.tools.logging :refer :all]
|
|
|
|
[jepsen
|
|
|
|
[nemesis :as nemesis]
|
|
|
|
[control :as c]
|
|
|
|
[generator :as gen]]
|
|
|
|
[jepsen.nukeeper.constants :refer :all]
|
|
|
|
[jepsen.nukeeper.utils :refer :all]))
|
2021-03-16 08:03:47 +00:00
|
|
|
|
2021-03-18 11:32:45 +00:00
|
|
|
(defn random-node-killer-nemesis
|
2021-03-16 08:03:47 +00:00
|
|
|
[]
|
|
|
|
(nemesis/node-start-stopper
|
2021-03-16 12:37:46 +00:00
|
|
|
rand-nth
|
|
|
|
(fn start [test node] (kill-clickhouse! node test))
|
|
|
|
(fn stop [test node] (start-clickhouse! node test))))
|
|
|
|
|
2021-03-18 11:32:45 +00:00
|
|
|
(defn all-nodes-killer-nemesis
|
|
|
|
[]
|
|
|
|
(nemesis/node-start-stopper
|
|
|
|
identity
|
|
|
|
(fn start [test node] (kill-clickhouse! node test))
|
|
|
|
(fn stop [test node] (start-clickhouse! node test))))
|
|
|
|
|
|
|
|
(defn random-node-hammer-time-nemesis
|
2021-03-16 14:53:49 +00:00
|
|
|
[]
|
|
|
|
(nemesis/hammer-time "clickhouse"))
|
|
|
|
|
2021-03-18 11:32:45 +00:00
|
|
|
(defn all-nodes-hammer-time-nemesis
|
|
|
|
[]
|
|
|
|
(nemesis/hammer-time identity "clickhouse"))
|
|
|
|
|
2021-03-17 07:11:55 +00:00
|
|
|
(defn select-last-file
|
|
|
|
[path]
|
2021-03-17 08:13:52 +00:00
|
|
|
(last (clojure.string/split
|
2021-03-17 11:35:37 +00:00
|
|
|
(c/exec :find path :-type :f :-printf "%T+ %p\n" :| :grep :-v :tmp_ :| :sort :| :awk "{print $2}")
|
2021-03-17 08:13:52 +00:00
|
|
|
#"\n")))
|
|
|
|
|
|
|
|
(defn random-file-pos
|
|
|
|
[fname]
|
|
|
|
(let [fsize (Integer/parseInt (c/exec :du :-b fname :| :cut :-f1))]
|
|
|
|
(rand-int fsize)))
|
2021-03-17 07:11:55 +00:00
|
|
|
|
|
|
|
(defn corrupt-file
|
|
|
|
[fname]
|
2021-03-17 11:35:37 +00:00
|
|
|
(if (not (empty? fname))
|
|
|
|
(do
|
|
|
|
(info "Corrupting" fname)
|
|
|
|
(c/exec :dd "if=/dev/zero" (str "of=" fname) "bs=1" "count=1" (str "seek=" (random-file-pos fname)) "conv=notrunc"))
|
|
|
|
(info "Nothing to corrupt")))
|
2021-03-17 07:11:55 +00:00
|
|
|
|
|
|
|
(defn corruptor-nemesis
|
|
|
|
[path corruption-op]
|
|
|
|
(reify nemesis/Nemesis
|
2021-03-17 08:13:52 +00:00
|
|
|
|
2021-03-17 07:11:55 +00:00
|
|
|
(setup! [this test] this)
|
|
|
|
|
|
|
|
(invoke! [this test op]
|
2021-03-17 08:13:52 +00:00
|
|
|
(cond (= (:f op) :corrupt)
|
2021-03-17 11:35:37 +00:00
|
|
|
(let [nodes (list (rand-nth (:nodes test)))]
|
|
|
|
(info "Corruption on node" nodes)
|
|
|
|
(c/on-nodes test nodes
|
|
|
|
(fn [test node]
|
|
|
|
(c/su
|
|
|
|
(kill-clickhouse! node test)
|
|
|
|
(corruption-op path)
|
|
|
|
(start-clickhouse! node test))))
|
|
|
|
(assoc op :type :info, :value :corrupted))
|
|
|
|
:else (do (c/on-nodes test (:nodes test)
|
|
|
|
(fn [test node]
|
|
|
|
(c/su
|
|
|
|
(start-clickhouse! node test))))
|
|
|
|
(assoc op :type :info, :value :done))))
|
2021-03-17 07:11:55 +00:00
|
|
|
|
|
|
|
(teardown! [this test])))
|
|
|
|
|
|
|
|
(defn logs-corruption-nemesis
|
|
|
|
[]
|
2021-03-17 11:35:37 +00:00
|
|
|
(corruptor-nemesis logsdir #(corrupt-file (select-last-file %1))))
|
2021-03-17 07:11:55 +00:00
|
|
|
|
|
|
|
(defn snapshots-corruption-nemesis
|
|
|
|
[]
|
2021-03-17 11:35:37 +00:00
|
|
|
(corruptor-nemesis snapshotsdir #(corrupt-file (select-last-file %1))))
|
|
|
|
|
|
|
|
(defn logs-and-snapshots-corruption-nemesis
|
|
|
|
[]
|
|
|
|
(corruptor-nemesis coordinationdir (fn [path]
|
|
|
|
(do
|
|
|
|
(corrupt-file (select-last-file (str path "/snapshots")))
|
|
|
|
(corrupt-file (select-last-file (str path "/logs")))))))
|
|
|
|
(defn drop-all-corruption-nemesis
|
|
|
|
[]
|
|
|
|
(corruptor-nemesis coordinationdir (fn [path]
|
|
|
|
(c/exec :rm :-fr path))))
|
|
|
|
|
|
|
|
(defn start-stop-generator
|
2021-03-18 11:32:45 +00:00
|
|
|
[time-corrupt time-ok]
|
2021-03-17 11:35:37 +00:00
|
|
|
(->>
|
2021-03-18 11:32:45 +00:00
|
|
|
(cycle [(gen/sleep time-ok)
|
2021-03-17 11:35:37 +00:00
|
|
|
{:type :info, :f :start}
|
2021-03-18 11:32:45 +00:00
|
|
|
(gen/sleep time-corrupt)
|
2021-03-17 11:35:37 +00:00
|
|
|
{:type :info, :f :stop}])))
|
|
|
|
|
|
|
|
(defn corruption-generator
|
|
|
|
[]
|
|
|
|
(->>
|
|
|
|
(cycle [(gen/sleep 5)
|
|
|
|
{:type :info, :f :corrupt}])))
|
2021-03-17 07:11:55 +00:00
|
|
|
|
2021-03-16 12:37:46 +00:00
|
|
|
(def custom-nemesises
|
2021-03-18 11:32:45 +00:00
|
|
|
{"random-node-killer" {:nemesis (random-node-killer-nemesis)
|
|
|
|
:generator (start-stop-generator 5 5)}
|
|
|
|
"all-nodes-killer" {:nemesis (all-nodes-killer-nemesis)
|
|
|
|
:generator (start-stop-generator 1 10)}
|
2021-03-16 12:37:46 +00:00
|
|
|
"simple-partitioner" {:nemesis (nemesis/partition-random-halves)
|
2021-03-18 11:32:45 +00:00
|
|
|
:generator (start-stop-generator 5 5)}
|
|
|
|
"random-node-hammer-time" {:nemesis (random-node-hammer-time-nemesis)
|
|
|
|
:generator (start-stop-generator 5 5)}
|
|
|
|
"all-nodes-hammer-time" {:nemesis (all-nodes-hammer-time-nemesis)
|
|
|
|
:generator (start-stop-generator 1 10)}
|
2021-03-17 11:35:37 +00:00
|
|
|
"logs-corruptor" {:nemesis (logs-corruption-nemesis)
|
|
|
|
:generator (corruption-generator)}
|
|
|
|
"snapshots-corruptor" {:nemesis (snapshots-corruption-nemesis)
|
|
|
|
:generator (corruption-generator)}
|
|
|
|
"logs-and-snapshots-corruptor" {:nemesis (logs-and-snapshots-corruption-nemesis)
|
|
|
|
:generator (corruption-generator)}
|
|
|
|
"drop-data-corruptor" {:nemesis (drop-all-corruption-nemesis)
|
|
|
|
:generator (corruption-generator)}})
|