forked from Deuxfleurs/garage
even without nemesis, s3 get/put/delete is not linearizable (is this normal?)
This commit is contained in:
parent
70c1d3db46
commit
dc5245ce65
3 changed files with 64 additions and 37 deletions
|
@ -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.
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
{ pkgs ? import <nixpkgs> {} }:
|
||||
pkgs.mkShell {
|
||||
nativeBuildInputs = [
|
||||
pkgs.leiningen
|
||||
pkgs.vagrant
|
||||
nativeBuildInputs = with pkgs; [
|
||||
leiningen
|
||||
vagrant
|
||||
gnuplot
|
||||
];
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in a new issue