Debug.cpp 6.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  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 <AzCore/Debug/StackTracer.h>
  9. #include <AzCore/Debug/TraceMessageBus.h>
  10. #include <AzCore/Debug/Profiler.h>
  11. #include <AzCore/std/parallel/thread.h>
  12. #include <AzCore/Math/Crc.h>
  13. #include <AzCore/std/time.h>
  14. #include <AzCore/std/chrono/chrono.h>
  15. #include <AzCore/std/string/conversions.h>
  16. #include <AzCore/UnitTest/TestTypes.h>
  17. using namespace AZ;
  18. using namespace AZ::Debug;
  19. namespace UnitTest
  20. {
  21. TEST(StackTracer, Test)
  22. {
  23. // Test can be executed only on supported platforms
  24. StackFrame frames[10];
  25. unsigned int numFrames = StackRecorder::Record(frames, AZ_ARRAY_SIZE(frames));
  26. if (numFrames)
  27. {
  28. u32 numValidFrames = 0;
  29. for (u32 i = 0; i < AZ_ARRAY_SIZE(frames); ++i)
  30. {
  31. if (frames[i].IsValid())
  32. {
  33. ++numValidFrames;
  34. }
  35. }
  36. AZ_TEST_ASSERT(numValidFrames == numFrames);
  37. #if AZ_TRAIT_OS_STACK_FRAMES_VALID
  38. // We have:
  39. // StackTracer::run
  40. // DebugSuite::run
  41. // main_tests.cpp : DoTests
  42. // main_tests.cpp : main()
  43. // + system calls (in release some func are inlined but still >= 5)
  44. AZ_TEST_ASSERT(numValidFrames >= 5);
  45. #else
  46. AZ_TEST_ASSERT(numValidFrames == 0);
  47. #endif
  48. #if AZ_TRAIT_OS_STACK_FRAMES_TRACE // Symbols are available only on windows.
  49. {
  50. // We should have loaded at least AzCore.Tests dynamic library (where this test is)
  51. int isFoundModule = 0;
  52. char expectedNameBuffer[AZ_ARRAY_SIZE(SymbolStorage::ModuleInfo::m_modName)];
  53. #if defined(AZCORETEST_DLL_NAME)
  54. azstrncpy(expectedNameBuffer, AZ_ARRAY_SIZE(expectedNameBuffer), AZCORETEST_DLL_NAME, AZ_ARRAY_SIZE(expectedNameBuffer));
  55. #else
  56. azstrncpy(expectedNameBuffer, "azcoretests.dll", AZ_ARRAY_SIZE(expectedNameBuffer));
  57. #endif
  58. AZStd::to_lower(expectedNameBuffer, expectedNameBuffer + AZ_ARRAY_SIZE(expectedNameBuffer));
  59. for (u32 i = 0; i < SymbolStorage::GetNumLoadedModules(); ++i)
  60. {
  61. char nameBuffer[AZ_ARRAY_SIZE(SymbolStorage::ModuleInfo::m_modName)];
  62. azstrncpy(nameBuffer, AZ_ARRAY_SIZE(nameBuffer), SymbolStorage::GetModuleInfo(i)->m_fileName, AZ_ARRAY_SIZE(nameBuffer));
  63. AZStd::to_lower(nameBuffer, nameBuffer + AZ_ARRAY_SIZE(nameBuffer));
  64. if (strstr(nameBuffer, expectedNameBuffer))
  65. {
  66. isFoundModule = 1;
  67. break;
  68. }
  69. }
  70. AZ_TEST_ASSERT(isFoundModule);
  71. SymbolStorage::StackLine stackLines[AZ_ARRAY_SIZE(frames)];
  72. AZ_TracePrintf("StackTracer", "\n====================================\n");
  73. AZ_TracePrintf("StackTracer", "Callstack:\n");
  74. SymbolStorage::DecodeFrames(frames, numFrames, stackLines);
  75. for (u32 i = 0; i < numFrames; ++i)
  76. {
  77. AZ_TEST_ASSERT(strlen(stackLines[i]) > 0); // We should some result for each stack frame
  78. AZ_TracePrintf("StackTracer", "%s\n", stackLines[i]);
  79. }
  80. AZ_TracePrintf("StackTracer", "====================================\n");
  81. }
  82. #elif AZ_TRAIT_OS_STACK_FRAMES_PRINT
  83. {
  84. SymbolStorage::StackLine stackLines[AZ_ARRAY_SIZE(frames)];
  85. printf("\n====================================\n");
  86. printf("Callstack:\n");
  87. SymbolStorage::DecodeFrames(frames, numFrames, stackLines);
  88. for (u32 i = 0; i < numFrames; ++i)
  89. {
  90. AZ_TEST_ASSERT(strlen(stackLines[i]) > 0); // We should some result for each stack frame
  91. printf("%s\n", stackLines[i]);
  92. }
  93. printf("====================================\n");
  94. }
  95. #endif
  96. }
  97. }
  98. class TraceTest
  99. : public AZ::Debug::TraceMessageBus::Handler
  100. , public ::testing::Test
  101. {
  102. int m_numTracePrintfs;
  103. public:
  104. TraceTest()
  105. : m_numTracePrintfs(0) {}
  106. //////////////////////////////////////////////////////////////////////////
  107. // TraceMessageBus
  108. bool OnPrintf(const char* windowName, const char* message) override
  109. {
  110. (void)windowName;
  111. (void)message;
  112. ++m_numTracePrintfs;
  113. return false;
  114. }
  115. //////////////////////////////////////////////////////////////////////////
  116. void run()
  117. {
  118. bool falseExp = false;
  119. int m_data = 0;
  120. (void)falseExp;
  121. (void)m_data;
  122. BusConnect();
  123. printf("\n");
  124. // Assert
  125. AZ_Assert(true, "Constand expression - always pass!");
  126. // Error
  127. // Regular warning
  128. AZ_Warning("Streamer", falseExp, "Test Message");
  129. // Printf
  130. int oldNumTracePrintfs = m_numTracePrintfs;
  131. AZ_Printf("AI | A*", "Test Message");
  132. // only one traceprintf should have occurred here.
  133. AZ_TEST_ASSERT(m_numTracePrintfs == oldNumTracePrintfs + 1);
  134. // test verify
  135. bool result = false;
  136. AZ_Verify(result = true, "Expression should execute even in release!");
  137. AZ_TEST_ASSERT(result == true);
  138. result = false;
  139. AZ_VerifyError("Test", result = true, "Expression should execute even in release!");
  140. AZ_TEST_ASSERT(result == true);
  141. result = false;
  142. AZ_VerifyWarning("Test", result = true, "Expression should execute even in release!");
  143. AZ_TEST_ASSERT(result == true);
  144. (void)result;
  145. BusDisconnect();
  146. }
  147. };
  148. TEST_F(TraceTest, Test)
  149. {
  150. run();
  151. }
  152. TEST(Time, Test)
  153. {
  154. AZStd::sys_time_t ticksPerSecond = AZStd::GetTimeTicksPerSecond();
  155. AZ_TEST_ASSERT(ticksPerSecond != 0);
  156. AZStd::sys_time_t timeNowSeconds = AZStd::GetTimeNowSecond();
  157. AZ_TEST_ASSERT(timeNowSeconds != 0);
  158. AZStd::sys_time_t timeNowTicks = AZStd::GetTimeNowTicks();
  159. AZ_TEST_ASSERT(timeNowTicks != 0);
  160. AZStd::sys_time_t timeNowMs = AZStd::GetTimeNowMicroSecond();
  161. AZ_TEST_ASSERT(timeNowMs != 0);
  162. AZ::u64 timeNowUTCms = AZStd::GetTimeUTCMilliSecond();
  163. AZ_TEST_ASSERT(timeNowUTCms != 0);
  164. };
  165. }