Commit Graph
230 Commits
Author SHA1 Message Date
Adrien Beraud fa78704062 transport: test permanent grants and authority transitions 2026-11-01 22:12:28 -05:00
Adrien Beraud 625625a186 tests: isolate projection scheduling from transport handshakes 2026-10-29 23:35:22 -04:00
Adrien Beraud f0d039b4a0 tests: keep persisted transport paths as filesystem paths 2026-10-29 23:28:48 -04:00
Adrien Beraud d464214d73 tests: use portable paths for persisted transport keys 2026-10-29 23:28:48 -04:00
Adrien Beraud 3d9ee6a51a tests: verify cached private authorization expires and renews 2026-10-29 23:28:48 -04:00
Adrien Beraud f71697c81b tests: cover private client authorization and cached credential limits 2026-10-29 23:28:48 -04:00
Adrien Beraud b071022283 tests: fix transport test portability on GCC and Windows 2026-10-29 23:28:48 -04:00
Adrien Beraud 20464e6f16 tests: cover rejected sessions and cross-sender fragments 2026-10-29 23:28:48 -04:00
Adrien Beraud bde661a2d4 tests: verify session key destruction erases secrets 2026-10-29 23:28:48 -04:00
Adrien Beraud e5903d5c94 tests: check separate request, session and public-key rate limits 2026-10-29 23:28:48 -04:00
Adrien Beraud c14858a82a tests: exercise private routing and unreachable search peers 2026-10-29 23:28:48 -04:00
Adrien Beraud 1010a4c90f tests: cover establishment failure and legacy fallback 2026-10-29 23:28:48 -04:00
Adrien Beraud 36f67747d7 tests: preserve routing progress during cold session establishment 2026-10-29 23:28:48 -04:00
Adrien Beraud b093dc0907 tests: cover cold establishment and delayed recovery replies 2026-10-29 23:28:48 -04:00
Adrien Beraud 35aa47029e tests: reject unvalidated transport value requests 2026-10-29 23:28:48 -04:00
Adrien Beraud 858867dc56 tests: check that session recovery withholds every request to the peer 2026-10-29 23:28:48 -04:00
Adrien Beraud dc09983b6b tests: require session recovery before resending payloads, and envelope-sized fragments 2026-10-29 23:28:48 -04:00
Adrien Beraud ed8131a3c6 tests: require value fragments to fit the IPv6 minimum MTU 2026-10-29 23:28:48 -04:00
Adrien Beraud 3cf24c89d4 tests: require atomic transport-key state persistence 2026-10-29 23:28:48 -04:00
Adrien Beraud 8ac6baee22 tests: require fixed-width node transport badges 2026-10-29 23:28:48 -04:00
Adrien Beraud 35f486e035 tests: cover node transport state formatting 2026-10-29 23:28:48 -04:00
Adrien Beraud efc372dc3f tests: cover transport trust and address validation boundaries 2026-10-29 23:28:48 -04:00
Adrien Beraud 51324683e8 tests: cover forged parts in encrypted fragmented messages
Value data fragments carry no node ID. Parts of a message received in
envelopes must all come under the sender key of the envelopes, so that
plaintext or foreign-key parts spoofed from the sender's address, which
would otherwise be merged first, are ignored.
2026-10-29 23:28:48 -04:00
Adrien Beraud 32709230c6 tests: cover session cache hijacking by unvalidated senders
Replies to Initial and Hello envelopes must not cache a session at the
source address, which can be spoofed, and the cache must evict the least
recently used session rather than the lowest address. A node that started
with an Initial envelope only switches to Data envelopes once the peer
answered a Session envelope, which is when the peer caches the session.
2026-10-29 23:28:48 -04:00
Adrien Beraud d23cb42b27 tests: cover a peer restarting with the same key
A node restarting with the same key and contacting a peer by address gets answers encrypted with the ephemeral key of its previous run.
2026-10-29 23:28:48 -04:00
Adrien Beraud 40560eec4e tests: cover keyless Data envelopes and session confirmation
Steady-state traffic uses Data envelopes, without sender keys nor credential, once the peer answered a request. Data envelopes only open from the session address, also authorize writes, and survive the receiver's epoch rotation.
2026-10-29 23:28:48 -04:00
Adrien Beraud dfb66c5a23 tests: cover session-based write authorization and address-bound keys
Encrypted writes must come in a Session envelope, whose ephemeral key is bound to the sender address. Plaintext writes still need a token, now issued by the network engine.
2026-10-29 23:28:48 -04:00
Adrien Beraud 791a667fe2 tests: cover ephemeral key rotation, peer restart and hello
The previous ephemeral key is accepted for one more period, then erased.
A request retry restarts with an Initial envelope and our credential.
A hello is only answered and doesn't change what is known of its sender.
2026-10-29 23:28:48 -04:00
Adrien Beraud b693e3028b tests: cover forward-secret transport keys and envelope header
Session keys are directional and mix both static and ephemeral keys,
Initial keys are used before the peer's ephemeral key is known.
2026-10-29 23:28:48 -04:00
Adrien Beraud 43147b8791 tests: check generated transport key persistence 2026-10-29 23:28:48 -04:00
Adrien Beraud 68b5996ba9 tests: cover encrypted transport and private networks 2026-10-29 23:28:48 -04:00
Adrien Beraud 523dda8b3d tests: add transport primitives tests 2026-10-29 23:28:48 -04:00
Adrien Beraud a09cfefe5e tests: require native alignment for C hashes 2026-10-27 00:03:07 -04:00
Adrien Beraud 3f7b1bc3f5 tests: cover unaligned C hash storage 2026-10-26 23:56:59 -04:00
Adrien Beraud 019c25633e tests: initialize GnuTLS for MSVC C bindings 2026-10-26 23:56:43 -04:00
Adrien Beraud 0d120eb5d4 tests: cover projected query request scheduling 2026-10-26 09:21:10 -04:00
Cyrille BéraudandCopilot 9b9056c0c8 dht: do not report unfiltered answers to filtered queries
Query::isSatisfiedBy() considers an unfiltered answer sufficient for a
filtered query, which is true for a vanilla get: onGetValuesDone() applies
the operation filter to the values before calling back.

