Files
MeshCore/test/fixtures/power_saving_diagnostics.cpp
T
mikecarper 21194b9825 Fix compile and capacity blockers in the full release matrix
Resolve Serial macro and ESP-NOW wrapper compilation errors. Preserve queue, neighbor, advert-history and Room post capacities while using qualified RTC, PSRAM and word-only IRAM storage on constrained ESP32 targets. Reduce Full infrastructure flash through lossless Room web compression, compact crypto and unused exception metadata removal.

Add focused native regressions for storage ownership, exact protocol output, OTA proofs and build policy. Keep physical flash sizes, OTA slots and RAM guard formulas unchanged.
2026-10-24 05:38:23 -07:00

178 lines
9.0 KiB
C++

#include <helpers/PowerSavingDiagnostics.h>
#include <assert.h>
#include <limits.h>
#include <initializer_list>
using namespace mesh::powerdiag;
extern void powerDiagnosticsOtherTranslationUnit();
static bool command(const char* text, char* out, uint32_t now = 0) {
return handleCommand(text, out, 157, now);
}
int main(int argc, char** argv) {
assert(argc == 2);
state() = Snapshot();
const char* test = argv[1];
if (!strcmp(test, "disabled")) {
assert(!enabled());
decision(mask(Reason::UsbSession), 10);
sleepBegin(10); sleepEnd(20);
boardVeto(Reason::Board, 20); boardError(-7, 30);
const Snapshot value = snapshot(1000);
assert(!value.observed && !value.current && !value.calls && !value.errors);
assert(!value.board_vetoes && !value.eligible_ms && !value.union_blocked_ms);
} else if (!strcmp(test, "overlap")) {
setEnabled(true, 10);
decision(mask(Reason::UsbSession) | mask(Reason::Bridge), 10);
decision(mask(Reason::Bridge), 40);
decision(mask(Reason::Bridge), 50);
decision(0, 60);
const Snapshot value = snapshot(80);
assert(value.union_blocked_ms == 50 && value.eligible_ms == 20);
assert(value.blocked_ms[(int)Reason::UsbSession] == 30);
assert(value.blocked_ms[(int)Reason::Bridge] == 50);
assert(value.transitions[(int)Reason::UsbSession] == 1);
assert(value.transitions[(int)Reason::Bridge] == 1);
assert(value.seen == (mask(Reason::UsbSession) | mask(Reason::Bridge)));
assert(state().eligible_ms == 0); // Formatting/snapshot does not mutate state.
assert(snapshot(80).eligible_ms == 20);
} else if (!strcmp(test, "freeze")) {
setEnabled(true, 0);
decision(mask(Reason::UsbSession), 0);
decision(mask(Reason::Calibration), 50);
setEnabled(false, 100);
decision(mask(Reason::Bridge), 200);
const Snapshot value = snapshot(1000);
assert(value.union_blocked_ms == 100 && value.eligible_ms == 0);
assert(value.blocked_ms[(int)Reason::UsbSession] == 50);
assert(value.blocked_ms[(int)Reason::Calibration] == 50);
assert(value.current == mask(Reason::Calibration));
setEnabled(true, 1100);
assert(!state().observed && !state().current && !state().seen);
assert(!state().union_blocked_ms && !state().eligible_ms);
} else if (!strcmp(test, "reset")) {
setEnabled(true, 0); decision(mask(Reason::SerialIO), 1);
sleepBegin(1); sleepEnd(20); reset(10);
assert(enabled() && !state().observed && !state().calls && !state().seen);
decision(0, 11); assert(snapshot(20).eligible_ms == 9);
setEnabled(false, 20); reset(30);
assert(!enabled() && !state().observed && !state().eligible_ms);
} else if (!strcmp(test, "wrap")) {
setEnabled(true, UINT32_MAX - 9);
decision(mask(Reason::Queue), UINT32_MAX - 9);
decision(0, 10);
assert(state().union_blocked_ms == 20);
sleepBegin(UINT32_MAX - 49); sleepEnd(50);
assert(state().last_call_us == 100 && !state().short_returns);
sleepBegin(50); sleepEnd(149);
assert(state().short_returns == 1 && state().last_call_us == 99);
assert(state().calls == 2 && state().returns == 2 && state().call_us == 199);
} else if (!strcmp(test, "veto_error")) {
setEnabled(true, 0); decision(0, 0);
sleepBegin(1); boardVeto(Reason::BridgeCleanup, 1, 7); sleepEnd(1001);
assert(state().calls == 1 && state().returns == 0 && state().board_vetoes == 1);
assert(state().current == mask(Reason::BridgeCleanup) && state().detail == 7);
decision(0, 2); sleepBegin(2000); boardError(-17, 3); sleepEnd(3000);
assert(state().errors == 1 && state().detail == -17 && state().returns == 0);
assert(state().current == mask(Reason::Board));
decision(0, 4); sleepBegin(4000); sleepEnd(4000); sleepEnd(5000);
assert(state().returns == 1 && state().short_returns == 1);
assert(state().call_us == 0 && state().board_vetoes == 1);
decision(0, 5); sleepBegin(5000); sleepEnd(5010); boardError(-9, 6);
// A reported API return is not a claim that its result was successful.
assert(state().returns == 2 && state().errors == 2 && state().call_us == 10);
assert(state().detail == -9 && state().current == mask(Reason::Board));
} else if (!strcmp(test, "saturation")) {
setEnabled(true, 0); decision(mask(Reason::Board), 0);
state().union_blocked_ms = UINT32_MAX - 5;
state().blocked_ms[(int)Reason::Board] = UINT32_MAX - 5;
state().transitions[(int)Reason::Board] = UINT16_MAX;
decision(0, 10); decision(mask(Reason::Board), 11);
assert(state().union_blocked_ms == UINT32_MAX);
assert(state().blocked_ms[(int)Reason::Board] == UINT32_MAX);
assert(state().transitions[(int)Reason::Board] == UINT16_MAX);
state().calls = state().returns = state().short_returns = UINT32_MAX;
state().call_us = UINT32_MAX - 5;
sleepBegin(20); sleepEnd(30);
assert(state().calls == UINT32_MAX && state().returns == UINT32_MAX);
assert(state().short_returns == UINT32_MAX && state().call_us == UINT32_MAX);
} else if (!strcmp(test, "commands")) {
char out[157];
assert(command("set powersaving.diag on", out, 1) && enabled());
assert(strstr(out, "RAM only") && strstr(out, "unchanged"));
decision(mask(Reason::Calibration), 2);
assert(command("set powersaving.diag on", out, 3));
assert(state().seen == mask(Reason::Calibration)); // Repeated on is not a clear.
assert(command("get powersaving.diag calibration", out, 5));
assert(strstr(out, "active=1") && strstr(out, "blocked_ms=3"));
assert(command("get powersaving.diag\t calls \t", out, 5));
assert(strstr(out, "calls=0"));
assert(command("set powersaving.diag off \t", out, 5) && !enabled());
assert(command("clear powersaving.diag", out, 6) && !enabled());
assert(!state().observed && !state().seen);
} else if (!strcmp(test, "strict")) {
char out[157] = "untouched";
assert(!command("get powersaving.diagfoo", out));
assert(!command("set powersaving.diagon", out));
assert(!command("get powersaving", out));
assert(!strcmp(out, "untouched"));
for (const char* text : {"set powersaving.diag", "set powersaving.diag on junk",
"set powersaving.diag 1", "clear powersaving.diag all",
"get powersaving.diag 9", "get powersaving.diag 01",
"get powersaving.diag 1junk", "get powersaving.diag state junk"}) {
assert(command(text, out)); assert(strstr(out, "Error:"));
assert(!enabled() && !state().observed && !state().calls);
}
} else if (!strcmp(test, "format")) {
char out[157];
assert(command("get powersaving.diag", out, 100));
assert(strstr(out, "age_ms=unknown") && strstr(out, "why=unobserved"));
assert(command("get powersaving.diag usb.session", out, 100));
assert(strstr(out, "age_ms=unknown"));
setEnabled(true, 100); decision(mask(Reason::UsbSession), 100);
assert(command("get powersaving.diag state", out, 10000));
assert(strstr(out, "age_ms=9900") && strstr(out, "why=usb.session"));
assert(state().decision_at_ms == 100 && state().last_ms == 100);
assert(command("get powersaving.diag time", out, 10000));
assert(strstr(out, "NOT sleep residency"));
assert(command("get powersaving.diag 3", out, 10000));
assert(strstr(out, "usb.session=1/9900"));
} else if (!strcmp(test, "capacity")) {
setEnabled(true, 0); decision(ValidMask, 0);
state().union_blocked_ms = state().eligible_ms = UINT32_MAX;
state().calls = state().returns = state().short_returns = UINT32_MAX;
state().board_vetoes = state().errors = UINT32_MAX;
state().call_us = state().max_call_us = state().last_call_us = UINT32_MAX;
state().detail = INT32_MIN;
for (size_t i = 0; i < ReasonCount; ++i) {
state().blocked_ms[i] = UINT32_MAX; state().transitions[i] = UINT16_MAX;
}
for (unsigned page = 0; page <= 8; ++page) {
char large[512], bounded[157];
formatPage(page, large, sizeof(large), UINT32_MAX);
formatPage(page, bounded, sizeof(bounded), UINT32_MAX);
assert(strlen(large) < sizeof(bounded)); assert(!strcmp(large, bounded));
}
for (size_t capacity = 1; capacity < 160; ++capacity) {
char guarded[162]; memset(guarded, '!', sizeof(guarded));
assert(handleCommand("get powersaving.diag time", guarded + 1, capacity, 0));
assert(guarded[0] == '!' && guarded[capacity + 1] == '!');
assert(memchr(guarded + 1, 0, capacity));
}
char untouched = '!';
assert(!handleCommand("get powersaving.diag", &untouched, 0, 0));
assert(untouched == '!');
assert(!handleCommand(nullptr, &untouched, 1, 0));
assert(!handleCommand("get powersaving.diag", nullptr, 1, 0));
} else if (!strcmp(test, "shared")) {
setEnabled(true, 0); powerDiagnosticsOtherTranslationUnit();
assert(state().current == mask(Reason::UsbRecovery));
assert(state().transitions[(int)Reason::UsbRecovery] == 1);
} else if (!strcmp(test, "unknown_mask")) {
setEnabled(true, 0); decision(UINT32_MAX, 0);
assert(state().current == ValidMask && state().seen == ValidMask);
assert(mask(Reason::Count) == 0 && !strcmp(reasonName(Reason::Count), "unknown"));
} else assert(false);
}