• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2018 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 <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 #include <stdio.h>
18 
19 #include <chrono>
20 #include <thread>
21 #include <vector>
22 
23 #include "../metrics/metrics_test_helper.h"
24 #include "src/stats_log_util.h"
25 #include "stats_event.h"
26 #include "tests/statsd_test_util.h"
27 
28 #ifdef __ANDROID__
29 
30 namespace android {
31 namespace os {
32 namespace statsd {
33 
34 using namespace testing;
35 using std::make_shared;
36 using std::shared_ptr;
37 using std::vector;
38 using std::this_thread::sleep_for;
39 using testing::Contains;
40 
41 namespace {
42 int pullTagId = 10014;
43 
44 bool pullSuccess;
45 vector<std::shared_ptr<LogEvent>> pullData;
46 long pullDelayNs;
47 
48 class FakePuller : public StatsPuller {
49 public:
FakePuller()50     FakePuller()
51         : StatsPuller(pullTagId, /*coolDownNs=*/MillisToNano(10), /*timeoutNs=*/MillisToNano(5)){};
52 
53 private:
PullInternal(vector<std::shared_ptr<LogEvent>> * data)54     bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override {
55         (*data) = pullData;
56         sleep_for(std::chrono::nanoseconds(pullDelayNs));
57         return pullSuccess;
58     }
59 };
60 
61 FakePuller puller;
62 
createSimpleEvent(int64_t eventTimeNs,int64_t value)63 std::unique_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) {
64     AStatsEvent* statsEvent = AStatsEvent_obtain();
65     AStatsEvent_setAtomId(statsEvent, pullTagId);
66     AStatsEvent_overwriteTimestamp(statsEvent, eventTimeNs);
67     AStatsEvent_writeInt64(statsEvent, value);
68 
69     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
70     parseStatsEventToLogEvent(statsEvent, logEvent.get());
71     return logEvent;
72 }
73 
74 class StatsPullerTest : public ::testing::Test {
75 public:
StatsPullerTest()76     StatsPullerTest() {
77     }
78 
SetUp()79     void SetUp() override {
80         puller.ForceClearCache();
81         pullSuccess = false;
82         pullDelayNs = 0;
83         pullData.clear();
84     }
85 };
86 
87 }  // Anonymous namespace.
88 
TEST_F(StatsPullerTest,PullSuccess)89 TEST_F(StatsPullerTest, PullSuccess) {
90     pullData.push_back(createSimpleEvent(1111L, 33));
91 
92     pullSuccess = true;
93 
94     vector<std::shared_ptr<LogEvent>> dataHolder;
95     EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
96     ASSERT_EQ(1, dataHolder.size());
97     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
98     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
99     ASSERT_EQ(1, dataHolder[0]->size());
100     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
101 
102     sleep_for(std::chrono::milliseconds(11));
103 
104     pullData.clear();
105     pullData.push_back(createSimpleEvent(2222L, 44));
106 
107     pullSuccess = true;
108 
109     EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
110     ASSERT_EQ(1, dataHolder.size());
111     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
112     EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs());
113     ASSERT_EQ(1, dataHolder[0]->size());
114     EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value);
115 }
116 
TEST_F(StatsPullerTest,PullFailAfterSuccess)117 TEST_F(StatsPullerTest, PullFailAfterSuccess) {
118     pullData.push_back(createSimpleEvent(1111L, 33));
119 
120     pullSuccess = true;
121 
122     vector<std::shared_ptr<LogEvent>> dataHolder;
123     EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
124     ASSERT_EQ(1, dataHolder.size());
125     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
126     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
127     ASSERT_EQ(1, dataHolder[0]->size());
128     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
129 
130     sleep_for(std::chrono::milliseconds(11));
131 
132     pullData.clear();
133     pullData.push_back(createSimpleEvent(2222L, 44));
134 
135     pullSuccess = false;
136     dataHolder.clear();
137     EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
138     ASSERT_EQ(0, dataHolder.size());
139 
140     // Fails due to hitting the cool down.
141     pullSuccess = true;
142     dataHolder.clear();
143     EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
144     ASSERT_EQ(0, dataHolder.size());
145 }
146 
147 // Test pull takes longer than timeout, 2nd pull happens shorter than cooldown
TEST_F(StatsPullerTest,PullTakeTooLongAndPullFast)148 TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) {
149     pullData.push_back(createSimpleEvent(1111L, 33));
150     pullSuccess = true;
151     // timeout is 5ms
152     pullDelayNs = MillisToNano(6);
153 
154     vector<std::shared_ptr<LogEvent>> dataHolder;
155     EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
156     ASSERT_EQ(0, dataHolder.size());
157 
158     pullData.clear();
159     pullData.push_back(createSimpleEvent(2222L, 44));
160     pullDelayNs = 0;
161 
162     pullSuccess = true;
163     dataHolder.clear();
164     EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
165     ASSERT_EQ(0, dataHolder.size());
166 }
167 
TEST_F(StatsPullerTest,PullFail)168 TEST_F(StatsPullerTest, PullFail) {
169     pullData.push_back(createSimpleEvent(1111L, 33));
170 
171     pullSuccess = false;
172 
173     vector<std::shared_ptr<LogEvent>> dataHolder;
174     EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
175     ASSERT_EQ(0, dataHolder.size());
176 }
177 
TEST_F(StatsPullerTest,PullTakeTooLong)178 TEST_F(StatsPullerTest, PullTakeTooLong) {
179     pullData.push_back(createSimpleEvent(1111L, 33));
180 
181     pullSuccess = true;
182     pullDelayNs = MillisToNano(6);
183 
184     vector<std::shared_ptr<LogEvent>> dataHolder;
185     EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
186     ASSERT_EQ(0, dataHolder.size());
187 }
188 
TEST_F(StatsPullerTest,PullTooFast)189 TEST_F(StatsPullerTest, PullTooFast) {
190     pullData.push_back(createSimpleEvent(1111L, 33));
191 
192     pullSuccess = true;
193 
194     vector<std::shared_ptr<LogEvent>> dataHolder;
195     EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
196     ASSERT_EQ(1, dataHolder.size());
197     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
198     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
199     ASSERT_EQ(1, dataHolder[0]->size());
200     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
201 
202     pullData.clear();
203     pullData.push_back(createSimpleEvent(2222L, 44));
204 
205     pullSuccess = true;
206 
207     dataHolder.clear();
208     EXPECT_TRUE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
209     ASSERT_EQ(1, dataHolder.size());
210     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
211     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
212     ASSERT_EQ(1, dataHolder[0]->size());
213     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
214 }
215 
TEST_F(StatsPullerTest,PullFailsAndTooFast)216 TEST_F(StatsPullerTest, PullFailsAndTooFast) {
217     pullData.push_back(createSimpleEvent(1111L, 33));
218 
219     pullSuccess = false;
220 
221     vector<std::shared_ptr<LogEvent>> dataHolder;
222     EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
223     ASSERT_EQ(0, dataHolder.size());
224 
225     pullData.clear();
226     pullData.push_back(createSimpleEvent(2222L, 44));
227 
228     pullSuccess = true;
229 
230     EXPECT_FALSE(puller.Pull(getElapsedRealtimeNs(), &dataHolder));
231     ASSERT_EQ(0, dataHolder.size());
232 }
233 
TEST_F(StatsPullerTest,PullSameEventTime)234 TEST_F(StatsPullerTest, PullSameEventTime) {
235     pullData.push_back(createSimpleEvent(1111L, 33));
236 
237     pullSuccess = true;
238     int64_t eventTimeNs = getElapsedRealtimeNs();
239 
240     vector<std::shared_ptr<LogEvent>> dataHolder;
241     EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
242     ASSERT_EQ(1, dataHolder.size());
243     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
244     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
245     ASSERT_EQ(1, dataHolder[0]->size());
246     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
247 
248     pullData.clear();
249     pullData.push_back(createSimpleEvent(2222L, 44));
250 
251     // Sleep to ensure the cool down expires.
252     sleep_for(std::chrono::milliseconds(11));
253     pullSuccess = true;
254 
255     dataHolder.clear();
256     EXPECT_TRUE(puller.Pull(eventTimeNs, &dataHolder));
257     ASSERT_EQ(1, dataHolder.size());
258     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
259     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
260     ASSERT_EQ(1, dataHolder[0]->size());
261     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
262 }
263 
264 // Test pull takes longer than timeout, 2nd pull happens at same event time
TEST_F(StatsPullerTest,PullTakeTooLongAndPullSameEventTime)265 TEST_F(StatsPullerTest, PullTakeTooLongAndPullSameEventTime) {
266     pullData.push_back(createSimpleEvent(1111L, 33));
267     pullSuccess = true;
268     int64_t eventTimeNs = getElapsedRealtimeNs();
269     // timeout is 5ms
270     pullDelayNs = MillisToNano(6);
271 
272     vector<std::shared_ptr<LogEvent>> dataHolder;
273     EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
274     ASSERT_EQ(0, dataHolder.size());
275 
276     // Sleep to ensure the cool down expires. 6ms is taken by the delay, so only 5 is needed here.
277     sleep_for(std::chrono::milliseconds(5));
278 
279     pullData.clear();
280     pullData.push_back(createSimpleEvent(2222L, 44));
281     pullDelayNs = 0;
282 
283     pullSuccess = true;
284     dataHolder.clear();
285     EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
286     ASSERT_EQ(0, dataHolder.size());
287 }
288 
TEST_F(StatsPullerTest,PullFailsAndPullSameEventTime)289 TEST_F(StatsPullerTest, PullFailsAndPullSameEventTime) {
290     pullData.push_back(createSimpleEvent(1111L, 33));
291 
292     pullSuccess = false;
293     int64_t eventTimeNs = getElapsedRealtimeNs();
294 
295     vector<std::shared_ptr<LogEvent>> dataHolder;
296     EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
297     ASSERT_EQ(0, dataHolder.size());
298 
299     // Sleep to ensure the cool down expires.
300     sleep_for(std::chrono::milliseconds(11));
301 
302     pullData.clear();
303     pullData.push_back(createSimpleEvent(2222L, 44));
304 
305     pullSuccess = true;
306 
307     EXPECT_FALSE(puller.Pull(eventTimeNs, &dataHolder));
308     ASSERT_EQ(0, dataHolder.size());
309 }
310 
311 }  // namespace statsd
312 }  // namespace os
313 }  // namespace android
314 #else
315 GTEST_LOG_(INFO) << "This test does nothing.\n";
316 #endif
317