-
Notifications
You must be signed in to change notification settings - Fork 726
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
See http://robustirc.net/ for more information, specifically: http://robustirc.net/docs/adminguide.html for setup/overview http://robustirc.net/docs/robustsession.html for the protocol
- Loading branch information
1 parent
7b3fbbb
commit 9b0ae18
Showing
6 changed files
with
353 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
(defproject jepsen.robustirc "0.1.0" | ||
:description "Jepsen tests for RobustIRC" | ||
:url "https://github.com/aphyr/jepsen" | ||
:license {:name "Eclipse Public License" | ||
:url "http://www.eclipse.org/legal/epl-v10.html"} | ||
:dependencies [[org.clojure/clojure "1.6.0"] | ||
[jepsen "0.0.5"] | ||
[clj-http "2.0.0"] | ||
[digest "1.4.4"] | ||
[cheshire "5.5.0"] | ||
[org.clojure/clojure "1.6.0"] | ||
[org.clojure/core.async "0.1.346.0-17112a-alpha"] | ||
]) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,19 @@ | ||
-----BEGIN CERTIFICATE----- | ||
MIIDJjCCAg6gAwIBAgIQLezNyzLAh3x8vDkmkXp1xjANBgkqhkiG9w0BAQsFADAd | ||
MRswGQYDVQQKExJSb2J1c3RJUkMgbG9jYWxuZXQwHhcNMTUxMDA0MTgwMzE1WhcN | ||
MjUxMDAxMTgwMzE1WjAdMRswGQYDVQQKExJSb2J1c3RJUkMgbG9jYWxuZXQwggEi | ||
MA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDYSluq4S/nveSin3q8pyZNBzQY | ||
KB+6LFN0VgPzY0QjakK9rjLg/YEH4vi32n3je+ONhsZEl/pYBP0tgO3dyEWwl6WE | ||
BuVJ/jA8/BQ/E7sZVKNr+Pf89x6cMz4v22dEiR9yUCLJ+zkRg8x+zSxFjP/nGeDp | ||
hsuGdYZZC4ekzKGRRhHIJT3kNx9UTWob7+godAJu1T+s8zb642my5bPBxljd9+Eb | ||
o89CkrfEszI3uy3J9xmiS+Snl89m/ye7PXUvLO2FCXmG/FsEOGf0NoqVWpIS73NQ | ||
cb50hdjdokaYwzvOlv2KwlwymWdcUJffUBcvrw/sbD5HZwr3+re0M+CvL9exAgMB | ||
AAGjYjBgMA4GA1UdDwEB/wQEAwICpDATBgNVHSUEDDAKBggrBgEFBQcDATAPBgNV | ||
HRMBAf8EBTADAQH/MCgGA1UdEQQhMB+CCWxvY2FsaG9zdIICbjGCAm4yggJuM4IC | ||
bjSCAm41MA0GCSqGSIb3DQEBCwUAA4IBAQAX7siP/O0+Tk5Fv/PKH2YDt3mdW1+V | ||
+2rtFBfxNKi5J74ifECcXJ6S52IrM9mVHh+0v4ElKfEAU66ADbvawn8jEi4RR/lN | ||
RFI+RljlZOX14EhGPTY8iC8Xd+321OUPH1SILwp7GlH8jrp+mD6oURt2XyX7/lvU | ||
YeKYbK3C+CjA0VZOkIBk2tPfbfShZXEboQbrZgvhwQOOrb2iWl2KqbsiYgrOyEPx | ||
O83WH7AWDBFwjZJa0X39HLoelP0Y7PyaOi7XMQ99kXdtloUVYY8fL6utXFq4XlU0 | ||
X0LV63lZWvNxDo3KafepxrEp2EexuycCgzP02CBLGG9ju3oDnTMGphAV | ||
-----END CERTIFICATE----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
package main | ||
|
||
import ( | ||
"crypto/rand" | ||
"crypto/rsa" | ||
"crypto/x509" | ||
"crypto/x509/pkix" | ||
"encoding/pem" | ||
"log" | ||
"math/big" | ||
"os" | ||
"path/filepath" | ||
"time" | ||
) | ||
|
||
func main() { | ||
dir := "/tmp/" | ||
priv, err := rsa.GenerateKey(rand.Reader, 2048) | ||
if err != nil { | ||
log.Panicf("failed to generate private key: %s", err) | ||
} | ||
|
||
notBefore := time.Now() | ||
notAfter := notBefore.Add(10 * 365 * 24 * time.Hour) | ||
|
||
serialNumberLimit := new(big.Int).Lsh(big.NewInt(1), 128) | ||
serialNumber, err := rand.Int(rand.Reader, serialNumberLimit) | ||
if err != nil { | ||
log.Panicf("failed to generate serial number: %s", err) | ||
} | ||
|
||
template := x509.Certificate{ | ||
SerialNumber: serialNumber, | ||
Subject: pkix.Name{ | ||
Organization: []string{"RobustIRC localnet"}, | ||
}, | ||
DNSNames: []string{"localhost", "n1", "n2", "n3", "n4", "n5"}, | ||
NotBefore: notBefore, | ||
NotAfter: notAfter, | ||
|
||
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign, | ||
IsCA: true, | ||
ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, | ||
BasicConstraintsValid: true, | ||
} | ||
|
||
derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) | ||
if err != nil { | ||
log.Panicf("Failed to create certificate: %s", err) | ||
} | ||
|
||
certOut, err := os.Create(filepath.Join(dir, "cert.pem")) | ||
if err != nil { | ||
log.Panicf("failed to open cert.pem for writing: %s", err) | ||
} | ||
pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) | ||
certOut.Close() | ||
log.Print("written cert.pem\n") | ||
|
||
keyOut, err := os.OpenFile(filepath.Join(dir, "key.pem"), os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) | ||
if err != nil { | ||
log.Print("failed to open key.pem for writing:", err) | ||
return | ||
} | ||
pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) | ||
keyOut.Close() | ||
log.Print("written key.pem\n") | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
-----BEGIN RSA PRIVATE KEY----- | ||
MIIEowIBAAKCAQEA2EpbquEv573kop96vKcmTQc0GCgfuixTdFYD82NEI2pCva4y | ||
4P2BB+L4t9p943vjjYbGRJf6WAT9LYDt3chFsJelhAblSf4wPPwUPxO7GVSja/j3 | ||
/PcenDM+L9tnRIkfclAiyfs5EYPMfs0sRYz/5xng6YbLhnWGWQuHpMyhkUYRyCU9 | ||
5DcfVE1qG+/oKHQCbtU/rPM2+uNpsuWzwcZY3ffhG6PPQpK3xLMyN7styfcZokvk | ||
p5fPZv8nuz11LyzthQl5hvxbBDhn9DaKlVqSEu9zUHG+dIXY3aJGmMM7zpb9isJc | ||
MplnXFCX31AXL68P7Gw+R2cK9/q3tDPgry/XsQIDAQABAoIBACFwPYPJlLJrNTG/ | ||
HiaUYON/vZoOefk6aRyPP8UdD6e6Ad95UvxdtNkXSgSCjvvgZ2m18GkiZd29x7aF | ||
PEEReVS33SrwNfqeha6n+ilWT5K29xz2PMCrI9xaP77+WJTL7kSqBvbbFBOVIMRp | ||
y/JkvhtocNEpucVr3f1ePvZHfKMMvWga/UxjafbAouduIDqoXLfSTzYhwqr+uTmO | ||
dTCUd5r47YAUJqM+ifb3j1LcefEgDh1NJyN3Spypayx47cMH7X9bOh3BjAqKW7XY | ||
JB6pcSj67EvaDHJPMwUspOHz3iRH1YWP7qnuI+mYwnMs8hXdI+m/7g03qIrf0mfe | ||
7sru0dECgYEA6Te/LQ6wEAUBQxGtvcOdr6bJag7E85+7ONGbuzwgUmTI5ll7fwmL | ||
551OuKAwQpQeDO+31p/zsUI0/Epj7kUTCdJ7rUVX9jYfIkG2zgmjLbqs4odps13T | ||
DaOK2lzEE/ryhJ6Wn/xjMpyvufIdMtGs3b1+oYayr1d7mDlZqb7pHj8CgYEA7WtM | ||
KEwPVpuJW0obKaqoqEdQFBDD0grGQKOlkXWJhR+GSd4ca4adkqrxGdJEWr8lX6Nv | ||
3LGsdCbpTVnnuInx2p6gJ5hdgEr0oSgkukBh/uoYl0jSEQrh9ULKqWoqNRAHrG5O | ||
mOSHuD3xng31nT8z+gTJo0sFRGs5wmfrVBl4bg8CgYAxrI0MxM8damN9bJuMCslg | ||
a28FJwYuOfx/uq2n8MOVqR/daHvUcC0bdTcaPgxpcfEAomKO1VzriYWNoy6rxoyq | ||
j+mF23pD1/1Dp6mPMyBNkjBWw67w5HAavJXLsuyUsOPM+ZZtly1tz0/ilD5B38Up | ||
Kb56Gx2eGU0a/EQr0p0GswKBgQC29LNobkx3mj48GhxafIehveqou86bIvBpyXIC | ||
aMgDzSpH7CCMf90XtCE9m7pPD/O2ApVmRYi2rXGlyP13SN4WcZzLRm/vOFPRiMTc | ||
vlaGAVHX6ybuOSutO74+1XAXGfY/23U3/wvTX/C8stcuSRE9vsi/zEUP121YMYq4 | ||
cTRL4wKBgAtFfumGuptom+ikYlgswMURkJY2LwhFnLF5ITgwf0UezGxdcGvkYGrq | ||
LRx94Tq/wBogLq9AvMl7kS0WcFQ2Ce3y04gFGSFBa0/yRb5EtSSSuHgfkst5E20x | ||
JIXDAAb8GDqhUvOvWtbXPGlNqCmWLJCmD9LfAitHdkCyiIeSM9Tr | ||
-----END RSA PRIVATE KEY----- |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,217 @@ | ||
(ns jepsen.robustirc | ||
(:require | ||
[clojure.tools.logging :refer [debug info warn]] | ||
[clojure.java.io :as io] | ||
[clojure.string :as str] | ||
[clojure.core.async :as async] | ||
[clj-http.client :as httpclient] | ||
[digest :as digest] | ||
[jepsen | ||
[client :as client] | ||
[core :as jepsen] | ||
[db :as db] | ||
[tests :as tests] | ||
[control :as c :refer [|]] | ||
[checker :as checker] | ||
[nemesis :as nemesis] | ||
[generator :as gen]] | ||
[jepsen.os.debian :as debian] | ||
[cheshire.core :as json]) | ||
(:import | ||
[java.net URL])) | ||
|
||
(defn db [] | ||
"RobustIRC." | ||
(reify db/DB | ||
(setup! [this test node] | ||
(c/su | ||
(c/ssh* {:cmd "killall robustirc"}) | ||
(try (c/exec :dpkg-query :-l :golang-go) | ||
(catch RuntimeException _ | ||
(info "Installing golang-go") | ||
(c/exec :apt-get :install :-y :golang-go))) | ||
(try (c/exec :dpkg-query :-l :mercurial) | ||
(catch RuntimeException _ | ||
(info "Installing mercurial") | ||
(c/exec :apt-get :install :-y :mercurial))) | ||
(c/exec :env "GOPATH=~/gocode" | ||
:go :get :-u "github.com/robustirc/robustirc") | ||
|
||
; generated by resources/gencert.go | ||
(c/upload (.getFile (io/resource "cert.pem")) "/tmp/cert.pem") | ||
(c/upload (.getFile (io/resource "key.pem")) "/tmp/key.pem") | ||
(c/ssh* {:cmd "rm -rf /var/lib/robustirc"}) | ||
(c/ssh* {:cmd "mkdir -p /var/lib/robustirc"}) | ||
(jepsen/synchronize test) | ||
|
||
(let [cmd (str | ||
"/sbin/start-stop-daemon --start --background --exec ~/gocode/bin/robustirc --" | ||
" -listen=" (name node) ":13001" | ||
" -network_password=secret" | ||
" -network_name=jepsen" | ||
" -tls_cert_path=/tmp/cert.pem" | ||
" -tls_ca_file=/tmp/cert.pem" | ||
" -tls_key_path=/tmp/key.pem" | ||
" -singlenode")] | ||
(if-not (= node (jepsen/primary test)) | ||
(Thread/sleep 1000) | ||
(do | ||
(info node (str "running: " cmd)) | ||
(c/ssh* {:cmd cmd}) | ||
(Thread/sleep 5000)))) | ||
(jepsen/synchronize test) | ||
(let [cmd (str | ||
"/sbin/start-stop-daemon --start --background --exec ~/gocode/bin/robustirc --" | ||
" -listen=" (name node) ":13001" | ||
" -network_password=secret" | ||
" -network_name=jepsen" | ||
" -tls_cert_path=/tmp/cert.pem" | ||
" -tls_ca_file=/tmp/cert.pem" | ||
" -tls_key_path=/tmp/key.pem" | ||
" -join=" (name (jepsen/primary test)) ":13001")] | ||
(if (= node (jepsen/primary test)) | ||
(Thread/sleep 100) | ||
(do | ||
(info node (str "running: " cmd)) | ||
(c/ssh* {:cmd cmd}) | ||
(Thread/sleep 5000)))) | ||
(jepsen/synchronize test) | ||
(info node "setup done"))) | ||
|
||
(teardown! [this test node] | ||
(c/su | ||
(c/ssh* {:cmd "killall robustirc"})) | ||
))) | ||
|
||
(defn with-nemesis | ||
"Wraps a client generator in a nemesis that induces failures and eventually | ||
stops." | ||
[client] | ||
(gen/phases | ||
(gen/phases | ||
(->> client | ||
(gen/nemesis | ||
(gen/seq (cycle [(gen/sleep 0) | ||
{:type :info, :f :start} | ||
(gen/sleep 10) | ||
{:type :info, :f :stop}]))) | ||
(gen/time-limit 30)) | ||
(gen/nemesis (gen/once {:type :info, :f :stop})) | ||
(gen/sleep 5)))) | ||
|
||
(defn create-session | ||
[node] | ||
(assoc (json/parse-string | ||
(get | ||
(httpclient/post (str "https://" (name node) ":13001/robustirc/v1/session") | ||
{:insecure? true}) | ||
:body)) | ||
:node node)) | ||
|
||
(defn post-message | ||
[session ircmessage] | ||
(let [msgid (bit-or (rand-int Integer/MAX_VALUE) | ||
(Long/parseLong (subs (digest/md5 ircmessage) 17) 16))] | ||
(httpclient/post | ||
(str "https://" (name (get session :node)) ":13001/robustirc/v1/" (get session "Sessionid") "/message") | ||
{:headers {"X-Session-Auth" (get session "Sessionauth")} | ||
:insecure? true | ||
:content-type :json | ||
:form-params {:Data ircmessage | ||
:ClientMessageId msgid}}))) | ||
|
||
(defn read-all | ||
[session timeoutmsec] | ||
(let [out (atom [])] | ||
(jepsen.util/timeout | ||
timeoutmsec | ||
@out | ||
(doseq [msg (json/parsed-seq (io/reader (get (httpclient/get | ||
(str "https://" (name (get session :node)) ":13001/robustirc/v1/" (get session "Sessionid") "/messages") | ||
{:headers {"X-Session-Auth" (get session "Sessionauth")} | ||
:query-params {:lastseen "0.0"} | ||
:insecure? true | ||
:as :stream}) :body)))] | ||
(swap! out conj msg))))) | ||
|
||
; XXX: use a proper IRC parser for filter-topic and extract-topic | ||
(defn filter-topic | ||
[msg] | ||
(let [s (str/split (get msg "Data") #" ")] | ||
(and | ||
(> (count s) 1) | ||
(= (nth s 1) "TOPIC")))) | ||
|
||
(defn extract-topic | ||
[msg] | ||
(let [s (str/split (get msg "Data") #":")] | ||
(Integer/parseInt (nth s (- (count s) 1))))) | ||
|
||
(defrecord SetClient [node session] | ||
client/Client | ||
|
||
(setup! [this test node] | ||
(info node "creating robustsession") | ||
(let [session (create-session node)] | ||
(info node (str "session " (get session "Sessionid"))) | ||
(post-message session (str "NICK " (name node))) | ||
(post-message session "USER j j j j") | ||
(post-message session "JOIN #jepsen") | ||
(assoc this :node node | ||
:session session))) | ||
|
||
(invoke! [this test op] | ||
(try | ||
(case (:f op) | ||
:add (try | ||
(do | ||
(post-message (-> session) (str "TOPIC #jepsen :" (:value op))) | ||
(assoc op :type :ok)) | ||
(catch Exception e | ||
(assoc op :type :fail :value :node-failure))) | ||
:read (let [msgs (read-all session 1000) | ||
filtered (filter filter-topic msgs) | ||
converted (map extract-topic filtered)] | ||
(assoc op | ||
:type :ok | ||
:value (set converted)))))) | ||
|
||
(teardown! [this test] | ||
(info node "teardown code goes here"))) | ||
|
||
(defn set-client | ||
[node] | ||
(SetClient. nil nil)) | ||
|
||
(defn basic-test | ||
[opts] | ||
(merge tests/noop-test | ||
{:name (str "robustirc " (:name opts)) | ||
:os debian/os | ||
:db (db) | ||
:nemesis (nemesis/partition-random-halves)} | ||
(dissoc opts :name :version))) | ||
|
||
(defn sets-test | ||
[version] | ||
(basic-test | ||
{:name "set" | ||
:version version | ||
:client (set-client nil) | ||
:generator (gen/phases | ||
(->> (range) | ||
(map (partial array-map | ||
:type :invoke | ||
:f :add | ||
:value)) | ||
gen/seq | ||
(gen/delay 1/10) | ||
with-nemesis) | ||
(->> {:type :invoke, :f :read, :value nil} | ||
gen/once | ||
gen/clients)) | ||
:checker (checker/compose | ||
{:perf (checker/perf) | ||
:set checker/set})})) | ||
|
||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
(ns jepsen.robustirc-test | ||
(:require [clojure.test :refer :all] | ||
[jepsen.core :refer [run!]] | ||
[jepsen.robustirc :refer :all])) | ||
|
||
(def version "0.1") | ||
|
||
(deftest sets-test' | ||
(is (:valid? (:results (run! (sets-test version)))))) |