A projected query is different. It receives the fields another query selected
and can no longer evaluate its own filters on them, all the more so as those
filters may target fields that were not selected at all. Two concurrent
queries such as "SELECT id" and "SELECT id WHERE value_type=1" therefore made
the filtered callback report identifiers whose type does not match, and
searchNodeGetDone() additionally cancelled its own request so it never got a
correctly filtered answer.

Add Query::isProjectionSatisfiedBy(), which additionally requires both queries
to apply the same filters, and use it for operations with a query callback.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-26 09:21:10 -04:00
Cyrille BéraudandCopilot bf8e3ea251 value: compare field values in FieldValueIndex::containedIn
containedIn() only checked that the other index declared the same field
keys, never that they held the same values, contradicting its documented
contract of containment "with the same value".

Dht::query() uses containedIn() to deduplicate projected results. Because
every result of a given query shares the same projection schema, any two
results compared equal: the first one suppressed all the later ones, and the
"lesser" branch even erased the already reported result. A query selecting a
field therefore reported a single value regardless of how many matched.

Compare the FieldValue as well, and add a regression covering distinct
values, equal indexes and a narrower projection contained in a wider one.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-26 09:21:10 -04:00
Adrien Beraud da438d1bd2 value: reproduce sequence filter serialization failure 2026-10-26 09:12:12 -04:00
Adrien Beraud 42e4419b75 bindings: verify retained values and queued push delivery 2026-10-26 00:51:27 -04:00
Adrien Beraud 0285acc766 c: cover lifecycle progress and crypto persistence APIs 2026-10-26 00:51:27 -04:00
Adrien Beraud aa01f68cb5 c: cover binding ownership and invalid crypto input 2026-10-26 00:51:27 -04:00
Cyrille BéraudandCopilot 20fa751da0 tests: check push platform of proxy notifications
Move the fake push gateway of the full chain test into a reusable
helper, and add two tests showing that the proxy server pushes to the
wrong platform:
- when a device refreshes its subscription with another platform,
  new values keep being pushed with the platform of the first
  subscription;
- a platform set after the proxy client started is not used by its
  subscriptions.

