1 // Copyright (C) 2019 The Android Open Source Project 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 #include "logd/LogEventQueue.h" 16 17 #include <gmock/gmock.h> 18 #include <gtest/gtest.h> 19 #include <thread> 20 21 #include <stdio.h> 22 23 namespace android { 24 namespace os { 25 namespace statsd { 26 27 using namespace android; 28 using namespace testing; 29 30 using std::unique_ptr; 31 32 #ifdef __ANDROID__ 33 TEST(LogEventQueue_test, TestGoodConsumer) { 34 LogEventQueue queue(50); 35 int64_t timeBaseNs = 100; 36 std::thread writer([&queue, timeBaseNs] { 37 for (int i = 0; i < 100; i++) { 38 int64_t oldestEventNs; 39 bool success = queue.push(std::make_unique<LogEvent>(10, timeBaseNs + i * 1000), 40 &oldestEventNs); 41 EXPECT_TRUE(success); 42 std::this_thread::sleep_for(std::chrono::milliseconds(1)); 43 } 44 }); 45 46 std::thread reader([&queue, timeBaseNs] { 47 for (int i = 0; i < 100; i++) { 48 auto event = queue.waitPop(); 49 EXPECT_TRUE(event != nullptr); 50 // All events are in right order. 51 EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs()); 52 } 53 }); 54 55 reader.join(); 56 writer.join(); 57 } 58 59 TEST(LogEventQueue_test, TestSlowConsumer) { 60 LogEventQueue queue(50); 61 int64_t timeBaseNs = 100; 62 std::thread writer([&queue, timeBaseNs] { 63 int failure_count = 0; 64 int64_t oldestEventNs; 65 for (int i = 0; i < 100; i++) { 66 bool success = queue.push(std::make_unique<LogEvent>(10, timeBaseNs + i * 1000), 67 &oldestEventNs); 68 if (!success) failure_count++; 69 std::this_thread::sleep_for(std::chrono::milliseconds(1)); 70 } 71 72 // There is some remote chance that reader thread not get chance to run before writer thread 73 // ends. That's why the following comparison is not "==". 74 // There will be at least 45 events lost due to overflow. 75 EXPECT_TRUE(failure_count >= 45); 76 // The oldest event must be at least the 6th event. 77 EXPECT_TRUE(oldestEventNs <= (100 + 5 * 1000)); 78 }); 79 80 std::thread reader([&queue, timeBaseNs] { 81 // The consumer quickly processed 5 events, then it got stuck (not reading anymore). 82 for (int i = 0; i < 5; i++) { 83 auto event = queue.waitPop(); 84 EXPECT_TRUE(event != nullptr); 85 // All events are in right order. 86 EXPECT_EQ(timeBaseNs + i * 1000, event->GetElapsedTimestampNs()); 87 } 88 }); 89 90 reader.join(); 91 writer.join(); 92 } 93 94 #else 95 GTEST_LOG_(INFO) << "This test does nothing.\n"; 96 #endif 97 98 } // namespace statsd 99 } // namespace os 100 } // namespace android 101