feat(cli): support relative minutes in radio schedules
This commit is contained in:
1 parent
7c9cb59400
commit
ff50589b69
8 files changed
+121
-16
No files matched your search
+28
@@ -187,6 +187,33 @@ static void scheduledSaveFailureKeepsOriginalTimes() {
|
||||
assert(f.radio.p.secondary.params.freq == 910.5f);
|
||||
}
|
||||
|
||||
static void relativeSchedules() {
|
||||
Fixture f;
|
||||
f.cmd("set tempradioat2 910.5,500,8,5,rxtx,+1,+3,80");
|
||||
f.advance(59000);
|
||||
assert(!f.radio.p.enabled());
|
||||
f.advance(1000);
|
||||
assert(f.radio.p.secondary_temporary);
|
||||
f.advance(119000);
|
||||
assert(f.radio.p.secondary_temporary);
|
||||
f.advance(1000);
|
||||
assert(!f.radio.p.enabled());
|
||||
char command[160];
|
||||
snprintf(command, sizeof(command), "set tempradioat2 911.5,500,8,5,rxtx,+1,%lu,80",
|
||||
(unsigned long)(f.clock.epoch + 120));
|
||||
f.cmd(command);
|
||||
f.advance(60000);
|
||||
assert(f.radio.p.secondary_temporary && f.radio.p.secondary.params.freq == 911.5f);
|
||||
f.advance(60000);
|
||||
assert(!f.radio.p.enabled());
|
||||
f.cmd("set radioat2 912.5,500,8,5,rx,+1,80");
|
||||
f.advance(60000);
|
||||
assert(!f.radio.p.secondary_temporary && f.radio.p.secondary.params.freq == 912.5f);
|
||||
f.cmd("set radioat2 912.5,500,8,5,rx,+0,80", false);
|
||||
f.cmd("set radioat2 912.5,500,8,5,rx,+4294967295,80", false);
|
||||
f.cmd("set tempradioat2 912.5,500,8,5,rx,+3,+1,80", false);
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
if (argc == 2) {
|
||||
if (!strcmp(argv[1], "permanent_order")) permanentScheduleOrder();
|
||||
@@ -195,6 +222,7 @@ int main(int argc, char** argv) {
|
||||
else if (!strcmp(argv[1], "save_failure")) scheduledSaveFailureKeepsOriginalTimes();
|
||||
else if (!strcmp(argv[1], "schedule_permutations")) schedulePermutations();
|
||||
else if (!strcmp(argv[1], "storage_isolation")) storageBackoffDoesNotDelayTemporaryWindows();
|
||||
else if (!strcmp(argv[1], "relative_schedule")) relativeSchedules();
|
||||
else return 2;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -20,7 +20,8 @@ class RadioProfileCLITest(unittest.TestCase):
|
||||
str(ROOT/'test/fixtures/radio_profiles/cli_test.cpp'),
|
||||
'-o', str(exe)], check=True, capture_output=True, text=True)
|
||||
for scenario in (None, 'permanent_order', 'temporary_boundary', 'lease_creation',
|
||||
'save_failure', 'schedule_permutations', 'storage_isolation'):
|
||||
'save_failure', 'schedule_permutations', 'storage_isolation',
|
||||
'relative_schedule'):
|
||||
with self.subTest(scenario=scenario or 'commands_persistence_and_timers'):
|
||||
subprocess.run([str(exe)] + ([scenario] if scenario else []), check=True)
|
||||
|
||||
|
||||
@@ -557,6 +557,51 @@ class RepeaterRadioTimingIntegrationTest(unittest.TestCase):
|
||||
defines = "#define USE_LR2021 1\n" if lr2021 else ""
|
||||
self.compile_and_run(defines + HARNESS.replace("@METHODS@", methods))
|
||||
|
||||
def test_scheduled_radio_relative_and_absolute_times(self):
|
||||
source = (ROOT / "src/helpers/CommonCLI.cpp").read_text(encoding="utf-8")
|
||||
parsers = "\n".join(method(source, signature) for signature in [
|
||||
"static bool looksUnsignedInteger(", "static const char* skipSpacesConst(",
|
||||
"static bool parseUint32Strict(", "static int countSeparatedParts(",
|
||||
"static bool parseScheduledRadioArgs(",
|
||||
])
|
||||
utils = (ROOT / "src/Utils.cpp").read_text(encoding="utf-8")
|
||||
parts = method(utils, "int Utils::parseTextParts(")
|
||||
self.compile_and_run(r'''
|
||||
#include <cassert>
|
||||
#include <cstdio>
|
||||
#include <cstring>
|
||||
#include <initializer_list>
|
||||
#include <helpers/CLICommandUtils.h>
|
||||
struct StrHelper {
|
||||
static void strncpy(char* dst, const char* src, size_t n) { snprintf(dst, n, "%s", src); }
|
||||
};
|
||||
namespace mesh {
|
||||
struct Utils { static int parseTextParts(char*, const char*[], int, char); };
|
||||
@PARTS@
|
||||
}
|
||||
@PARSERS@
|
||||
int main() {
|
||||
const uint32_t now = 1700000000;
|
||||
float freq, bw; uint8_t sf, cr; uint32_t start, end;
|
||||
assert(parseScheduledRadioArgs("910.5,500,8,5,+5,+15", true, freq,bw,sf,cr,start,end,now));
|
||||
assert(start == now + 300 && end == now + 900);
|
||||
assert(parseScheduledRadioArgs("910.5,500,8,5,1700000300,1700000900", true, freq,bw,sf,cr,start,end,now));
|
||||
assert(start == now + 300 && end == now + 900);
|
||||
assert(parseScheduledRadioArgs("910.5,500,8,5,1700000300,+15", true, freq,bw,sf,cr,start,end,now));
|
||||
assert(start == now + 300 && end == now + 900);
|
||||
assert(parseScheduledRadioArgs("910.5,500,8,5,+5", false, freq,bw,sf,cr,start,end,now));
|
||||
assert(start == now + 300 && end == 0);
|
||||
for (const char* invalid : {"+0", "+", "++1", "+ 1", "-1", "+1.5", "+1x", "+4294967295", "4294967296"}) {
|
||||
start = 42;
|
||||
assert(!mesh::cli::parseRadioScheduleTime(invalid, now, start));
|
||||
assert(start == 42);
|
||||
}
|
||||
assert(mesh::cli::parseRadioScheduleTime(" +1 ", now, start) && start == now + 60);
|
||||
assert(mesh::cli::parseRadioScheduleTime("+1", UINT32_MAX - 60, start) && start == UINT32_MAX);
|
||||
assert(!mesh::cli::parseRadioScheduleTime("+1", UINT32_MAX - 59, start));
|
||||
}
|
||||
'''.replace("@PARTS@", parts).replace("@PARSERS@", parsers))
|
||||
|
||||
def test_production_cli_replies_and_duration_validation(self):
|
||||
source = (ROOT / "src/helpers/CommonCLI.cpp").read_text(encoding="utf-8")
|
||||
parsers = "\n".join(method(source, signature) for signature in [
|
||||
|
||||
Reference in new issue
Block a user