mirror of
https://github.com/mikecarper/MeshCore.git
synced 2026-10-23 09:52:23 +00:00
feat(ota): channel-base resolver + arg parser with native tests
(cherry picked from commit 52a4ccc39093891b64e3752316fe7c191fd9b9ca)
This commit is contained in:
1 parent
47c80fecf3
commit
f04d163bea
3 files changed
+113
-1
No files matched your search
+17
-1
@@ -177,7 +177,7 @@ build_flags = -std=c++17
|
||||
-I src
|
||||
-I test/mocks
|
||||
test_build_src = yes
|
||||
test_ignore = test_kiss_modem
|
||||
test_ignore = test_kiss_modem, test_ota_channel
|
||||
build_src_filter =
|
||||
-<*>
|
||||
+<../src/Utils.cpp>
|
||||
@@ -203,3 +203,19 @@ build_src_filter =
|
||||
lib_deps =
|
||||
google/googletest @ 1.17.0
|
||||
bblanchon/ArduinoJson @ 7.4.3
|
||||
|
||||
[env:native_ota_channel]
|
||||
platform = native
|
||||
test_framework = googletest
|
||||
build_flags = -std=c++17
|
||||
-I test/mocks
|
||||
-I src
|
||||
-DOTA_MANIFEST_BASE="\"https://stable.example/mqtt/v\""
|
||||
-DOTA_MANIFEST_BASE_STABLE="\"https://stable.example/mqtt/v\""
|
||||
-DOTA_MANIFEST_BASE_DEV="\"https://dev.example/mqtt/dev/v\""
|
||||
test_build_src = yes
|
||||
test_filter = test_ota_channel
|
||||
build_src_filter =
|
||||
-<*>
|
||||
lib_deps =
|
||||
google/googletest @ 1.17.0
|
||||
@@ -0,0 +1,62 @@
|
||||
#pragma once
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
|
||||
// OTA release-channel selector, persisted in NodePrefs::ota_channel.
|
||||
enum OtaChannel : uint8_t {
|
||||
OTA_CH_NATIVE = 0, // follow the channel this build was made for
|
||||
OTA_CH_STABLE = 1,
|
||||
OTA_CH_DEV = 2,
|
||||
};
|
||||
|
||||
// Resolve the effective manifest base URL for a channel selector.
|
||||
// build.sh injects the three bases as compile-time macros:
|
||||
// OTA_MANIFEST_BASE = this build's native channel (defined on every OTA build)
|
||||
// OTA_MANIFEST_BASE_STABLE = stable channel
|
||||
// OTA_MANIFEST_BASE_DEV = dev channel
|
||||
// stable/dev fall back to the native base when their macro is undefined (legacy/local
|
||||
// builds that only define OTA_MANIFEST_BASE), so this never returns nullptr on an
|
||||
// OTA-capable build. On a non-OTA build it returns nullptr.
|
||||
static inline const char* ota_resolve_base(uint8_t channel) {
|
||||
#if defined(OTA_MANIFEST_BASE)
|
||||
switch (channel) {
|
||||
case OTA_CH_STABLE:
|
||||
#if defined(OTA_MANIFEST_BASE_STABLE)
|
||||
return OTA_MANIFEST_BASE_STABLE;
|
||||
#else
|
||||
return OTA_MANIFEST_BASE;
|
||||
#endif
|
||||
case OTA_CH_DEV:
|
||||
#if defined(OTA_MANIFEST_BASE_DEV)
|
||||
return OTA_MANIFEST_BASE_DEV;
|
||||
#else
|
||||
return OTA_MANIFEST_BASE;
|
||||
#endif
|
||||
case OTA_CH_NATIVE:
|
||||
default:
|
||||
return OTA_MANIFEST_BASE;
|
||||
}
|
||||
#else
|
||||
(void)channel;
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Human label for a selector (for the `ota branch` report).
|
||||
static inline const char* ota_channel_name(uint8_t channel) {
|
||||
switch (channel) {
|
||||
case OTA_CH_STABLE: return "stable";
|
||||
case OTA_CH_DEV: return "dev";
|
||||
default: return "native";
|
||||
}
|
||||
}
|
||||
|
||||
// Parse an `ota branch` argument. Returns true and sets *out on a known keyword
|
||||
// (stable|dev|default; "default" -> native); returns false and leaves *out untouched
|
||||
// otherwise.
|
||||
static inline bool ota_parse_channel(const char* arg, uint8_t* out) {
|
||||
if (strcmp(arg, "stable") == 0) { *out = OTA_CH_STABLE; return true; }
|
||||
if (strcmp(arg, "dev") == 0) { *out = OTA_CH_DEV; return true; }
|
||||
if (strcmp(arg, "default") == 0) { *out = OTA_CH_NATIVE; return true; }
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
#include <gtest/gtest.h>
|
||||
#include "helpers/OtaChannel.h"
|
||||
|
||||
// The three base URLs are provided as -D macros by the test env (see platformio.ini).
|
||||
TEST(OtaChannel, ResolvesNativeToBaseMacro) {
|
||||
EXPECT_STREQ(ota_resolve_base(OTA_CH_NATIVE), "https://stable.example/mqtt/v");
|
||||
}
|
||||
TEST(OtaChannel, ResolvesStable) {
|
||||
EXPECT_STREQ(ota_resolve_base(OTA_CH_STABLE), "https://stable.example/mqtt/v");
|
||||
}
|
||||
TEST(OtaChannel, ResolvesDev) {
|
||||
EXPECT_STREQ(ota_resolve_base(OTA_CH_DEV), "https://dev.example/mqtt/dev/v");
|
||||
}
|
||||
TEST(OtaChannel, ParseKnownKeywords) {
|
||||
uint8_t ch = 99;
|
||||
EXPECT_TRUE(ota_parse_channel("stable", &ch)); EXPECT_EQ(ch, OTA_CH_STABLE);
|
||||
EXPECT_TRUE(ota_parse_channel("dev", &ch)); EXPECT_EQ(ch, OTA_CH_DEV);
|
||||
EXPECT_TRUE(ota_parse_channel("default", &ch)); EXPECT_EQ(ch, OTA_CH_NATIVE);
|
||||
}
|
||||
TEST(OtaChannel, ParseRejectsUnknownAndLeavesOutputUntouched) {
|
||||
uint8_t ch = 7;
|
||||
EXPECT_FALSE(ota_parse_channel("beta", &ch));
|
||||
EXPECT_EQ(ch, 7);
|
||||
}
|
||||
TEST(OtaChannel, NameLabels) {
|
||||
EXPECT_STREQ(ota_channel_name(OTA_CH_NATIVE), "native");
|
||||
EXPECT_STREQ(ota_channel_name(OTA_CH_STABLE), "stable");
|
||||
EXPECT_STREQ(ota_channel_name(OTA_CH_DEV), "dev");
|
||||
}
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
::testing::InitGoogleTest(&argc, argv);
|
||||
return RUN_ALL_TESTS();
|
||||
}
|
||||
Reference in new issue
Block a user