Co-authored-by: Copilot (Claude Opus 5.5) <223556219+Copilot@users.noreply.github.com>
2026-10-26 02:55:59 +00:00
Adrien Beraud 9ffccb3956 pht: test prefix padding compatibility 2026-10-25 03:03:35 +00:00
Cyrille BéraudandCopilot d99324ebd4 pht: fix the bit arithmetic of Prefix
Prefix::size_ counts bits, but commonBits walked content_ a byte at a
time up to it. Two prefixes that agree on their whole common length are
therefore read well past their end, which AddressSanitizer reports as a
heap-buffer-overflow, and the count that comes back is eight times too
large. A lookup with a common prefix length hits this as soon as an
index entry matches the key it is looking for, and entry.prefix comes
straight off the network. The flags were indexed the same way, so a
partially known prefix was read at the wrong position too.

swapBit had the other half of the confusion: it flipped bit
(8 - bit) % 8 of the byte, while isActiveBit reads bit 7 - (bit % 8).
getSibling, which flips the last bit of a prefix to name the sibling
node in the trie, therefore returned a prefix differing in some other
bit and sharing the last one, so lookup and insertion looked up the
wrong node. Splitting a leaf and finding a canary both rely on it.

Add tests covering both, which fail before the fix: commonBits returns
193 for two identical 160 bit prefixes, and a prefix and its sibling
share 7 bits rather than all but the last.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-10-25 03:03:35 +00:00
Cyrille BéraudandCopilot 18fedf431f tests: cover pushes received by stopped runners
Require immediate completion before run and after join, including a burst of notifications. Keep active-runner coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-09-21 16:02:47 -04:00
Adrien Beraud 1f6efd5736 tests: cover same-content higher-seq re-announce in ValueCache
Value::operator== ignores seq, so a node re-announcing identical content
with a bumped seq is the same value refreshed, not an edition. ValueCache
must not re-emit it: a source-counting OpValueCache above would count the
node twice and keep the value after the node is gone.
2026-09-04 15:44:35 -04:00
Adrien Beraud 1315489a7b tests: cover expiry of an uncounted same-seq version in OpValueCache
A source reporting a different payload with the same seq is ignored on
add and not counted; its later expiration must not release the value
still held by the counted sources.
2026-09-04 15:18:35 -04:00
Adrien Béraud 74a894229f value_cache, op_cache: fix value accounting after edition and re-delivery
OpValueCache counted every re-delivery of an identical value as a new
source, but the proxy client is a single logical source that re-sends
values on push refresh or listen restart: the refcount grew unbounded
and expirations were never propagated. Add a countSources flag to
OpValueCache, OpCache and SearchCache; the proxy client disables it.

When a value is edited (same id, higher seq), only the reporting source
is known to hold the new version: replace it in place, reset the
refcount to 1 and emit a single add. Ignore older versions from lagging
sources on add, and ignore their expiration so they cannot release a
newer version still held by others.

ValueCache emits an edited value as an add instead of silently
refreshing its old copy, and applies a grace period of one type
expiration while the listen is synced so that a single lost refresh
notification does not drop a value the remote node still holds.

SearchCache::get only answers from the cache once the listen is synced,
so a get never returns a partial view that the network would complete.

Add the single-source OpCacheTester cases enabled by countSources.
2026-09-04 15:18:13 -04:00
Adrien Beraud c81c1f70c8 tests: add listen cache tests for OpValueCache, ValueCache, DhtRunner and proxy
OpCacheTester and ValueCacheTester exercise the listen caches in
isolation: add/edit/expire flows, per-source refcounting, stale
versions, sync status, SearchCache::get and node drop.

DhtRunnerTester and DhtProxyTester gain end-to-end listen tests for
value edition, duplicate puts, multi-source and partial expiration,
get after a synced listen, and the push refresh/expire paths.

The proxy fixture joins the proxy DhtRunner before destroying the
DhtProxyServer so no DHT callback can reach a destroyed server, and
push notifications are never awaited while holding the mutex taken by
listen callbacks: the result is produced on the DHT thread.

Register the new executables in CMake and Meson.
2026-09-04 15:17:34 -04:00