1 /*
2 * Copyright (C) 2023 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "utils/DbUtils.h"
18
19 #include <gtest/gtest.h>
20
21 #include "android-base/stringprintf.h"
22 #include "storage/StorageManager.h"
23 #include "tests/statsd_test_util.h"
24
25 #ifdef __ANDROID__
26
27 using namespace std;
28
29 namespace android {
30 namespace os {
31 namespace statsd {
32 namespace dbutils {
33
34 using base::StringPrintf;
35
36 namespace {
37 const ConfigKey key = ConfigKey(111, 222);
38 const int64_t metricId = 111;
39 const int32_t tagId = 1;
40
makeAStatsEvent(int32_t atomId,int64_t timestampNs)41 AStatsEvent* makeAStatsEvent(int32_t atomId, int64_t timestampNs) {
42 AStatsEvent* statsEvent = AStatsEvent_obtain();
43 AStatsEvent_setAtomId(statsEvent, atomId);
44 AStatsEvent_overwriteTimestamp(statsEvent, timestampNs);
45 return statsEvent;
46 }
47
makeLogEvent(AStatsEvent * statsEvent)48 LogEvent makeLogEvent(AStatsEvent* statsEvent) {
49 LogEvent event(/*uid=*/0, /*pid=*/0);
50 parseStatsEventToLogEvent(statsEvent, &event);
51 return event;
52 }
53
54 class DbUtilsTest : public ::testing::Test {
55 public:
SetUp()56 void SetUp() override {
57 if (!isAtLeastU()) {
58 GTEST_SKIP();
59 }
60 }
TearDown()61 void TearDown() override {
62 if (!isAtLeastU()) {
63 GTEST_SKIP();
64 }
65 deleteDb(key);
66 }
67 };
68 } // Anonymous namespace.
69
TEST_F(DbUtilsTest,TestInsertString)70 TEST_F(DbUtilsTest, TestInsertString) {
71 int64_t eventElapsedTimeNs = 10000000000;
72
73 AStatsEvent* statsEvent = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
74 AStatsEvent_writeString(statsEvent, "test_string");
75 LogEvent logEvent = makeLogEvent(statsEvent);
76 vector<LogEvent> events{logEvent};
77
78 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
79 string err;
80 EXPECT_TRUE(insert(key, metricId, events, err));
81
82 std::vector<int32_t> columnTypes;
83 std::vector<string> columnNames;
84 std::vector<std::vector<std::string>> rows;
85 string zSql = "SELECT * FROM metric_111 ORDER BY elapsedTimestampNs";
86 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
87
88 ASSERT_EQ(rows.size(), 1);
89 EXPECT_THAT(rows[0], ElementsAre("1", to_string(eventElapsedTimeNs + 10), _, "test_string"));
90 EXPECT_THAT(columnTypes,
91 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_TEXT));
92 EXPECT_THAT(columnNames,
93 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
94 }
95
TEST_F(DbUtilsTest,TestMaliciousString)96 TEST_F(DbUtilsTest, TestMaliciousString) {
97 int64_t eventElapsedTimeNs = 10000000000;
98
99 AStatsEvent* statsEvent = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
100 AStatsEvent_writeString(statsEvent, "111); DROP TABLE metric_111;--");
101 LogEvent logEvent = makeLogEvent(statsEvent);
102 vector<LogEvent> events{logEvent};
103
104 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
105 string err;
106 EXPECT_TRUE(insert(key, metricId, events, err));
107
108 std::vector<int32_t> columnTypes;
109 std::vector<string> columnNames;
110 std::vector<std::vector<std::string>> rows;
111 string zSql = "SELECT * FROM metric_111 ORDER BY elapsedTimestampNs";
112 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
113
114 ASSERT_EQ(rows.size(), 1);
115 EXPECT_THAT(rows[0], ElementsAre("1", to_string(eventElapsedTimeNs + 10), _,
116 "111); DROP TABLE metric_111;--"));
117 EXPECT_THAT(columnTypes,
118 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_TEXT));
119 EXPECT_THAT(columnNames,
120 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
121 }
122
TEST_F(DbUtilsTest,TestInsertStringNegativeMetricId)123 TEST_F(DbUtilsTest, TestInsertStringNegativeMetricId) {
124 int64_t eventElapsedTimeNs = 10000000000;
125 int64_t metricId2 = -111;
126
127 AStatsEvent* statsEvent = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
128 AStatsEvent_writeString(statsEvent, "111");
129 LogEvent logEvent = makeLogEvent(statsEvent);
130 vector<LogEvent> events{logEvent};
131
132 EXPECT_TRUE(createTableIfNeeded(key, metricId2, logEvent));
133 string err;
134 EXPECT_TRUE(insert(key, metricId2, events, err));
135
136 std::vector<int32_t> columnTypes;
137 std::vector<string> columnNames;
138 std::vector<std::vector<std::string>> rows;
139 string zSql = "SELECT * FROM metric_n111 ORDER BY elapsedTimestampNs";
140 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
141
142 ASSERT_EQ(rows.size(), 1);
143 EXPECT_THAT(rows[0], ElementsAre("1", to_string(eventElapsedTimeNs + 10), _, "111"));
144 EXPECT_THAT(columnTypes,
145 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_TEXT));
146 EXPECT_THAT(columnNames,
147 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
148 }
149
TEST_F(DbUtilsTest,TestInsertInteger)150 TEST_F(DbUtilsTest, TestInsertInteger) {
151 int64_t eventElapsedTimeNs = 10000000000;
152
153 AStatsEvent* statsEvent = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
154 AStatsEvent_writeInt32(statsEvent, 11);
155 AStatsEvent_writeInt64(statsEvent, 111);
156 LogEvent logEvent = makeLogEvent(statsEvent);
157 vector<LogEvent> events{logEvent};
158
159 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
160 string err;
161 EXPECT_TRUE(insert(key, metricId, events, err));
162
163 std::vector<int32_t> columnTypes;
164 std::vector<string> columnNames;
165 std::vector<std::vector<std::string>> rows;
166 string zSql = "SELECT * FROM metric_111 ORDER BY elapsedTimestampNs";
167 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
168
169 ASSERT_EQ(rows.size(), 1);
170 EXPECT_THAT(rows[0], ElementsAre("1", to_string(eventElapsedTimeNs + 10), _, "11", "111"));
171 EXPECT_THAT(columnTypes, ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER,
172 SQLITE_INTEGER, SQLITE_INTEGER));
173 EXPECT_THAT(columnNames, ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs",
174 "field_1", "field_2"));
175 }
176
TEST_F(DbUtilsTest,TestInsertFloat)177 TEST_F(DbUtilsTest, TestInsertFloat) {
178 int64_t eventElapsedTimeNs = 10000000000;
179
180 AStatsEvent* statsEvent = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
181 AStatsEvent_writeFloat(statsEvent, 11.0);
182 LogEvent logEvent = makeLogEvent(statsEvent);
183 vector<LogEvent> events{logEvent};
184
185 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
186 string err;
187 EXPECT_TRUE(insert(key, metricId, events, err));
188
189 std::vector<int32_t> columnTypes;
190 std::vector<string> columnNames;
191 std::vector<std::vector<std::string>> rows;
192 string zSql = "SELECT * FROM metric_111 ORDER BY elapsedTimestampNs";
193 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
194
195 ASSERT_EQ(rows.size(), 1);
196 EXPECT_THAT(rows[0], ElementsAre("1", to_string(eventElapsedTimeNs + 10), _, _));
197 EXPECT_FLOAT_EQ(/*field1=*/std::stof(rows[0][3]), 11.0);
198 EXPECT_THAT(columnTypes,
199 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_FLOAT));
200 EXPECT_THAT(columnNames,
201 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
202 }
203
TEST_F(DbUtilsTest,TestInsertTwoEvents)204 TEST_F(DbUtilsTest, TestInsertTwoEvents) {
205 int64_t eventElapsedTimeNs = 10000000000;
206
207 AStatsEvent* statsEvent1 = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
208 AStatsEvent_writeString(statsEvent1, "111");
209 LogEvent logEvent1 = makeLogEvent(statsEvent1);
210
211 AStatsEvent* statsEvent2 = makeAStatsEvent(tagId, eventElapsedTimeNs + 20);
212 AStatsEvent_writeString(statsEvent2, "222");
213 LogEvent logEvent2 = makeLogEvent(statsEvent2);
214
215 vector<LogEvent> events{logEvent1, logEvent2};
216
217 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent1));
218 string err;
219 EXPECT_TRUE(insert(key, metricId, events, err));
220
221 std::vector<int32_t> columnTypes;
222 std::vector<string> columnNames;
223 std::vector<std::vector<std::string>> rows;
224 string zSql = "SELECT * FROM metric_111 ORDER BY elapsedTimestampNs";
225 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
226
227 ASSERT_EQ(rows.size(), 2);
228 EXPECT_THAT(rows[0], ElementsAre("1", to_string(eventElapsedTimeNs + 10), _, "111"));
229 EXPECT_THAT(rows[1], ElementsAre("1", to_string(eventElapsedTimeNs + 20), _, "222"));
230 EXPECT_THAT(columnTypes,
231 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_TEXT));
232 EXPECT_THAT(columnNames,
233 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
234 }
235
TEST_F(DbUtilsTest,TestInsertTwoEventsEnforceTtl)236 TEST_F(DbUtilsTest, TestInsertTwoEventsEnforceTtl) {
237 int64_t eventElapsedTimeNs = 10000000000;
238 int64_t eventWallClockNs = 50000000000;
239
240 AStatsEvent* statsEvent1 = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
241 AStatsEvent_writeString(statsEvent1, "111");
242 LogEvent logEvent1 = makeLogEvent(statsEvent1);
243 logEvent1.setLogdWallClockTimestampNs(eventWallClockNs);
244
245 AStatsEvent* statsEvent2 = makeAStatsEvent(tagId, eventElapsedTimeNs + 20);
246 AStatsEvent_writeString(statsEvent2, "222");
247 LogEvent logEvent2 = makeLogEvent(statsEvent2);
248 logEvent2.setLogdWallClockTimestampNs(eventWallClockNs + eventElapsedTimeNs);
249
250 vector<LogEvent> events{logEvent1, logEvent2};
251
252 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent1));
253 sqlite3* db = getDb(key);
254 string err;
255 EXPECT_TRUE(insert(db, metricId, events, err));
256 EXPECT_TRUE(flushTtl(db, metricId, eventWallClockNs));
257 closeDb(db);
258
259 std::vector<int32_t> columnTypes;
260 std::vector<string> columnNames;
261 std::vector<std::vector<std::string>> rows;
262 string zSql = "SELECT * FROM metric_111 ORDER BY elapsedTimestampNs";
263 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
264
265 ASSERT_EQ(rows.size(), 1);
266 EXPECT_THAT(rows[0], ElementsAre("1", to_string(eventElapsedTimeNs + 20), _, "222"));
267 EXPECT_THAT(columnTypes,
268 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_TEXT));
269 EXPECT_THAT(columnNames,
270 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
271 }
272
TEST_F(DbUtilsTest,TestMaliciousQuery)273 TEST_F(DbUtilsTest, TestMaliciousQuery) {
274 int64_t eventElapsedTimeNs = 10000000000;
275
276 AStatsEvent* statsEvent = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
277 AStatsEvent_writeString(statsEvent, "111");
278 LogEvent logEvent = makeLogEvent(statsEvent);
279 vector<LogEvent> events{logEvent};
280
281 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
282 string err;
283 EXPECT_TRUE(insert(key, metricId, events, err));
284
285 std::vector<int32_t> columnTypes;
286 std::vector<string> columnNames;
287 std::vector<std::vector<std::string>> rows;
288 string zSql = "DROP TABLE metric_111";
289 EXPECT_FALSE(query(key, zSql, rows, columnTypes, columnNames, err));
290 EXPECT_THAT(err, StartsWith("attempt to write a readonly database"));
291 }
292
TEST_F(DbUtilsTest,TestInsertStringIntegrityCheckPasses)293 TEST_F(DbUtilsTest, TestInsertStringIntegrityCheckPasses) {
294 int64_t eventElapsedTimeNs = 10000000000;
295
296 AStatsEvent* statsEvent = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
297 AStatsEvent_writeString(statsEvent, "111");
298 LogEvent logEvent = makeLogEvent(statsEvent);
299 vector<LogEvent> events{logEvent};
300
301 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
302 string err;
303 EXPECT_TRUE(insert(key, metricId, events, err));
304 verifyIntegrityAndDeleteIfNecessary(key);
305
306 std::vector<int32_t> columnTypes;
307 std::vector<string> columnNames;
308 std::vector<std::vector<std::string>> rows;
309 string zSql = "SELECT * FROM metric_111 ORDER BY elapsedTimestampNs";
310 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
311 ASSERT_EQ(rows.size(), 1);
312 EXPECT_THAT(rows[0], ElementsAre("1", to_string(eventElapsedTimeNs + 10), _, "111"));
313 EXPECT_THAT(columnTypes,
314 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_TEXT));
315 EXPECT_THAT(columnNames,
316 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
317 }
318
TEST_F(DbUtilsTest,TestInsertStringIntegrityCheckFails)319 TEST_F(DbUtilsTest, TestInsertStringIntegrityCheckFails) {
320 int64_t eventElapsedTimeNs = 10000000000;
321
322 AStatsEvent* statsEvent = makeAStatsEvent(tagId, eventElapsedTimeNs + 10);
323 AStatsEvent_writeString(statsEvent, "111");
324 LogEvent logEvent = makeLogEvent(statsEvent);
325 vector<LogEvent> events{logEvent};
326 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
327 string err;
328 EXPECT_TRUE(insert(key, metricId, events, err));
329
330 string randomData("1232hasha14125ashfas21512sh31321");
331 string fileName = StringPrintf("%s/%d_%lld.db", STATS_RESTRICTED_DATA_DIR, key.GetUid(),
332 (long long)key.GetId());
333 StorageManager::writeFile(fileName.c_str(), randomData.data(), randomData.size());
334 EXPECT_TRUE(StorageManager::hasFile(fileName.c_str()));
335 verifyIntegrityAndDeleteIfNecessary(key);
336 std::vector<int32_t> columnTypes;
337 std::vector<string> columnNames;
338 std::vector<std::vector<std::string>> rows;
339 string zSql = "SELECT * FROM metric_111 ORDER BY elapsedTimestampNs";
340 EXPECT_FALSE(query(key, zSql, rows, columnTypes, columnNames, err));
341 EXPECT_THAT(err, StartsWith("unable to open database file"));
342 EXPECT_FALSE(StorageManager::hasFile(fileName.c_str()));
343 }
344
TEST_F(DbUtilsTest,TestEventCompatibilityEventMatchesTable)345 TEST_F(DbUtilsTest, TestEventCompatibilityEventMatchesTable) {
346 AStatsEvent* statsEvent = makeAStatsEvent(tagId, /*eventElapsedTime=*/10000000000);
347 AStatsEvent_writeString(statsEvent, "111");
348 AStatsEvent_writeFloat(statsEvent, 111.0);
349 AStatsEvent_writeInt32(statsEvent, 23);
350 LogEvent logEvent = makeLogEvent(statsEvent);
351
352 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
353
354 EXPECT_TRUE(isEventCompatible(key, metricId, logEvent));
355 }
356
TEST_F(DbUtilsTest,TestEventCompatibilityEventDoesNotMatchesTable)357 TEST_F(DbUtilsTest, TestEventCompatibilityEventDoesNotMatchesTable) {
358 AStatsEvent* statsEvent = makeAStatsEvent(tagId, /*eventElapsedTime=*/10000000000);
359 AStatsEvent_writeString(statsEvent, "111");
360 AStatsEvent_writeFloat(statsEvent, 111.0);
361 AStatsEvent_writeInt32(statsEvent, 23);
362 LogEvent logEvent = makeLogEvent(statsEvent);
363
364 AStatsEvent* statsEvent2 = makeAStatsEvent(tagId, /*eventElapsedTime=*/10000000000);
365 AStatsEvent_writeString(statsEvent2, "111");
366 AStatsEvent_writeFloat(statsEvent2, 111.0);
367 AStatsEvent_writeInt32(statsEvent2, 23);
368 AStatsEvent_writeInt32(statsEvent2, 25);
369 LogEvent logEvent2 = makeLogEvent(statsEvent2);
370
371 EXPECT_TRUE(createTableIfNeeded(key, metricId, logEvent));
372
373 EXPECT_FALSE(isEventCompatible(key, metricId, logEvent2));
374 }
375
TEST_F(DbUtilsTest,TestEventCompatibilityTableNotCreated)376 TEST_F(DbUtilsTest, TestEventCompatibilityTableNotCreated) {
377 AStatsEvent* statsEvent = makeAStatsEvent(tagId, /*eventElapsedTime=*/10000000000);
378 AStatsEvent_writeString(statsEvent, "111");
379 AStatsEvent_writeFloat(statsEvent, 111.0);
380 AStatsEvent_writeInt32(statsEvent, 23);
381 LogEvent logEvent = makeLogEvent(statsEvent);
382
383 EXPECT_TRUE(isEventCompatible(key, metricId, logEvent));
384 }
385
TEST_F(DbUtilsTest,TestUpdateDeviceInfoTable)386 TEST_F(DbUtilsTest, TestUpdateDeviceInfoTable) {
387 string err;
388 updateDeviceInfoTable(key, err);
389
390 std::vector<int32_t> columnTypes;
391 std::vector<string> columnNames;
392 std::vector<std::vector<std::string>> rows;
393 string zSql = "SELECT * FROM device_info";
394 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
395
396 ASSERT_EQ(rows.size(), 1);
397 EXPECT_THAT(rows[0], ElementsAre(_, _, _, _, _, _, _, _, _, _));
398 EXPECT_THAT(columnTypes,
399 ElementsAre(SQLITE_INTEGER, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT,
400 SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT));
401 EXPECT_THAT(columnNames,
402 ElementsAre("sdkVersion", "model", "product", "hardware", "device", "osBuild",
403 "fingerprint", "brand", "manufacturer", "board"));
404 }
405
TEST_F(DbUtilsTest,TestUpdateDeviceInfoTableInvokeTwice)406 TEST_F(DbUtilsTest, TestUpdateDeviceInfoTableInvokeTwice) {
407 string err;
408 updateDeviceInfoTable(key, err);
409 updateDeviceInfoTable(key, err);
410
411 std::vector<int32_t> columnTypes;
412 std::vector<string> columnNames;
413 std::vector<std::vector<std::string>> rows;
414 string zSql = "SELECT * FROM device_info";
415 EXPECT_TRUE(query(key, zSql, rows, columnTypes, columnNames, err));
416
417 ASSERT_EQ(rows.size(), 1);
418 EXPECT_THAT(rows[0], ElementsAre(_, _, _, _, _, _, _, _, _, _));
419 EXPECT_THAT(columnTypes,
420 ElementsAre(SQLITE_INTEGER, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT,
421 SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT));
422 EXPECT_THAT(columnNames,
423 ElementsAre("sdkVersion", "model", "product", "hardware", "device", "osBuild",
424 "fingerprint", "brand", "manufacturer", "board"));
425 }
426
427 } // namespace dbutils
428 } // namespace statsd
429 } // namespace os
430 } // namespace android
431 #else
432 GTEST_LOG_(INFO) << "This test does nothing.\n";
433 #endif
434