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