diff --git a/tools/projmgr/include/ProjMgrLogger.h b/tools/projmgr/include/ProjMgrLogger.h index 0b9039c67..620951a12 100644 --- a/tools/projmgr/include/ProjMgrLogger.h +++ b/tools/projmgr/include/ProjMgrLogger.h @@ -59,7 +59,7 @@ class ProjMgrLogger { void Info(const std::string& msg, const std::string& context = std::string(), const std::string& file = std::string(), const int line = 0, const int column = 0); - /** + /** * @brief print debug * @param message */ @@ -78,15 +78,25 @@ class ProjMgrLogger { static bool IsQuiet() { return m_quiet || m_silent; } /** - * @brief flag to suppress infos and warnings + * @brief check if in verbose mode + * @return true if verbose + */ + static bool IsVerbose() { return m_verbose; } + + /** + * @brief flag to suppress infos and warnings */ static bool m_quiet; - /** - * @brief flag to suppress all output and redirect cout to string buffer + /** + * @brief flag to suppress all output and redirect cout to string buffer */ static bool m_silent; + /** + * @brief flag to enable verbose for infos + */ + static bool m_verbose; /** * @brief get errors diff --git a/tools/projmgr/src/ProjMgr.cpp b/tools/projmgr/src/ProjMgr.cpp index eb653ea95..aeef2d896 100644 --- a/tools/projmgr/src/ProjMgr.cpp +++ b/tools/projmgr/src/ProjMgr.cpp @@ -230,6 +230,7 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { m_cbuildgen = parseResult.count("cbuildgen"); m_worker.SetCbuild2Cmake(!m_cbuildgen); ProjMgrLogger::m_quiet = parseResult.count("quiet"); + ProjMgrLogger::m_verbose = m_verbose; m_rpcServer.SetContentLengthHeader(parseResult.count("content-length")); m_rpcServer.SetDebug(m_debug); m_locked = parseResult.count("locked"); @@ -313,6 +314,12 @@ int ProjMgr::ParseCommandLine(int argc, char** argv) { return PrintUsage(optionsDict, m_command, m_args) ? -1 : 1; } + // Validate mutually exclusive options + if (ProjMgrLogger::m_quiet && ProjMgrLogger::m_verbose) { + ProjMgrLogger::Get().Error("command line options '--quiet' and '--verbose' are mutually exclusive"); + return ErrorCode::ERROR; + } + // Set load packs policy if (!SetLoadPacksPolicy()) { return ErrorCode::ERROR; diff --git a/tools/projmgr/src/ProjMgrLogger.cpp b/tools/projmgr/src/ProjMgrLogger.cpp index 085dbbd95..16bdd1224 100644 --- a/tools/projmgr/src/ProjMgrLogger.cpp +++ b/tools/projmgr/src/ProjMgrLogger.cpp @@ -22,6 +22,7 @@ static constexpr const char* PROJMGR_INFO = "info"; bool ProjMgrLogger::m_quiet = false; bool ProjMgrLogger::m_silent = false; +bool ProjMgrLogger::m_verbose = false; // singleton instance static unique_ptr theProjMgrLogger = 0; @@ -73,7 +74,7 @@ void ProjMgrLogger::Info(const string& msg, const string& context, const string mark = (line > 0 ? ":" + to_string(line) : "") + (column > 0 ? ":" + to_string(column) : ""); CollectionUtils::PushBackUniquely(m_infos[context], (file.empty() ? "" : RteUtils::ExtractFileName(file) + mark + " - ") + msg); - if (!IsQuiet() ) { + if (!IsQuiet() && IsVerbose()) { cout << (file.empty() ? "" : file + mark + " - ") << PROJMGR_INFO << PROJMGR_TOOL << msg << endl; } } diff --git a/tools/projmgr/test/data/TestLayers/ref/config.cbuild-idx.yml b/tools/projmgr/test/data/TestLayers/ref/config.cbuild-idx.yml index f28b93220..e8e54fc75 100644 --- a/tools/projmgr/test/data/TestLayers/ref/config.cbuild-idx.yml +++ b/tools/projmgr/test/data/TestLayers/ref/config.cbuild-idx.yml @@ -88,3 +88,9 @@ build-idx: configuration: .CompatibleLayers+RteTest_ARMCM3 clayers: - clayer: config.clayer.yml + messages: + info: + - "valid configuration #1: (context 'config.CompatibleLayers+RteTest_ARMCM3')\n ${DEVTOOLS(data)}/TestLayers/config.clayer.yml\n set: set1.select1 (connect R - set 1 select 1)\n ${DEVTOOLS(data)}/TestLayers/config.cproject.yml\n set: set1.select1 (project X - set 1 select 1)\n ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Layers/config1.clayer.yml (layer type: Config1)\n set: set1.select1 (connect A - set 1 select 1)\n set: set2.select1 (connect C - set 2 select 1)\n ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Layers/config2.clayer.yml (layer type: Config2)\n set: set1.select1 (connect F - set 1 select 1)\n" + - "valid configuration #2: (context 'config.CompatibleLayers+RteTest_ARMCM3')\n ${DEVTOOLS(data)}/TestLayers/config.clayer.yml\n set: set1.select1 (connect R - set 1 select 1)\n ${DEVTOOLS(data)}/TestLayers/config.cproject.yml\n set: set1.select1 (project X - set 1 select 1)\n ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Layers/config1.clayer.yml (layer type: Config1)\n set: set1.select1 (connect A - set 1 select 1)\n set: set2.select1 (connect C - set 2 select 1)\n ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Layers/config3.clayer.yml (layer type: Config2)\n set: set3.select1 (connect F - set 3 select 1)\n" + - "valid configuration #3: (context 'config.CompatibleLayers+RteTest_ARMCM3')\n ${DEVTOOLS(data)}/TestLayers/config.clayer.yml\n set: set1.select2 (connect S - set 1 select 2)\n ${DEVTOOLS(data)}/TestLayers/config.cproject.yml\n set: set1.select2 (project Y - set 1 select 2)\n ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Layers/config1.clayer.yml (layer type: Config1)\n set: set1.select2 (connect B - set 1 select 2)\n set: set2.select2 (connect D - set 2 select 2)\n ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Layers/config2.clayer.yml (layer type: Config2)\n set: set1.select2 (connect G - set 1 select 2)\n" + - "valid configuration #4: (context 'config.CompatibleLayers+RteTest_ARMCM3')\n ${DEVTOOLS(data)}/TestLayers/config.clayer.yml\n set: set1.select2 (connect S - set 1 select 2)\n ${DEVTOOLS(data)}/TestLayers/config.cproject.yml\n set: set1.select2 (project Y - set 1 select 2)\n ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Layers/config1.clayer.yml (layer type: Config1)\n set: set1.select2 (connect B - set 1 select 2)\n set: set2.select2 (connect D - set 2 select 2)\n ${DEVTOOLS(packs)}/ARM/RteTest_DFP/0.2.0/Layers/config3.clayer.yml (layer type: Config2)\n set: set3.select2 (connect G - set 3 select 2)\n" diff --git a/tools/projmgr/test/data/TestLayers/ref/no_compiler.cbuild-idx.yml b/tools/projmgr/test/data/TestLayers/ref/no_compiler.cbuild-idx.yml index d7a2bfca6..85db971d3 100644 --- a/tools/projmgr/test/data/TestLayers/ref/no_compiler.cbuild-idx.yml +++ b/tools/projmgr/test/data/TestLayers/ref/no_compiler.cbuild-idx.yml @@ -30,3 +30,7 @@ build-idx: configuration: +RteTest_ARMCM3 clayers: - clayer: select.clayer.yml + messages: + info: + - "valid configuration #1: (context 'no_compiler+RteTest_ARMCM3')\n ${DEVTOOLS(data)}/TestLayers/no_compiler.cproject.yml\n set: set1.select1 (project X - set 1 select 1)\n ${DEVTOOLS(data)}/TestLayers/select.clayer.yml (layer type: Board)\n set: set1.select1 (provided connections A and B - set 1 select 1)\n" + - "valid configuration #2: (context 'no_compiler+RteTest_ARMCM3')\n ${DEVTOOLS(data)}/TestLayers/no_compiler.cproject.yml\n set: set1.select2 (project Y - set 1 select 2)\n ${DEVTOOLS(data)}/TestLayers/select.clayer.yml (layer type: Board)\n set: set1.select2 (provided connections B and C - set 1 select 2)\n" diff --git a/tools/projmgr/test/data/TestLayers/ref/select.cbuild-idx.yml b/tools/projmgr/test/data/TestLayers/ref/select.cbuild-idx.yml index dcd24f190..4622724d6 100644 --- a/tools/projmgr/test/data/TestLayers/ref/select.cbuild-idx.yml +++ b/tools/projmgr/test/data/TestLayers/ref/select.cbuild-idx.yml @@ -27,3 +27,7 @@ build-idx: configuration: +RteTest_ARMCM3 clayers: - clayer: select.clayer.yml + messages: + info: + - "valid configuration #1: (context 'select+RteTest_ARMCM3')\n ${DEVTOOLS(data)}/TestLayers/select.cproject.yml\n set: set1.select1 (project X - set 1 select 1)\n ${DEVTOOLS(data)}/TestLayers/select.clayer.yml (layer type: Board)\n set: set1.select1 (provided connections A and B - set 1 select 1)\n" + - "valid configuration #2: (context 'select+RteTest_ARMCM3')\n ${DEVTOOLS(data)}/TestLayers/select.cproject.yml\n set: set1.select2 (project Y - set 1 select 2)\n ${DEVTOOLS(data)}/TestLayers/select.clayer.yml (layer type: Board)\n set: set1.select2 (provided connections B and C - set 1 select 2)\n" diff --git a/tools/projmgr/test/src/ProjMgrGeneratorUnitTests.cpp b/tools/projmgr/test/src/ProjMgrGeneratorUnitTests.cpp index d6b8a4b96..195554a85 100644 --- a/tools/projmgr/test/src/ProjMgrGeneratorUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrGeneratorUnitTests.cpp @@ -6,6 +6,7 @@ #include "ProjMgr.h" #include "ProjMgrTestEnv.h" +#include "ProjMgrLogger.h" #include "RteFsUtils.h" #include "gtest/gtest.h" #include @@ -17,6 +18,12 @@ class ProjMgrGeneratorUnitTests : public ProjMgrGenerator, public ::testing::Tes protected: ProjMgrGeneratorUnitTests() {} virtual ~ProjMgrGeneratorUnitTests() {} + + void TearDown() { + // return mode to normal to avoid affecting other tests + ProjMgrLogger::m_quiet = false; + ProjMgrLogger::m_verbose = false; + } }; TEST_F(ProjMgrGeneratorUnitTests, GetStringFromVector) { @@ -159,7 +166,7 @@ TEST_F(ProjMgrGeneratorUnitTests, DryRunIncapableGenerator) { } TEST_F(ProjMgrGeneratorUnitTests, DryRun) { - char* argv[7], *envp[2]; + char* argv[8], *envp[2]; string gcc = "GCC_TOOLCHAIN_11_2_1=" + testinput_folder; envp[0] = (char*)gcc.c_str(); envp[1] = (char*)'\0'; @@ -172,6 +179,7 @@ TEST_F(ProjMgrGeneratorUnitTests, DryRun) { argv[4] = (char*)"-g"; argv[5] = (char*)"RteTestGeneratorIdentifier"; argv[6] = (char*)"--dry-run"; + argv[7] = (char*)"--verbose"; const string generatorInputFile = testinput_folder + "/TestSolution/tmp/TestProject3_1.Debug+TypeA.cbuild-gen.yml"; const string generatorDestination = testinput_folder + "/TestSolution/TestProject3_1/gendir"; @@ -181,7 +189,7 @@ TEST_F(ProjMgrGeneratorUnitTests, DryRun) { RteFsUtils::RemoveDir(generatorDestination); RteFsUtils::RemoveDir(rteDir); - EXPECT_EQ(0, ProjMgr::RunProjMgr(7, argv, envp)); + EXPECT_EQ(0, ProjMgr::RunProjMgr(8, argv, envp)); ProjMgrTestEnv::CompareFile(testinput_folder + "/TestSolution/ref/TestProject3_1.Debug+TypeA.cbuild-gen.yml", generatorInputFile, ProjMgrTestEnv::StripAbsoluteFunc); @@ -208,7 +216,7 @@ TEST_F(ProjMgrGeneratorUnitTests, DryRun) { } TEST_F(ProjMgrGeneratorUnitTests, DryRunNoLdScript) { - char* argv[7], *envp[2]; + char* argv[8], *envp[2]; string gcc = "GCC_TOOLCHAIN_11_2_1=" + testinput_folder; envp[0] = (char*)gcc.c_str(); envp[1] = (char*)'\0'; @@ -221,6 +229,7 @@ TEST_F(ProjMgrGeneratorUnitTests, DryRunNoLdScript) { argv[4] = (char*)"-g"; argv[5] = (char*)"RteTestGeneratorIdentifier"; argv[6] = (char*)"--dry-run"; + argv[7] = (char*)"--verbose"; const string generatorInputFile = testinput_folder + "/TestSolution/tmp/TestProject3_5.Debug+TypeA.cbuild-gen.yml"; const string generatorDestination = testinput_folder + "/TestSolution/TestProject3_5/gendir"; @@ -230,7 +239,7 @@ TEST_F(ProjMgrGeneratorUnitTests, DryRunNoLdScript) { RteFsUtils::RemoveDir(generatorDestination); RteFsUtils::RemoveDir(rteDir); - EXPECT_EQ(0, ProjMgr::RunProjMgr(7, argv, envp)); + EXPECT_EQ(0, ProjMgr::RunProjMgr(8, argv, envp)); ProjMgrTestEnv::CompareFile(testinput_folder + "/TestSolution/ref/TestProject3_5.Debug+TypeA.cbuild-gen.yml", generatorInputFile, ProjMgrTestEnv::StripAbsoluteFunc); diff --git a/tools/projmgr/test/src/ProjMgrUnitTests.cpp b/tools/projmgr/test/src/ProjMgrUnitTests.cpp index e5500a04d..2d008d687 100644 --- a/tools/projmgr/test/src/ProjMgrUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrUnitTests.cpp @@ -36,7 +36,9 @@ class ProjMgrUnitTests : public ProjMgr, public ::testing::Test { }; void TearDown() { - // reserved + // return mode to normal to avoid affecting other tests + ProjMgrLogger::m_quiet = false; + ProjMgrLogger::m_verbose = false; } void GetFilesInTree(const string& dir, set& files) { @@ -95,16 +97,46 @@ TEST_F(ProjMgrUnitTests, Validate_Logger) { }; auto& ss = ProjMgrLogger::Get().GetStringStream(); - // Test quite mode + + // Test verbose mode + ProjMgrLogger::Get().Clear(); + ProjMgrLogger::m_quiet = false; + ProjMgrLogger::m_verbose = true; + string expErrMsg = "debug csolution: debug-1 test message\n\ +warning csolution: warning-1 test message\n\ +test.warn - warning csolution: warning-2 test message\n\ +test.warn:1:1 - warning csolution: warning-3 test message\n\ +error csolution: error-1 test message\n\ +test.err - error csolution: error-2 test message\n\ +test.err:1:1 - error csolution: error-3 test message\n"; + string expOutMsg = "info csolution: info-1 test message\n\ +test.info - info csolution: info-2 test message\n\ +test.info:1:1 - info csolution: info-3 test message\n\ +cout test message\n"; + + printLogMsgs(); + string outStr = streamRedirect.GetOutString(); + string errStr = streamRedirect.GetErrorString(); + EXPECT_STREQ(outStr.c_str(), expOutMsg.c_str()); + EXPECT_STREQ(errStr.c_str(), expErrMsg.c_str()); + EXPECT_EQ(ProjMgrLogger::Get().GetWarnsForContext().size(), 3); + EXPECT_EQ(ProjMgrLogger::Get().GetInfosForContext().size(), 3); + EXPECT_EQ(ProjMgrLogger::Get().GetErrorsForContext().size(), 3); + EXPECT_TRUE(ss.str().empty()); + + // Test quiet mode + ProjMgrLogger::Get().Clear(); ProjMgrLogger::m_quiet = true; - string expErrMsg = "error csolution: error-1 test message\n\ + ProjMgrLogger::m_verbose = false; + streamRedirect.ClearStringStreams(); + expErrMsg = "error csolution: error-1 test message\n\ test.err - error csolution: error-2 test message\n\ test.err:1:1 - error csolution: error-3 test message\n"; - string expOutMsg = "cout test message\n"; + expOutMsg = "cout test message\n"; printLogMsgs(); - auto outStr = streamRedirect.GetOutString(); - auto errStr = streamRedirect.GetErrorString(); + outStr = streamRedirect.GetOutString(); + errStr = streamRedirect.GetErrorString(); EXPECT_STREQ(outStr.c_str(), expOutMsg.c_str()); EXPECT_STREQ(errStr.c_str(), expErrMsg.c_str()); EXPECT_TRUE(ss.str().empty()); @@ -112,7 +144,7 @@ test.err:1:1 - error csolution: error-3 test message\n"; EXPECT_EQ(ProjMgrLogger::Get().GetInfosForContext().size(), 3); EXPECT_EQ(ProjMgrLogger::Get().GetErrorsForContext().size(), 3); - // Test non-quite mode + // Test normal mode (non-quiet and non-verbose) ProjMgrLogger::Get().Clear(); ProjMgrLogger::m_quiet = false; streamRedirect.ClearStringStreams(); @@ -123,10 +155,7 @@ test.warn:1:1 - warning csolution: warning-3 test message\n\ error csolution: error-1 test message\n\ test.err - error csolution: error-2 test message\n\ test.err:1:1 - error csolution: error-3 test message\n"; - expOutMsg = "info csolution: info-1 test message\n\ -test.info - info csolution: info-2 test message\n\ -test.info:1:1 - info csolution: info-3 test message\n\ -cout test message\n"; + expOutMsg = "cout test message\n"; printLogMsgs(); outStr = streamRedirect.GetOutString(); @@ -1088,7 +1117,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackNoPackList) { } TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFrozen) { - char* argv[8]; + char* argv[9]; StdStreamRedirect streamRedirect; // convert --solution solution.yml @@ -1104,26 +1133,28 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFrozen) { argv[4] = (char*)"-o"; argv[5] = (char*)output.c_str(); argv[6] = (char*)"--cbuildgen"; - argv[7] = (char*)"--frozen-packs"; + argv[7] = (char*)"--verbose"; + argv[8] = (char*)"--frozen-packs"; + // Ensure clean state when starting test ASSERT_TRUE(RteFsUtils::RemoveDir(rtePath)); // 1st run to verify that the cbuild-pack.yml content is stable - EXPECT_NE(0, RunProjMgr(8, argv, m_envp)); + EXPECT_NE(0, RunProjMgr(9, argv, m_envp)); EXPECT_NE(streamRedirect.GetErrorString().find(cbuildPack + " - error csolution: file not allowed to be updated"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPack, cbuildPack); EXPECT_FALSE(RteFsUtils::Exists(rtePath + "/Device")); // 2nd run to verify that the cbuild-pack.yml content is stable streamRedirect.ClearStringStreams(); - EXPECT_NE(0, RunProjMgr(8, argv, m_envp)); + EXPECT_NE(0, RunProjMgr(9, argv, m_envp)); EXPECT_NE(streamRedirect.GetErrorString().find(cbuildPack + " - error csolution: file not allowed to be updated"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPack, cbuildPack); EXPECT_FALSE(RteFsUtils::Exists(rtePath + "/Device")); // 3rd run without --frozen-packs to verify that the list can be updated streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRef, cbuildPack); EXPECT_TRUE(RteFsUtils::Exists(rtePath + "/Device")); @@ -1141,7 +1172,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFrozen) { // 4th run with --frozen-packs to verify that RTE directory can be generated ASSERT_TRUE(RteFsUtils::RemoveDir(rtePath)); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file is already up-to-date"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRef, cbuildPack); @@ -1199,7 +1230,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackReselectSelectedByPack) { TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackLoadArgument) { error_code ec; - char* argv[9]; + char* argv[10]; StdStreamRedirect streamRedirect; // convert --solution solution.yml @@ -1216,74 +1247,75 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackLoadArgument) { argv[4] = (char*)"-o"; argv[5] = (char*)output.c_str(); argv[6] = (char*)"--cbuildgen"; - argv[7] = (char*)"--load"; + argv[7] = (char*)"--verbose"; + argv[8] = (char*)"--load"; // Test with --load all and without cbuild-pack.yml file - argv[8] = (char*)"all"; + argv[9] = (char*)"all"; RteFsUtils::RemoveFile(cbuildPack); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackAll, cbuildPack); // Test with --load all and with cbuild-pack.yml file - argv[8] = (char*)"all"; + argv[9] = (char*)"all"; fs::copy(fs::path(expectedCbuildPackRequired), fs::path(cbuildPack), fs::copy_options::overwrite_existing, ec); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackAll, cbuildPack); // Test with --load latest and without cbuild-pack.yml file - argv[8] = (char*)"latest"; + argv[9] = (char*)"latest"; RteFsUtils::RemoveFile(cbuildPack); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackLatest, cbuildPack); // Test with --load latest and with cbuild-pack.yml file - argv[8] = (char*)"latest"; + argv[9] = (char*)"latest"; fs::copy(fs::path(expectedCbuildPackRequired), fs::path(cbuildPack), fs::copy_options::overwrite_existing, ec); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackLatest, cbuildPack); // Test with --load required and without cbuild-pack.yml file - argv[8] = (char*)"required"; + argv[9] = (char*)"required"; RteFsUtils::RemoveFile(cbuildPack); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackLatest, cbuildPack); // Test with --load required and with cbuild-pack.yml file - argv[8] = (char*)"required"; + argv[9] = (char*)"required"; fs::copy(fs::path(expectedCbuildPackRequired), fs::path(cbuildPack), fs::copy_options::overwrite_existing, ec); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file is already up-to-date"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequired, cbuildPack); // Test without --load and without cbuild-pack.yml file RteFsUtils::RemoveFile(cbuildPack); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackLatest, cbuildPack); // Test without --load but with cbuild-pack.yml file fs::copy(fs::path(expectedCbuildPackRequired), fs::path(cbuildPack), fs::copy_options::overwrite_existing, ec); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file is already up-to-date"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequired, cbuildPack); } TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFindUnspecifiedPackUsingLoadArgument) { error_code ec; - char* argv[9]; + char* argv[10]; StdStreamRedirect streamRedirect; // convert --solution solution.yml @@ -1301,54 +1333,55 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFindUnspecifiedPackUsingLoad argv[4] = (char*)"-o"; argv[5] = (char*)output.c_str(); argv[6] = (char*)"--cbuildgen"; - argv[7] = (char*)"--load"; + argv[7] = (char*)"--verbose"; + argv[8] = (char*)"--load"; // Test with --load all and without cbuild-pack.yml file - argv[8] = (char*)"all"; + argv[9] = (char*)"all"; RteFsUtils::RemoveFile(cbuildPack); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackAll, cbuildPack); // Test with --load all and with cbuild-pack.yml file - argv[8] = (char*)"all"; + argv[9] = (char*)"all"; fs::copy(fs::path(expectedCbuildPackRequired), fs::path(cbuildPack), fs::copy_options::overwrite_existing, ec); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackAll, cbuildPack); // Test with --load latest and without cbuild-pack.yml file - argv[8] = (char*)"latest"; + argv[9] = (char*)"latest"; RteFsUtils::RemoveFile(cbuildPack); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackLatest, cbuildPack); // Test with --load latest and with cbuild-pack.yml file - argv[8] = (char*)"latest"; + argv[9] = (char*)"latest"; fs::copy(fs::path(expectedCbuildPackRequired), fs::path(cbuildPack), fs::copy_options::overwrite_existing, ec); streamRedirect.ClearStringStreams(); - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackLatest, cbuildPack); // Test with --load required and without cbuild-pack.yml file - argv[8] = (char*)"required"; + argv[9] = (char*)"required"; RteFsUtils::RemoveFile(cbuildPack); streamRedirect.ClearStringStreams(); - EXPECT_EQ(1, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(1, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: component 'RteTest:ComponentLevel' not found in included packs"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequiredUpdated, cbuildPack); // Test with --load required and with cbuild-pack.yml file - argv[8] = (char*)"required"; + argv[9] = (char*)"required"; fs::copy(fs::path(expectedCbuildPackRequired), fs::path(cbuildPack), fs::copy_options::overwrite_existing, ec); streamRedirect.ClearStringStreams(); - EXPECT_EQ(1, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(1, RunProjMgr(10, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file is already up-to-date"), string::npos); EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: component 'RteTest:ComponentLevel' not found in included packs"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequired, cbuildPack); @@ -1356,7 +1389,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFindUnspecifiedPackUsingLoad // Test without --load and without cbuild-pack.yml file RteFsUtils::RemoveFile(cbuildPack); streamRedirect.ClearStringStreams(); - EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); + EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file generated successfully"), string::npos); EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: component 'RteTest:ComponentLevel' not found in included packs"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequiredUpdated, cbuildPack); @@ -1364,7 +1397,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_LockPackFindUnspecifiedPackUsingLoad // Test without --load but with cbuild-pack.yml file fs::copy(fs::path(expectedCbuildPackRequired), fs::path(cbuildPack), fs::copy_options::overwrite_existing, ec); streamRedirect.ClearStringStreams(); - EXPECT_EQ(1, RunProjMgr(7, argv, m_envp)); + EXPECT_EQ(1, RunProjMgr(8, argv, m_envp)); EXPECT_NE(streamRedirect.GetOutString().find(cbuildPack + " - info csolution: file is already up-to-date"), string::npos); EXPECT_NE(streamRedirect.GetErrorString().find("error csolution: component 'RteTest:ComponentLevel' not found in included packs"), string::npos); ProjMgrTestEnv::CompareFile(expectedCbuildPackRequired, cbuildPack); @@ -1659,7 +1692,7 @@ TEST_F(ProjMgrUnitTests, ListLayersAll) { TEST_F(ProjMgrUnitTests, ListLayersCompatible) { StdStreamRedirect streamRedirect; - char* argv[8]; + char* argv[9]; const string& csolution = testinput_folder + "/TestLayers/genericlayers.csolution.yml"; const string& context = "genericlayers.CompatibleLayers+AnyBoard"; argv[1] = (char*)"list"; @@ -1669,7 +1702,8 @@ TEST_F(ProjMgrUnitTests, ListLayersCompatible) { argv[5] = (char*)"-c"; argv[6] = (char*)context.c_str(); argv[7] = (char*)"-d"; - EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); + argv[8] = (char*)"--verbose"; + EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); const string& expectedErrStr = "\ debug csolution: check for context 'genericlayers.CompatibleLayers\\+AnyBoard'\n\ @@ -1740,17 +1774,18 @@ info csolution: valid configuration #3: \\(context 'genericlayers.CompatibleLaye TEST_F(ProjMgrUnitTests, ListLayersConfigurations_update_idx_pack_layer) { StdStreamRedirect streamRedirect; - char* argv[6]; + char* argv[7]; const string& csolution = testinput_folder + "/TestLayers/config.csolution.yml"; - string expectedOutStr = ".*config.cbuild-idx.yml - info csolution: file generated successfully\\n"; + string expectedOutStr = "[\\s\\S]*config.cbuild-idx.yml - info csolution: file generated successfully\\n"; argv[1] = (char*)"list"; argv[2] = (char*)"layers"; argv[3] = (char*)"--solution"; argv[4] = (char*)csolution.c_str(); argv[5] = (char*)"--update-idx"; + argv[6] = (char*)"--verbose"; - EXPECT_EQ(0, RunProjMgr(6, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); EXPECT_TRUE(regex_match(streamRedirect.GetOutString(), regex(expectedOutStr))); ProjMgrTestEnv::CompareFile(testinput_folder + "/TestLayers/ref/config.cbuild-idx.yml", @@ -1760,20 +1795,21 @@ TEST_F(ProjMgrUnitTests, ListLayersConfigurations_update_idx_pack_layer) { TEST_F(ProjMgrUnitTests, ListLayersConfigurations_update_idx_local_layer) { StdStreamRedirect streamRedirect; - char* argv[6]; + char* argv[7]; const string& csolution = testinput_folder + "/TestLayers/select.csolution.yml"; - string expectedOutStr = ".*select.cbuild-idx.yml - info csolution: file generated successfully\\n"; + string expectedOutStr = "[\\s\\S]*select.cbuild-idx.yml - info csolution: file generated successfully\\n"; argv[1] = (char*)"list"; argv[2] = (char*)"layers"; argv[3] = (char*)"--solution"; argv[4] = (char*)csolution.c_str(); argv[5] = (char*)"--update-idx"; + argv[6] = (char*)"--verbose"; - EXPECT_EQ(0, RunProjMgr(6, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); EXPECT_TRUE(regex_match(streamRedirect.GetOutString(), regex(expectedOutStr))); ProjMgrTestEnv::CompareFile(testinput_folder + "/TestLayers/ref/select.cbuild-idx.yml", - testinput_folder + "/TestLayers/select.cbuild-idx.yml"); + testinput_folder + "/TestLayers/select.cbuild-idx.yml", ProjMgrTestEnv::StripAbsoluteFunc); EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/TestLayers/select.cbuild-idx.yml")); } @@ -1795,14 +1831,15 @@ TEST_F(ProjMgrUnitTests, ListLayersConfigurations_Error) { TEST_F(ProjMgrUnitTests, ListLayersConfigurations) { StdStreamRedirect streamRedirect; - char* argv[6]; + char* argv[7]; const string& csolution = testinput_folder + "/TestLayers/config.csolution.yml"; argv[1] = (char*)"list"; argv[2] = (char*)"layers"; argv[3] = (char*)"--solution"; argv[4] = (char*)csolution.c_str(); argv[5] = (char*)"-d"; - EXPECT_EQ(0, RunProjMgr(6, argv, m_envp)); + argv[6] = (char*)"--verbose"; + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); const string& outStr = streamRedirect.GetOutString(); const string& errStr = streamRedirect.GetErrorString(); @@ -2020,7 +2057,7 @@ TEST_F(ProjMgrUnitTests, ListToolchains_with_unknown_toolchain) { TEST_F(ProjMgrUnitTests, ListLayersUniquelyCompatibleBoard) { StdStreamRedirect streamRedirect; - char* argv[8]; + char* argv[9]; const string& csolution = testinput_folder + "/TestLayers/genericlayers.csolution.yml"; const string& context = "genericlayers.CompatibleLayers+Board3"; argv[1] = (char*)"list"; @@ -2030,7 +2067,8 @@ TEST_F(ProjMgrUnitTests, ListLayersUniquelyCompatibleBoard) { argv[5] = (char*)"-c"; argv[6] = (char*)context.c_str(); argv[7] = (char*)"-d"; - EXPECT_EQ(0, RunProjMgr(8, argv, m_envp)); + argv[8] = (char*)"--verbose"; + EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); const string& expectedErrStr = "\ debug csolution: check for context 'genericlayers.CompatibleLayers\\+Board3'\n\ @@ -5016,7 +5054,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgrInvalidContext) { TEST_F(ProjMgrUnitTests, RunProjMgrCovertMultipleContext) { StdStreamRedirect streamRedirect; - char* argv[11]; + char* argv[12]; // convert --solution solution.yml const string& csolution = testinput_folder + "/TestSolution/test.csolution.yml"; @@ -5030,8 +5068,9 @@ TEST_F(ProjMgrUnitTests, RunProjMgrCovertMultipleContext) { argv[8] = (char*)"-c"; argv[9] = (char*)"test1.Release+CM0"; argv[10] = (char*)"--cbuildgen"; + argv[11] = (char*)"--verbose"; - EXPECT_EQ(0, RunProjMgr(11, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(12, argv, m_envp)); auto outStr = streamRedirect.GetOutString(); EXPECT_NE(string::npos, outStr.find("test2.Debug+CM0.cprj")); EXPECT_NE(string::npos, outStr.find("test1.Release+CM0.cprj")); @@ -5068,7 +5107,7 @@ TEST_F(ProjMgrUnitTests, RunProjMgr_YamlEmitterFileCaseIssue) { TEST_F(ProjMgrUnitTests, RunProjMgr_Reverse_Context_Syntax) { StdStreamRedirect streamRedirect; - char* argv[11]; + char* argv[12]; // convert --solution solution.yml const string& csolution = testinput_folder + "/TestSolution/test.csolution.yml"; @@ -5082,8 +5121,9 @@ TEST_F(ProjMgrUnitTests, RunProjMgr_Reverse_Context_Syntax) { argv[8] = (char*)"-c"; argv[9] = (char*)"test1+CM0.Release"; argv[10] = (char*)"--cbuildgen"; + argv[11] = (char*)"--verbose"; - EXPECT_EQ(0, RunProjMgr(11, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(12, argv, m_envp)); auto outStr = streamRedirect.GetOutString(); EXPECT_NE(string::npos, outStr.find("test2.Debug+CM0.cprj - info csolution: file generated successfully")); EXPECT_NE(string::npos, outStr.find("test1.Release+CM0.cprj - info csolution: file generated successfully")); @@ -5328,8 +5368,9 @@ TEST_F(ProjMgrUnitTests, RunProjMgrSolution_cbuildset_file) { argv[6] = (char*)"-c"; argv[7] = (char*)"test1.Release+CM0"; argv[8] = (char*)"--cbuildgen"; + argv[9] = (char*)"--verbose"; - EXPECT_EQ(0, RunProjMgr(9, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(10, argv, m_envp)); auto outStr = streamRedirect.GetOutString(); EXPECT_NE(outStr.find("test1.Release+CM0.cprj - info csolution: file generated successfully"), string::npos); EXPECT_NE(outStr.find("test1.Release+CM0.cbuild.yml - info csolution: file generated successfully"), string::npos); @@ -6589,21 +6630,22 @@ TEST_F(ProjMgrUnitTests, RunProjMgr_conflict_cbuild_set) { TEST_F(ProjMgrUnitTests, ListLayers_update_idx_with_no_compiler_selected) { StdStreamRedirect streamRedirect; - char* argv[6]; + char* argv[7]; const string& csolution = testinput_folder + "/TestLayers/no_compiler.csolution.yml"; - string expectedOutStr = ".*no_compiler.cbuild-idx.yml - info csolution: file generated successfully\\n"; + string expectedOutStr = "[\\s\\S]*no_compiler.cbuild-idx.yml - info csolution: file generated successfully\\n"; argv[1] = (char*)"list"; argv[2] = (char*)"layers"; argv[3] = (char*)"--solution"; argv[4] = (char*)csolution.c_str(); argv[5] = (char*)"--update-idx"; + argv[6] = (char*)"--verbose"; - EXPECT_EQ(0, RunProjMgr(6, argv, m_envp)); + EXPECT_EQ(0, RunProjMgr(7, argv, m_envp)); EXPECT_TRUE(regex_match(streamRedirect.GetOutString(), regex(expectedOutStr))); ProjMgrTestEnv::CompareFile(testinput_folder + "/TestLayers/ref/no_compiler.cbuild-idx.yml", - testinput_folder + "/TestLayers/no_compiler.cbuild-idx.yml"); + testinput_folder + "/TestLayers/no_compiler.cbuild-idx.yml", ProjMgrTestEnv::StripAbsoluteFunc); EXPECT_TRUE(ProjMgrYamlSchemaChecker().Validate(testinput_folder + "/TestLayers/no_compiler.cbuild-idx.yml")); } @@ -7453,3 +7495,18 @@ TEST_F(ProjMgrUnitTests, DuplicateComponents) { } } } + +TEST_F(ProjMgrUnitTests, ParseCommandLine_MutualExclusionOptions) { + StdStreamRedirect streamRedirect; + const string csolution = testinput_folder + "/TestSolution/test.csolution.yml"; + char* argv[6]; + argv[1] = (char*)"convert"; + argv[2] = (char*)"--solution"; + argv[3] = (char*)csolution.c_str(); + argv[4] = (char*)"--quiet"; + argv[5] = (char*)"--verbose"; + + EXPECT_EQ(1, RunProjMgr(6, argv, m_envp)); + auto errStr = streamRedirect.GetErrorString(); + EXPECT_NE(string::npos, errStr.find("error csolution: command line options '--quiet' and '--verbose' are mutually exclusive")); +} diff --git a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp index ce943d5e3..d3a15e2c4 100644 --- a/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp +++ b/tools/projmgr/test/src/ProjMgrWorkerUnitTests.cpp @@ -21,6 +21,12 @@ class ProjMgrWorkerUnitTests : public ProjMgrWorker, public ::testing::Test { ProjMgrWorkerUnitTests() : ProjMgrWorker(&parser, nullptr) {} virtual ~ProjMgrWorkerUnitTests() {} + void TearDown() { + // return mode to normal to avoid affecting other tests + ProjMgrLogger::m_quiet = false; + ProjMgrLogger::m_verbose = false; + } + void SetCsolutionPacks(CsolutionItem* csolution, std::vector packs, std::string targetType); }; @@ -1520,6 +1526,7 @@ TEST_F(ProjMgrWorkerUnitTests, CheckAndGenerateRegionsHeader) { ContextItem context; LoadPacks(context); InitializeTarget(context); + ProjMgrLogger::m_verbose = true; // Generation fails context.directories.cprj = testoutput_folder;