diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1a5f3524..7722ec0c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -97,7 +97,9 @@ jobs: run: python3 scripts/check_reticulum_runtime_budget_policy.py - name: Verify track file streaming - run: python3 scripts/check_track_file_streaming.py + run: | + python3 tests/test_track_file_streaming_guard.py + python3 scripts/check_track_file_streaming.py - name: Verify repository root has no build artifacts run: python3 scripts/check_root_build_artifacts.py diff --git a/modules/core_chat/include/chat/ports/i_geocaching_transport.h b/modules/core_chat/include/chat/ports/i_geocaching_transport.h index 2faab24d..2501c49b 100644 --- a/modules/core_chat/include/chat/ports/i_geocaching_transport.h +++ b/modules/core_chat/include/chat/ports/i_geocaching_transport.h @@ -1,8 +1,8 @@ #pragma once #include "chat/domain/chat_types.h" #include "chat/infra/lxmf/lxmf_wire.h" -#include #include +#include namespace chat { @@ -28,7 +28,7 @@ struct GeocachingAnnouncementView ByteSpan app_data; }; using GeocachingAnnouncementHandler = void (*)(const GeocachingAnnouncementView&, void*); -} +} // namespace lxmf // Optional application transport capability; unrelated adapters need not // implement it. The owning router controls lifetime and serializes access. class IGeocachingTransport @@ -36,9 +36,15 @@ class IGeocachingTransport public: virtual ~IGeocachingTransport() = default; virtual bool getGeocachingAuthorKey(uint8_t out[64]) - { if (out) std::memset(out, 0, 64); return false; } + { + if (out) std::memset(out, 0, 64); + return false; + } virtual bool signGeocachingRecord(lxmf::ByteSpan, uint8_t*, size_t, uint8_t*, size_t, size_t& written) - { written = 0; return false; } + { + written = 0; + return false; + } // Input bytes are borrowed for this call only; deferred transport work must // own its encoded payload and must not retain the caller's pointer. virtual MeshSendResult sendGeocachingData(const uint8_t destination_hash[16], diff --git a/modules/core_geocaching/include/geocaching/gpx/write_record.h b/modules/core_geocaching/include/geocaching/gpx/write_record.h index b6c0ee17..0d3f93a5 100644 --- a/modules/core_geocaching/include/geocaching/gpx/write_record.h +++ b/modules/core_geocaching/include/geocaching/gpx/write_record.h @@ -1,12 +1,12 @@ #pragma once -#include "gps/gpx/text_writer.h" #include "geocaching/protocol/verify_record.h" +#include "gps/gpx/text_writer.h" #include namespace geocaching::gpx { -using gps::gpx::OutputSink; using gps::gpx::GpxTextWriter; +using gps::gpx::OutputSink; inline bool writeGeocacheGpx(const protocol::VerifiedRecordView& verified, protocol::RecordCrypto& crypto, OutputSink& sink) { diff --git a/modules/core_geocaching/include/geocaching/protocol/verify_record.h b/modules/core_geocaching/include/geocaching/protocol/verify_record.h index 2f19c599..87176718 100644 --- a/modules/core_geocaching/include/geocaching/protocol/verify_record.h +++ b/modules/core_geocaching/include/geocaching/protocol/verify_record.h @@ -41,14 +41,16 @@ inline VerificationResult deriveGeocacheHashes(ByteView encoded, RecordCrypto& c uint8_t* workspace, size_t capacity, GeocacheId& id, RevisionHash& hash) { - id = {}; hash = {}; + id = {}; + hash = {}; RecordView record; if (!decodeGeocacheRecord(encoded, record)) return VerificationResult::InvalidRecord; constexpr char id_domain[] = "trailmate.geocache/id/v1"; constexpr char revision_domain[] = "trailmate.geocache/revision/v1"; const auto required = sizeof(revision_domain) + encoded.size; if (!workspace || capacity < required || capacity < sizeof(id_domain) + 80) return VerificationResult::WorkspaceTooSmall; - GeocacheId candidate_id; RevisionHash candidate_hash; + GeocacheId candidate_id; + RevisionHash candidate_hash; std::memcpy(workspace, id_domain, sizeof(id_domain)); std::memcpy(workspace + sizeof(id_domain), record.author_public_key.data, 64); std::memcpy(workspace + sizeof(id_domain) + 64, record.creation_nonce.data, 16); @@ -56,7 +58,8 @@ inline VerificationResult deriveGeocacheHashes(ByteView encoded, RecordCrypto& c std::memcpy(workspace, revision_domain, sizeof(revision_domain)); std::memcpy(workspace + sizeof(revision_domain), encoded.data, encoded.size); if (!crypto.sha256({workspace, required}, candidate_hash.bytes.data())) return VerificationResult::CryptoUnavailable; - id = candidate_id; hash = candidate_hash; + id = candidate_id; + hash = candidate_hash; return VerificationResult::Valid; } diff --git a/modules/core_geocaching/include/geocaching/storage/attempt_references.h b/modules/core_geocaching/include/geocaching/storage/attempt_references.h index f0efcbbe..bd08a0d5 100644 --- a/modules/core_geocaching/include/geocaching/storage/attempt_references.h +++ b/modules/core_geocaching/include/geocaching/storage/attempt_references.h @@ -1,17 +1,20 @@ #pragma once -#include "geocaching/storage/tx_attempt.h" #include "geocaching/storage/logical_state.h" #include "geocaching/storage/outgoing_record.h" +#include "geocaching/storage/tx_attempt.h" namespace geocaching::storage { inline bool validateAttemptReferences(const LogicalState::View& state) { - size_t cursor = 0; MutationView entry; + size_t cursor = 0; + MutationView entry; while (state.next(cursor, entry)) { if (entry.table != 13) continue; - TxAttemptView attempt; ByteView outgoing_bytes; OutgoingView outgoing; + TxAttemptView attempt; + ByteView outgoing_bytes; + OutgoingView outgoing; if (!decodeTxAttempt(entry.key, entry.value, attempt) || !state.find(5, attempt.request_key, outgoing_bytes) || !decodeOutgoing(attempt.request_key, outgoing_bytes, outgoing)) return false; } diff --git a/modules/core_geocaching/include/geocaching/storage/attempt_timeout.h b/modules/core_geocaching/include/geocaching/storage/attempt_timeout.h index 59f40f86..dbe549d5 100644 --- a/modules/core_geocaching/include/geocaching/storage/attempt_timeout.h +++ b/modules/core_geocaching/include/geocaching/storage/attempt_timeout.h @@ -6,7 +6,7 @@ namespace geocaching::storage // Expiry means outcome unknown and eligible for policy-controlled retry, not // proof that the remote side did not receive it. Never reuse the old LXMF hash. inline bool attemptTimeoutReached(const TxAttemptView& attempt, const StoredTime& now, - uint64_t recovery_started_ms, uint64_t timeout_ms) + uint64_t recovery_started_ms, uint64_t timeout_ms) { if (!timeout_ms || attempt.has_finished) return false; if (attempt.submitted.boot_id == now.boot_id) diff --git a/modules/core_geocaching/include/geocaching/storage/author_history.h b/modules/core_geocaching/include/geocaching/storage/author_history.h index 04b4340f..13846ce9 100644 --- a/modules/core_geocaching/include/geocaching/storage/author_history.h +++ b/modules/core_geocaching/include/geocaching/storage/author_history.h @@ -9,7 +9,8 @@ namespace geocaching::storage // deleting a reservation would permit a second signed version at the same key. inline bool validateAuthorHistory(const LogicalState::View& before, const LogicalState::View& candidate) { - size_t cursor = 0; MutationView entry; + size_t cursor = 0; + MutationView entry; while (candidate.next(cursor, entry)) { if (entry.table != 3) continue; diff --git a/modules/core_geocaching/include/geocaching/storage/author_issued.h b/modules/core_geocaching/include/geocaching/storage/author_issued.h index 13f56a22..c0ddeee8 100644 --- a/modules/core_geocaching/include/geocaching/storage/author_issued.h +++ b/modules/core_geocaching/include/geocaching/storage/author_issued.h @@ -19,20 +19,23 @@ inline bool decodeAuthorIssued(ByteView key, ByteView value, AuthorIssuedView& o candidate.cache_id = {key.data, 32}; for (unsigned i = 0; i < 4; ++i) candidate.revision = (candidate.revision << 8) | key.data[32 + i]; if (!candidate.revision) return false; - protocol::CmpReader reader(value); size_t fields = 0; + protocol::CmpReader reader(value); + size_t fields = 0; if (!reader.array(fields, 3) || fields != 3 || !reader.binary(candidate.revision_hash, 32) || candidate.revision_hash.size != 32 || !reader.binary(candidate.author_public_key, 64) || candidate.author_public_key.size != 64 || !decodeStoredTime(reader, candidate.issued_at) || !reader.finished()) return false; - out = candidate; return true; + out = candidate; + return true; } inline bool encodeAuthorIssued(const RevisionHash& hash, ByteView public_key, const StoredTime& issued_at, - uint8_t* output, size_t capacity, size_t& written) + uint8_t* output, size_t capacity, size_t& written) { written = 0; if (!public_key.data || public_key.size != 64) return false; protocol::CmpWriter writer(output, capacity); if (!writer.array(3) || !writer.binary({hash.bytes.data(), 32}) || !writer.binary(public_key) || !encodeStoredTime(writer, issued_at)) return false; - written = writer.size(); return true; + written = writer.size(); + return true; } } // namespace geocaching::storage diff --git a/modules/core_geocaching/include/geocaching/storage/checkpoint_selection.h b/modules/core_geocaching/include/geocaching/storage/checkpoint_selection.h index 8fcb06ef..2b0e449e 100644 --- a/modules/core_geocaching/include/geocaching/storage/checkpoint_selection.h +++ b/modules/core_geocaching/include/geocaching/storage/checkpoint_selection.h @@ -4,7 +4,13 @@ namespace geocaching::storage { -enum class CheckpointCandidateState : uint8_t { Missing, Unavailable, Invalid, Verified }; +enum class CheckpointCandidateState : uint8_t +{ + Missing, + Unavailable, + Invalid, + Verified +}; struct CheckpointCandidate { // Verified may be set only after full file framing, tail and EOF checks. @@ -12,7 +18,14 @@ struct CheckpointCandidate uint64_t sequence = 0; std::array digest{}; }; -enum class CheckpointChoice : uint8_t { NoCheckpoint, SlotA, SlotB, RetryLater, Corrupt }; +enum class CheckpointChoice : uint8_t +{ + NoCheckpoint, + SlotA, + SlotB, + RetryLater, + Corrupt +}; inline CheckpointChoice selectCheckpoint(const CheckpointCandidate& a, const CheckpointCandidate& b) { diff --git a/modules/core_geocaching/include/geocaching/storage/outgoing_record.h b/modules/core_geocaching/include/geocaching/storage/outgoing_record.h index 4abc2644..395d8b57 100644 --- a/modules/core_geocaching/include/geocaching/storage/outgoing_record.h +++ b/modules/core_geocaching/include/geocaching/storage/outgoing_record.h @@ -48,7 +48,7 @@ inline bool decodeOutgoing(ByteView key, ByteView value, OutgoingView& out) } // Updates reuse original request/time views. Input views must not overlap output. inline bool encodeOutgoing(ByteView key, const OutgoingView& value, - uint8_t* output, size_t capacity, size_t& written) + uint8_t* output, size_t capacity, size_t& written) { written = 0; if (!value.request.data || value.request.size > 8192 || value.terminal_data.size > 8192) return false; @@ -60,6 +60,7 @@ inline bool encodeOutgoing(ByteView key, const OutgoingView& value, !(value.terminal_data.size ? writer.binary(value.terminal_data) : writer.nil())) return false; OutgoingView checked; if (!decodeOutgoing(key, {output, writer.size()}, checked)) return false; - written = writer.size(); return true; + written = writer.size(); + return true; } } // namespace geocaching::storage diff --git a/modules/core_geocaching/include/geocaching/storage/pending_request.h b/modules/core_geocaching/include/geocaching/storage/pending_request.h index 5b98f51e..f36ee43c 100644 --- a/modules/core_geocaching/include/geocaching/storage/pending_request.h +++ b/modules/core_geocaching/include/geocaching/storage/pending_request.h @@ -1,11 +1,16 @@ #pragma once +#include "geocaching/storage/cache_head.h" #include "geocaching/storage/logical_state.h" #include "geocaching/storage/task_record.h" -#include "geocaching/storage/cache_head.h" namespace geocaching::storage { -enum class PendingRequestResult : uint8_t { Ready, None, Corrupt }; +enum class PendingRequestResult : uint8_t +{ + Ready, + None, + Corrupt +}; struct PendingRequestView { std::array key{}; @@ -16,27 +21,30 @@ struct PendingRequestView }; inline PendingRequestResult inspectPendingRequest(const LogicalState::View& state, const Destination& local, - ByteView key, ByteView value, PendingRequestView& out) + ByteView key, ByteView value, PendingRequestView& out) { out = {}; OutgoingView outgoing; if (!decodeOutgoing(key, value, outgoing)) return PendingRequestResult::Corrupt; if (!outgoing.continue_intent || (outgoing.state != 0 && outgoing.state != 3) || std::memcmp(key.data, local.bytes.data(), 16)) return PendingRequestResult::None; - ByteView task_bytes; TaskView task; + ByteView task_bytes; + TaskView task; if (!state.find(10, outgoing.task_id, task_bytes) || !decodeTask(outgoing.task_id, task_bytes, task) || !requestBelongsToTask(outgoing.task_id, task, key, outgoing)) return PendingRequestResult::Corrupt; if (!task.continue_intent || task.state > 2) return PendingRequestResult::None; if ((task.kind == 2 || task.kind == 4) && outgoing.install_generation) { - ByteView head_bytes; CacheHeadView head; + ByteView head_bytes; + CacheHeadView head; if (!state.find(2, task.cache_id, head_bytes) || !decodeCacheHead(task.cache_id, head_bytes, head)) return PendingRequestResult::Corrupt; if (head.install_generation != outgoing.install_generation) return PendingRequestResult::None; } std::memcpy(out.key.data(), key.data, 48); std::memcpy(out.destination.bytes.data(), key.data + 16, 16); std::memcpy(out.request_id.bytes.data(), key.data + 32, 16); - out.request = outgoing.request; out.task_id = outgoing.task_id; + out.request = outgoing.request; + out.task_id = outgoing.task_id; return PendingRequestResult::Ready; } @@ -49,16 +57,22 @@ inline PendingRequestResult nextPendingRequest(const LogicalState::View& state, out = {}; if (after_key.size && (!after_key.data || after_key.size != 48)) return PendingRequestResult::Corrupt; bool found = false; - size_t cursor = 0; MutationView entry; + size_t cursor = 0; + MutationView entry; while (state.next(cursor, entry)) { if (entry.table != 5) continue; PendingRequestView candidate; const auto result = inspectPendingRequest(state, local, entry.key, entry.value, candidate); - if (result == PendingRequestResult::Corrupt) { out = {}; return result; } + if (result == PendingRequestResult::Corrupt) + { + out = {}; + return result; + } if (result != PendingRequestResult::Ready || (after_key.size && std::memcmp(entry.key.data, after_key.data, 48) <= 0)) continue; if (found && std::memcmp(entry.key.data, out.key.data(), 48) >= 0) continue; - out = candidate; found = true; + out = candidate; + found = true; } return found ? PendingRequestResult::Ready : PendingRequestResult::None; } diff --git a/modules/core_geocaching/include/geocaching/storage/stored_time.h b/modules/core_geocaching/include/geocaching/storage/stored_time.h index a62d426c..787d2edc 100644 --- a/modules/core_geocaching/include/geocaching/storage/stored_time.h +++ b/modules/core_geocaching/include/geocaching/storage/stored_time.h @@ -21,7 +21,10 @@ inline bool encodeStoredTime(protocol::CmpWriter& writer, const StoredTime& time inline bool decodeStoredTime(protocol::CmpReader& reader, StoredTime& out) { out = {}; - StoredTime candidate; ByteView boot; size_t fields = 0; uint64_t trusted = 0; + StoredTime candidate; + ByteView boot; + size_t fields = 0; + uint64_t trusted = 0; if (!reader.array(fields, 4) || fields != 4 || !reader.binary(boot, 16) || boot.size != 16 || !reader.unsignedInteger(candidate.monotonic_ms)) return false; std::memcpy(candidate.boot_id.data(), boot.data, 16); @@ -34,6 +37,7 @@ inline bool decodeStoredTime(protocol::CmpReader& reader, StoredTime& out) } if (!reader.unsignedInteger(trusted) || trusted > 1 || (trusted && !candidate.has_utc)) return false; candidate.utc_trusted = trusted != 0; - out = candidate; return true; + out = candidate; + return true; } } // namespace geocaching::storage diff --git a/modules/core_geocaching/include/geocaching/storage/summary_cache.h b/modules/core_geocaching/include/geocaching/storage/summary_cache.h index 58dcd59a..d1a21d82 100644 --- a/modules/core_geocaching/include/geocaching/storage/summary_cache.h +++ b/modules/core_geocaching/include/geocaching/storage/summary_cache.h @@ -14,14 +14,17 @@ inline bool decodeSummaryCache(ByteView key, ByteView value, SummaryCacheView& o { out = {}; if (!key.data || key.size != 48 || !value.data || value.size > 32768) return false; - protocol::CmpReader reader(value); size_t fields = 0; SummaryCacheView candidate; + protocol::CmpReader reader(value); + size_t fields = 0; + SummaryCacheView candidate; if (!reader.array(fields, 3) || fields != 3 || !protocol::decodeSummary(reader, candidate.summary) || std::memcmp(key.data + 16, candidate.summary.id.bytes.data(), 32) || !reader.binary(candidate.snapshot_id, 16) || candidate.snapshot_id.size != 16 || !decodeStoredTime(reader, candidate.received) || !reader.finished()) return false; - out = candidate; return true; + out = candidate; + return true; } inline bool encodeSummaryCache(ByteView key, const protocol::SummaryView& item, ByteView snapshot_id, const StoredTime& received, - uint8_t* output, size_t capacity, size_t& written) + uint8_t* output, size_t capacity, size_t& written) { written = 0; protocol::CmpWriter writer(output, capacity); @@ -33,6 +36,7 @@ inline bool encodeSummaryCache(ByteView key, const protocol::SummaryView& item, !writer.binary(snapshot_id) || !encodeStoredTime(writer, received)) return false; SummaryCacheView checked; if (!decodeSummaryCache(key, {output, writer.size()}, checked)) return false; - written = writer.size(); return true; + written = writer.size(); + return true; } } // namespace geocaching::storage diff --git a/modules/core_geocaching/include/geocaching/storage/task_record.h b/modules/core_geocaching/include/geocaching/storage/task_record.h index 45fb3667..a358543f 100644 --- a/modules/core_geocaching/include/geocaching/storage/task_record.h +++ b/modules/core_geocaching/include/geocaching/storage/task_record.h @@ -56,10 +56,12 @@ inline bool encodeTask(ByteView key, const TaskView& task, uint8_t* output, size !(task.revision_hash.size ? writer.binary(task.revision_hash) : writer.nil()) || !writer.unsignedInteger(task.state) || !writer.unsignedInteger(task.continue_intent ? 1 : 0) || !writer.array(static_cast(task.request_count))) return false; - for (size_t i = 0; i < task.request_count; ++i) if (!writer.binary(task.requests[i])) return false; + for (size_t i = 0; i < task.request_count; ++i) + if (!writer.binary(task.requests[i])) return false; TaskView checked; if (!decodeTask(key, {output, writer.size()}, checked)) return false; - written = writer.size(); return true; + written = writer.size(); + return true; } // Both records must first pass their decoders. Recovery checks every task child diff --git a/modules/core_geocaching/include/geocaching/storage/volume_format.h b/modules/core_geocaching/include/geocaching/storage/volume_format.h index c3ae7ffe..78efceec 100644 --- a/modules/core_geocaching/include/geocaching/storage/volume_format.h +++ b/modules/core_geocaching/include/geocaching/storage/volume_format.h @@ -8,7 +8,12 @@ namespace geocaching::storage { using VolumeInstance = std::array; using VolumeHeader = std::array; -enum class VolumeFormatResult : uint8_t { Supported, Unsupported, Corrupt }; +enum class VolumeFormatResult : uint8_t +{ + Supported, + Unsupported, + Corrupt +}; inline VolumeHeader encodeVolumeHeader(const VolumeInstance& instance) { diff --git a/modules/core_geocaching/tests/fakes/platform/esp/arduino_common/chat/infra/mesh_adapter_router.h b/modules/core_geocaching/tests/fakes/platform/esp/arduino_common/chat/infra/mesh_adapter_router.h index 063fd755..c1ca902c 100644 --- a/modules/core_geocaching/tests/fakes/platform/esp/arduino_common/chat/infra/mesh_adapter_router.h +++ b/modules/core_geocaching/tests/fakes/platform/esp/arduino_common/chat/infra/mesh_adapter_router.h @@ -23,7 +23,7 @@ class MeshAdapterRouter return true; } MeshSendResult sendGeocachingData(const uint8_t[16], lxmf::ByteSpan bytes, bool, - std::array* hash, const uint8_t expected[16]) + std::array* hash, const uint8_t expected[16]) { ++sends; if (!ready || std::memcmp(expected, local.data(), 16)) return MeshSendResult::fail(MeshOperationFailure::NotReady); diff --git a/modules/core_geocaching/tests/test_attempt_timeout.cpp b/modules/core_geocaching/tests/test_attempt_timeout.cpp index 799649b5..08f1c3d0 100644 --- a/modules/core_geocaching/tests/test_attempt_timeout.cpp +++ b/modules/core_geocaching/tests/test_attempt_timeout.cpp @@ -2,18 +2,21 @@ int main() { using namespace geocaching::storage; - TxAttemptView attempt; StoredTime now; + TxAttemptView attempt; + StoredTime now; attempt.submitted.monotonic_ms = 100; now.monotonic_ms = 1099; if (attemptTimeoutReached(attempt, now, 0, 1000)) return 1; now.monotonic_ms = 1100; if (!attemptTimeoutReached(attempt, now, 0, 1000)) return 2; - now.boot_id[0] = 1; now.monotonic_ms = 5000; + now.boot_id[0] = 1; + now.monotonic_ms = 5000; if (attemptTimeoutReached(attempt, now, 4500, 1000)) return 3; now.monotonic_ms = 5500; if (!attemptTimeoutReached(attempt, now, 4500, 1000)) return 4; attempt.submitted.has_utc = attempt.submitted.utc_trusted = now.has_utc = now.utc_trusted = true; - attempt.submitted.utc_seconds = 100; now.utc_seconds = 101; + attempt.submitted.utc_seconds = 100; + now.utc_seconds = 101; if (attemptTimeoutReached(attempt, now, 0, 1001)) return 5; now.utc_seconds = 102; if (!attemptTimeoutReached(attempt, now, 0, 1001)) return 6; diff --git a/modules/core_geocaching/tests/test_author_issued.cpp b/modules/core_geocaching/tests/test_author_issued.cpp index 076440c1..050c81b2 100644 --- a/modules/core_geocaching/tests/test_author_issued.cpp +++ b/modules/core_geocaching/tests/test_author_issued.cpp @@ -3,9 +3,12 @@ int main() { using namespace geocaching; uint8_t key[36]{}, public_key[64]{}, bytes[192]{}; - key[35] = 1; public_key[0] = 7; - RevisionHash hash; hash.bytes[0] = 9; - storage::StoredTime time; time.monotonic_ms = 123; + key[35] = 1; + public_key[0] = 7; + RevisionHash hash; + hash.bytes[0] = 9; + storage::StoredTime time; + time.monotonic_ms = 123; size_t size = 0; if (!storage::encodeAuthorIssued(hash, {public_key, 64}, time, bytes, sizeof(bytes), size)) return 1; storage::AuthorIssuedView out; diff --git a/modules/core_geocaching/tests/test_cache_head.cpp b/modules/core_geocaching/tests/test_cache_head.cpp index b33ae67f..88ecf45f 100644 --- a/modules/core_geocaching/tests/test_cache_head.cpp +++ b/modules/core_geocaching/tests/test_cache_head.cpp @@ -1,5 +1,5 @@ -#include "geocaching/storage/cache_head.h" #include "geocaching/protocol/cmp_writer.h" +#include "geocaching/storage/cache_head.h" int main() { using namespace geocaching; @@ -15,7 +15,8 @@ int main() if (!storage::decodeCacheHead({key, 32}, {empty, sizeof(empty)}, head) || head.current_hash.size) return 4; empty[3] = 0; if (storage::decodeCacheHead({key, 32}, {empty, sizeof(empty)}, head)) return 5; - empty[3] = 1; empty[2] = 3; + empty[3] = 1; + empty[2] = 3; if (storage::decodeCacheHead({key, 32}, {empty, sizeof(empty)}, head)) return 6; return 0; } diff --git a/modules/core_geocaching/tests/test_checkpoint_selection.cpp b/modules/core_geocaching/tests/test_checkpoint_selection.cpp index 1ac35a53..e1a8c929 100644 --- a/modules/core_geocaching/tests/test_checkpoint_selection.cpp +++ b/modules/core_geocaching/tests/test_checkpoint_selection.cpp @@ -8,9 +8,11 @@ int main() if (selectCheckpoint(a, b) != CheckpointChoice::NoCheckpoint) return 2; a.state = CheckpointCandidateState::Invalid; if (selectCheckpoint(a, b) != CheckpointChoice::Corrupt) return 3; - b.state = CheckpointCandidateState::Verified; b.sequence = 4; + b.state = CheckpointCandidateState::Verified; + b.sequence = 4; if (selectCheckpoint(a, b) != CheckpointChoice::SlotB) return 4; - a.state = CheckpointCandidateState::Verified; a.sequence = 5; + a.state = CheckpointCandidateState::Verified; + a.sequence = 5; if (selectCheckpoint(a, b) != CheckpointChoice::SlotA) return 5; a.sequence = 4; if (selectCheckpoint(a, b) != CheckpointChoice::SlotA) return 6; diff --git a/modules/core_geocaching/tests/test_crypto_pipeline.cpp b/modules/core_geocaching/tests/test_crypto_pipeline.cpp index 6134d6de..48926101 100644 --- a/modules/core_geocaching/tests/test_crypto_pipeline.cpp +++ b/modules/core_geocaching/tests/test_crypto_pipeline.cpp @@ -1,6 +1,6 @@ -#include "geocaching/protocol/verify_record.h" -#include "chat/infra/reticulum/reticulum_wire.h" #include "chat/infra/meshcore/crypto/ed25519/ed_25519.h" +#include "chat/infra/reticulum/reticulum_wire.h" +#include "geocaching/protocol/verify_record.h" #include #include #include @@ -9,7 +9,10 @@ struct NativeCrypto : geocaching::protocol::RecordCrypto { bool sha256(geocaching::ByteView in, std::uint8_t out[32]) override - { chat::reticulum::fullHash(in.data, in.size, out); return true; } + { + chat::reticulum::fullHash(in.data, in.size, out); + return true; + } geocaching::protocol::VerificationResult verifyEd25519(geocaching::ByteView key, geocaching::ByteView sig, geocaching::ByteView msg) override { using R = geocaching::protocol::VerificationResult; diff --git a/modules/core_geocaching/tests/test_download_task_record.cpp b/modules/core_geocaching/tests/test_download_task_record.cpp index 4f16a279..ca85eade 100644 --- a/modules/core_geocaching/tests/test_download_task_record.cpp +++ b/modules/core_geocaching/tests/test_download_task_record.cpp @@ -3,26 +3,35 @@ int main() { using namespace geocaching; - RequestId request_id; Destination local, remote; GeocacheId cache; RevisionHash hash; + RequestId request_id; + Destination local, remote; + GeocacheId cache; + RevisionHash hash; std::array task{}; - uint8_t request[256]{}; size_t request_size = 0; + uint8_t request[256]{}; + size_t request_size = 0; if (!protocol::encodeGetRequest(request_id, cache, &hash, nullptr, 8192, request, sizeof(request), request_size)) return 1; std::array value_buffer{}; auto workspace = std::make_unique(value_buffer.data(), value_buffer.size()); - std::array output{}; size_t size = 0; + std::array output{}; + size_t size = 0; storage::RequestTaskTarget target{{cache.bytes.data(), 32}, {hash.bytes.data(), 32}, 1}; if (!storage::encodeNewRequestTask(0, local, remote, request_id, task, 2, {request, request_size}, {}, - *workspace, output.data(), output.size(), size, target)) return 2; - storage::MutationView mutations[2]; storage::TransactionView transaction; + *workspace, output.data(), output.size(), size, target)) return 2; + storage::MutationView mutations[2]; + storage::TransactionView transaction; if (!storage::decodeTransaction({output.data(), size}, 0, mutations, 2, transaction)) return 3; - protocol::CmpReader record(mutations[1].value); size_t fields = 0; uint64_t kind = 0; ByteView stored_id, stored_hash; + protocol::CmpReader record(mutations[1].value); + size_t fields = 0; + uint64_t kind = 0; + ByteView stored_id, stored_hash; if (!record.array(fields, 6) || fields != 6 || !record.unsignedInteger(kind) || kind != 2 || !record.binary(stored_id, 32) || stored_id.size != 32 || !record.binary(stored_hash, 32) || stored_hash.size != 32) return 4; target.install_generation = 0; if (storage::encodeNewRequestTask(0, local, remote, request_id, task, 2, {request, request_size}, {}, - *workspace, output.data(), output.size(), size, target)) return 5; + *workspace, output.data(), output.size(), size, target)) return 5; target.install_generation = 1; if (storage::encodeNewRequestTask(0, local, remote, request_id, task, 1, {request, request_size}, {}, - *workspace, output.data(), output.size(), size, target)) return 6; + *workspace, output.data(), output.size(), size, target)) return 6; return 0; } diff --git a/modules/core_geocaching/tests/test_gpx_hash.cpp b/modules/core_geocaching/tests/test_gpx_hash.cpp index 15af0f3a..8f2aac93 100644 --- a/modules/core_geocaching/tests/test_gpx_hash.cpp +++ b/modules/core_geocaching/tests/test_gpx_hash.cpp @@ -1,41 +1,61 @@ -#include "platform/esp/arduino_common/geocaching/sd_gpx_hash.h" #include "chat/infra/reticulum/reticulum_wire.h" -#include +#include "platform/esp/arduino_common/geocaching/sd_gpx_hash.h" #include +#include std::vector bytes(1025, 7); namespace platform::esp::arduino_common::storage { -class SdRuntimeFile::Impl { public: bool open = false; size_t offset = 0; }; +class SdRuntimeFile::Impl +{ + public: + bool open = false; + size_t offset = 0; +}; SdRuntimeFile::SdRuntimeFile() : impl_(new Impl) {} SdRuntimeFile::~SdRuntimeFile() { delete impl_; } -bool SdRuntimeFile::open(const char*, const char*) { impl_->open = true; impl_->offset = 0; return true; } +bool SdRuntimeFile::open(const char*, const char*) +{ + impl_->open = true; + impl_->offset = 0; + return true; +} void SdRuntimeFile::close() { impl_->open = false; } bool SdRuntimeFile::is_open() const { return impl_->open; } uint64_t SdRuntimeFile::size() const { return bytes.size(); } int SdRuntimeFile::read(void* out, size_t count) { const auto n = std::min(count, bytes.size() - impl_->offset); - std::memcpy(out, bytes.data() + impl_->offset, n); impl_->offset += n; return static_cast(n); -} + std::memcpy(out, bytes.data() + impl_->offset, n); + impl_->offset += n; + return static_cast(n); } +} // namespace platform::esp::arduino_common::storage struct Digest { std::vector data; void update(const uint8_t* bytes, size_t size) { data.insert(data.end(), bytes, bytes + size); } - bool finalize(uint8_t* out, size_t) { chat::reticulum::fullHash(data.data(), data.size(), out); return true; } + bool finalize(uint8_t* out, size_t) + { + chat::reticulum::fullHash(data.data(), data.size(), out); + return true; + } }; int main() { using namespace platform::esp::arduino_common::geocaching; - Digest digest; SdGpxHash reader(digest); + Digest digest; + SdGpxHash reader(digest); std::array actual, expected; chat::reticulum::fullHash(bytes.data(), bytes.size(), expected.data()); if (!reader.open("local.gpx") || reader.result(actual)) return 1; - for (unsigned i = 0; i < 3; ++i) if (reader.step() != GpxHashStep::Reading) return 2; + for (unsigned i = 0; i < 3; ++i) + if (reader.step() != GpxHashStep::Reading) return 2; if (reader.step() != GpxHashStep::Complete || !reader.result(actual) || actual != expected) return 3; - Digest growing_digest; SdGpxHash growing(growing_digest); + Digest growing_digest; + SdGpxHash growing(growing_digest); if (!growing.open("local.gpx")) return 4; - for (unsigned i = 0; i < 3; ++i) if (growing.step() != GpxHashStep::Reading) return 5; + for (unsigned i = 0; i < 3; ++i) + if (growing.step() != GpxHashStep::Reading) return 5; bytes.push_back(9); if (growing.step() != GpxHashStep::IoError || growing.result(actual)) return 6; return 0; diff --git a/modules/core_geocaching/tests/test_gpx_record.cpp b/modules/core_geocaching/tests/test_gpx_record.cpp index 662eaf43..5248f6e0 100644 --- a/modules/core_geocaching/tests/test_gpx_record.cpp +++ b/modules/core_geocaching/tests/test_gpx_record.cpp @@ -8,7 +8,11 @@ struct FileSink : geocaching::gpx::OutputSink { std::ofstream file; explicit FileSink(const char* path) : file(path, std::ios::binary) {} - bool write(std::string_view bytes) override { file.write(bytes.data(), bytes.size()); return file.good(); } + bool write(std::string_view bytes) override + { + file.write(bytes.data(), bytes.size()); + return file.good(); + } }; struct FixtureCrypto : geocaching::protocol::RecordCrypto { @@ -16,10 +20,13 @@ struct FixtureCrypto : geocaching::protocol::RecordCrypto bool sha256(geocaching::ByteView input, std::uint8_t output[32]) override { if (input.size != 64) return false; - std::memcpy(output, author_hash.data(), 32); return true; + std::memcpy(output, author_hash.data(), 32); + return true; } geocaching::protocol::VerificationResult verifyEd25519(geocaching::ByteView, geocaching::ByteView, geocaching::ByteView) override - { return geocaching::protocol::VerificationResult::CryptoUnavailable; } + { + return geocaching::protocol::VerificationResult::CryptoUnavailable; + } }; int main(int argc, char** argv) { diff --git a/modules/core_geocaching/tests/test_install_record.cpp b/modules/core_geocaching/tests/test_install_record.cpp index ffcb7314..685c7370 100644 --- a/modules/core_geocaching/tests/test_install_record.cpp +++ b/modules/core_geocaching/tests/test_install_record.cpp @@ -1,23 +1,27 @@ -#include "geocaching/storage/install_record.h" #include "geocaching/protocol/cmp_writer.h" +#include "geocaching/storage/install_record.h" int main() { using namespace geocaching; uint8_t key[16]{}, cache[32]{}, revision[32]{}, file_hash[32]{}, bytes[256]{}; - revision[0] = 1; file_hash[0] = 2; + revision[0] = 1; + file_hash[0] = 2; protocol::CmpWriter writer(bytes, sizeof(bytes)); if (!writer.array(6) || !writer.binary({cache, 32}) || !writer.binary({revision, 32}) || !writer.binary({file_hash, 32}) || !writer.nil() || !writer.unsignedInteger(1) || !writer.unsignedInteger(0)) return 1; storage::InstallRecordView record; if (!storage::decodeInstallRecord({key, 16}, {bytes, writer.size()}, record) || record.new_file_hash.data[0] != 2) return 2; - storage::CacheHeadView head; head.install_generation = 1; + storage::CacheHeadView head; + head.install_generation = 1; using Action = storage::InstallRecoveryAction; if (storage::classifyInstallRecovery({cache, 32}, head, record) != Action::VerifyFiles) return 3; head.install_generation = 2; if (storage::classifyInstallRecovery({cache, 32}, head, record) != Action::Superseded) return 4; - head.install_generation = 1; record.generation = 2; + head.install_generation = 1; + record.generation = 2; if (storage::classifyInstallRecovery({cache, 32}, head, record) != Action::Inconsistent) return 5; - record.generation = 1; record.phase = storage::InstallPhase::ConflictExternal; + record.generation = 1; + record.phase = storage::InstallPhase::ConflictExternal; if (storage::classifyInstallRecovery({cache, 32}, head, record) != Action::ExternalConflict) return 6; record.phase = storage::InstallPhase::Installed; if (storage::classifyInstallRecovery({cache, 32}, head, record) != Action::Inconsistent) return 7; diff --git a/modules/core_geocaching/tests/test_journal_inventory.cpp b/modules/core_geocaching/tests/test_journal_inventory.cpp index 0c31b784..879c7759 100644 --- a/modules/core_geocaching/tests/test_journal_inventory.cpp +++ b/modules/core_geocaching/tests/test_journal_inventory.cpp @@ -1,22 +1,36 @@ #include "platform/esp/arduino_common/geocaching/sd_journal_inventory.h" -#include -#include #include +#include +#include std::vector names; bool busy_once = false; bool fail_after_first = false; namespace platform::esp::arduino_common::storage { -class SdRuntimeDir::Impl { public: bool open = false; size_t index = 0; }; +class SdRuntimeDir::Impl +{ + public: + bool open = false; + size_t index = 0; +}; SdRuntimeDir::SdRuntimeDir() : impl_(new Impl) {} SdRuntimeDir::~SdRuntimeDir() { delete impl_; } -bool SdRuntimeDir::open(const char*) { impl_->open = true; impl_->index = 0; return true; } +bool SdRuntimeDir::open(const char*) +{ + impl_->open = true; + impl_->index = 0; + return true; +} void SdRuntimeDir::close() { impl_->open = false; } bool SdRuntimeDir::is_open() const { return impl_->open; } SdDirReadStatus SdRuntimeDir::read_next_status(char* name, size_t capacity, bool* is_dir) { - if (busy_once) { busy_once = false; return SdDirReadStatus::Busy; } + if (busy_once) + { + busy_once = false; + return SdDirReadStatus::Busy; + } if (fail_after_first && impl_->index == 1) { fail_after_first = false; @@ -24,17 +38,21 @@ SdDirReadStatus SdRuntimeDir::read_next_status(char* name, size_t capacity, bool return SdDirReadStatus::IoError; } if (impl_->index == names.size()) return SdDirReadStatus::End; - std::snprintf(name, capacity, "%s", names[impl_->index++].c_str()); *is_dir = false; + std::snprintf(name, capacity, "%s", names[impl_->index++].c_str()); + *is_dir = false; return SdDirReadStatus::Entry; } SdFileReadResult sd_read_file(const char*, uint8_t* buffer, size_t capacity) { const auto header = ::geocaching::storage::encodeVolumeHeader({}); - SdFileReadResult result; result.status = SdFileReadStatus::Ready; - result.file_size = header.size(); result.bytes_read = std::min(capacity, header.size()); - std::memcpy(buffer, header.data(), result.bytes_read); return result; -} + SdFileReadResult result; + result.status = SdFileReadStatus::Ready; + result.file_size = header.size(); + result.bytes_read = std::min(capacity, header.size()); + std::memcpy(buffer, header.data(), result.bytes_read); + return result; } +} // namespace platform::esp::arduino_common::storage int main() { using namespace platform::esp::arduino_common::geocaching; diff --git a/modules/core_geocaching/tests/test_journal_read.cpp b/modules/core_geocaching/tests/test_journal_read.cpp index 93b10749..581bdd85 100644 --- a/modules/core_geocaching/tests/test_journal_read.cpp +++ b/modules/core_geocaching/tests/test_journal_read.cpp @@ -13,14 +13,15 @@ SdFileReadResult sd_read_file(const char*, uint8_t* buffer, size_t capacity) if (result.bytes_read) std::memcpy(buffer, disk.data(), result.bytes_read); return result; } -} +} // namespace platform::esp::arduino_common::storage int main() { using namespace platform::esp::arduino_common::geocaching; const uint8_t payload[] = {0x93, 1, 0, 0x91, 0x93, 5, 0xc4, 1, 0xab, 0xc0}; ::geocaching::storage::RecordHeader header; if (!::geocaching::storage::makeRecordHeader(::geocaching::storage::RecordKind::Transaction, 1, {payload, sizeof(payload)}, header)) return 1; - disk.assign(header.begin(), header.end()); disk.insert(disk.end(), payload, payload + sizeof(payload)); + disk.assign(header.begin(), header.end()); + disk.insert(disk.end(), payload, payload + sizeof(payload)); std::array buffer{}; ::geocaching::storage::MutationView scratch; ::geocaching::storage::TransactionView out; diff --git a/modules/core_geocaching/tests/test_journal_segment.cpp b/modules/core_geocaching/tests/test_journal_segment.cpp index 2e541b28..6456ac7d 100644 --- a/modules/core_geocaching/tests/test_journal_segment.cpp +++ b/modules/core_geocaching/tests/test_journal_segment.cpp @@ -3,19 +3,31 @@ std::vector data; namespace platform::esp::arduino_common::storage { -class SdRuntimeFile::Impl { public: size_t offset = 0; bool open = false; }; +class SdRuntimeFile::Impl +{ + public: + size_t offset = 0; + bool open = false; +}; SdRuntimeFile::SdRuntimeFile() : impl_(new Impl) {} SdRuntimeFile::~SdRuntimeFile() { delete impl_; } -bool SdRuntimeFile::open(const char*, const char*) { impl_->open = true; impl_->offset = 0; return true; } +bool SdRuntimeFile::open(const char*, const char*) +{ + impl_->open = true; + impl_->offset = 0; + return true; +} void SdRuntimeFile::close() { impl_->open = false; } bool SdRuntimeFile::is_open() const { return impl_->open; } uint64_t SdRuntimeFile::size() const { return data.size(); } int SdRuntimeFile::read(void* buffer, size_t count) { const auto n = std::min(count, data.size() - impl_->offset); - std::memcpy(buffer, data.data() + impl_->offset, n); impl_->offset += n; return static_cast(n); -} + std::memcpy(buffer, data.data() + impl_->offset, n); + impl_->offset += n; + return static_cast(n); } +} // namespace platform::esp::arduino_common::storage int main() { using namespace platform::esp::arduino_common::geocaching; @@ -24,9 +36,12 @@ int main() { ::geocaching::storage::RecordHeader header; if (!::geocaching::storage::makeRecordHeader(::geocaching::storage::RecordKind::Transaction, sequence, {payload, sizeof(payload)}, header)) return 1; - data.insert(data.end(), header.begin(), header.end()); data.insert(data.end(), payload, payload + sizeof(payload)); + data.insert(data.end(), header.begin(), header.end()); + data.insert(data.end(), payload, payload + sizeof(payload)); } - SdJournalSegment segment; uint8_t buffer[128]; ::geocaching::storage::RecordFrameView frame; + SdJournalSegment segment; + uint8_t buffer[128]; + ::geocaching::storage::RecordFrameView frame; if (!segment.open(1) || segment.next(buffer, sizeof(buffer), frame) != SegmentReadResult::Record || frame.sequence != 1 || segment.next(buffer, sizeof(buffer), frame) != SegmentReadResult::Record || frame.sequence != 2 || segment.next(buffer, sizeof(buffer), frame) != SegmentReadResult::End) return 2; diff --git a/modules/core_geocaching/tests/test_logical_state.cpp b/modules/core_geocaching/tests/test_logical_state.cpp index 96029274..68c5db27 100644 --- a/modules/core_geocaching/tests/test_logical_state.cpp +++ b/modules/core_geocaching/tests/test_logical_state.cpp @@ -6,15 +6,18 @@ int main() LogicalState state(first, second, sizeof(first)); uint8_t key = 1, other_key = 2, value = 9; MutationView initial{5, {&key, 1}, {&value, 1}, false}; - auto accept = [](const LogicalState::View&) { return true; }; + auto accept = [](const LogicalState::View&) + { return true; }; if (!state.apply(&initial, 1, accept)) return 1; MutationView changes[] = {{5, {&key, 1}, {}, true}, {5, {&other_key, 1}, {&value, 1}, false}}; - if (state.apply(changes, 2, [](const LogicalState::View&) { return false; })) return 2; + if (state.apply(changes, 2, [](const LogicalState::View&) + { return false; })) return 2; geocaching::ByteView found; if (!state.view().find(5, {&key, 1}, found) || found.size != 1 || found.data[0] != 9 || state.view().size() != 1) return 3; if (!state.apply(changes, 2, accept) || state.view().find(5, {&key, 1}, found) || !state.view().find(5, {&other_key, 1}, found)) return 4; - uint8_t large[32]{}; MutationView overflow{5, {&key, 1}, {large, sizeof(large)}, false}; + uint8_t large[32]{}; + MutationView overflow{5, {&key, 1}, {large, sizeof(large)}, false}; if (state.apply(&overflow, 1, accept) || state.view().size() != 1 || !state.view().find(5, {&other_key, 1}, found)) return 5; return 0; } diff --git a/modules/core_geocaching/tests/test_lxmf_custom.cpp b/modules/core_geocaching/tests/test_lxmf_custom.cpp index db17e92b..aa3b2b21 100644 --- a/modules/core_geocaching/tests/test_lxmf_custom.cpp +++ b/modules/core_geocaching/tests/test_lxmf_custom.cpp @@ -1,9 +1,9 @@ #include "chat/infra/lxmf/lxmf_wire.h" #include "geocaching/protocol/cmp_reader.h" #include +#include #include #include -#include #ifdef _MSC_VER #include #endif diff --git a/modules/core_geocaching/tests/test_outgoing_record.cpp b/modules/core_geocaching/tests/test_outgoing_record.cpp index 4cf5aabb..f2fc2531 100644 --- a/modules/core_geocaching/tests/test_outgoing_record.cpp +++ b/modules/core_geocaching/tests/test_outgoing_record.cpp @@ -1,20 +1,26 @@ +#include "geocaching/protocol/query_request.h" #include "geocaching/storage/outgoing_record.h" #include "geocaching/storage/queued_request.h" -#include "geocaching/protocol/query_request.h" #include int main() { using namespace geocaching; - RequestId id; id.bytes[0] = 1; - uint8_t request[64]; size_t request_size = 0; + RequestId id; + id.bytes[0] = 1; + uint8_t request[64]; + size_t request_size = 0; if (!protocol::encodeCapabilitiesRequest(id, request, sizeof(request), request_size)) return 1; std::array value_buffer{}; auto scratch = std::make_unique(value_buffer.data(), value_buffer.size()); - std::array bytes; size_t size = 0; - storage::StoredTime time; time.monotonic_ms = 123; time.boot_id[0] = 7; + std::array bytes; + size_t size = 0; + storage::StoredTime time; + time.monotonic_ms = 123; + time.boot_id[0] = 7; if (!storage::encodeNewRequestTask(0, {}, {}, id, {}, 3, {request, request_size}, time, *scratch, bytes.data(), bytes.size(), size)) return 2; - storage::MutationView mutations[2]; storage::TransactionView transaction; + storage::MutationView mutations[2]; + storage::TransactionView transaction; if (!storage::decodeTransaction({bytes.data(), size}, 0, mutations, 2, transaction)) return 3; storage::OutgoingView out; if (!storage::decodeOutgoing(mutations[0].key, mutations[0].value, out) || out.state != 0 || diff --git a/modules/core_geocaching/tests/test_paging.cpp b/modules/core_geocaching/tests/test_paging.cpp index 759dd454..a6ce85a2 100644 --- a/modules/core_geocaching/tests/test_paging.cpp +++ b/modules/core_geocaching/tests/test_paging.cpp @@ -26,7 +26,7 @@ struct PagingPort : geocaching::QueryClientPort geocaching::QueryPersistence cancel(const geocaching::Destination&, const geocaching::RequestId&) override { return geocaching::QueryPersistence::Committed; } geocaching::QueryPersistence commitCapabilities(const geocaching::Destination&, const geocaching::RequestId&, geocaching::ByteView) override { return geocaching::QueryPersistence::Committed; } geocaching::QueryPersistence commitPage(const geocaching::Destination&, const geocaching::RequestId&, geocaching::ByteView, - const geocaching::protocol::QueryPageView&) override + const geocaching::protocol::QueryPageView&) override { if (fail_commit) return geocaching::QueryPersistence::Rejected; ++commits; diff --git a/modules/core_geocaching/tests/test_pending_request.cpp b/modules/core_geocaching/tests/test_pending_request.cpp index a595f873..a07172bf 100644 --- a/modules/core_geocaching/tests/test_pending_request.cpp +++ b/modules/core_geocaching/tests/test_pending_request.cpp @@ -1,31 +1,41 @@ +#include "geocaching/protocol/query_request.h" #include "geocaching/storage/pending_request.h" #include "geocaching/storage/queued_request.h" #include "geocaching/storage/task_references.h" -#include "geocaching/protocol/query_request.h" #include int main() { using namespace geocaching; - Destination local, remote; local.bytes[0] = 1; remote.bytes[0] = 2; - RequestId id; id.bytes[0] = 3; - uint8_t request[64]; size_t request_size = 0; + Destination local, remote; + local.bytes[0] = 1; + remote.bytes[0] = 2; + RequestId id; + id.bytes[0] = 3; + uint8_t request[64]; + size_t request_size = 0; if (!protocol::encodeCapabilitiesRequest(id, request, sizeof(request), request_size)) return 1; std::array value_buffer{}; auto workspace = std::make_unique(value_buffer.data(), value_buffer.size()); - uint8_t encoded[512]{}; size_t size = 0; + uint8_t encoded[512]{}; + size_t size = 0; if (!storage::encodeNewRequestTask(0, local, remote, id, {}, 3, {request, request_size}, {}, - *workspace, encoded, sizeof(encoded), size)) return 2; - storage::MutationView mutations[2]; storage::TransactionView transaction; + *workspace, encoded, sizeof(encoded), size)) return 2; + storage::MutationView mutations[2]; + storage::TransactionView transaction; if (!storage::decodeTransaction({encoded, size}, 0, mutations, 2, transaction)) return 3; - uint8_t a[512]{}, b[512]{}; storage::LogicalState state(a, b, sizeof(a)); + uint8_t a[512]{}, b[512]{}; + storage::LogicalState state(a, b, sizeof(a)); if (!state.apply(mutations, 2, storage::validateTaskReferences)) return 4; storage::PendingRequestView pending; if (storage::nextPendingRequest(state.view(), local, {}, pending) != storage::PendingRequestResult::Ready || pending.destination.bytes != remote.bytes || pending.request_id.bytes != id.bytes || pending.request.size != request_size) return 5; if (storage::nextPendingRequest(state.view(), remote, {}, pending) != storage::PendingRequestResult::None) return 6; - uint8_t task_key[16]{}; ByteView task_bytes; storage::TaskView task; + uint8_t task_key[16]{}; + ByteView task_bytes; + storage::TaskView task; if (!state.view().find(10, {task_key, 16}, task_bytes) || !storage::decodeTask({task_key, 16}, task_bytes, task)) return 7; - task.state = 5; task.continue_intent = false; + task.state = 5; + task.continue_intent = false; uint8_t stopped[256]{}; if (!storage::encodeTask({task_key, 16}, task, stopped, sizeof(stopped), size)) return 8; storage::MutationView stop{10, {task_key, 16}, {stopped, size}, false}; diff --git a/modules/core_geocaching/tests/test_query_client.cpp b/modules/core_geocaching/tests/test_query_client.cpp index d9fdd612..d8bfa9d5 100644 --- a/modules/core_geocaching/tests/test_query_client.cpp +++ b/modules/core_geocaching/tests/test_query_client.cpp @@ -21,7 +21,7 @@ struct Port : geocaching::QueryClientPort geocaching::QueryPersistence cancel(const geocaching::Destination&, const geocaching::RequestId&) override { return geocaching::QueryPersistence::Committed; } geocaching::QueryPersistence commitCapabilities(const geocaching::Destination&, const geocaching::RequestId&, geocaching::ByteView) override { return geocaching::QueryPersistence::Committed; } geocaching::QueryPersistence commitPage(const geocaching::Destination&, const geocaching::RequestId&, geocaching::ByteView, - const geocaching::protocol::QueryPageView& page) override + const geocaching::protocol::QueryPageView& page) override { geocaching::protocol::CmpReader rows(page.encoded_items); geocaching::protocol::SummaryView item; diff --git a/modules/core_geocaching/tests/test_queued_request.cpp b/modules/core_geocaching/tests/test_queued_request.cpp index 10d91463..bb9c697e 100644 --- a/modules/core_geocaching/tests/test_queued_request.cpp +++ b/modules/core_geocaching/tests/test_queued_request.cpp @@ -1,29 +1,40 @@ -#include "geocaching/storage/queued_request.h" #include "geocaching/protocol/query_request.h" +#include "geocaching/storage/queued_request.h" #include int main() { using namespace geocaching; - RequestId request_id; request_id.bytes[0] = 1; - Destination local, remote; local.bytes[0] = 2; remote.bytes[0] = 3; - std::array task_id{}; task_id[0] = 4; - uint8_t request[128]{}; size_t request_size = 0; + RequestId request_id; + request_id.bytes[0] = 1; + Destination local, remote; + local.bytes[0] = 2; + remote.bytes[0] = 3; + std::array task_id{}; + task_id[0] = 4; + uint8_t request[128]{}; + size_t request_size = 0; if (!protocol::encodeCapabilitiesRequest(request_id, request, sizeof(request), request_size)) return 1; std::array value_buffer{}; auto scratch = std::make_unique(value_buffer.data(), value_buffer.size()); - std::array output{}; size_t size = 0; - storage::StoredTime time; time.boot_id[0] = 5; + std::array output{}; + size_t size = 0; + storage::StoredTime time; + time.boot_id[0] = 5; if (!storage::encodeNewRequestTask(7, local, remote, request_id, task_id, 3, {request, request_size}, time, *scratch, output.data(), output.size(), size)) return 2; - storage::MutationView mutations[2]; storage::TransactionView transaction; + storage::MutationView mutations[2]; + storage::TransactionView transaction; if (!storage::decodeTransaction({output.data(), size}, 7, mutations, 2, transaction) || transaction.count != 2 || mutations[0].table != 5 || mutations[0].key.size != 48 || mutations[1].table != 10 || mutations[1].key.size != 16) return 3; - protocol::CmpReader outgoing(mutations[0].value); size_t count = 0; ByteView stored_request; + protocol::CmpReader outgoing(mutations[0].value); + size_t count = 0; + ByteView stored_request; if (!outgoing.array(count, 7) || count != 7 || !outgoing.binary(stored_request, 8192) || stored_request.size != request_size || std::memcmp(stored_request.data, request, request_size)) return 4; request_id.bytes[0] = 9; if (storage::encodeNewRequestTask(7, local, remote, request_id, task_id, 3, - {request, request_size}, time, *scratch, output.data(), output.size(), size) || size) return 5; + {request, request_size}, time, *scratch, output.data(), output.size(), size) || + size) return 5; return 0; } diff --git a/modules/core_geocaching/tests/test_record_encoder.cpp b/modules/core_geocaching/tests/test_record_encoder.cpp index c57d0af1..64cd9036 100644 --- a/modules/core_geocaching/tests/test_record_encoder.cpp +++ b/modules/core_geocaching/tests/test_record_encoder.cpp @@ -8,16 +8,20 @@ int main(int argc, char** argv) if (argc != 2) return 1; std::ifstream file(argv[1], std::ios::binary); std::vector data((std::istreambuf_iterator(file)), {}); - protocol::CmpReader reader({data.data(), data.size()}); size_t fields = 0; ByteView encoded; + protocol::CmpReader reader({data.data(), data.size()}); + size_t fields = 0; + ByteView encoded; if (!reader.array(fields, 2) || !reader.binary(encoded, 4096)) return 2; RecordView record; if (!protocol::decodeGeocacheRecord(encoded, record)) return 3; - std::array output{}; size_t written = 0; + std::array output{}; + size_t written = 0; if (!protocol::encodeGeocacheRecord(record, output.data(), output.size(), written) || written != encoded.size || std::memcmp(output.data(), encoded.data, written)) return 4; record.name = " "; if (protocol::encodeGeocacheRecord(record, output.data(), output.size(), written) || written) return 5; - record.name = "A"; record.longitude_e7 = 1800000000; + record.name = "A"; + record.longitude_e7 = 1800000000; if (protocol::encodeGeocacheRecord(record, output.data(), output.size(), written) || written) return 6; return 0; } diff --git a/modules/core_geocaching/tests/test_record_read_budget.cpp b/modules/core_geocaching/tests/test_record_read_budget.cpp index d7a9e3c1..ca090813 100644 --- a/modules/core_geocaching/tests/test_record_read_budget.cpp +++ b/modules/core_geocaching/tests/test_record_read_budget.cpp @@ -5,10 +5,20 @@ std::vector data; size_t bytes_read = 0, calls = 0, short_limit = SIZE_MAX; namespace platform::esp::arduino_common::storage { -class SdRuntimeFile::Impl { public: bool open = false; size_t offset = 0; }; +class SdRuntimeFile::Impl +{ + public: + bool open = false; + size_t offset = 0; +}; SdRuntimeFile::SdRuntimeFile() : impl_(new Impl) {} SdRuntimeFile::~SdRuntimeFile() { delete impl_; } -bool SdRuntimeFile::open(const char*, const char*) { impl_->open = true; impl_->offset = 0; return true; } +bool SdRuntimeFile::open(const char*, const char*) +{ + impl_->open = true; + impl_->offset = 0; + return true; +} void SdRuntimeFile::close() { impl_->open = false; } bool SdRuntimeFile::is_open() const { return impl_->open; } uint64_t SdRuntimeFile::size() const { return data.size(); } @@ -16,18 +26,22 @@ int SdRuntimeFile::read(void* out, size_t count) { ++calls; const auto n = std::min(std::min(count, short_limit), data.size() - impl_->offset); - std::memcpy(out, data.data() + impl_->offset, n); impl_->offset += n; bytes_read += n; + std::memcpy(out, data.data() + impl_->offset, n); + impl_->offset += n; + bytes_read += n; return static_cast(n); } -} +} // namespace platform::esp::arduino_common::storage bool exercise(size_t size, size_t read_limit) { using namespace platform::esp::arduino_common::geocaching; std::vector payload(size, 7), output(size + 24); ::geocaching::storage::RecordHeader header; if (!::geocaching::storage::makeRecordHeader(::geocaching::storage::RecordKind::Transaction, 1, {payload.data(), payload.size()}, header)) return false; - data.assign(header.begin(), header.end()); data.insert(data.end(), payload.begin(), payload.end()); - bytes_read = calls = 0; short_limit = read_limit; + data.assign(header.begin(), header.end()); + data.insert(data.end(), payload.begin(), payload.end()); + bytes_read = calls = 0; + short_limit = read_limit; SdJournalSegment segment; if (!segment.open(1)) return false; bool yielded = false; @@ -40,10 +54,11 @@ bool exercise(size_t size, size_t read_limit) if (result == SegmentReadResult::InProgress) { if (frame.payload.data || frame.payload.size) return false; - yielded = true; continue; + yielded = true; + continue; } return result == SegmentReadResult::Record && yielded && frame.payload.size == payload.size() && - !std::memcmp(frame.payload.data, payload.data(), payload.size()) && bytes_read == data.size(); + !std::memcmp(frame.payload.data, payload.data(), payload.size()) && bytes_read == data.size(); } return false; } diff --git a/modules/core_geocaching/tests/test_sd_volume.cpp b/modules/core_geocaching/tests/test_sd_volume.cpp index 6a0a734a..119b1bb5 100644 --- a/modules/core_geocaching/tests/test_sd_volume.cpp +++ b/modules/core_geocaching/tests/test_sd_volume.cpp @@ -1,39 +1,60 @@ #include "platform/esp/arduino_common/geocaching/sd_volume.h" +#include #include #include #include -#include std::map files; std::set directories; unsigned writes = 0; namespace platform::esp::arduino_common::storage { -class SdRuntimeFile::Impl { public: std::string path; }; +class SdRuntimeFile::Impl +{ + public: + std::string path; +}; SdRuntimeFile::SdRuntimeFile() : impl_(new Impl) {} SdRuntimeFile::~SdRuntimeFile() { delete impl_; } -bool SdRuntimeFile::open(const char* path, const char*) { impl_->path = path; files[path].clear(); return true; } +bool SdRuntimeFile::open(const char* path, const char*) +{ + impl_->path = path; + files[path].clear(); + return true; +} void SdRuntimeFile::close() {} size_t SdRuntimeFile::write(const void* data, size_t count) { - ++writes; files[impl_->path].append(static_cast(data), count); return count; + ++writes; + files[impl_->path].append(static_cast(data), count); + return count; } bool SdRuntimeFile::flush() { return true; } bool sd_card_ready() { return true; } bool sd_external_block_owner_active() { return false; } bool sd_exists(const char* path) { return directories.count(path) || files.count(path); } bool sd_is_directory(const char* path) { return directories.count(path) != 0; } -bool sd_mkdir(const char* path) { directories.insert(path); return true; } +bool sd_mkdir(const char* path) +{ + directories.insert(path); + return true; +} SdFileReadResult sd_read_file(const char* path, uint8_t* buffer, size_t capacity) { SdFileReadResult result; auto found = files.find(path); - if (found == files.end()) { result.status = SdFileReadStatus::Missing; return result; } - result.file_size = found->second.size(); result.bytes_read = std::min(capacity, found->second.size()); + if (found == files.end()) + { + result.status = SdFileReadStatus::Missing; + return result; + } + result.file_size = found->second.size(); + result.bytes_read = std::min(capacity, found->second.size()); std::memcpy(buffer, found->second.data(), result.bytes_read); - result.status = SdFileReadStatus::Ready; return result; -} + result.status = SdFileReadStatus::Ready; + return result; } +} // namespace platform::esp::arduino_common::storage int main() { using namespace platform::esp::arduino_common::geocaching; diff --git a/modules/core_geocaching/tests/test_shared_track.cpp b/modules/core_geocaching/tests/test_shared_track.cpp index 24552c8c..a649178b 100644 --- a/modules/core_geocaching/tests/test_shared_track.cpp +++ b/modules/core_geocaching/tests/test_shared_track.cpp @@ -1,12 +1,14 @@ -#include "gps/gpx/track_writer.h" #include "gps/gpx/ostream_sink.h" +#include "gps/gpx/track_writer.h" #include #include int main() { - std::ostringstream stream;gps::gpx::OstreamSink sink(stream); - assert(gps::gpx::writeTrackPoint(sink,30.25,120.15,"2026-09-16T00:00:00Z",8)); - assert(stream.str()=="\n 0.0\n \n \n 0.00\n 0.0\n 0.0\n 8\n \n\n"); - stream.str("");assert(gps::gpx::writeTrackPoint(sink,30.25,120.15,"",0,7)); - assert(stream.str().find("30.2500000")!=std::string::npos && stream.str().find("