Integrating latest 47acbe8

This commit is contained in:
alexpete
2021-03-25 13:57:57 -07:00
parent 448c549698
commit 75dc720198
10312 changed files with 2711566 additions and 671451 deletions
@@ -0,0 +1,266 @@
/*
* All or portions of this file Copyright (c) Amazon.com, Inc. or its affiliates or
* its licensors.
*
* For complete copyright and license terms please see the LICENSE at the root of this
* distribution (the "License"). All use of this software is governed by the License,
* or, if provided, by the license below or the license accompanying this file. Do not
* remove or modify any license notices. This file is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
*
*/
#include <limits>
#include <AzCore/Debug/LocalFileEventLogger.h>
#include <AzCore/IO/Path/Path.h>
#include <AzCore/std/parallel/atomic.h>
#include <AzCore/UnitTest/TestTypes.h>
namespace AZ::Debug
{
class LocalFileEventLoggerTest
: public UnitTest::AllocatorsFixture
{
public:
inline static constexpr EventNameHash MessageId = EventNameHash("Message");
inline static constexpr const char* LogFileName = "TestLog.azel";
};
TEST_F(LocalFileEventLoggerTest, RecordEvent_SingleString_WrittenToLog)
{
constexpr const char* message = "Hello world";
LocalFileEventLogger realLogger;
AZ::Test::ScopedAutoTempDirectory tempDir;
auto logFilePath = tempDir.Resolve(LogFileName);
auto logger = Interface<IEventLogger>::Get();
ASSERT_NE(logger, nullptr);
realLogger.Start(logFilePath.c_str());
logger->RecordStringEvent(MessageId, message);
realLogger.Stop();
EventLogReader reader;
ASSERT_TRUE(reader.ReadLog(logFilePath.c_str()));
EXPECT_EQ(reader.GetEventName(), PrologEventHash);
ASSERT_TRUE(reader.Next());
EXPECT_EQ(reader.GetEventName(), MessageId);
EXPECT_STREQ(reader.GetString().data(), message);
EXPECT_FALSE(reader.Next());
}
TEST_F(LocalFileEventLoggerTest, RecordEvent_SeveralStrings_WrittenToLog)
{
constexpr const char* messages[] = {
"Hello world",
"And goodbye",
"It has been a long and strange journey"
};
LocalFileEventLogger realLogger;
AZ::Test::ScopedAutoTempDirectory tempDir;
auto logFilePath = tempDir.Resolve(LogFileName);
auto logger = Interface<IEventLogger>::Get();
ASSERT_NE(logger, nullptr);
realLogger.Start(logFilePath.c_str());
for (auto message : messages)
{
logger->RecordStringEvent(MessageId, message);
}
realLogger.Stop();
EventLogReader reader;
ASSERT_TRUE(reader.ReadLog(logFilePath.c_str()));
EXPECT_EQ(reader.GetEventName(), PrologEventHash);
for (auto message : messages)
{
ASSERT_TRUE(reader.Next());
EXPECT_EQ(reader.GetEventName(), MessageId);
EXPECT_STREQ(reader.GetString().data(), message);
}
EXPECT_FALSE(reader.Next());
}
TEST_F(LocalFileEventLoggerTest, RecordEvent_StringsFromMultipleThreads_WrittenToLog)
{
constexpr const char* messages[] = {
"Hello world",
"And goodbye"
};
constexpr size_t totalThreads = 4;
AZ::Test::ScopedAutoTempDirectory tempDir;
LocalFileEventLogger realLogger;
auto logFilePath = tempDir.Resolve(LogFileName);
realLogger.Start(logFilePath.c_str());
AZStd::atomic_bool startLogging = false;
AZStd::thread threads[totalThreads];
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
{
threads[threadIndex] = AZStd::thread([&startLogging, &messages]()
{
while (!startLogging)
{
AZStd::this_thread::yield();
}
auto logger = Interface<IEventLogger>::Get();
ASSERT_NE(logger, nullptr);
for (auto message : messages)
{
logger->RecordStringEvent(MessageId, message);
}
});
}
startLogging = true;
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
{
threads[threadIndex].join();
}
realLogger.Stop();
EventLogReader reader;
ASSERT_TRUE(reader.ReadLog(logFilePath.c_str()));
uint64_t threadIds[totalThreads]{ 0 };
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
{
EXPECT_EQ(reader.GetEventName(), PrologEventHash);
threadIds[threadIndex] = reader.GetThreadId();
for (size_t otherThreadIndex = 0; otherThreadIndex < threadIndex; ++otherThreadIndex)
{
EXPECT_NE(threadIds[threadIndex], threadIds[otherThreadIndex]);
}
for (auto message : messages)
{
ASSERT_TRUE(reader.Next());
EXPECT_EQ(reader.GetEventName(), MessageId);
EXPECT_STREQ(reader.GetString().data(), message);
}
reader.Next();
}
}
TEST_F(LocalFileEventLoggerTest, RecordEvent_BufferGetsWrittenWhenFull_WrittenToLog)
{
constexpr EventNameHash largeBlockId = EventNameHash("Large block");
constexpr size_t largeBlockSizeOffset = 14;
constexpr size_t largeBlockSize = AZStd::numeric_limits<uint16_t>::max() - largeBlockSizeOffset;
struct LargeBlock
{
char m_block[largeBlockSize];
};
constexpr const char* message = "The message after the large block.";
LocalFileEventLogger realLogger;
AZ::Test::ScopedAutoTempDirectory tempDir;
auto logFilePath = tempDir.Resolve(LogFileName);
auto logger = Interface<IEventLogger>::Get();
ASSERT_NE(logger, nullptr);
realLogger.Start(logFilePath.c_str());
LargeBlock& block = logger->RecordEventBegin<LargeBlock>(largeBlockId);
logger->RecordEventEnd();
logger->RecordStringEvent(MessageId, message);
realLogger.Stop();
EventLogReader reader;
ASSERT_TRUE(reader.ReadLog(logFilePath.c_str()));
EXPECT_EQ(reader.GetEventName(), PrologEventHash);
ASSERT_TRUE(reader.Next());
EXPECT_EQ(reader.GetEventName(), largeBlockId);
EXPECT_EQ(reader.GetEventSize(), largeBlockSize);
ASSERT_TRUE(reader.Next());
EXPECT_EQ(reader.GetEventName(), PrologEventHash); // Another prolog as a new cache block started.
ASSERT_TRUE(reader.Next());
EXPECT_EQ(reader.GetEventName(), MessageId);
EXPECT_STREQ(reader.GetString().data(), message);
EXPECT_FALSE(reader.Next());
}
TEST_F(LocalFileEventLoggerTest, Flush_DuringMultipleRecords_FlushDoesNotDeadlock)
{
constexpr size_t totalThreads = 8;
constexpr size_t recordsPerThreadCount = 2000;
constexpr size_t recordsYieldCount = totalThreads * 1000;
constexpr const char* message = "This is a threaded message test.";
LocalFileEventLogger realLogger;
AZ::Test::ScopedAutoTempDirectory tempDir;
auto logFilePath = tempDir.Resolve(LogFileName);
realLogger.Start(logFilePath.c_str());
AZStd::atomic_int totalRecordsWritten = 0;
AZStd::atomic_bool startLogging = false;
AZStd::thread threads[totalThreads];
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
{
threads[threadIndex] = AZStd::thread([&startLogging, &totalRecordsWritten, &message, recordsPerThreadCount]()
{
while (!startLogging)
{
AZStd::this_thread::yield();
}
auto logger = Interface<IEventLogger>::Get();
ASSERT_NE(logger, nullptr);
for (size_t recordCount = 0; recordCount < recordsPerThreadCount; ++recordCount)
{
logger->RecordStringEvent(MessageId, message);
++totalRecordsWritten;
}
});
}
startLogging = true;
while (totalRecordsWritten < recordsYieldCount)
{
AZStd::this_thread::yield();
}
realLogger.Flush();
for (size_t threadIndex = 0; threadIndex < totalThreads; ++threadIndex)
{
threads[threadIndex].join();
}
realLogger.Stop();
}
} // namespace AZ::Debug