AtlatestRepositorycourier
1
(import (sigil test)2
(sigil string)3
(sigil fs)4
(sigil path)5
(sigil process)6
(courier poller))8
;; ============================================================9
;; getUpdates offset persistence (the second-spam-cause fix)10
;; ============================================================11
;;12
;; The poller's getUpdates offset (tg-client last-update-id) must13
;; survive a process restart, or a fresh child starts at offset 0 and14
;; re-delivers Telegram's entire ~24h backlog -- the leader then acks15
;; each re-delivered message, an outbound storm. These tests cover the16
;; durable-offset primitives: round-trip, and the "cold start" signals17
;; (missing / non-positive / garbage file) that trigger a silent drain18
;; instead of delivering a stale backlog.20
;; Point the relay dir (and thus the offset file) at a fresh temp dir.21
;; offset-file-path is <dirname(relay-dir)>/telegram-offset.22
(define (with-temp-offset thunk)23
(let ((tmp (make-temp-directory)))24
(setenv! "COURIER_RELAY_DIR" (path-join tmp "relays"))25
(let ((result (thunk tmp)))26
(setenv! "COURIER_RELAY_DIR" "")27
(guard (e (else #f)) (delete-directory tmp))28
result)))30
(test-group "offset-file-path"31
(test "sits beside the relay dir, not inside it"32
(with-temp-offset33
(lambda (tmp)34
;; dirname(<tmp>/relays) == <tmp>35
(assert-equal (path-join tmp "telegram-offset")36
(offset-file-path))))))38
(test-group "load-persisted-offset — cold-start signals"39
(test "missing file -> #f (cold start: drain the backlog)"40
(with-temp-offset41
(lambda (tmp)42
(assert-false (load-persisted-offset)))))44
(test "garbage file -> #f (corrupt: treat as cold start)"45
(with-temp-offset46
(lambda (tmp)47
(write-file-string (offset-file-path) "not-a-number")48
(assert-false (load-persisted-offset)))))50
(test "zero -> #f (offset 0 means no offset -> would re-fetch backlog)"51
(with-temp-offset52
(lambda (tmp)53
(write-file-string (offset-file-path) "0")54
(assert-false (load-persisted-offset)))))56
(test "empty file -> #f"57
(with-temp-offset58
(lambda (tmp)59
(write-file-string (offset-file-path) "")60
(assert-false (load-persisted-offset))))))62
(test-group "save-offset! / load-persisted-offset round-trip"63
(test "a saved positive offset reloads exactly"64
(with-temp-offset65
(lambda (tmp)66
(save-offset! 42)67
(assert-equal 42 (load-persisted-offset)))))69
(test "re-saving overwrites (offset only advances forward)"70
(with-temp-offset71
(lambda (tmp)72
(save-offset! 42)73
(save-offset! 100)74
(assert-equal 100 (load-persisted-offset)))))76
(test "large update_id round-trips (no precision loss)"77
(with-temp-offset78
(lambda (tmp)79
(save-offset! 999999999)80
(assert-equal 999999999 (load-persisted-offset)))))82
(test "trailing whitespace in the file is tolerated"83
(with-temp-offset84
(lambda (tmp)85
(write-file-string (offset-file-path) "57\n")86
(assert-equal 57 (load-persisted-offset))))))88
;; ============================================================89
;; Sentinel-zero hole (the 2026-07-02 live storm)90
;; ============================================================91
;;92
;; A count=0 cold-start drain leaves the offset at 0. Persisting 0 seeds93
;; Telegram's "no offset / send me everything" sentinel; a later start94
;; that trusts it re-fetches and re-delivers the whole backlog. So95
;; save-offset! must NEVER write a non-positive value, and must clear any96
;; existing file so the next start cold-drains instead.98
(test-group "save-offset! — never persists the sentinel 0"99
(test "saving 0 writes NO file"100
(with-temp-offset101
(lambda (tmp)102
(save-offset! 0)103
(assert-false (file-exists? (offset-file-path)))104
(assert-false (load-persisted-offset)))))106
(test "saving 0 CLEARS a previously-persisted offset"107
(with-temp-offset108
(lambda (tmp)109
(save-offset! 99)110
(assert-equal 99 (load-persisted-offset))111
;; e.g. a later empty-backlog cold start112
(save-offset! 0)113
(assert-false (file-exists? (offset-file-path)))114
(assert-false (load-persisted-offset)))))116
(test "saving a negative value writes NO file"117
(with-temp-offset118
(lambda (tmp)119
(save-offset! -3)120
(assert-false (file-exists? (offset-file-path)))121
(assert-false (load-persisted-offset)))))123
(test "a positive offset still persists and reloads"124
(with-temp-offset125
(lambda (tmp)126
(save-offset! 7)127
(assert-true (file-exists? (offset-file-path)))128
(assert-equal 7 (load-persisted-offset))))))130
(run-tests)