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__
TEST(LogEventQueue_test,TestGoodConsumer)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
TEST(LogEventQueue_test,TestSlowConsumer)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