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
|
# jepsen.garage
|
||||||
|
|
||||||
A Clojure library designed to ... well, that part is up to you.
|
Jepsen checking of Garage consistency properties.
|
||||||
|
|
||||||
## Usage
|
## 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
|
## License
|
||||||
|
|
||||||
Copyright © 2023 FIXME
|
Copyright © 2023 Alex Auvolat
|
||||||
|
|
||||||
This program and the accompanying materials are made available under the
|
This program and the accompanying materials are made available under the
|
||||||
terms of the Eclipse Public License 2.0 which is available at
|
terms of the GNU General Public License v3.0.
|
||||||
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.
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
{ pkgs ? import <nixpkgs> {} }:
|
{ pkgs ? import <nixpkgs> {} }:
|
||||||
pkgs.mkShell {
|
pkgs.mkShell {
|
||||||
nativeBuildInputs = [
|
nativeBuildInputs = with pkgs; [
|
||||||
pkgs.leiningen
|
leiningen
|
||||||
pkgs.vagrant
|
vagrant
|
||||||
|
gnuplot
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,14 +1,18 @@
|
||||||
(ns jepsen.garage
|
(ns jepsen.garage
|
||||||
(:require [clojure.tools.logging :refer :all]
|
(:require [clojure.tools.logging :refer :all]
|
||||||
[clojure.string :as str]
|
[clojure.string :as str]
|
||||||
[jepsen [cli :as cli]
|
[jepsen [checker :as checker]
|
||||||
|
[cli :as cli]
|
||||||
[client :as client]
|
[client :as client]
|
||||||
[control :as c]
|
[control :as c]
|
||||||
[db :as db]
|
[db :as db]
|
||||||
[generator :as gen]
|
[generator :as gen]
|
||||||
|
[nemesis :as nemesis]
|
||||||
[tests :as tests]]
|
[tests :as tests]]
|
||||||
|
[jepsen.checker.timeline :as timeline]
|
||||||
[jepsen.control.util :as cu]
|
[jepsen.control.util :as cu]
|
||||||
[jepsen.os.debian :as debian]
|
[jepsen.os.debian :as debian]
|
||||||
|
[knossos.model :as model]
|
||||||
[slingshot.slingshot :refer [try+]]
|
[slingshot.slingshot :refer [try+]]
|
||||||
[amazonica.aws.s3 :as s3]
|
[amazonica.aws.s3 :as s3]
|
||||||
[amazonica.aws.s3transfer :as s3transfer]))
|
[amazonica.aws.s3transfer :as s3transfer]))
|
||||||
|
@ -82,9 +86,9 @@
|
||||||
(log-files [_ test node]
|
(log-files [_ test node]
|
||||||
[logfile])))
|
[logfile])))
|
||||||
|
|
||||||
(defn op-get [_ _] {:type :invoke, :f :get-object, :value nil})
|
(defn op-get [_ _] {:type :invoke, :f :read, :value nil})
|
||||||
(defn op-put [_ _] {:type :invoke, :f :put-object, :value (str (rand-int 50))})
|
(defn op-put [_ _] {:type :invoke, :f :write, :value (str (rand-int 9))})
|
||||||
(defn op-del [_ _] {:type :invoke, :f :del-object, :value nil})
|
(defn op-del [_ _] {:type :invoke, :f :write, :value nil})
|
||||||
|
|
||||||
(defrecord Client [creds]
|
(defrecord Client [creds]
|
||||||
client/Client
|
client/Client
|
||||||
|
@ -102,7 +106,7 @@
|
||||||
(setup! [this test])
|
(setup! [this test])
|
||||||
(invoke! [this test op]
|
(invoke! [this test op]
|
||||||
(case (:f op)
|
(case (:f op)
|
||||||
:get-object (try+
|
:read (try+
|
||||||
(let [value
|
(let [value
|
||||||
(-> (s3/get-object (:creds this) grg-bucket grg-object)
|
(-> (s3/get-object (:creds this) grg-bucket grg-object)
|
||||||
:input-stream
|
:input-stream
|
||||||
|
@ -110,21 +114,21 @@
|
||||||
(assoc op :type :ok, :value value))
|
(assoc op :type :ok, :value value))
|
||||||
(catch (re-find #"Key not found" (.getMessage %)) ex
|
(catch (re-find #"Key not found" (.getMessage %)) ex
|
||||||
(assoc op :type :ok, :value nil)))
|
(assoc op :type :ok, :value nil)))
|
||||||
:put-object
|
:write
|
||||||
(let [some-bytes (.getBytes (:value op) "UTF-8")
|
(if (= (:value op) nil)
|
||||||
bytes-stream (java.io.ByteArrayInputStream. some-bytes)]
|
(do
|
||||||
(s3/put-object (:creds this)
|
(s3/delete-object (:creds this)
|
||||||
:bucket-name grg-bucket
|
:bucket-name grg-bucket
|
||||||
:key grg-object
|
:key grg-object)
|
||||||
:input-stream bytes-stream
|
(assoc op :type :ok, :value nil))
|
||||||
:metadata {:content-length (count some-bytes)})
|
(let [some-bytes (.getBytes (:value op) "UTF-8")
|
||||||
(assoc op :type :ok))
|
bytes-stream (java.io.ByteArrayInputStream. some-bytes)]
|
||||||
:del-object
|
(s3/put-object (:creds this)
|
||||||
(do
|
:bucket-name grg-bucket
|
||||||
(s3/delete-object (:creds this)
|
:key grg-object
|
||||||
:bucket-name grg-bucket
|
:input-stream bytes-stream
|
||||||
:key grg-object)
|
:metadata {:content-length (count some-bytes)})
|
||||||
(assoc op :type :ok, :value nil))))
|
(assoc op :type :ok)))))
|
||||||
(teardown! [this test])
|
(teardown! [this test])
|
||||||
(close! [this test]))
|
(close! [this test]))
|
||||||
|
|
||||||
|
@ -139,10 +143,22 @@
|
||||||
:os debian/os
|
:os debian/os
|
||||||
:db (db "v0.8.2")
|
:db (db "v0.8.2")
|
||||||
:client (Client. nil)
|
: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])
|
:generator (->> (gen/mix [op-get op-put op-del])
|
||||||
(gen/stagger 1)
|
(gen/stagger 0.02)
|
||||||
(gen/nemesis nil)
|
(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
|
(defn -main
|
||||||
"Handles command line arguments. Can either run a test, or a web server for
|
"Handles command line arguments. Can either run a test, or a web server for
|
||||||
|
|
Loading…
Reference in a new issue