persist: atomic batch append — contiguous block + transactional guard + 10 tests
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 43s
Some checks failed
Test, Build, and Deploy / test-build-deploy (push) Failing after 43s
batch.sx: persist/append-batch commits (type at data) specs as one contiguous block; persist/append-batch-expect checks the stream is still at expected before writing any event, so the batch is all-or-nothing under a concurrent writer (conflict is a value, not a partial write). 162/162. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
122
lib/persist/tests/batch.sx
Normal file
122
lib/persist/tests/batch.sx
Normal file
@@ -0,0 +1,122 @@
|
||||
; Extension — atomic batch append: contiguous seqs, transactional all-or-nothing.
|
||||
|
||||
(persist-test
|
||||
"batch assigns contiguous seqs"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(let
|
||||
((evs (persist/append-batch b "s" (list (list "a" 0 {}) (list "b" 0 {}) (list "c" 0 {})))))
|
||||
(list
|
||||
(persist/event-seq (first evs))
|
||||
(persist/event-seq (nth evs 2)))))
|
||||
(list 1 3))
|
||||
(persist-test
|
||||
"batch returns events in order"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(let
|
||||
((evs (persist/append-batch b "s" (list (list "a" 0 {}) (list "b" 0 {})))))
|
||||
(list
|
||||
(persist/event-type (first evs))
|
||||
(persist/event-type (nth evs 1)))))
|
||||
(list "a" "b"))
|
||||
(persist-test
|
||||
"batch grows the stream by its size"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(begin
|
||||
(persist/append-batch
|
||||
b
|
||||
"s"
|
||||
(list
|
||||
(list "a" 0 {})
|
||||
(list "b" 0 {})
|
||||
(list "c" 0 {})))
|
||||
(persist/count b "s")))
|
||||
3)
|
||||
(persist-test
|
||||
"batch continues an existing stream"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(begin
|
||||
(persist/append b "s" "x" 0 {})
|
||||
(let
|
||||
((evs (persist/append-batch b "s" (list (list "a" 0 {}) (list "b" 0 {})))))
|
||||
(persist/event-seq (first evs)))))
|
||||
2)
|
||||
(persist-test
|
||||
"empty batch is a no-op"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(begin (persist/append-batch b "s" (list)) (persist/count b "s")))
|
||||
0)
|
||||
(persist-test
|
||||
"batch-expect with correct seq commits all"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(begin
|
||||
(persist/append-batch-expect
|
||||
b
|
||||
"s"
|
||||
0
|
||||
(list
|
||||
(list "a" 0 {})
|
||||
(list "b" 0 {})))
|
||||
(persist/count b "s")))
|
||||
2)
|
||||
(persist-test
|
||||
"batch-expect with stale seq writes nothing"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(begin
|
||||
(persist/append b "s" "x" 0 {})
|
||||
(persist/append-batch-expect
|
||||
b
|
||||
"s"
|
||||
0
|
||||
(list
|
||||
(list "a" 0 {})
|
||||
(list "b" 0 {})))
|
||||
(persist/count b "s")))
|
||||
1)
|
||||
(persist-test
|
||||
"batch-expect stale returns a conflict"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(begin
|
||||
(persist/append b "s" "x" 0 {})
|
||||
(persist/conflict?
|
||||
(persist/append-batch-expect
|
||||
b
|
||||
"s"
|
||||
0
|
||||
(list (list "a" 0 {}))))))
|
||||
true)
|
||||
(persist-test
|
||||
"batch data is preserved"
|
||||
(let
|
||||
((b (persist/open)))
|
||||
(begin
|
||||
(persist/append-batch
|
||||
b
|
||||
"order"
|
||||
(list
|
||||
(list "placed" 0 {:id 1})
|
||||
(list "line" 0 {:sku "x"})))
|
||||
(get
|
||||
(persist/event-data (nth (persist/read b "order") 1))
|
||||
:sku)))
|
||||
"x")
|
||||
(persist-test
|
||||
"batch works on the durable backend"
|
||||
(let
|
||||
((db (persist/mock-durable (persist/mem-backend))))
|
||||
(begin
|
||||
(persist/append-batch
|
||||
db
|
||||
"s"
|
||||
(list
|
||||
(list "a" 0 {})
|
||||
(list "b" 0 {})))
|
||||
(persist/last-seq db "s")))
|
||||
2)
|
||||
Reference in New Issue
Block a user