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 #include <chrono>
19 #include <thread>
20 #include <vector>
21 #include "../metrics/metrics_test_helper.h"
22 #include "src/stats_log_util.h"
23 #include "tests/statsd_test_util.h"
24 
25 #ifdef __ANDROID__
26 
27 namespace android {
28 namespace os {
29 namespace statsd {
30 
31 using namespace testing;
32 using std::make_shared;
33 using std::shared_ptr;
34 using std::vector;
35 using std::this_thread::sleep_for;
36 using testing::Contains;
37 
38 // cooldown time 1sec.
39 int pullTagId = 10014;
40 
41 bool pullSuccess;
42 vector<std::shared_ptr<LogEvent>> pullData;
43 long pullDelayNs;
44 
45 class FakePuller : public StatsPuller {
46 public:
FakePuller()47     FakePuller() : StatsPuller(pullTagId){};
48 
49 private:
PullInternal(vector<std::shared_ptr<LogEvent>> * data)50     bool PullInternal(vector<std::shared_ptr<LogEvent>>* data) override {
51         (*data) = pullData;
52         sleep_for(std::chrono::nanoseconds(pullDelayNs));
53         return pullSuccess;
54     }
55 };
56 
57 FakePuller puller;
58 
createSimpleEvent(int64_t eventTimeNs,int64_t value)59 shared_ptr<LogEvent> createSimpleEvent(int64_t eventTimeNs, int64_t value) {
60     shared_ptr<LogEvent> event = make_shared<LogEvent>(pullTagId, eventTimeNs);
61     event->write(value);
62     event->init();
63     return event;
64 }
65 
66 class StatsPullerTest : public ::testing::Test {
67 public:
StatsPullerTest()68     StatsPullerTest() {
69     }
70 
SetUp()71     void SetUp() override {
72         puller.ForceClearCache();
73         pullSuccess = false;
74         pullDelayNs = 0;
75         pullData.clear();
76     }
77 };
78 
TEST_F(StatsPullerTest,PullSucces)79 TEST_F(StatsPullerTest, PullSucces) {
80     pullData.push_back(createSimpleEvent(1111L, 33));
81 
82     pullSuccess = true;
83 
84     vector<std::shared_ptr<LogEvent>> dataHolder;
85     EXPECT_TRUE(puller.Pull(&dataHolder));
86     EXPECT_EQ(1, dataHolder.size());
87     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
88     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
89     EXPECT_EQ(1, dataHolder[0]->size());
90     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
91 
92     sleep_for(std::chrono::seconds(1));
93 
94     pullData.clear();
95     pullData.push_back(createSimpleEvent(2222L, 44));
96 
97     pullSuccess = true;
98 
99     EXPECT_TRUE(puller.Pull(&dataHolder));
100     EXPECT_EQ(1, dataHolder.size());
101     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
102     EXPECT_EQ(2222L, dataHolder[0]->GetElapsedTimestampNs());
103     EXPECT_EQ(1, dataHolder[0]->size());
104     EXPECT_EQ(44, dataHolder[0]->getValues()[0].mValue.int_value);
105 }
106 
TEST_F(StatsPullerTest,PullFailAfterSuccess)107 TEST_F(StatsPullerTest, PullFailAfterSuccess) {
108     pullData.push_back(createSimpleEvent(1111L, 33));
109 
110     pullSuccess = true;
111 
112     vector<std::shared_ptr<LogEvent>> dataHolder;
113     EXPECT_TRUE(puller.Pull(&dataHolder));
114     EXPECT_EQ(1, dataHolder.size());
115     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
116     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
117     EXPECT_EQ(1, dataHolder[0]->size());
118     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
119 
120     sleep_for(std::chrono::seconds(1));
121 
122     pullData.clear();
123     pullData.push_back(createSimpleEvent(2222L, 44));
124 
125     pullSuccess = false;
126     dataHolder.clear();
127     EXPECT_FALSE(puller.Pull(&dataHolder));
128     EXPECT_EQ(0, dataHolder.size());
129 
130     pullSuccess = true;
131     dataHolder.clear();
132     EXPECT_FALSE(puller.Pull(&dataHolder));
133     EXPECT_EQ(0, dataHolder.size());
134 }
135 
136 // Test pull takes longer than timeout, 2nd pull happens shorter than cooldown
TEST_F(StatsPullerTest,PullTakeTooLongAndPullFast)137 TEST_F(StatsPullerTest, PullTakeTooLongAndPullFast) {
138     pullData.push_back(createSimpleEvent(1111L, 33));
139     pullSuccess = true;
140     // timeout is 0.5
141     pullDelayNs = (long)(0.8 * NS_PER_SEC);
142 
143     vector<std::shared_ptr<LogEvent>> dataHolder;
144     EXPECT_FALSE(puller.Pull(&dataHolder));
145     EXPECT_EQ(0, dataHolder.size());
146 
147     pullData.clear();
148     pullData.push_back(createSimpleEvent(2222L, 44));
149 
150     pullSuccess = true;
151     dataHolder.clear();
152     EXPECT_FALSE(puller.Pull(&dataHolder));
153     EXPECT_EQ(0, dataHolder.size());
154 }
155 
TEST_F(StatsPullerTest,PullFail)156 TEST_F(StatsPullerTest, PullFail) {
157     pullData.push_back(createSimpleEvent(1111L, 33));
158 
159     pullSuccess = false;
160 
161     vector<std::shared_ptr<LogEvent>> dataHolder;
162     EXPECT_FALSE(puller.Pull(&dataHolder));
163     EXPECT_EQ(0, dataHolder.size());
164 }
165 
TEST_F(StatsPullerTest,PullTakeTooLong)166 TEST_F(StatsPullerTest, PullTakeTooLong) {
167     pullData.push_back(createSimpleEvent(1111L, 33));
168 
169     pullSuccess = true;
170     pullDelayNs = NS_PER_SEC;
171 
172     vector<std::shared_ptr<LogEvent>> dataHolder;
173     EXPECT_FALSE(puller.Pull(&dataHolder));
174     EXPECT_EQ(0, dataHolder.size());
175 }
176 
TEST_F(StatsPullerTest,PullTooFast)177 TEST_F(StatsPullerTest, PullTooFast) {
178     pullData.push_back(createSimpleEvent(1111L, 33));
179 
180     pullSuccess = true;
181 
182     vector<std::shared_ptr<LogEvent>> dataHolder;
183     EXPECT_TRUE(puller.Pull(&dataHolder));
184     EXPECT_EQ(1, dataHolder.size());
185     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
186     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
187     EXPECT_EQ(1, dataHolder[0]->size());
188     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
189 
190     pullData.clear();
191     pullData.push_back(createSimpleEvent(2222L, 44));
192 
193     pullSuccess = true;
194 
195     dataHolder.clear();
196     EXPECT_TRUE(puller.Pull(&dataHolder));
197     EXPECT_EQ(1, dataHolder.size());
198     EXPECT_EQ(pullTagId, dataHolder[0]->GetTagId());
199     EXPECT_EQ(1111L, dataHolder[0]->GetElapsedTimestampNs());
200     EXPECT_EQ(1, dataHolder[0]->size());
201     EXPECT_EQ(33, dataHolder[0]->getValues()[0].mValue.int_value);
202 }
203 
TEST_F(StatsPullerTest,PullFailsAndTooFast)204 TEST_F(StatsPullerTest, PullFailsAndTooFast) {
205     pullData.push_back(createSimpleEvent(1111L, 33));
206 
207     pullSuccess = false;
208 
209     vector<std::shared_ptr<LogEvent>> dataHolder;
210     EXPECT_FALSE(puller.Pull(&dataHolder));
211     EXPECT_EQ(0, dataHolder.size());
212 
213     pullData.clear();
214     pullData.push_back(createSimpleEvent(2222L, 44));
215 
216     pullSuccess = true;
217 
218     EXPECT_FALSE(puller.Pull(&dataHolder));
219     EXPECT_EQ(0, dataHolder.size());
220 }
221 
222 }  // namespace statsd
223 }  // namespace os
224 }  // namespace android
225 #else
226 GTEST_LOG_(INFO) << "This test does nothing.\n";
227 #endif
228