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