From dc5245ce65e6acc4c2b1f81dfdf38fc76fe06d3f Mon Sep 17 00:00:00 2001 From: Alex Auvolat Date: Tue, 18 Apr 2023 17:47:53 +0200 Subject: [PATCH] even without nemesis, s3 get/put/delete is not linearizable (is this normal?) --- script/jepsen.garage/README.md | 34 +++++++----- script/jepsen.garage/shell.nix | 7 +-- script/jepsen.garage/src/jepsen/garage.clj | 60 ++++++++++++++-------- 3 files changed, 64 insertions(+), 37 deletions(-) diff --git a/script/jepsen.garage/README.md b/script/jepsen.garage/README.md index e1d1a555..ed956830 100644 --- a/script/jepsen.garage/README.md +++ b/script/jepsen.garage/README.md @@ -1,22 +1,32 @@ # jepsen.garage -A Clojure library designed to ... well, that part is up to you. +Jepsen checking of Garage consistency properties. ## Usage -FIXME +Requirements: + +- vagrant +- VirtualBox, configured so that nodes can take an IP in a private network `192.168.56.0/24` +- a user that can create VirtualBox VMs +- leiningen +- gnuplot + +Set up VMs: + +``` +vagrant up +``` + +Run tests: + +``` +lein run test --nodes-file nodes.vagrant +``` ## License -Copyright © 2023 FIXME +Copyright © 2023 Alex Auvolat This program and the accompanying materials are made available under the -terms of the Eclipse Public License 2.0 which is available at -http://www.eclipse.org/legal/epl-2.0. - -This Source Code may also be made available under the following Secondary -Licenses when the conditions for such availability set forth in the Eclipse -Public License, v. 2.0 are satisfied: GNU General Public License as published by -the Free Software Foundation, either version 2 of the License, or (at your -option) any later version, with the GNU Classpath Exception which is available -at https://www.gnu.org/software/classpath/license.html. +terms of the GNU General Public License v3.0. diff --git a/script/jepsen.garage/shell.nix b/script/jepsen.garage/shell.nix index b0dda6d1..595a78d9 100644 --- a/script/jepsen.garage/shell.nix +++ b/script/jepsen.garage/shell.nix @@ -1,7 +1,8 @@ { pkgs ? import {} }: pkgs.mkShell { - nativeBuildInputs = [ - pkgs.leiningen - pkgs.vagrant + nativeBuildInputs = with pkgs; [ + leiningen + vagrant + gnuplot ]; } diff --git a/script/jepsen.garage/src/jepsen/garage.clj b/script/jepsen.garage/src/jepsen/garage.clj index 9d6f891e..df3c8f7d 100644 --- a/script/jepsen.garage/src/jepsen/garage.clj +++ b/script/jepsen.garage/src/jepsen/garage.clj @@ -1,14 +1,18 @@ (ns jepsen.garage (:require [clojure.tools.logging :refer :all] [clojure.string :as str] - [jepsen [cli :as cli] + [jepsen [checker :as checker] + [cli :as cli] [client :as client] [control :as c] [db :as db] [generator :as gen] + [nemesis :as nemesis] [tests :as tests]] + [jepsen.checker.timeline :as timeline] [jepsen.control.util :as cu] [jepsen.os.debian :as debian] + [knossos.model :as model] [slingshot.slingshot :refer [try+]] [amazonica.aws.s3 :as s3] [amazonica.aws.s3transfer :as s3transfer])) @@ -82,9 +86,9 @@ (log-files [_ test node] [logfile]))) -(defn op-get [_ _] {:type :invoke, :f :get-object, :value nil}) -(defn op-put [_ _] {:type :invoke, :f :put-object, :value (str (rand-int 50))}) -(defn op-del [_ _] {:type :invoke, :f :del-object, :value nil}) +(defn op-get [_ _] {:type :invoke, :f :read, :value nil}) +(defn op-put [_ _] {:type :invoke, :f :write, :value (str (rand-int 9))}) +(defn op-del [_ _] {:type :invoke, :f :write, :value nil}) (defrecord Client [creds] client/Client @@ -102,7 +106,7 @@ (setup! [this test]) (invoke! [this test op] (case (:f op) - :get-object (try+ + :read (try+ (let [value (-> (s3/get-object (:creds this) grg-bucket grg-object) :input-stream @@ -110,21 +114,21 @@ (assoc op :type :ok, :value value)) (catch (re-find #"Key not found" (.getMessage %)) ex (assoc op :type :ok, :value nil))) - :put-object - (let [some-bytes (.getBytes (:value op) "UTF-8") - bytes-stream (java.io.ByteArrayInputStream. some-bytes)] - (s3/put-object (:creds this) - :bucket-name grg-bucket - :key grg-object - :input-stream bytes-stream - :metadata {:content-length (count some-bytes)}) - (assoc op :type :ok)) - :del-object - (do - (s3/delete-object (:creds this) - :bucket-name grg-bucket - :key grg-object) - (assoc op :type :ok, :value nil)))) + :write + (if (= (:value op) nil) + (do + (s3/delete-object (:creds this) + :bucket-name grg-bucket + :key grg-object) + (assoc op :type :ok, :value nil)) + (let [some-bytes (.getBytes (:value op) "UTF-8") + bytes-stream (java.io.ByteArrayInputStream. some-bytes)] + (s3/put-object (:creds this) + :bucket-name grg-bucket + :key grg-object + :input-stream bytes-stream + :metadata {:content-length (count some-bytes)}) + (assoc op :type :ok))))) (teardown! [this test]) (close! [this test])) @@ -139,10 +143,22 @@ :os debian/os :db (db "v0.8.2") :client (Client. nil) + :nemesis (nemesis/partition-random-halves) + :checker (checker/compose + {:perf (checker/perf) + :timeline (timeline/html) + :linear (checker/linearizable + {:model (model/register) + :algorithm :linear})}) :generator (->> (gen/mix [op-get op-put op-del]) - (gen/stagger 1) + (gen/stagger 0.02) (gen/nemesis nil) - (gen/time-limit 20))})) + ; (gen/nemesis + ; (cycle [(gen/sleep 5) + ; {:type :info, :f :start} + ; (gen/sleep 5) + ; {:type :info, :f :stop}])) + (gen/time-limit (+ (:time-limit opts) 5)))})) (defn -main "Handles command line arguments. Can either run a test, or a web server for