<commit_before>(ns atomix-jepsen.core
    (:require [clojure [pprint :refer :all]
               [string :as str]]
              [clojure.java.io :as io]
              [clojure.tools.logging :refer [debug info warn error]]
              [atomix-jepsen.util :as cutil]
              [trinity.core :as trinity]
              [jepsen [core :as jepsen]
               [db :as db]
               [util :as util :refer [meh timeout]]
               [control :as c :refer [|]]
               [client :as client]
               [checker :as checker]
               [model :as model]
               [generator :as gen]
               [nemesis :as nemesis]
               [store :as store]
               [report :as report]
               [tests :as tests]]
              [jepsen.control [net :as net]
               [util :as net/util]]
              [jepsen.os.debian :as debian]
              [jepsen.checker.timeline :as timeline])

  ;(:import (java.util.concurrent ExecutionException)
  ;         (net.kuujo.copycat Copycat CopycatClient CopycatReplica))
  )

(defn- node-id [node]
  (Integer/parseInt (subs (name node) 1)))

; Test lifecycle

(defn install!
  "Installs atomix on the given node."
  [node version]

  ; Setup for non atomix-jepsen Docker environments
  (when (nil? (debian/installed-version "oracle-java8-installer"))
    (info node "installing JDK")
    (c/su
      (c/exec :echo (c/lit "\"deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main\" | tee /etc/apt/sources.list.d/webupd8team-java.list"))
      (c/exec :echo (c/lit "\"deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main\" | tee -a /etc/apt/sources.list.d/webupd8team-java.list"))
      (c/exec :echo (c/lit "oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections"))
      (c/exec :apt-key (c/lit "adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886")))
    (debian/update!)
    (debian/install ["oracle-java8-installer" "oracle-java8-set-default" "git" "maven"]))

  ; Install atomix
  (when (not (get (System/getenv) "DEV"))
    (c/su
      (info node "fetching atomix")
      (if-not (cutil/dir-exists "/opt/atomix")
        (c/cd "/opt"
              (c/exec :git :clone "https://github.com/atomix/atomix.git"))
        (c/cd "/opt/atomix"
              (c/exec :git :pull)))
      (info node "building atomix")
      (c/cd "/opt/atomix"
            (c/exec :git :checkout)
            (c/exec :mvn :clean :install "-DskipTests=true"))
      (c/cd "/opt/atomix/examples"
            (c/exec :mvn :clean :install)))))

