Fork me on GitHub
#xtdb
<
2021-08-10
>
sheluchin01:08:00

I'm trying to add some integration tests and I keep getting inconsistent results between runs. Any help would be appreciated. The code:

(ns sheluchin.server.db.queries
  (:require
    [crux.query]
    [crux.api :as crux]
    [com.fulcrologic.guardrails.core :refer [>defn >def | ? =>]]
    [clojure.spec.alpha :as s]
    [taoensso.timbre :as log]
    [sheluchin.server.db.mounts :as db]))

(>defn put!
  [node doc]
  [:sheluchin.specs/crux-node (s/keys :req [:crux.db/id]) => (s/keys :req [:crux.tx/tx-id :crux.tx/tx-time])]
  (crux/submit-tx node [[:crux.tx/put doc]]))

(>defn new-note-list!
  "Save a new NoteList to the database"
  [node {:note-list/keys [id]}]
  ;; TODO: change to :sheluchin.ui/note-list
  [:sheluchin.specs/crux-node (s/map-of keyword? :note-list/id) => map?]
  (log/info "Creating NoteList with :note-list/id " id)
  (put! node
    {:crux.db/id id
     :note-list/id id}))

(defn- query
  [node q]
  (crux/q (crux/db node) q))

(>defn get-note-lists
  [node]
  [:sheluchin.specs/crux-node => (s/coll-of vector?)]
  (query node
          '{:find [id]
            :where [[id :note-list/id]]}))
The tests:
(ns sheluchin.prj.query-test
  (:require [clojure.test :as t]
            [crux.api :as crux]
            [fulcro-spec.core :refer [specification  ;; a wrapper for deftest
                                      behavior
                                      component
                                      assertions
                                      when-mocking]]
            [sheluchin.server.db.queries :as q]
            [sheluchin.specs]))
            ; [hashp.core :include-macros true]))

(def crux-node nil)

(defn with-crux [f]
  (with-redefs [crux-node (crux/start-node {})]
    (f)))

(defn with-note-list [f]
  (let [note-list {:note-list/id :singleton}]
    (q/new-note-list! crux-node note-list)
    (f)
    (q/delete-note-list! crux-node note-list)))

(t/use-fixtures :each with-crux
                      with-note-list
                      #_
                      with-notes)

(t/deftest fixture-test
  (t/testing "Do fixtures work?"
    (t/is (= #{[:singleton]} (q/get-note-lists crux-node)))
    (t/is (= [:crux.tx/tx-id :crux.tx/tx-time]
             (keys (q/new-note-list! crux-node {:note-list/id :test-note-list}))))
    (t/is (= #{[:singleton] [:test-note-list]} (q/get-note-lists crux-node)))))
Here are three different sets of errors, all of which I got by just re-running the tests:
;; fixture-test: Do fixtures work? (Line: 34)
expected: #{[:singleton]}
  actual: #{}
   diffs: - #{[:singleton]}
          + nil

;; fixture-test: Do fixtures work? (Line: 37)
expected: #{[:singleton] [:test-note-list]}
  actual: #{}
   diffs: - #{[:singleton] [:test-note-list]}
          + nil
;; fixture-test: Do fixtures work? (Line: 34)
expected: #{[:singleton]}
  actual: #{}
   diffs: - #{[:singleton]}
          + nil

;; fixture-test: Do fixtures work? (Line: 37)
expected: #{[:singleton] [:test-note-list]}
  actual: #{[:singleton]}
   diffs: - #{[:test-note-list]}
          + nil
;; fixture-test: Do fixtures work? (Line: 34)
expected: #{[:singleton]}
  actual: #{}
   diffs: - #{[:singleton]}
          + nil
Oh, and sometimes all tests pass using all the same code 🙂

seancorfield01:08:23

@alex.sheluchin My first thought is that submit-tx is async and you're not waiting for the TX to complete/sync.

seancorfield01:08:58

I think you need to update with-note-list to call crux/await-tx on the result of q/new-note-list! to ensure that the TX has been indexed before you run your test/functions. (caveat: I'm brand new to Crux)

🙏 4
sheluchin14:08:39

@U04V70XH6 thanks very much. That did it.

michael zhou16:08:16

There is a babashka pod for datalevin https://github.com/juji-io/datalevin#babashka-pod. Crux is great! Wish a bb pod for crux to do with data locally. @taylor.jeremydavid Thanks.

refset17:08:36

Hi 🙂 thanks for the pointer, the pod implementation doesn't look like it would be hugely dissimilar for Crux either so this is pretty good starting point: https://github.com/juji-io/datalevin/blob/master/src/pod/huahaiy/datalevin.clj The main difference would be that Crux still requires a JVM since we don't officially support Graal native compilation Would you be interested to pair on it together sometime? Could be fun! Also I'll probably never get around to it otherwise 😅

refset23:08:31

The idea in the other thread about using crux-http-client is probably the way to go

michael zhou00:08:26

thanks, will try.