| #include "aos/common/queue_testutils.h" |
| |
| #include <string.h> |
| #include <sys/mman.h> |
| #include <unistd.h> |
| #include <stdlib.h> |
| #include <assert.h> |
| |
| #include "gtest/gtest.h" |
| |
| #include "aos/common/queue.h" |
| #include "aos/common/logging/logging_impl.h" |
| #include "aos/common/once.h" |
| |
| using ::aos::logging::LogMessage; |
| |
| namespace aos { |
| namespace common { |
| namespace testing { |
| namespace { |
| |
| class TestLogImplementation : public logging::HandleMessageLogImplementation { |
| public: |
| const ::std::vector<LogMessage> &messages() { return messages_; } |
| |
| // This class has to be a singleton so that everybody can get access to the |
| // same instance to read out the messages etc. |
| static TestLogImplementation *GetInstance() { |
| static Once<TestLogImplementation> once(CreateInstance); |
| return once.Get(); |
| } |
| |
| // Clears out all of the messages already recorded. |
| void ClearMessages() { |
| messages_.clear(); |
| } |
| |
| // Prints out all of the messages (like when a test fails). |
| void PrintAllMessages() { |
| for (auto it = messages_.begin(); it != messages_.end(); ++it) { |
| logging::internal::PrintMessage(stdout, *it); |
| } |
| } |
| |
| private: |
| TestLogImplementation() {} |
| |
| static TestLogImplementation *CreateInstance() { |
| return new TestLogImplementation(); |
| } |
| |
| virtual void HandleMessage(const LogMessage &message) override { |
| if (!logging::log_gt_important(WARNING, message.level)) { |
| logging::internal::PrintMessage(stdout, message); |
| } |
| |
| messages_.push_back(message); |
| } |
| |
| ::std::vector<LogMessage> messages_; |
| }; |
| |
| class MyTestEventListener : public ::testing::EmptyTestEventListener { |
| virtual void OnTestStart(const ::testing::TestInfo &/*test_info*/) { |
| TestLogImplementation::GetInstance()->ClearMessages(); |
| } |
| virtual void OnTestEnd(const ::testing::TestInfo &test_info) { |
| if (test_info.result()->Failed()) { |
| printf("Test %s failed. Printing out all log messages.\n", |
| test_info.name()); |
| fputs("\tThis will include already printed WARNING and up messages.\n", |
| stdout); |
| fputs("\tIt will also include duplicates of all gtest failures.\n", |
| stdout); |
| TestLogImplementation::GetInstance()->PrintAllMessages(); |
| } |
| } |
| |
| virtual void OnTestPartResult( const ::testing::TestPartResult &result) { |
| if (result.failed()) { |
| const char *failure_type = "unknown"; |
| switch (result.type()) { |
| case ::testing::TestPartResult::Type::kNonFatalFailure: |
| failure_type = "EXPECT"; |
| break; |
| case ::testing::TestPartResult::Type::kFatalFailure: |
| failure_type = "ASSERT"; |
| break; |
| case ::testing::TestPartResult::Type::kSuccess: |
| break; |
| } |
| log_do(ERROR, "%s: %d: gtest %s failure\n%s\n", |
| result.file_name(), |
| result.line_number(), |
| failure_type, |
| result.message()); |
| } |
| } |
| }; |
| |
| void *DoEnableTestLogging() { |
| logging::Init(); |
| logging::AddImplementation(TestLogImplementation::GetInstance()); |
| |
| ::testing::UnitTest::GetInstance()->listeners().Append( |
| new MyTestEventListener()); |
| |
| return NULL; |
| } |
| |
| Once<void> enable_test_logging_once(DoEnableTestLogging); |
| |
| const size_t kCoreSize = 0x100000; |
| |
| void TerminateExitHandler() { |
| _exit(EXIT_SUCCESS); |
| } |
| |
| } // namespace |
| |
| GlobalCoreInstance::GlobalCoreInstance() { |
| global_core = &global_core_data_; |
| global_core->owner = true; |
| // Use mmap(2) manually instead of through malloc(3) so that we can pass |
| // MAP_SHARED which allows forked processes to communicate using the |
| // "shared" memory. |
| void *memory = mmap(NULL, kCoreSize, PROT_READ | PROT_WRITE, |
| MAP_SHARED | MAP_ANONYMOUS, -1, 0); |
| assert(memory != MAP_FAILED); |
| |
| assert(aos_core_use_address_as_shared_mem(memory, kCoreSize) == 0); |
| |
| EnableTestLogging(); |
| } |
| |
| GlobalCoreInstance::~GlobalCoreInstance() { |
| assert(munmap(global_core->mem_struct, kCoreSize) == 0); |
| global_core = NULL; |
| } |
| |
| void EnableTestLogging() { |
| enable_test_logging_once.Get(); |
| } |
| |
| void PreventExit() { |
| assert(atexit(TerminateExitHandler) == 0); |
| } |
| |
| } // namespace testing |
| } // namespace common |
| } // namespace aos |