Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

QA-3909 Append scenario for AI3 #4

Merged
merged 30 commits into from
Nov 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
89271d0
Append test, not working yet
ahitrin Oct 30, 2023
3eeba16
Avoid infinite print
ahitrin Nov 1, 2023
01b9d97
Do not shadow names like "test" and "key"
ahitrin Nov 1, 2023
9be060c
Rebalance open! and setup! methods
ahitrin Nov 1, 2023
ed2da47
Stupid value insert (ignoring jepsen data for now)
ahitrin Nov 1, 2023
1aee052
wip
ahitrin Nov 2, 2023
71f6a7d
wip
ahitrin Nov 2, 2023
dadb739
extract
ahitrin Nov 2, 2023
918849f
fixes
ahitrin Nov 2, 2023
0371300
convert result into list
ahitrin Nov 2, 2023
13a5d7b
insert or update
ahitrin Nov 2, 2023
b520274
destructure
ahitrin Nov 2, 2023
0053c29
simplify
ahitrin Nov 2, 2023
33aa17a
fix
ahitrin Nov 2, 2023
981fd18
Add pseudo-nemesis for append test
ahitrin Nov 2, 2023
d02caf7
Comment out debug logging
ahitrin Nov 2, 2023
f75442f
cleanup
ahitrin Nov 3, 2023
bfc7ff5
cleanup imports
ahitrin Nov 3, 2023
aff40a8
extract run-sql function
ahitrin Nov 3, 2023
fac6e10
Try to setup consistency models
ahitrin Nov 3, 2023
aa0694c
Remove unused pds settings
ahitrin Nov 3, 2023
2c9d4b1
convert long expression into several steps
ahitrin Nov 3, 2023
c0d499a
Fix: do not use test name "basic-test"
ahitrin Nov 3, 2023
2224265
Explicitly open transaction for read
ahitrin Nov 3, 2023
1703392
simplify
ahitrin Nov 3, 2023
4961395
Convert ignite3/generator into ignite3/wrap-generator
ahitrin Nov 6, 2023
2484356
Fix: make append test finishable
ahitrin Nov 6, 2023
4a396bc
Fixes: use txn to read, return :process
ahitrin Nov 6, 2023
89992c8
Fix hostory creation: use assoc to keep all fields needed
ahitrin Nov 6, 2023
05621ea
Remove temporary nemesis implementation
ahitrin Nov 7, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 9 additions & 12 deletions ignite-3/src/jepsen/ignite3.clj
Original file line number Diff line number Diff line change
Expand Up @@ -96,29 +96,26 @@
(info node files)
(into [] (.split files "\n"))))))

