From 3e35faec2fa220a5c9bee4dc95e6609e458cb321 Mon Sep 17 00:00:00 2001 From: Daniel Brondani Date: Tue, 19 Aug 2025 10:25:09 +0200 Subject: [PATCH 1/2] [projmgr] Handle `LoadSolution` method request with `activeTarget` parameter --- tools/projmgr/CMakeLists.txt | 4 +-- tools/projmgr/include/ProjMgr.h | 3 +- tools/projmgr/src/ProjMgr.cpp | 11 ++++++-- tools/projmgr/src/ProjMgrRpcServer.cpp | 7 +++-- .../test/data/TestRpc/minimal.csolution.yml | 4 +++ tools/projmgr/test/src/ProjMgrRpcTests.cpp | 28 +++++++++++-------- 6 files changed, 36 insertions(+), 21 deletions(-) diff --git a/tools/projmgr/CMakeLists.txt b/tools/projmgr/CMakeLists.txt index 57f6d99e9..901dccee1 100644 --- a/tools/projmgr/CMakeLists.txt +++ b/tools/projmgr/CMakeLists.txt @@ -17,8 +17,8 @@ include(FetchContent) FetchContent_Declare( rpc-interface DOWNLOAD_EXTRACT_TIMESTAMP ON - URL https://github.com/Open-CMSIS-Pack/csolution-rpc/releases/download/v0.0.3/csolution-rpc.zip - URL_HASH SHA256=edc762373b3b7dad5b966ecb271f03866b12841675e0967a809c10c9883f29f4 + URL https://github.com/brondani/csolution-rpc/releases/download/v0.0.4/csolution-rpc.zip + URL_HASH SHA256=643ab30d25f47b55735bc6fecd3622ad1c7619d8fac901e2b19cd594a01df8b2 ) FetchContent_MakeAvailable(rpc-interface) diff --git a/tools/projmgr/include/ProjMgr.h b/tools/projmgr/include/ProjMgr.h index f5c020c13..cd4b5fc5e 100644 --- a/tools/projmgr/include/ProjMgr.h +++ b/tools/projmgr/include/ProjMgr.h @@ -65,9 +65,10 @@ class ProjMgr { /** * @brief load solution * @param path to .csolution.yml file + * @param active target set in the format [@] * @return processing status */ - bool LoadSolution(const std::string& csolution); + bool LoadSolution(const std::string& csolution, const std::string& activeTargetSet); protected: /** diff --git a/tools/projmgr/src/ProjMgr.cpp b/tools/projmgr/src/ProjMgr.cpp index c2a012bdc..27fb1489d 100644 --- a/tools/projmgr/src/ProjMgr.cpp +++ b/tools/projmgr/src/ProjMgr.cpp @@ -1286,15 +1286,20 @@ void ProjMgr::Clear() { ProjMgrLogger::Get().Clear(); } -bool ProjMgr::LoadSolution(const std::string& csolution) { +bool ProjMgr::LoadSolution(const std::string& csolution, const std::string& activeTargetSet) { Clear(); m_csolutionFile = csolution; m_rootDir = RteUtils::ExtractFilePath(m_csolutionFile, false); - - m_contextSet = true; m_updateRteFiles = false; + if (activeTargetSet.empty()) { + // fallback to 'context-set' for backward compatibility + m_contextSet = true; + } else { + m_activeTargetSet = activeTargetSet; + } + if (!PopulateContexts()) { return false; } diff --git a/tools/projmgr/src/ProjMgrRpcServer.cpp b/tools/projmgr/src/ProjMgrRpcServer.cpp index 548f09f66..d7ae56df8 100644 --- a/tools/projmgr/src/ProjMgrRpcServer.cpp +++ b/tools/projmgr/src/ProjMgrRpcServer.cpp @@ -81,7 +81,7 @@ class RpcHandler : public RpcMethods { RpcArgs::SuccessResult Apply(const string& context) override; RpcArgs::SuccessResult Resolve(const string& context) override; RpcArgs::SuccessResult LoadPacks(void) override; - RpcArgs::SuccessResult LoadSolution(const string& solution) override; + RpcArgs::SuccessResult LoadSolution(const string& solution, const string& activeTarget) override; RpcArgs::UsedItems GetUsedItems(const string& context) override; RpcArgs::PacksInfo GetPacksInfo(const string& context) override; RpcArgs::DeviceList GetDeviceList(const string& context, const string& namePattern, const string& vendor) override; @@ -201,6 +201,7 @@ RpcArgs::GetVersionResult RpcHandler::GetVersion(void) { RpcArgs::GetVersionResult res = {{true}}; res.message = string("Running ") + INTERNAL_NAME + " " + VERSION_STRING; res.version = VERSION_STRING; + res.apiVersion = RPC_API_VERSION; return res; } @@ -279,7 +280,7 @@ RpcArgs::SuccessResult RpcHandler::LoadPacks(void) { return result; } -RpcArgs::SuccessResult RpcHandler::LoadSolution(const string& solution) { +RpcArgs::SuccessResult RpcHandler::LoadSolution(const string& solution, const string& activeTarget) { RpcArgs::SuccessResult result = {false}; const auto csolutionFile = RteFsUtils::MakePathCanonical(solution); if (!regex_match(csolutionFile, regex(".*\\.csolution\\.(yml|yaml)"))) { @@ -290,7 +291,7 @@ RpcArgs::SuccessResult RpcHandler::LoadSolution(const string& solution) { result.message = "Packs must be loaded before loading solution"; return result; } - result.success = m_solutionLoaded = m_manager.LoadSolution(csolutionFile); + result.success = m_solutionLoaded = m_manager.LoadSolution(csolutionFile, activeTarget); if (!m_solutionLoaded) { result.message = "failed to load and process solution " + csolutionFile; } diff --git a/tools/projmgr/test/data/TestRpc/minimal.csolution.yml b/tools/projmgr/test/data/TestRpc/minimal.csolution.yml index 469b7f75c..d36a489e4 100644 --- a/tools/projmgr/test/data/TestRpc/minimal.csolution.yml +++ b/tools/projmgr/test/data/TestRpc/minimal.csolution.yml @@ -7,6 +7,10 @@ solution: target-types: - type: TestHW device: RteTest_ARMCM4_NOFP + target-set: + - set: + images: + - project-context: minimal projects: - project: minimal.cproject.yml diff --git a/tools/projmgr/test/src/ProjMgrRpcTests.cpp b/tools/projmgr/test/src/ProjMgrRpcTests.cpp index e7f5a04a6..ea3cb6cf4 100644 --- a/tools/projmgr/test/src/ProjMgrRpcTests.cpp +++ b/tools/projmgr/test/src/ProjMgrRpcTests.cpp @@ -26,7 +26,10 @@ class ProjMgrRpcTests : public ProjMgr, public ::testing::Test { vector RunRpcMethods(const string& strIn); string RunRpcMethodsWithContent(const string& strIn); - string CreateLoadRequests(const string& solution, const vector& contextList = RteUtils::EMPTY_STRING_VECTOR); + string CreateLoadRequests(const string& solution, + const string& activeTarget = RteUtils::EMPTY_STRING, + const vector& contextList = RteUtils::EMPTY_STRING_VECTOR + ); }; @@ -41,12 +44,12 @@ string ProjMgrRpcTests::FormatRequest(const int id, const string& method, const return request.dump(); } -string ProjMgrRpcTests::CreateLoadRequests(const string& solution, const vector& contextList) +string ProjMgrRpcTests::CreateLoadRequests(const string& solution, const string& activeTarget, const vector& contextList) { string loadSolutionRequest; if(!solution.empty()) { auto csolutionPath = testinput_folder + solution; - loadSolutionRequest = FormatRequest(2, "LoadSolution", json({{ "solution", csolutionPath }})); + loadSolutionRequest = FormatRequest(2, "LoadSolution", json({{ "solution", csolutionPath }, { "activeTarget", activeTarget } })); if(!contextList.empty()) { YAML::Node cbuildset; cbuildset["cbuild-set"]["generated-by"] = "ProjMrgUnitTests"; @@ -110,6 +113,7 @@ TEST_F(ProjMgrRpcTests, RpcGetVersion) { EXPECT_EQ(1, responses[0]["id"]); EXPECT_TRUE(responses[0]["result"]["success"]); EXPECT_EQ(string(VERSION_STRING), responses[0]["result"]["version"]); + EXPECT_EQ(string(RPC_API_VERSION), responses[0]["result"]["apiVersion"]); } TEST_F(ProjMgrRpcTests, RpcGetVersionWithContent) { @@ -119,7 +123,7 @@ TEST_F(ProjMgrRpcTests, RpcGetVersionWithContent) { } TEST_F(ProjMgrRpcTests, RpcLoadSolution) { - const auto& requests = CreateLoadRequests("/TestRpc/minimal.csolution.yml"); + const auto& requests = CreateLoadRequests("/TestRpc/minimal.csolution.yml", "TestHW"); const auto& responses = RunRpcMethods(requests); EXPECT_TRUE(responses[0]["result"]["success"]); EXPECT_TRUE(responses[1]["result"]["success"]); @@ -145,7 +149,7 @@ TEST_F(ProjMgrRpcTests, RpcLoadNotSolution) { TEST_F(ProjMgrRpcTests, RpcLoadSolutionNoPacks) { auto csolutionPath = testinput_folder + "/TestRpc/minimal.csolution.yml"; - const auto& requests = FormatRequest(1, "LoadSolution", json({ { "solution", csolutionPath } })); + const auto& requests = FormatRequest(1, "LoadSolution", json({ { "solution", csolutionPath }, { "activeTarget", "TestHW" } })); const auto& responses = RunRpcMethods(requests); EXPECT_FALSE(responses[0]["result"]["success"]); string msg = responses[0]["result"]["message"]; @@ -207,7 +211,7 @@ TEST_F(ProjMgrRpcTests, RpcDeviceListContext) { vector contextList = { context }; - auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", contextList); + auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", "", contextList); // all devices requests += FormatRequest(3, "GetDeviceList", json({{"context", "selectable+CM0"},{ "namePattern", ""}, {"vendor", ""}})); requests += FormatRequest(4, "GetDeviceList", json({{"context", "selectable+CM0"},{ "namePattern", "*Dual*"}, {"vendor", ""}})); @@ -336,7 +340,7 @@ TEST_F(ProjMgrRpcTests, RpcBoardListContext) { vector contextList = { context }; - auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", contextList); + auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", "", contextList); // all boards requests += FormatRequest(2, "GetBoardList", json({{"context", "selectable+CM0"},{ "namePattern", ""}, {"vendor", ""}})); @@ -442,7 +446,7 @@ TEST_F(ProjMgrRpcTests, RpcValidateComponents) { "incompatible+CM0", "incompatible-variant+CM0", }; - auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", contextList); + auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", "", contextList); int id = 3; for (const auto& context : contextList) { requests += FormatRequest(id++, "ValidateComponents", json({ { "context", context } })); @@ -497,7 +501,7 @@ TEST_F(ProjMgrRpcTests, RpcResolveComponents) { vector contextList = { context }; - auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", contextList); + auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", "", contextList); requests += FormatRequest(3, "ValidateComponents", json({{ "context", context }})); requests += FormatRequest(4, "Resolve", json({{ "context", context }})); requests += FormatRequest(5, "ValidateComponents", json({{ "context", context }})); @@ -528,7 +532,7 @@ TEST_F(ProjMgrRpcTests, RpcSelectComponent) { param["count"] = 1; param["options"] = json::object(); - auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", contextList); + auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", "", contextList); requests += FormatRequest(3, "ValidateComponents", json({{ "context", context }})); requests += FormatRequest(4, "GetComponentsTree", json({{ "context", context }, {"all", false}})); requests += FormatRequest(5, "SelectComponent", param); @@ -561,7 +565,7 @@ TEST_F(ProjMgrRpcTests, RpcSelectVariant) { param["id"] = "ARM::RteTest:Dependency:Variant"; param["variant"] = "Compatible"; - auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", contextList); + auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", "", contextList); requests += FormatRequest(3, "ValidateComponents", json({{ "context", context }})); requests += FormatRequest(4, "SelectVariant", param); requests += FormatRequest(5, "ValidateComponents", json({{ "context", context }})); @@ -598,7 +602,7 @@ TEST_F(ProjMgrRpcTests, RpcGetUsedItems) { param["count"] = 1; RpcArgs::to_json(param["options"], opt); - auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", contextList); + auto requests = CreateLoadRequests("/Validation/dependencies.csolution.yml", "", contextList); requests += FormatRequest(3, "GetUsedItems", json({{ "context", context }})); requests += FormatRequest(4, "SelectComponent", param); requests += FormatRequest(5, "Apply", param); From 09ee3c38bcfb112f9d3bbe1bed29b36c162b0689 Mon Sep 17 00:00:00 2001 From: Daniel Brondani Date: Wed, 20 Aug 2025 13:35:51 +0200 Subject: [PATCH 2/2] [projmgr] Add `ConvertSolution` RPC method handling --- tools/projmgr/CMakeLists.txt | 4 +-- tools/projmgr/include/ProjMgr.h | 12 ++++++- tools/projmgr/src/ProjMgr.cpp | 20 +++++++---- tools/projmgr/src/ProjMgrRpcServer.cpp | 25 +++++++++++++ tools/projmgr/test/src/ProjMgrRpcTests.cpp | 40 +++++++++++++++++++-- tools/projmgr/test/src/ProjMgrTestEnv.cpp | 31 +++++++++++++++- tools/projmgr/test/src/ProjMgrTestEnv.h | 4 +++ tools/projmgr/test/src/ProjMgrUnitTests.cpp | 26 +------------- 8 files changed, 125 insertions(+), 37 deletions(-) diff --git a/tools/projmgr/CMakeLists.txt b/tools/projmgr/CMakeLists.txt index 901dccee1..9864320c5 100644 --- a/tools/projmgr/CMakeLists.txt +++ b/tools/projmgr/CMakeLists.txt @@ -17,8 +17,8 @@ include(FetchContent) FetchContent_Declare( rpc-interface DOWNLOAD_EXTRACT_TIMESTAMP ON - URL https://github.com/brondani/csolution-rpc/releases/download/v0.0.4/csolution-rpc.zip - URL_HASH SHA256=643ab30d25f47b55735bc6fecd3622ad1c7619d8fac901e2b19cd594a01df8b2 + URL https://github.com/Open-CMSIS-Pack/csolution-rpc/releases/download/v0.0.4/csolution-rpc.zip + URL_HASH SHA256=ca9bfdacb35b44b6cadf29d87123adbfc1a5e944af7f2aefda0ccf7fd4bd216f ) FetchContent_MakeAvailable(rpc-interface) diff --git a/tools/projmgr/include/ProjMgr.h b/tools/projmgr/include/ProjMgr.h index cd4b5fc5e..2318b288b 100644 --- a/tools/projmgr/include/ProjMgr.h +++ b/tools/projmgr/include/ProjMgr.h @@ -70,6 +70,16 @@ class ProjMgr { */ bool LoadSolution(const std::string& csolution, const std::string& activeTargetSet); + /** + * @brief convert solution and generate yml files + * @param path to .csolution.yml file + * @param active target set in the format [@] + * @param update-rte: create/update configuration files + * @return processing status + */ + bool RunConvert(const std::string&csolution = RteUtils::EMPTY_STRING, + const std::string& activeTargetSet = RteUtils::EMPTY_STRING, const bool& updateRte = false); + protected: /** * @brief parse command line options @@ -185,7 +195,6 @@ class ProjMgr { std::set m_failedContext; bool RunConfigure(); - bool RunConvert(); bool RunCodeGenerator(); bool RunListPacks(); bool RunListBoards(); @@ -212,6 +221,7 @@ class ProjMgr { bool ParseAndValidateContexts(); bool ProcessContexts(); bool IsSolutionImageOnly(); + void InitSolution(const std::string& csolution, const std::string& activeTargetSet, const bool& updateRte); }; #endif // PROJMGR_H diff --git a/tools/projmgr/src/ProjMgr.cpp b/tools/projmgr/src/ProjMgr.cpp index 27fb1489d..92820310e 100644 --- a/tools/projmgr/src/ProjMgr.cpp +++ b/tools/projmgr/src/ProjMgr.cpp @@ -563,7 +563,7 @@ bool ProjMgr::PopulateContexts(void) { bool ProjMgr::GenerateYMLConfigurationFiles(bool previousResult) { // Generate cbuild pack file - const bool isUsingContexts = m_contextSet || m_context.size() != 0; + const bool isUsingContexts = m_contextSet || m_activeTargetSet.has_value() || m_context.size() != 0; if (!m_emitter.GenerateCbuildPack(m_processedContexts, isUsingContexts, m_frozenPacks)) { return false; } @@ -750,7 +750,12 @@ bool ProjMgr::RunConfigure() { return success; } -bool ProjMgr::RunConvert(void) { +bool ProjMgr::RunConvert(const std::string& csolution, const std::string& activeTargetSet, const bool& updateRte) { + // Set csolution.yml file and options + if (!csolution.empty()) { + InitSolution(csolution, activeTargetSet, updateRte); + } + // Configure bool Success = Configure(); @@ -1286,19 +1291,22 @@ void ProjMgr::Clear() { ProjMgrLogger::Get().Clear(); } -bool ProjMgr::LoadSolution(const std::string& csolution, const std::string& activeTargetSet) { +void ProjMgr::InitSolution(const std::string& csolution, const std::string& activeTargetSet, const bool& updateRte) { Clear(); - m_csolutionFile = csolution; m_rootDir = RteUtils::ExtractFilePath(m_csolutionFile, false); - m_updateRteFiles = false; - + m_updateRteFiles = updateRte; if (activeTargetSet.empty()) { // fallback to 'context-set' for backward compatibility m_contextSet = true; } else { m_activeTargetSet = activeTargetSet; } +} + +bool ProjMgr::LoadSolution(const std::string& csolution, const std::string& activeTargetSet) { + + InitSolution(csolution, activeTargetSet, false); if (!PopulateContexts()) { return false; diff --git a/tools/projmgr/src/ProjMgrRpcServer.cpp b/tools/projmgr/src/ProjMgrRpcServer.cpp index d7ae56df8..aa522e360 100644 --- a/tools/projmgr/src/ProjMgrRpcServer.cpp +++ b/tools/projmgr/src/ProjMgrRpcServer.cpp @@ -95,6 +95,7 @@ class RpcHandler : public RpcMethods { RpcArgs::Results ValidateComponents(const string& context) override; RpcArgs::LogMessages GetLogMessages(void) override; RpcArgs::DraftProjectsInfo GetDraftProjects(const RpcArgs::DraftProjectsFilter& filter) override; + RpcArgs::ConvertSolutionResult ConvertSolution(const string& solution, const string& activeTarget, const bool& updateRte) override; protected: enum Exception @@ -674,4 +675,28 @@ RpcArgs::DraftProjectsInfo RpcHandler::GetDraftProjects(const RpcArgs::DraftProj return applications; } +RpcArgs::ConvertSolutionResult RpcHandler::ConvertSolution(const string& solution, const string& activeTarget, const bool& updateRte) { + RpcArgs::ConvertSolutionResult result = { false }; + const auto csolutionFile = RteFsUtils::MakePathCanonical(solution); + if (!regex_match(csolutionFile, regex(".*\\.csolution\\.(yml|yaml)"))) { + result.message = solution + " is not a *.csolution.yml file"; + return result; + } + if (!m_manager.RunConvert(csolutionFile, activeTarget, updateRte) || !ProjMgrLogger::Get().GetErrors().empty()) { + if (m_worker.HasVarDefineError()) { + const auto& vars = m_worker.GetUndefLayerVars(); + result.undefinedLayers = StrVec(vars.begin(), vars.end()); + result.message = "Layer variables undefined, names can be found under 'undefinedLayers'"; + } else if (m_worker.HasCompilerDefineError()) { + result.selectCompiler = m_worker.GetSelectableCompilers(); + result.message = "Compiler undefined, selectable values can be found under 'selectCompiler'"; + } else { + result.message = "Convert solution failed, see log messages"; + } + return result; + } + result.success = true; + return result; +} + // end of ProkMgrRpcServer.cpp diff --git a/tools/projmgr/test/src/ProjMgrRpcTests.cpp b/tools/projmgr/test/src/ProjMgrRpcTests.cpp index ea3cb6cf4..797998b50 100644 --- a/tools/projmgr/test/src/ProjMgrRpcTests.cpp +++ b/tools/projmgr/test/src/ProjMgrRpcTests.cpp @@ -12,6 +12,7 @@ #include "CrossPlatformUtils.h" #include "ProductInfo.h" +#include "RteFsUtils.h" #include "yaml-cpp/yaml.h" #include @@ -72,7 +73,7 @@ vector ProjMgrRpcTests::RunRpcMethods(const string& strIn) { StdStreamRedirect streamRedirect; streamRedirect.SetInString(strIn); char* argv[] = { (char*)"csolution", (char*)"rpc" }; - EXPECT_EQ(0, RunProjMgr(2, argv, 0)); + EXPECT_EQ(0, RunProjMgr(2, argv, m_envp)); string line; vector responses; istringstream iss(streamRedirect.GetOutString()); @@ -86,7 +87,7 @@ string ProjMgrRpcTests::RunRpcMethodsWithContent(const string& strIn) { StdStreamRedirect streamRedirect; streamRedirect.SetInString(strIn); char* argv[] = { (char*)"csolution", (char*)"rpc", (char*)"--content-length" }; - EXPECT_EQ(0, RunProjMgr(3, argv, 0)); + EXPECT_EQ(0, RunProjMgr(3, argv, m_envp)); return streamRedirect.GetOutString(); } @@ -704,4 +705,39 @@ TEST_F(ProjMgrRpcTests, RpcGetDraftProjects) { EXPECT_EQ(responses[0]["result"]["message"], "Packs must be loaded before retrieving draft projects"); } +TEST_F(ProjMgrRpcTests, RpcConvertSolution) { + auto csolutionPath = testinput_folder + "/TestRpc/minimal.csolution.yml"; + auto requests = FormatRequest(1, "ConvertSolution", + json({ { "solution", csolutionPath }, { "activeTarget", "TestHW" }, { "updateRte", true } })); + auto responses = RunRpcMethods(requests); + EXPECT_TRUE(responses[0]["result"]["success"]); + EXPECT_TRUE(RteFsUtils::Exists(testinput_folder + "/TestRpc/minimal.cbuild-idx.yml")); + EXPECT_TRUE(RteFsUtils::Exists(testinput_folder + "/TestRpc/minimal.cbuild-pack.yml")); + EXPECT_TRUE(RteFsUtils::Exists(testinput_folder + "/TestRpc/out/minimal+TestHW.cbuild-run.yml")); + EXPECT_TRUE(RteFsUtils::Exists(testinput_folder + "/TestRpc/out/minimal/TestHW/minimal+TestHW.cbuild.yml")); + + // convert fail + csolutionPath = testinput_folder + "/TestRpc/unknown-component.csolution.yml"; + requests = FormatRequest(1, "ConvertSolution", + json({ { "solution", csolutionPath }, { "activeTarget", "" }, { "updateRte", true } })); + responses = RunRpcMethods(requests); + EXPECT_FALSE(responses[0]["result"]["success"]); + + // undefined compiler + csolutionPath = testinput_folder + "/TestSolution/SelectableToolchains/select-compiler.csolution.yml"; + requests = FormatRequest(1, "ConvertSolution", + json({ { "solution", csolutionPath }, { "activeTarget", "" }, { "updateRte", true } })); + responses = RunRpcMethods(requests); + EXPECT_FALSE(responses[0]["result"]["success"]); + EXPECT_EQ(responses[0]["result"]["selectCompiler"][0], "AC6@>=6.0.0"); + EXPECT_EQ(responses[0]["result"]["selectCompiler"][1], "GCC@>=8.0.0"); + + // undefined layer + csolutionPath = testinput_folder + "/TestLayers/variables-notdefined.csolution.yml"; + requests = FormatRequest(1, "ConvertSolution", + json({ { "solution", csolutionPath }, { "activeTarget", "" }, { "updateRte", true } })); + responses = RunRpcMethods(requests); + EXPECT_FALSE(responses[0]["result"]["success"]); + EXPECT_EQ(responses[0]["result"]["undefinedLayers"][0], "NotDefined"); +} // end of ProjMgrRpcTests.cpp diff --git a/tools/projmgr/test/src/ProjMgrTestEnv.cpp b/tools/projmgr/test/src/ProjMgrTestEnv.cpp index 6b1a39f60..8283da05e 100644 --- a/tools/projmgr/test/src/ProjMgrTestEnv.cpp +++ b/tools/projmgr/test/src/ProjMgrTestEnv.cpp @@ -23,6 +23,7 @@ string schema_folder; string templates_folder; string etc_folder; string bin_folder; +char* m_envp[4]; StdStreamRedirect::StdStreamRedirect() : m_outbuffer(""), m_cerrbuffer(""), @@ -153,10 +154,13 @@ void ProjMgrTestEnv::SetUp() { // copy linker script template files fs::copy(fs::path(templates_folder), fs::path(testcmsiscompiler_folder), fs::copy_options::recursive, ec); + + // env vars + SetUpEnvp(); } void ProjMgrTestEnv::TearDown() { - // Reserved + CleanUpEnvp(); } void ProjMgrTestEnv::CompareFile(const string& file1, const string& file2, LineReplaceFunc_t file2LineReplaceFunc) { @@ -277,6 +281,31 @@ int ProjMgrTestEnv::CountOccurrences(const std::string input, const std::string return occurrences; } +void ProjMgrTestEnv::SetUpEnvp() { + std::string ac6 = "AC6_TOOLCHAIN_6_18_0=" + testinput_folder; + std::string gcc = "GCC_TOOLCHAIN_11_2_1=" + testinput_folder; + std::string iar = "IAR_TOOLCHAIN_8_50_6=" + testinput_folder; + + // Allocate memory for environment variables + m_envp[0] = new char[ac6.size() + 1]; + m_envp[1] = new char[iar.size() + 1]; + m_envp[2] = new char[gcc.size() + 1]; + + // Copy strings to allocated memory + strcpy(m_envp[0], ac6.c_str()); + strcpy(m_envp[1], iar.c_str()); + strcpy(m_envp[2], gcc.c_str()); + + // Null terminator + m_envp[3] = nullptr; +} + +void ProjMgrTestEnv::CleanUpEnvp() { + delete[] m_envp[0]; + delete[] m_envp[1]; + delete[] m_envp[2]; +} + int main(int argc, char **argv) { try { testing::InitGoogleTest(&argc, argv); diff --git a/tools/projmgr/test/src/ProjMgrTestEnv.h b/tools/projmgr/test/src/ProjMgrTestEnv.h index 757fdf03e..380d1c3d8 100644 --- a/tools/projmgr/test/src/ProjMgrTestEnv.h +++ b/tools/projmgr/test/src/ProjMgrTestEnv.h @@ -20,6 +20,8 @@ extern std::string testcmsiscompiler_folder; extern std::string schema_folder; extern std::string etc_folder; extern std::string bin_folder; +extern char* m_envp[4]; + /** * @brief direct console output to string */ @@ -66,6 +68,8 @@ class ProjMgrTestEnv : public ::testing::Environment { static bool FilterId(const std::string& id, const std::string& includeIds); static bool IsFileInCbuildFilesList(const std::vector> files, const std::string file); static int CountOccurrences(const std::string input, const std::string substring); + void SetUpEnvp(); + void CleanUpEnvp(); }; #endif // PROJMGRTESTENV_H diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index 7985b5f40..94eca5219 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -33,32 +33,10 @@ class ProjMgrUnitTests : public ProjMgr, public ::testing::Test { void SetUp() { m_context.clear(); - std::string ac6 = "AC6_TOOLCHAIN_6_18_0=" + testinput_folder; - std::string gcc = "GCC_TOOLCHAIN_11_2_1=" + testinput_folder; - std::string iar = "IAR_TOOLCHAIN_8_50_6=" + testinput_folder; - - // Allocate memory for environment variables - m_envp[0] = new char[ac6.size() + 1]; - m_envp[1] = new char[iar.size() + 1]; - m_envp[2] = new char[gcc.size() + 1]; - - // Copy strings to allocated memory - std::strcpy(m_envp[0], ac6.c_str()); - std::strcpy(m_envp[1], iar.c_str()); - std::strcpy(m_envp[2], gcc.c_str()); - - // Null terminator - m_envp[3] = nullptr; }; void TearDown() { - cleanupEnvp(); - } - - void cleanupEnvp() { - delete[] m_envp[0]; - delete[] m_envp[1]; - delete[] m_envp[2]; + // reserved } void GetFilesInTree(const string& dir, set& files) { @@ -98,8 +76,6 @@ class ProjMgrUnitTests : public ProjMgr, public ::testing::Test { fout.close(); return csolutionFile; } - - char* m_envp[4]; }; TEST_F(ProjMgrUnitTests, Validate_Logger) {