LogLines.cpp 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222
  1. /*
  2. * Copyright (c) Contributors to the Open 3D Engine Project.
  3. * For complete copyright and license terms please see the LICENSE at the root of this distribution.
  4. *
  5. * SPDX-License-Identifier: Apache-2.0 OR MIT
  6. *
  7. */
  8. #include <AzTest/AzTest.h>
  9. #include <AzToolsFramework/UI/Logging/LogLine.h>
  10. using namespace AZ;
  11. using namespace AzToolsFramework;
  12. using namespace AzToolsFramework::Logging;
  13. namespace UnitTest
  14. {
  15. static const char* s_logPrefix = "~~1541632104059~~1~~8240~~RC Builder~~";
  16. static const char* s_logWindow = "RC Builder";
  17. TEST(LogLines, BasicTest)
  18. {
  19. const char* messages[] = {
  20. R"X(Executing RC.EXE: '"E:\lyengine\dev\windows\bin\profile\rc.exe" "E:/Directory/File.tga")X",
  21. R"X(Executing RC.EXE with working directory : '')X",
  22. R"X(ResourceCompiler 64 - bit DEBUG)X",
  23. R"X(Platform support : PC, PowerVR)X",
  24. R"X(Version 1.1.8.6 Nov 5 2018 13 : 28 : 28)X"
  25. };
  26. AZStd::string textBuffer;
  27. for (const char* message : messages)
  28. {
  29. if (textBuffer.size() > 0)
  30. {
  31. textBuffer.append("\n");
  32. }
  33. textBuffer.append(s_logPrefix);
  34. textBuffer.append(message);
  35. }
  36. AZStd::list<LogLine> lines;
  37. LogLine::ParseLog(lines, textBuffer.c_str(), textBuffer.size() + 1);
  38. EXPECT_EQ(lines.size(), sizeof(messages) / sizeof(messages[0]));
  39. size_t index = 0;
  40. for (LogLine& line : lines)
  41. {
  42. EXPECT_STREQ(s_logWindow, line.GetLogWindow().c_str());
  43. EXPECT_STREQ(line.GetLogMessage().c_str(), messages[index]);
  44. EXPECT_EQ(line.GetLogType(), LogLine::TYPE_MESSAGE);
  45. index++;
  46. }
  47. }
  48. TEST(LogLines, Junk)
  49. {
  50. const char* messages[] = {
  51. R"X(small string)X",
  52. R"X(tiny)X",
  53. R"X(unformatted string)X",
  54. };
  55. AZStd::string textBuffer;
  56. for (const char* message : messages)
  57. {
  58. if (textBuffer.size() > 0)
  59. {
  60. textBuffer.append("\n");
  61. }
  62. textBuffer.append(s_logPrefix);
  63. textBuffer.append(message);
  64. }
  65. AZStd::list<LogLine> lines;
  66. LogLine::ParseLog(lines, textBuffer.c_str(), textBuffer.size() + 1);
  67. EXPECT_EQ(lines.size(), sizeof(messages) / sizeof(messages[0]));
  68. size_t index = 0;
  69. for (LogLine& line : lines)
  70. {
  71. EXPECT_STREQ(s_logWindow, line.GetLogWindow().c_str());
  72. EXPECT_STREQ(line.GetLogMessage().c_str(), messages[index]);
  73. EXPECT_EQ(line.GetLogType(), LogLine::TYPE_MESSAGE);
  74. index++;
  75. }
  76. }
  77. TEST(LogLines, RCParsingWithoutType)
  78. {
  79. const char* message = "Memory: working set 15.6Mb (peak 15.6Mb), pagefile 35.9Mb (peak 35.9Mb)";
  80. const char* timeStampWithProperRCSpacing = " 0:00 "; // <-- exact number of spaces specified by RC
  81. const char* timeStampWithWrongRCSpacing = " 0:00 "; // <-- a different number of spaces
  82. AZStd::string textBuffer;
  83. textBuffer.append(AZStd::string::format("%s%s%s", s_logPrefix, timeStampWithProperRCSpacing, message));
  84. textBuffer.append("\n");
  85. AZStd::string messageWithTimeStampNotParsed = AZStd::string::format("%s%s", timeStampWithWrongRCSpacing, message);
  86. textBuffer.append(AZStd::string::format("%s%s", s_logPrefix, messageWithTimeStampNotParsed.c_str()));
  87. AZStd::list<LogLine> lines;
  88. LogLine::ParseLog(lines, textBuffer.c_str(), textBuffer.size() + 1);
  89. EXPECT_EQ(lines.size(), 2);
  90. LogLine& lineWithRCFormatting = lines.front();
  91. EXPECT_STREQ(s_logWindow, lineWithRCFormatting.GetLogWindow().c_str());
  92. EXPECT_STREQ(lineWithRCFormatting.GetLogMessage().c_str(), message);
  93. EXPECT_EQ(lineWithRCFormatting.GetLogType(), LogLine::TYPE_MESSAGE);
  94. LogLine& lineWithoutRCFormatting = lines.back();
  95. EXPECT_STREQ(s_logWindow, lineWithoutRCFormatting.GetLogWindow().c_str());
  96. EXPECT_STREQ(lineWithoutRCFormatting.GetLogMessage().c_str(), messageWithTimeStampNotParsed.c_str());
  97. EXPECT_EQ(lineWithoutRCFormatting.GetLogType(), LogLine::TYPE_MESSAGE);
  98. }
  99. TEST(LogLines, RCParsingToEmptyLine)
  100. {
  101. const char* timeStampWithProperRCSpacing = " 0:00"; // <-- exact number of spaces specified by RC, but no space on the end
  102. AZStd::string textBuffer;
  103. textBuffer.append(AZStd::string::format("%s%s", s_logPrefix, timeStampWithProperRCSpacing));
  104. AZStd::list<LogLine> lines;
  105. LogLine::ParseLog(lines, textBuffer.c_str(), textBuffer.size() + 1);
  106. EXPECT_EQ(lines.size(), 1);
  107. LogLine& lineWithRCFormatting = lines.front();
  108. EXPECT_STREQ(s_logWindow, lineWithRCFormatting.GetLogWindow().c_str());
  109. EXPECT_STREQ(lineWithRCFormatting.GetLogMessage().c_str(), "");
  110. EXPECT_EQ(lineWithRCFormatting.GetLogType(), LogLine::TYPE_MESSAGE);
  111. }
  112. TEST(LogLines, RCParsingWithType)
  113. {
  114. const char* rcPrefix = "E: 0:00 ";
  115. const char* message = R"X(CImageCompiler::ProcessImplementation: LoadInput(file:'E:\Directory\File.tga', ext:'tga') failed)X";
  116. AZStd::string textBuffer;
  117. textBuffer.append(AZStd::string::format("%s%s%s", s_logPrefix, rcPrefix, message));
  118. AZStd::list<LogLine> lines;
  119. LogLine::ParseLog(lines, textBuffer.c_str(), textBuffer.size() + 1);
  120. EXPECT_EQ(lines.size(), 1);
  121. LogLine& line = lines.front();
  122. EXPECT_STREQ(s_logWindow, line.GetLogWindow().c_str());
  123. EXPECT_STREQ(line.GetLogMessage().c_str(), message);
  124. EXPECT_EQ(line.GetLogType(), LogLine::TYPE_ERROR);
  125. }
  126. static AZStd::string CreateContextLine(const char* context, const char* data)
  127. {
  128. return AZStd::string::format("C: [%s] = %s", context, data);
  129. }
  130. TEST(LogLines, ContextParsing)
  131. {
  132. std::pair<const char*, const char*> contextInfos[] = {
  133. std::make_pair("Source", "scriptcanvas / AntiAlias.scriptcanvas"),
  134. std::make_pair("Platforms", "pc")
  135. };
  136. const char* messages[] = {
  137. R"X(C: [Source] = scriptcanvas / AntiAlias.scriptcanvas)X",
  138. R"X(C: [Platforms] = pc)X"
  139. };
  140. AZStd::string textBuffer;
  141. for (auto& contextInfo : contextInfos)
  142. {
  143. if (textBuffer.size() > 0)
  144. {
  145. textBuffer.append("\n");
  146. }
  147. textBuffer.append(s_logPrefix);
  148. textBuffer.append(CreateContextLine(contextInfo.first, contextInfo.second));
  149. }
  150. AZStd::list<LogLine> lines;
  151. LogLine::ParseLog(lines, textBuffer.c_str(), textBuffer.size() + 1);
  152. EXPECT_EQ(lines.size(), sizeof(messages) / sizeof(messages[0]));
  153. size_t index = 0;
  154. for (LogLine& line : lines)
  155. {
  156. EXPECT_EQ(AZStd::string(s_logWindow), line.GetLogWindow());
  157. AZStd::string message = CreateContextLine(contextInfos[index].first, contextInfos[index].second);
  158. EXPECT_STREQ(line.GetLogMessage().c_str(), message.c_str());
  159. EXPECT_EQ(line.GetLogType(), LogLine::TYPE_CONTEXT);
  160. std::pair<QString, QString> result;
  161. bool contextLineParsed = LogLine::ParseContextLogLine(line, result);
  162. EXPECT_TRUE(contextLineParsed);
  163. const char* expectedContext = contextInfos[index].first;
  164. const char* expectedData = contextInfos[index].second;
  165. QByteArray parsedContext = result.first.toUtf8();
  166. QByteArray parsedData = result.second.toUtf8();
  167. EXPECT_STREQ(expectedContext, parsedContext.data());
  168. EXPECT_STREQ(expectedData, parsedData.data());
  169. index++;
  170. }
  171. }
  172. }