(defn generator
[operations time-limit]
(->> (gen/mix operations)
(defn wrap-generator
"Add default wrapper for generator (frequency, nemesis, time limit)."
[generator time-limit]
(->> generator
(gen/stagger 1/10)
(gen/nemesis
; without "take 100", we fail into infinity here (most probably, during print)
(take 100 (cycle [(gen/sleep 5)
{:type :info, :f :start}
(gen/sleep 1)
{:type :info, :f :stop}])))
(cycle [(gen/sleep 5)
{:type :info, :f :start}
(gen/sleep 1)
{:type :info, :f :stop}]))
(gen/time-limit time-limit)))

(defn basic-test
"Sets up the test parameters common to all tests."
[options]
(info :opts options)
(merge tests/noop-test
(dissoc options :test-fns)
{:name "basic-test"
:os (case (:os options)
{:os (case (:os options)
:centos centos/os
:debian debian/os
:noop jepsen.os/noop)
:db (db (:version options))
:pds (:pds options)
:nemesis (:nemesis options)}))
116 changes: 116 additions & 0 deletions ignite-3/src/jepsen/ignite3/append.clj
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
(ns jepsen.ignite3.append
"Append test.
Values are lists of integers. Each operation performs a transaction,
comprised of micro-operations which are either reads of some value (returning
the entire list) or appends (adding a single number to whatever the present
value of the given list is). We detect cycles in these transactions using
Jepsen's cycle-detection system."
(:require [clojure.tools.logging :as log]
[jepsen [client :as client]
[ignite3 :as ignite3]
[nemesis :as nemesis]]
[jepsen.tests.cycle.append :as app])
(:import (org.apache.ignite Ignite)
(org.apache.ignite.client IgniteClient)))

(def table-name "APPEND")

(def sql-create (str "create table if not exists " table-name "(key int primary key, vals varchar(1000))"))

(def sql-insert (str "insert into " table-name " (key, vals) values (?, ?)"))

(def sql-update (str "update " table-name " set vals = ? where key = ?"))

(def sql-select (str "select * from " table-name " where key = ?"))

(defn run-sql
"Run a SQL query. Return ResultSet instance that should be closed afterwards."
([session query params] (run-sql session nil query params))
([session txn query params]
(log/info query params)
(.execute session txn query (object-array params))))

(defn invoke-op [^Ignite ignite [opcode k v]]
"Perform a single operation in separate transaction."
(let [txn (.begin (.transactions ignite))
sql (.sql ignite)]
(if
(= :r opcode)
(let [select-result
(with-open [session (.createSession sql)
rs (run-sql session txn sql-select [k])]
(if (.hasNext rs)
(let [raw-result (.stringValue (.next rs) 1)
strings (clojure.string/split raw-result #",")]
(->> strings
(map #(Integer/parseInt %))
(into [])))
[]))]
(.commit txn)
[:r k select-result])
(with-open [session (.createSession sql)
read-rs (run-sql session txn sql-select [k])]
(if (.hasNext read-rs)
; update existing list
(let [old-list (.stringValue (.next read-rs) 1)
new-list (str old-list "," v)]
(with-open [write-rs (run-sql session txn sql-update [new-list k])]))
; create a new list
(do
(with-open [write-rs (run-sql session txn sql-insert [k (str v)])])))
(.commit txn)
[opcode k v]))))

(defrecord Client [^Ignite ignite]
client/Client
;
(open! [this test node]
; (log/info "Node: " node)
(let [ignite (.build (.addresses (IgniteClient/builder) (into-array [(str node ":10800")])))]
(assoc this :ignite ignite)))
;
(setup! [this test]
(with-open [create-stmt (.createStatement (.sql ignite) sql-create)
session (.createSession (.sql ignite))
rs (run-sql session create-stmt [])]
(log/info "Table" table-name "created")))
;
(invoke! [this test op]
; (log/info "Received: " op)
(let [ops (:value op)
result (map #(invoke-op ignite %) ops)
overall-result (assoc op
:type :info
:value (into [] result))]
; (log/info "Returned: " overall-result)
overall-result))
;
(teardown! [this test])
;
(close! [this test]
(.close ignite)))

(comment "for repl"

(def c (client/open! (Client. nil) {} "127.0.0.1"))
(client/setup! c {})

(client/invoke! c {} {:type :invoke, :process 0, :f :txn, :value [[:r 9 nil]]})

(client/invoke! c {} {:type :invoke, :process 1, :f :txn, :value [[:append 9 2]]})

(client/close! c {})

"/for repl"
)

(defn append-test
[opts]
(ignite3/basic-test
(merge
(let [test-ops {:consistency-models [:serializable]}]
{:name "append-test"
:client (Client. nil)
:checker (app/checker test-ops)
:generator (ignite3/wrap-generator (app/gen test-ops) (:time-limit opts))})
opts)))
17 changes: 10 additions & 7 deletions ignite-3/src/jepsen/ignite3/register.clj
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
(:require [clojure.tools.logging :as log]
[jepsen [checker :as checker]
[client :as client]
[generator :as gen]
[ignite3 :as ignite3]
[independent :as independent]]
[jepsen.checker.timeline :as timeline]
Expand All @@ -11,7 +12,7 @@

(def table-name "REGISTER")

(def key "k")
(def common-key "k")

(def sql-create (str"create table if not exists " table-name "(key varchar primary key, val int)"))

Expand Down Expand Up @@ -45,21 +46,21 @@
(try
(case (:f op)
:read (let [kv-view (.keyValueView (.table (.tables ignite) table-name) String Integer)
value (.get kv-view nil key)]
value (.get kv-view nil common-key)]
(assoc op :type :ok :value value))
:write (let [kv-view (.keyValueView (.table (.tables ignite) table-name) String Integer)]
(.put kv-view nil key (:value op))
(.put kv-view nil common-key (:value op))
(assoc op :type :ok))
:cas (let [kv-view (.keyValueView (.table (.tables ignite) table-name) String Integer)
[value value'] (:value op)]
(assoc op :type (if (.replace kv-view nil key value value') :ok :fail))))))
(assoc op :type (if (.replace kv-view nil common-key value value') :ok :fail))))))

(teardown! [this test])

(close! [this test]
(.close ignite)))

(defn test
(defn register-test
[opts]
(ignite3/basic-test
(merge
Expand All @@ -69,5 +70,7 @@
(checker/compose
{:linearizable (checker/linearizable {:model (model/cas-register)})
:timeline (timeline/html)}))
:generator (ignite3/generator [r w cas] (:time-limit opts))}
opts)))
:generator (ignite3/wrap-generator
(gen/mix [r w cas])
(:time-limit opts))}
opts)))
17 changes: 9 additions & 8 deletions ignite-3/src/jepsen/ignite3/runner.clj
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
(ns jepsen.ignite3.runner
"Runs Apache Ignite 3 tests."
(:gen-class)
(:require [clojure.pprint :refer [pprint]]
[clojure.tools.logging :refer :all]
[jepsen.cli :as jc]
[jepsen.core :as jepsen]
[jepsen.ignite3.register :as register]))
(:require [clojure.pprint :refer [pprint]]
[clojure.tools.logging :refer :all]
[jepsen.cli :as jc]
[jepsen.core :as jepsen]
[jepsen.ignite3.append :as append]
[jepsen.ignite3.register :as register]))

(def tests
"A map of test names to test constructors."
{"register" register/test})
{"append" append/append-test
"register" register/register-test})

(def nemesis-types
{"noop" jepsen.nemesis/noop})
Expand All @@ -35,7 +37,7 @@

(defn log-test
[t]
(info "Testing\n" (with-out-str (pprint t)))
(binding [*print-length* 100] (info "Testing\n" (with-out-str (pprint t))))
t)

(defn test-cmd
Expand All @@ -48,7 +50,6 @@
:test :test-fns})))
:usage (jc/test-usage)
:run (fn [{:keys [options]}]
(pprint options)
(doseq [i (range (:test-count options))
test-fn (:test-fns options)]
; Rehydrate test and run
Expand Down