(defn start!
  "Starts atomix."
  [node test]
  (let [nodes (into #{} (:nodes test))
        other-nodes (clojure.set/difference nodes (set [node]))
        local-node-arg "5555"
        other-node-args (doall (map #(str (name %) ":5555")
                                    other-nodes))
        jarfile "/root/.m2/repository/io/atomix/atomix-standalone-server-example/0.1.0-SNAPSHOT/atomix-standalone-server-example-0.1.0-SNAPSHOT-shaded.jar"]
    (info node "starting atomix")
    (meh (c/exec :truncate :--size 0 "/var/log/atomix.log"))
    (c/su
      (meh (c/exec :rm :-rf "/root/logs/"))
      (c/cd "/root"
            (c/exec :java :-jar jarfile local-node-arg other-node-args
                    (c/lit "2>> /dev/null >> /var/log/atomix.log & echo $!"))))))

(defn stop!
  "Stops atomix."
  [node]
  (info node "stopping atomix")
  (c/su
    (meh (c/exec :pkill :-9 :java))))

(defn db
  "Atomix database"
  [version]
  (reify db/DB
    (setup! [this test node]
      (doto node
        (install! version)
        (start! test)))

    (teardown! [this test node]
      (stop! node))))

; Test clients

(defrecord CasRegisterClient [client register nodes]
  client/Client
  (setup! [this test node]
    (let [node-set (map #(hash-map :host (name %)
                                   :port 5555)
                        nodes)]
      (cutil/try-until-success
        #(do
          (info "Creating client connection to" node-set)
          (let [client (trinity/client node-set)
                test-name (:name test)]
            (debug node "Client connected!")
            (assoc this :client client)
            (debug node "Created atomix resource " test-name)
            (assoc this :register (trinity/dist-atom client test-name))))
        #(do
          (debug node "Connection attempt failed. Retrying..." %)
          (Thread/sleep 2000)))))

  (invoke! [this test op]
    (case (:f op)
      :read (assoc op
              :type :ok,
              :value (trinity/get register))

      :write (do
               (trinity/set! register (:value op))
               (assoc op :type :ok))

      :cas (let [[v v'] (:value op)
                 ok? (trinity/cas! register v v')]
             (assoc op :type (if ok? :ok :fail)))))

  (teardown! [this test]
    (info "Closing client " this)
    (trinity/close! client)))<commit_msg>Close client properly after test<commit_after>(ns atomix-jepsen.core
    (:require [clojure [pprint :refer :all]
               [string :as str]]
              [clojure.java.io :as io]
              [clojure.tools.logging :refer [debug info warn error]]
              [atomix-jepsen.util :as cutil]
              [trinity.core :as trinity]
              [jepsen [core :as jepsen]
               [db :as db]
               [util :as util :refer [meh timeout]]
               [control :as c :refer [|]]
               [client :as client]
               [checker :as checker]
               [model :as model]
               [generator :as gen]
               [nemesis :as nemesis]
               [store :as store]
               [report :as report]
               [tests :as tests]]
              [jepsen.control [net :as net]
               [util :as net/util]]
              [jepsen.os.debian :as debian]
              [jepsen.checker.timeline :as timeline])

  ;(:import (io.atomix Atomix AtomixClient AtomixReplica)
  ;         )
  )

(defn- node-id [node]
  (Integer/parseInt (subs (name node) 1)))

; Test lifecycle

(defn install!
  "Installs atomix on the given node."
  [node version]

  ; Setup for non atomix-jepsen Docker environments
  (when (nil? (debian/installed-version "oracle-java8-installer"))
    (info node "installing JDK")
    (c/su
      (c/exec :echo (c/lit "\"deb http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main\" | tee /etc/apt/sources.list.d/webupd8team-java.list"))
      (c/exec :echo (c/lit "\"deb-src http://ppa.launchpad.net/webupd8team/java/ubuntu trusty main\" | tee -a /etc/apt/sources.list.d/webupd8team-java.list"))
      (c/exec :echo (c/lit "oracle-java8-installer shared/accepted-oracle-license-v1-1 select true | sudo /usr/bin/debconf-set-selections"))
      (c/exec :apt-key (c/lit "adv --keyserver hkp://keyserver.ubuntu.com:80 --recv-keys EEA14886")))
    (debian/update!)
    (debian/install ["oracle-java8-installer" "oracle-java8-set-default" "git" "maven"]))

  ; Install atomix
  (when (not (get (System/getenv) "DEV"))
    (c/su
      (info node "fetching atomix")
      (if-not (cutil/dir-exists "/opt/atomix")
        (c/cd "/opt"
              (c/exec :git :clone "https://github.com/atomix/atomix.git"))
        (c/cd "/opt/atomix"
              (c/exec :git :pull)))
      (info node "building atomix")
      (c/cd "/opt/atomix"
            (c/exec :git :checkout)
            (c/exec :mvn :clean :install "-DskipTests=true"))
      (c/cd "/opt/atomix/examples"
            (c/exec :mvn :clean :install)))))

(defn start!
  "Starts atomix."
  [node test]
  (let [nodes (into #{} (:nodes test))
        other-nodes (clojure.set/difference nodes (set [node]))
        local-node-arg "5555"
        other-node-args (doall (map #(str (name %) ":5555")
                                    other-nodes))
        jarfile "/root/.m2/repository/io/atomix/atomix-standalone-server-example/0.1.0-SNAPSHOT/atomix-standalone-server-example-0.1.0-SNAPSHOT-shaded.jar"]
    (info node "starting atomix")
    (meh (c/exec :truncate :--size 0 "/var/log/atomix.log"))
    (c/su
      (meh (c/exec :rm :-rf "/root/logs/"))
      (c/cd "/root"
            (c/exec :java :-jar jarfile local-node-arg other-node-args
                    (c/lit "2>> /dev/null >> /var/log/atomix.log & echo $!"))))))

(defn stop!
  "Stops atomix."
  [node]
  (info node "stopping atomix")
  (c/su
    (meh (c/exec :pkill :-9 :java))))

(defn db
  "Atomix database"
  [version]
  (reify db/DB
    (setup! [this test node]
      (doto node
        (install! version)
        (start! test)))

    (teardown! [this test node]
      (stop! node))))

; Test clients

(defrecord CasRegisterClient [client register nodes]
  client/Client
  (setup! [this test node]
    (let [node-set (map #(hash-map :host (name %)
                                   :port 5555)
                        nodes)]
      (cutil/try-until-success
        #(do
          (info "Creating client connection to" node-set)
          (let [atomix-client (trinity/client node-set)
                _ (debug node "Client connected!")
                test-name (:name test)
                register (trinity/dist-atom atomix-client test-name)]
            (debug node "Created atomix resource " test-name)
            (assoc this :client atomix-client
                        :register register)))
        #(do
          (debug node "Connection attempt failed. Retrying..." %)
          (Thread/sleep 2000)))))

  (invoke! [this test op]
    (case (:f op)
      :read (assoc op
              :type :ok,
              :value (trinity/get register))

      :write (do
               (trinity/set! register (:value op))
               (assoc op :type :ok))

      :cas (let [[v v'] (:value op)
                 ok? (trinity/cas! register v v')]
             (assoc op :type (if ok? :ok :fail)))))

  (teardown! [this test]
    (info "Closing client " client)
    (trinity/close! client)))
{'fraction_non_alphanumeric': 0.15068078668683813, 'fraction_numerical': 0.008875441250630358, 'mean_word_length': 1.9398161873702935, 'pattern_counts': {'":': 2, '<': 3, '<?xml version=': 0, '>': 11, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4595659', 'n_tokens_mistral': 3446, 'n_tokens_neox': 3294, 'n_words': 841}