• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (C) 2023 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 <android-modules-utils/sdk_level.h>
16 #include <gtest/gtest.h>
17 
18 #include <vector>
19 
20 #include "android-base/stringprintf.h"
21 #include "flags/FlagProvider.h"
22 #include "src/StatsLogProcessor.h"
23 #include "src/state/StateTracker.h"
24 #include "src/stats_log_util.h"
25 #include "src/storage/StorageManager.h"
26 #include "src/utils/RestrictedPolicyManager.h"
27 #include "stats_annotations.h"
28 #include "tests/statsd_test_util.h"
29 
30 namespace android {
31 namespace os {
32 namespace statsd {
33 
34 using android::modules::sdklevel::IsAtLeastU;
35 using base::StringPrintf;
36 
37 #ifdef __ANDROID__
38 
39 namespace {
40 const int64_t oneMonthLater = getWallClockNs() + 31 * 24 * 3600 * NS_PER_SEC;
41 const int64_t configId = 12345;
42 const string delegate_package_name = "com.test.restricted.metrics.package";
43 const int32_t delegate_uid = 1005;
44 const string config_package_name = "com.test.config.package";
45 const int32_t config_app_uid = 123;
46 const ConfigKey configKey(config_app_uid, configId);
47 const int64_t eightDaysAgo = getWallClockNs() - 8 * 24 * 3600 * NS_PER_SEC;
48 const int64_t oneDayAgo = getWallClockNs() - 1 * 24 * 3600 * NS_PER_SEC;
49 }  // anonymous namespace
50 
51 // Setup for test fixture.
52 class RestrictedEventMetricE2eTest : public ::testing::Test {
53 protected:
54     shared_ptr<MockStatsQueryCallback> mockStatsQueryCallback;
55     vector<string> queryDataResult;
56     vector<string> columnNamesResult;
57     vector<int32_t> columnTypesResult;
58     int32_t rowCountResult = 0;
59     string error;
60     sp<UidMap> uidMap;
61     sp<StatsLogProcessor> processor;
62     int32_t atomTag;
63     int64_t restrictedMetricId;
64     int64_t configAddedTimeNs;
65     StatsdConfig config;
66 
67 private:
SetUp()68     void SetUp() override {
69         if (!IsAtLeastU()) {
70             GTEST_SKIP();
71         }
72 
73         mockStatsQueryCallback = SharedRefBase::make<StrictMock<MockStatsQueryCallback>>();
74         EXPECT_CALL(*mockStatsQueryCallback, sendResults(_, _, _, _))
75                 .Times(AnyNumber())
76                 .WillRepeatedly(Invoke(
77                         [this](const vector<string>& queryData, const vector<string>& columnNames,
78                                const vector<int32_t>& columnTypes, int32_t rowCount) {
79                             queryDataResult = queryData;
80                             columnNamesResult = columnNames;
81                             columnTypesResult = columnTypes;
82                             rowCountResult = rowCount;
83                             error = "";
84                             return Status::ok();
85                         }));
86         EXPECT_CALL(*mockStatsQueryCallback, sendFailure(_))
87                 .Times(AnyNumber())
88                 .WillRepeatedly(Invoke([this](const string& err) {
89                     error = err;
90                     queryDataResult.clear();
91                     columnNamesResult.clear();
92                     columnTypesResult.clear();
93                     rowCountResult = 0;
94                     return Status::ok();
95                 }));
96 
97         config.add_allowed_log_source("AID_ROOT");  // LogEvent defaults to UID of root.
98 
99         atomTag = 999;
100         AtomMatcher restrictedAtomMatcher = CreateSimpleAtomMatcher("restricted_matcher", atomTag);
101         *config.add_atom_matcher() = restrictedAtomMatcher;
102 
103         EventMetric restrictedEventMetric =
104                 createEventMetric("RestrictedMetricLogged", restrictedAtomMatcher.id(), nullopt);
105         *config.add_event_metric() = restrictedEventMetric;
106         restrictedMetricId = restrictedEventMetric.id();
107 
108         config.set_restricted_metrics_delegate_package_name(delegate_package_name.c_str());
109 
110         const int64_t baseTimeNs = 0;                     // 0:00
111         configAddedTimeNs = baseTimeNs + 1 * NS_PER_SEC;  // 0:01
112 
113         uidMap = new UidMap();
114         uidMap->updateApp(configAddedTimeNs, String16(delegate_package_name.c_str()),
115                           /*uid=*/delegate_uid, /*versionCode=*/1,
116                           /*versionString=*/String16("v2"),
117                           /*installer=*/String16(""), /*certificateHash=*/{});
118         uidMap->updateApp(configAddedTimeNs + 1, String16(config_package_name.c_str()),
119                           /*uid=*/config_app_uid, /*versionCode=*/1,
120                           /*versionString=*/String16("v2"),
121                           /*installer=*/String16(""), /*certificateHash=*/{});
122 
123         processor = CreateStatsLogProcessor(baseTimeNs, configAddedTimeNs, config, configKey,
124                                             /*puller=*/nullptr, /*atomTag=*/0, uidMap);
125     }
126 
TearDown()127     void TearDown() override {
128         Mock::VerifyAndClear(mockStatsQueryCallback.get());
129         queryDataResult.clear();
130         columnNamesResult.clear();
131         columnTypesResult.clear();
132         rowCountResult = 0;
133         error = "";
134         dbutils::deleteDb(configKey);
135         dbutils::deleteDb(ConfigKey(config_app_uid + 1, configId));
136         FlagProvider::getInstance().resetOverrides();
137     }
138 };
139 
TEST_F(RestrictedEventMetricE2eTest,TestQueryThreeEvents)140 TEST_F(RestrictedEventMetricE2eTest, TestQueryThreeEvents) {
141     std::vector<std::unique_ptr<LogEvent>> events;
142 
143     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
144     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 200));
145     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 300));
146 
147     // Send log events to StatsLogProcessor.
148     for (auto& event : events) {
149         processor->OnLogEvent(event.get());
150     }
151 
152     std::stringstream query;
153     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
154     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
155                         /*policyConfig=*/{}, mockStatsQueryCallback,
156                         /*configKey=*/configId, /*configPackage=*/config_package_name,
157                         /*callingUid=*/delegate_uid);
158 
159     EXPECT_EQ(rowCountResult, 3);
160     EXPECT_THAT(queryDataResult, ElementsAre(to_string(atomTag), to_string(configAddedTimeNs + 100),
161                                              _,  // wallClockNs
162                                              _,  // field_1
163                                              to_string(atomTag), to_string(configAddedTimeNs + 200),
164                                              _,  // wallClockNs
165                                              _,  // field_1
166                                              to_string(atomTag), to_string(configAddedTimeNs + 300),
167                                              _,  // wallClockNs
168                                              _   // field_1
169                                              ));
170 
171     EXPECT_THAT(columnNamesResult,
172                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
173 
174     EXPECT_THAT(columnTypesResult,
175                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
176 }
177 
TEST_F(RestrictedEventMetricE2eTest,TestInvalidSchemaIncreasingFieldCount)178 TEST_F(RestrictedEventMetricE2eTest, TestInvalidSchemaIncreasingFieldCount) {
179     std::vector<std::unique_ptr<LogEvent>> events;
180 
181     AStatsEvent* statsEvent = AStatsEvent_obtain();
182     AStatsEvent_setAtomId(statsEvent, atomTag);
183     AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY,
184                                    ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC);
185     AStatsEvent_overwriteTimestamp(statsEvent, configAddedTimeNs + 200);
186     // This event has two extra fields
187     AStatsEvent_writeString(statsEvent, "111");
188     AStatsEvent_writeInt32(statsEvent, 11);
189     AStatsEvent_writeFloat(statsEvent, 11.0);
190     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
191     parseStatsEventToLogEvent(statsEvent, logEvent.get());
192 
193     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
194     events.push_back(std::move(logEvent));
195 
196     // Send log events to StatsLogProcessor.
197     for (auto& event : events) {
198         processor->OnLogEvent(event.get());
199         processor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST,
200                                    event->GetElapsedTimestampNs() + 20 * NS_PER_SEC,
201                                    getWallClockNs());
202     }
203 
204     std::stringstream query;
205     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
206     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
207                         /*policyConfig=*/{}, mockStatsQueryCallback,
208                         /*configKey=*/configId, /*configPackage=*/config_package_name,
209                         /*callingUid=*/delegate_uid);
210 
211     EXPECT_EQ(rowCountResult, 1);
212     // Event 2 rejected.
213     EXPECT_THAT(queryDataResult, ElementsAre(to_string(atomTag), to_string(configAddedTimeNs + 100),
214                                              _,  // wallClockNs
215                                              _   // field_1
216                                              ));
217 
218     EXPECT_THAT(columnNamesResult,
219                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
220 
221     EXPECT_THAT(columnTypesResult,
222                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
223 }
224 
TEST_F(RestrictedEventMetricE2eTest,TestInvalidSchemaDecreasingFieldCount)225 TEST_F(RestrictedEventMetricE2eTest, TestInvalidSchemaDecreasingFieldCount) {
226     std::vector<std::unique_ptr<LogEvent>> events;
227 
228     AStatsEvent* statsEvent = AStatsEvent_obtain();
229     AStatsEvent_setAtomId(statsEvent, atomTag);
230     AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY,
231                                    ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC);
232     AStatsEvent_overwriteTimestamp(statsEvent, configAddedTimeNs + 100);
233     // This event has one extra field.
234     AStatsEvent_writeString(statsEvent, "111");
235     AStatsEvent_writeInt32(statsEvent, 11);
236     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
237     parseStatsEventToLogEvent(statsEvent, logEvent.get());
238 
239     events.push_back(std::move(logEvent));
240     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 200));
241 
242     // Send log events to StatsLogProcessor.
243     for (auto& event : events) {
244         processor->OnLogEvent(event.get());
245         processor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST,
246                                    event->GetElapsedTimestampNs() + 20 * NS_PER_SEC,
247                                    getWallClockNs());
248     }
249 
250     std::stringstream query;
251     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
252     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
253                         /*policyConfig=*/{}, mockStatsQueryCallback,
254                         /*configKey=*/configId, /*configPackage=*/config_package_name,
255                         /*callingUid=*/delegate_uid);
256 
257     EXPECT_EQ(rowCountResult, 1);
258     // Event 2 Rejected
259     EXPECT_THAT(queryDataResult, ElementsAre(to_string(atomTag), to_string(configAddedTimeNs + 100),
260                                              _,             // wallClockNs
261                                              "111",         // field_1
262                                              to_string(11)  // field_2
263                                              ));
264 
265     EXPECT_THAT(columnNamesResult, ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs",
266                                                "field_1", "field_2"));
267 
268     EXPECT_THAT(columnTypesResult, ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER,
269                                                SQLITE_TEXT, SQLITE_INTEGER));
270 }
271 
TEST_F(RestrictedEventMetricE2eTest,TestInvalidSchemaDifferentFieldType)272 TEST_F(RestrictedEventMetricE2eTest, TestInvalidSchemaDifferentFieldType) {
273     std::vector<std::unique_ptr<LogEvent>> events;
274 
275     AStatsEvent* statsEvent = AStatsEvent_obtain();
276     AStatsEvent_setAtomId(statsEvent, atomTag);
277     AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY,
278                                    ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC);
279     AStatsEvent_overwriteTimestamp(statsEvent, configAddedTimeNs + 200);
280     // This event has a string instead of an int field
281     AStatsEvent_writeString(statsEvent, "test_string");
282     std::unique_ptr<LogEvent> logEvent = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
283     parseStatsEventToLogEvent(statsEvent, logEvent.get());
284 
285     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
286     events.push_back(std::move(logEvent));
287 
288     // Send log events to StatsLogProcessor.
289     for (auto& event : events) {
290         processor->OnLogEvent(event.get());
291         processor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST,
292                                    event->GetElapsedTimestampNs() + 20 * NS_PER_SEC,
293                                    getWallClockNs());
294     }
295 
296     std::stringstream query;
297     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
298     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
299                         /*policyConfig=*/{}, mockStatsQueryCallback,
300                         /*configKey=*/configId, /*configPackage=*/config_package_name,
301                         /*callingUid=*/delegate_uid);
302 
303     EXPECT_EQ(rowCountResult, 1);
304     // Event 2 rejected.
305     EXPECT_THAT(queryDataResult, ElementsAre(to_string(atomTag), to_string(configAddedTimeNs + 100),
306                                              _,  // wallClockNs
307                                              _   // field_1
308                                              ));
309     EXPECT_THAT(columnNamesResult,
310                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
311     EXPECT_THAT(columnTypesResult,
312                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
313 }
314 
TEST_F(RestrictedEventMetricE2eTest,TestNewMetricSchemaAcrossReboot)315 TEST_F(RestrictedEventMetricE2eTest, TestNewMetricSchemaAcrossReboot) {
316     int64_t currentWallTimeNs = getWallClockNs();
317     int64_t originalEventElapsedTime = configAddedTimeNs + 100;
318     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(atomTag, originalEventElapsedTime);
319     processor->OnLogEvent(event1.get());
320 
321     std::stringstream query;
322     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
323     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
324                         /*policyConfig=*/{}, mockStatsQueryCallback,
325                         /*configKey=*/configId, /*configPackage=*/config_package_name,
326                         /*callingUid=*/delegate_uid);
327     EXPECT_EQ(rowCountResult, 1);
328     EXPECT_THAT(queryDataResult,
329                 ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime),
330                             _,  // wallTimestampNs
331                             _   // field_1
332                             ));
333     EXPECT_THAT(columnNamesResult,
334                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
335     EXPECT_THAT(columnTypesResult,
336                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
337 
338     // Create a new processor to simulate a reboot
339     auto processor2 =
340             CreateStatsLogProcessor(/*baseTimeNs=*/0, configAddedTimeNs, config, configKey,
341                                     /*puller=*/nullptr, /*atomTag=*/0, uidMap);
342 
343     // Create a restricted event with one extra field.
344     AStatsEvent* statsEvent = AStatsEvent_obtain();
345     AStatsEvent_setAtomId(statsEvent, atomTag);
346     AStatsEvent_addInt32Annotation(statsEvent, ASTATSLOG_ANNOTATION_ID_RESTRICTION_CATEGORY,
347                                    ASTATSLOG_RESTRICTION_CATEGORY_DIAGNOSTIC);
348     AStatsEvent_overwriteTimestamp(statsEvent, originalEventElapsedTime + 100);
349     // This event has one extra field.
350     AStatsEvent_writeString(statsEvent, "111");
351     AStatsEvent_writeInt32(statsEvent, 11);
352     std::unique_ptr<LogEvent> event2 = std::make_unique<LogEvent>(/*uid=*/0, /*pid=*/0);
353     parseStatsEventToLogEvent(statsEvent, event2.get());
354     processor2->OnLogEvent(event2.get());
355 
356     processor2->querySql(query.str(), /*minSqlClientVersion=*/0,
357                          /*policyConfig=*/{}, mockStatsQueryCallback,
358                          /*configKey=*/configId, /*configPackage=*/config_package_name,
359                          /*callingUid=*/delegate_uid);
360     EXPECT_EQ(rowCountResult, 1);
361     EXPECT_THAT(queryDataResult,
362                 ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime + 100),
363                             _,               // wallTimestampNs
364                             to_string(111),  // field_1
365                             to_string(11)    // field_2
366                             ));
367     EXPECT_THAT(columnNamesResult, ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs",
368                                                "field_1", "field_2"));
369     EXPECT_THAT(columnTypesResult, ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER,
370                                                SQLITE_TEXT, SQLITE_INTEGER));
371 }
372 
TEST_F(RestrictedEventMetricE2eTest,TestOneEventMultipleUids)373 TEST_F(RestrictedEventMetricE2eTest, TestOneEventMultipleUids) {
374     uidMap->updateApp(configAddedTimeNs, String16(delegate_package_name.c_str()),
375                       /*uid=*/delegate_uid + 1, /*versionCode=*/1,
376                       /*versionString=*/String16("v2"),
377                       /*installer=*/String16(""), /*certificateHash=*/{});
378     uidMap->updateApp(configAddedTimeNs + 1, String16(config_package_name.c_str()),
379                       /*uid=*/config_app_uid + 1, /*versionCode=*/1,
380                       /*versionString=*/String16("v2"),
381                       /*installer=*/String16(""), /*certificateHash=*/{});
382 
383     std::vector<std::unique_ptr<LogEvent>> events;
384 
385     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
386 
387     // Send log events to StatsLogProcessor.
388     for (auto& event : events) {
389         processor->OnLogEvent(event.get());
390     }
391 
392     std::stringstream query;
393     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
394     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
395                         /*policyConfig=*/{}, mockStatsQueryCallback,
396                         /*configKey=*/configId, /*configPackage=*/config_package_name,
397                         /*callingUid=*/delegate_uid);
398 
399     EXPECT_EQ(rowCountResult, 1);
400     EXPECT_THAT(queryDataResult, ElementsAre(to_string(atomTag), to_string(configAddedTimeNs + 100),
401                                              _,  // wallClockNs
402                                              _   // field_1
403                                              ));
404 }
405 
TEST_F(RestrictedEventMetricE2eTest,TestOneEventStaticUid)406 TEST_F(RestrictedEventMetricE2eTest, TestOneEventStaticUid) {
407     ConfigKey key2(2000, configId);  // shell uid
408     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, key2, config);
409 
410     std::vector<std::unique_ptr<LogEvent>> events;
411 
412     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
413 
414     // Send log events to StatsLogProcessor.
415     for (auto& event : events) {
416         processor->OnLogEvent(event.get());
417     }
418 
419     std::stringstream query;
420     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
421     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
422                         /*policyConfig=*/{}, mockStatsQueryCallback,
423                         /*configKey=*/configId, /*configPackage=*/"AID_SHELL",
424                         /*callingUid=*/delegate_uid);
425 
426     EXPECT_EQ(rowCountResult, 1);
427     EXPECT_THAT(queryDataResult, ElementsAre(to_string(atomTag), to_string(configAddedTimeNs + 100),
428                                              _,  // wallClockNs
429                                              _   // field_1
430                                              ));
431     dbutils::deleteDb(key2);
432 }
433 
TEST_F(RestrictedEventMetricE2eTest,TestTooManyConfigsAmbiguousQuery)434 TEST_F(RestrictedEventMetricE2eTest, TestTooManyConfigsAmbiguousQuery) {
435     ConfigKey key2(config_app_uid + 1, configId);
436     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, key2, config);
437 
438     uidMap->updateApp(configAddedTimeNs, String16(delegate_package_name.c_str()),
439                       /*uid=*/delegate_uid + 1, /*versionCode=*/1,
440                       /*versionString=*/String16("v2"),
441                       /*installer=*/String16(""), /*certificateHash=*/{});
442     uidMap->updateApp(configAddedTimeNs + 1, String16(config_package_name.c_str()),
443                       /*uid=*/config_app_uid + 1, /*versionCode=*/1,
444                       /*versionString=*/String16("v2"),
445                       /*installer=*/String16(""), /*certificateHash=*/{});
446 
447     std::vector<std::unique_ptr<LogEvent>> events;
448 
449     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
450 
451     // Send log events to StatsLogProcessor.
452     for (auto& event : events) {
453         processor->OnLogEvent(event.get());
454     }
455 
456     std::stringstream query;
457     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
458     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
459                         /*policyConfig=*/{}, mockStatsQueryCallback,
460                         /*configKey=*/configId, /*configPackage=*/config_package_name,
461                         /*callingUid=*/delegate_uid);
462 
463     EXPECT_EQ(error, "Ambiguous ConfigKey");
464     dbutils::deleteDb(key2);
465 }
466 
TEST_F(RestrictedEventMetricE2eTest,TestUnknownConfigPackage)467 TEST_F(RestrictedEventMetricE2eTest, TestUnknownConfigPackage) {
468     std::vector<std::unique_ptr<LogEvent>> events;
469 
470     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
471 
472     // Send log events to StatsLogProcessor.
473     for (auto& event : events) {
474         processor->OnLogEvent(event.get());
475     }
476 
477     std::stringstream query;
478     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
479     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
480                         /*policyConfig=*/{}, mockStatsQueryCallback,
481                         /*configKey=*/configId, /*configPackage=*/"unknown.config.package",
482                         /*callingUid=*/delegate_uid);
483 
484     EXPECT_EQ(error, "No configs found matching the config key");
485 }
486 
TEST_F(RestrictedEventMetricE2eTest,TestUnknownDelegatePackage)487 TEST_F(RestrictedEventMetricE2eTest, TestUnknownDelegatePackage) {
488     std::vector<std::unique_ptr<LogEvent>> events;
489 
490     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
491 
492     // Send log events to StatsLogProcessor.
493     for (auto& event : events) {
494         processor->OnLogEvent(event.get());
495     }
496 
497     std::stringstream query;
498     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
499     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
500                         /*policyConfig=*/{}, mockStatsQueryCallback,
501                         /*configKey=*/configId, /*configPackage=*/config_package_name,
502                         /*callingUid=*/delegate_uid + 1);
503 
504     EXPECT_EQ(error, "No matching configs for restricted metrics delegate");
505 }
506 
TEST_F(RestrictedEventMetricE2eTest,TestUnsupportedDatabaseVersion)507 TEST_F(RestrictedEventMetricE2eTest, TestUnsupportedDatabaseVersion) {
508     std::stringstream query;
509     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
510     processor->querySql(query.str(), /*minSqlClientVersion=*/INT_MAX,
511                         /*policyConfig=*/{}, mockStatsQueryCallback,
512                         /*configKey=*/configId, /*configPackage=*/config_package_name,
513                         /*callingUid=*/delegate_uid);
514 
515     EXPECT_THAT(error, StartsWith("Unsupported sqlite version"));
516 }
517 
TEST_F(RestrictedEventMetricE2eTest,TestInvalidQuery)518 TEST_F(RestrictedEventMetricE2eTest, TestInvalidQuery) {
519     std::vector<std::unique_ptr<LogEvent>> events;
520 
521     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
522 
523     // Send log events to StatsLogProcessor.
524     for (auto& event : events) {
525         processor->OnLogEvent(event.get());
526     }
527 
528     std::stringstream query;
529     query << "SELECT * FROM invalid_metric_" << dbutils::reformatMetricId(restrictedMetricId);
530     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
531                         /*policyConfig=*/{}, mockStatsQueryCallback,
532                         /*configKey=*/configId, /*configPackage=*/config_package_name,
533                         /*callingUid=*/delegate_uid);
534 
535     EXPECT_THAT(error, StartsWith("failed to query db"));
536 }
537 
TEST_F(RestrictedEventMetricE2eTest,TestEnforceTtlRemovesOldEvents)538 TEST_F(RestrictedEventMetricE2eTest, TestEnforceTtlRemovesOldEvents) {
539     int64_t currentWallTimeNs = getWallClockNs();
540     // 8 days are used here because the TTL threshold is 7 days.
541     int64_t eightDaysAgo = currentWallTimeNs - 8 * 24 * 3600 * NS_PER_SEC;
542     int64_t originalEventElapsedTime = configAddedTimeNs + 100;
543     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(atomTag, originalEventElapsedTime);
544     event1->setLogdWallClockTimestampNs(eightDaysAgo);
545 
546     // Send log events to StatsLogProcessor.
547     processor->OnLogEvent(event1.get(), originalEventElapsedTime);
548     processor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST, originalEventElapsedTime + 20 * NS_PER_SEC,
549                                getWallClockNs());
550     processor->EnforceDataTtls(currentWallTimeNs, originalEventElapsedTime + 100);
551 
552     std::stringstream query;
553     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
554     string err;
555     std::vector<int32_t> columnTypes;
556     std::vector<string> columnNames;
557     std::vector<std::vector<std::string>> rows;
558     EXPECT_TRUE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
559     ASSERT_EQ(rows.size(), 0);
560 }
561 
TEST_F(RestrictedEventMetricE2eTest,TestConfigRemovalDeletesData)562 TEST_F(RestrictedEventMetricE2eTest, TestConfigRemovalDeletesData) {
563     std::vector<std::unique_ptr<LogEvent>> events;
564 
565     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
566 
567     // Send log events to StatsLogProcessor.
568     for (auto& event : events) {
569         processor->OnLogEvent(event.get());
570     }
571     // Query to make sure data is flushed
572     std::stringstream query;
573     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
574     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
575                         /*policyConfig=*/{}, mockStatsQueryCallback,
576                         /*configKey=*/configId, /*configPackage=*/config_package_name,
577                         /*callingUid=*/delegate_uid);
578 
579     processor->OnConfigRemoved(configKey);
580 
581     string err;
582     std::vector<int32_t> columnTypes;
583     std::vector<string> columnNames;
584     std::vector<std::vector<std::string>> rows;
585     EXPECT_FALSE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
586 
587     EXPECT_THAT(err, StartsWith("unable to open database file"));
588 }
589 
TEST_F(RestrictedEventMetricE2eTest,TestConfigRemovalDeletesDataWithoutFlush)590 TEST_F(RestrictedEventMetricE2eTest, TestConfigRemovalDeletesDataWithoutFlush) {
591     std::vector<std::unique_ptr<LogEvent>> events;
592 
593     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
594 
595     // Send log events to StatsLogProcessor.
596     for (auto& event : events) {
597         processor->OnLogEvent(event.get());
598     }
599     processor->OnConfigRemoved(configKey);
600 
601     std::stringstream query;
602     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
603     string err;
604     std::vector<int32_t> columnTypes;
605     std::vector<string> columnNames;
606     std::vector<std::vector<std::string>> rows;
607     EXPECT_FALSE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
608 
609     EXPECT_THAT(err, StartsWith("unable to open database file"));
610 }
611 
TEST_F(RestrictedEventMetricE2eTest,TestConfigUpdateRestrictedDelegateCleared)612 TEST_F(RestrictedEventMetricE2eTest, TestConfigUpdateRestrictedDelegateCleared) {
613     std::vector<std::unique_ptr<LogEvent>> events;
614     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
615 
616     // Send log events to StatsLogProcessor.
617     for (auto& event : events) {
618         processor->OnLogEvent(event.get());
619     }
620 
621     // Update the existing config with no delegate
622     config.clear_restricted_metrics_delegate_package_name();
623     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, configKey, config);
624 
625     std::stringstream query;
626     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
627     string err;
628     std::vector<int32_t> columnTypes;
629     std::vector<string> columnNames;
630     std::vector<std::vector<std::string>> rows;
631     EXPECT_FALSE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
632     EXPECT_EQ(rows.size(), 0);
633     EXPECT_THAT(err, StartsWith("unable to open database file"));
634     dbutils::deleteDb(configKey);
635 }
636 
TEST_F(RestrictedEventMetricE2eTest,TestNonModularConfigUpdateRestrictedDelegate)637 TEST_F(RestrictedEventMetricE2eTest, TestNonModularConfigUpdateRestrictedDelegate) {
638     std::vector<std::unique_ptr<LogEvent>> events;
639     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
640 
641     // Send log events to StatsLogProcessor.
642     for (auto& event : events) {
643         processor->OnLogEvent(event.get());
644     }
645 
646     // Update the existing config without modular update
647     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, configKey, config, false);
648 
649     std::stringstream query;
650     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
651     string err;
652     std::vector<int32_t> columnTypes;
653     std::vector<string> columnNames;
654     std::vector<std::vector<std::string>> rows;
655     EXPECT_FALSE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
656     EXPECT_EQ(rows.size(), 0);
657     EXPECT_THAT(err, StartsWith("no such table"));
658     dbutils::deleteDb(configKey);
659 }
660 
TEST_F(RestrictedEventMetricE2eTest,TestModularConfigUpdateNewRestrictedDelegate)661 TEST_F(RestrictedEventMetricE2eTest, TestModularConfigUpdateNewRestrictedDelegate) {
662     config.clear_restricted_metrics_delegate_package_name();
663     // Update the existing config without a restricted delegate
664     processor->OnConfigUpdated(configAddedTimeNs + 10, configKey, config);
665 
666     // Update the existing config with a new restricted delegate
667     config.set_restricted_metrics_delegate_package_name("new.delegate.package");
668     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, configKey, config);
669 
670     std::vector<std::unique_ptr<LogEvent>> events;
671     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 2 * NS_PER_SEC));
672 
673     // Send log events to StatsLogProcessor.
674     for (auto& event : events) {
675         processor->OnLogEvent(event.get());
676     }
677 
678     uint64_t dumpTimeNs = configAddedTimeNs + 100 * NS_PER_SEC;
679     ConfigMetricsReportList reports;
680     vector<uint8_t> buffer;
681     processor->onDumpReport(configKey, dumpTimeNs, true, true, ADB_DUMP, FAST, &buffer);
682     EXPECT_TRUE(reports.ParseFromArray(&buffer[0], buffer.size()));
683     ASSERT_EQ(reports.reports_size(), 0);
684 
685     //  Assert the config update was not modular and a RestrictedEventMetricProducer was created.
686     std::stringstream query;
687     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
688     string err;
689     std::vector<int32_t> columnTypes;
690     std::vector<string> columnNames;
691     std::vector<std::vector<std::string>> rows;
692     EXPECT_TRUE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
693     EXPECT_EQ(rows.size(), 1);
694     EXPECT_THAT(rows[0],
695                 ElementsAre(to_string(atomTag), to_string(configAddedTimeNs + 2 * NS_PER_SEC),
696                             _,  // wallClockNs
697                             _   // field_1
698                             ));
699     EXPECT_THAT(columnNames,
700                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
701     EXPECT_THAT(columnTypes,
702                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
703 }
704 
TEST_F(RestrictedEventMetricE2eTest,TestModularConfigUpdateChangeRestrictedDelegate)705 TEST_F(RestrictedEventMetricE2eTest, TestModularConfigUpdateChangeRestrictedDelegate) {
706     std::vector<std::unique_ptr<LogEvent>> events;
707     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
708 
709     // Send log events to StatsLogProcessor.
710     for (auto& event : events) {
711         processor->OnLogEvent(event.get());
712     }
713 
714     // Update the existing config with a new restricted delegate
715     int32_t newDelegateUid = delegate_uid + 1;
716     config.set_restricted_metrics_delegate_package_name("new.delegate.package");
717     uidMap->updateApp(configAddedTimeNs, String16("new.delegate.package"),
718                       /*uid=*/newDelegateUid, /*versionCode=*/1,
719                       /*versionString=*/String16("v2"),
720                       /*installer=*/String16(""), /*certificateHash=*/{});
721     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, configKey, config);
722 
723     std::stringstream query;
724     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
725     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
726                         /*policyConfig=*/{}, mockStatsQueryCallback,
727                         /*configKey=*/configId, /*configPackage=*/config_package_name,
728                         /*callingUid=*/newDelegateUid);
729 
730     EXPECT_EQ(rowCountResult, 1);
731     EXPECT_THAT(queryDataResult, ElementsAre(to_string(atomTag), to_string(configAddedTimeNs + 100),
732                                              _,  // wallClockNs
733                                              _   // field_1
734                                              ));
735     EXPECT_THAT(columnNamesResult,
736                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
737     EXPECT_THAT(columnTypesResult,
738                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
739 }
740 
TEST_F(RestrictedEventMetricE2eTest,TestInvalidConfigUpdateRestrictedDelegate)741 TEST_F(RestrictedEventMetricE2eTest, TestInvalidConfigUpdateRestrictedDelegate) {
742     std::vector<std::unique_ptr<LogEvent>> events;
743     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
744 
745     // Send log events to StatsLogProcessor.
746     for (auto& event : events) {
747         processor->OnLogEvent(event.get());
748     }
749 
750     EventMetric metricWithoutMatcher = createEventMetric("metricWithoutMatcher", 999999, nullopt);
751     *config.add_event_metric() = metricWithoutMatcher;
752     // Update the existing config with an invalid config update
753     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, configKey, config);
754 
755     std::stringstream query;
756     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
757     string err;
758     std::vector<int32_t> columnTypes;
759     std::vector<string> columnNames;
760     std::vector<std::vector<std::string>> rows;
761     EXPECT_FALSE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
762     EXPECT_EQ(rows.size(), 0);
763     EXPECT_THAT(err, StartsWith("unable to open database file"));
764 }
765 
TEST_F(RestrictedEventMetricE2eTest,TestRestrictedConfigUpdateDoesNotUpdateUidMap)766 TEST_F(RestrictedEventMetricE2eTest, TestRestrictedConfigUpdateDoesNotUpdateUidMap) {
767     auto& configKeyMap = processor->getUidMap()->mLastUpdatePerConfigKey;
768     EXPECT_EQ(configKeyMap.find(configKey), configKeyMap.end());
769 }
770 
TEST_F(RestrictedEventMetricE2eTest,TestRestrictedConfigUpdateAddsDelegateRemovesUidMapEntry)771 TEST_F(RestrictedEventMetricE2eTest, TestRestrictedConfigUpdateAddsDelegateRemovesUidMapEntry) {
772     auto& configKeyMap = processor->getUidMap()->mLastUpdatePerConfigKey;
773     config.clear_restricted_metrics_delegate_package_name();
774     // Update the existing config without a restricted delegate
775     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, configKey, config);
776     EXPECT_NE(configKeyMap.find(configKey), configKeyMap.end());
777     // Update the existing config with a new restricted delegate
778     config.set_restricted_metrics_delegate_package_name(delegate_package_name.c_str());
779     processor->OnConfigUpdated(configAddedTimeNs + 1 * NS_PER_SEC, configKey, config);
780     EXPECT_EQ(configKeyMap.find(configKey), configKeyMap.end());
781 }
782 
TEST_F(RestrictedEventMetricE2eTest,TestLogEventsEnforceTtls)783 TEST_F(RestrictedEventMetricE2eTest, TestLogEventsEnforceTtls) {
784     int64_t currentWallTimeNs = getWallClockNs();
785     int64_t originalEventElapsedTime = configAddedTimeNs + 100;
786     // 2 hours used here because the TTL check period is 1 hour.
787     int64_t newEventElapsedTime = configAddedTimeNs + 2 * 3600 * NS_PER_SEC + 1;  // 2 hrs later
788     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(atomTag, originalEventElapsedTime);
789     event1->setLogdWallClockTimestampNs(eightDaysAgo);
790     std::unique_ptr<LogEvent> event2 =
791             CreateRestrictedLogEvent(atomTag, originalEventElapsedTime + 100);
792     event2->setLogdWallClockTimestampNs(oneDayAgo);
793     std::unique_ptr<LogEvent> event3 = CreateRestrictedLogEvent(atomTag, newEventElapsedTime);
794     event3->setLogdWallClockTimestampNs(currentWallTimeNs);
795 
796     processor->mLastTtlTime = originalEventElapsedTime;
797     // Send log events to StatsLogProcessor.
798     processor->OnLogEvent(event1.get(), originalEventElapsedTime);
799     processor->OnLogEvent(event2.get(), newEventElapsedTime);
800     processor->OnLogEvent(event3.get(), newEventElapsedTime + 100);
801     processor->flushRestrictedDataLocked(newEventElapsedTime);
802 
803     std::stringstream query;
804     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
805     string err;
806     std::vector<int32_t> columnTypes;
807     std::vector<string> columnNames;
808     std::vector<std::vector<std::string>> rows;
809     EXPECT_TRUE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
810     ASSERT_EQ(rows.size(), 2);
811     EXPECT_THAT(columnNames,
812                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
813     EXPECT_THAT(columnTypes,
814                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
815     EXPECT_THAT(rows[0], ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime + 100),
816                                      to_string(oneDayAgo), _));
817     EXPECT_THAT(rows[1], ElementsAre(to_string(atomTag), to_string(newEventElapsedTime),
818                                      to_string(currentWallTimeNs), _));
819 }
820 
TEST_F(RestrictedEventMetricE2eTest,TestLogEventsDoesNotEnforceTtls)821 TEST_F(RestrictedEventMetricE2eTest, TestLogEventsDoesNotEnforceTtls) {
822     int64_t currentWallTimeNs = getWallClockNs();
823     int64_t originalEventElapsedTime = configAddedTimeNs + 100;
824     // 30 min used here because the TTL check period is 1 hour.
825     int64_t newEventElapsedTime = configAddedTimeNs + (3600 * NS_PER_SEC) / 2;  // 30 min later
826     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(atomTag, originalEventElapsedTime);
827     event1->setLogdWallClockTimestampNs(eightDaysAgo);
828     std::unique_ptr<LogEvent> event2 = CreateRestrictedLogEvent(atomTag, newEventElapsedTime);
829     event2->setLogdWallClockTimestampNs(currentWallTimeNs);
830 
831     processor->mLastTtlTime = originalEventElapsedTime;
832     // Send log events to StatsLogProcessor.
833     processor->OnLogEvent(event1.get(), originalEventElapsedTime);
834     processor->OnLogEvent(event2.get(), newEventElapsedTime);
835     processor->flushRestrictedDataLocked(newEventElapsedTime);
836 
837     std::stringstream query;
838     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
839     string err;
840     std::vector<int32_t> columnTypes;
841     std::vector<string> columnNames;
842     std::vector<std::vector<std::string>> rows;
843     EXPECT_TRUE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
844     ASSERT_EQ(rows.size(), 2);
845     EXPECT_THAT(columnNames,
846                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
847     EXPECT_THAT(columnTypes,
848                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
849     EXPECT_THAT(rows[0], ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime),
850                                      to_string(eightDaysAgo), _));
851     EXPECT_THAT(rows[1], ElementsAre(to_string(atomTag), to_string(newEventElapsedTime),
852                                      to_string(currentWallTimeNs), _));
853 }
854 
TEST_F(RestrictedEventMetricE2eTest,TestQueryEnforceTtls)855 TEST_F(RestrictedEventMetricE2eTest, TestQueryEnforceTtls) {
856     int64_t currentWallTimeNs = getWallClockNs();
857     int64_t originalEventElapsedTime = configAddedTimeNs + 100;
858     // 30 min used here because the TTL check period is 1 hour.
859     int64_t newEventElapsedTime = configAddedTimeNs + (3600 * NS_PER_SEC) / 2;  // 30 min later
860     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(atomTag, originalEventElapsedTime);
861     event1->setLogdWallClockTimestampNs(eightDaysAgo);
862     std::unique_ptr<LogEvent> event2 = CreateRestrictedLogEvent(atomTag, newEventElapsedTime);
863     event2->setLogdWallClockTimestampNs(currentWallTimeNs);
864 
865     processor->mLastTtlTime = originalEventElapsedTime;
866     // Send log events to StatsLogProcessor.
867     processor->OnLogEvent(event1.get(), originalEventElapsedTime);
868     processor->OnLogEvent(event2.get(), newEventElapsedTime);
869 
870     std::stringstream query;
871     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
872     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
873                         /*policyConfig=*/{}, mockStatsQueryCallback,
874                         /*configKey=*/configId, /*configPackage=*/config_package_name,
875                         /*callingUid=*/delegate_uid);
876 
877     EXPECT_EQ(rowCountResult, 1);
878     EXPECT_THAT(queryDataResult, ElementsAre(to_string(atomTag), to_string(newEventElapsedTime),
879                                              to_string(currentWallTimeNs),
880                                              _  // field_1
881                                              ));
882     EXPECT_THAT(columnNamesResult,
883                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
884     EXPECT_THAT(columnTypesResult,
885                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
886 }
887 
TEST_F(RestrictedEventMetricE2eTest,TestNotFlushed)888 TEST_F(RestrictedEventMetricE2eTest, TestNotFlushed) {
889     std::vector<std::unique_ptr<LogEvent>> events;
890     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
891     // Send log events to StatsLogProcessor.
892     for (auto& event : events) {
893         processor->OnLogEvent(event.get(), event->GetElapsedTimestampNs());
894     }
895     std::stringstream query;
896     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
897     string err;
898     std::vector<int32_t> columnTypes;
899     std::vector<string> columnNames;
900     std::vector<std::vector<std::string>> rows;
901     EXPECT_FALSE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
902     EXPECT_EQ(rows.size(), 0);
903 }
904 
TEST_F(RestrictedEventMetricE2eTest,TestEnforceDbGuardrails)905 TEST_F(RestrictedEventMetricE2eTest, TestEnforceDbGuardrails) {
906     int64_t currentWallTimeNs = getWallClockNs();
907     int64_t originalEventElapsedTime =
908             configAddedTimeNs + (3600 * NS_PER_SEC) * 2;  // 2 hours after boot
909     // 2 hours used here because the TTL check period is 1 hour.
910     int64_t dbEnforcementTimeNs =
911             configAddedTimeNs + (3600 * NS_PER_SEC) * 4;  // 4 hours after boot
912     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(atomTag, originalEventElapsedTime);
913     event1->setLogdWallClockTimestampNs(currentWallTimeNs);
914     // Send log events to StatsLogProcessor.
915     processor->OnLogEvent(event1.get(), originalEventElapsedTime);
916 
917     EXPECT_TRUE(StorageManager::hasFile(
918             base::StringPrintf("%s/%s", STATS_RESTRICTED_DATA_DIR, "123_12345.db").c_str()));
919     std::stringstream query;
920     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
921     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
922                         /*policyConfig=*/{}, mockStatsQueryCallback,
923                         /*configKey=*/configId, /*configPackage=*/config_package_name,
924                         /*callingUid=*/delegate_uid);
925     EXPECT_EQ(rowCountResult, 1);
926     EXPECT_THAT(queryDataResult,
927                 ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime),
928                             to_string(currentWallTimeNs),
929                             _  // field_1
930                             ));
931     EXPECT_THAT(columnNamesResult,
932                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
933     EXPECT_THAT(columnTypesResult,
934                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
935 
936     processor->enforceDbGuardrailsIfNecessaryLocked(oneMonthLater, dbEnforcementTimeNs);
937 
938     EXPECT_FALSE(StorageManager::hasFile(
939             base::StringPrintf("%s/%s", STATS_RESTRICTED_DATA_DIR, "123_12345.db").c_str()));
940 }
941 
TEST_F(RestrictedEventMetricE2eTest,TestEnforceDbGuardrailsDoesNotDeleteBeforeGuardrail)942 TEST_F(RestrictedEventMetricE2eTest, TestEnforceDbGuardrailsDoesNotDeleteBeforeGuardrail) {
943     int64_t currentWallTimeNs = getWallClockNs();
944     int64_t originalEventElapsedTime =
945             configAddedTimeNs + (3600 * NS_PER_SEC) * 2;  // 2 hours after boot
946     // 2 hours used here because the TTL check period is 1 hour.
947     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(atomTag, originalEventElapsedTime);
948     event1->setLogdWallClockTimestampNs(currentWallTimeNs);
949     // Send log events to StatsLogProcessor.
950     processor->OnLogEvent(event1.get(), originalEventElapsedTime);
951 
952     EXPECT_TRUE(StorageManager::hasFile(
953             base::StringPrintf("%s/%s", STATS_RESTRICTED_DATA_DIR, "123_12345.db").c_str()));
954     std::stringstream query;
955     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
956     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
957                         /*policyConfig=*/{}, mockStatsQueryCallback,
958                         /*configKey=*/configId, /*configPackage=*/config_package_name,
959                         /*callingUid=*/delegate_uid);
960     EXPECT_EQ(rowCountResult, 1);
961     EXPECT_THAT(queryDataResult,
962                 ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime),
963                             to_string(currentWallTimeNs),
964                             _  // field_1
965                             ));
966     EXPECT_THAT(columnNamesResult,
967                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
968     EXPECT_THAT(columnTypesResult,
969                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
970 
971     processor->enforceDbGuardrailsIfNecessaryLocked(oneMonthLater, originalEventElapsedTime);
972 
973     EXPECT_TRUE(StorageManager::hasFile(
974             base::StringPrintf("%s/%s", STATS_RESTRICTED_DATA_DIR, "123_12345.db").c_str()));
975 }
976 
TEST_F(RestrictedEventMetricE2eTest,TestFlushInWriteDataToDisk)977 TEST_F(RestrictedEventMetricE2eTest, TestFlushInWriteDataToDisk) {
978     std::vector<std::unique_ptr<LogEvent>> events;
979     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
980     // Send log events to StatsLogProcessor.
981     for (auto& event : events) {
982         processor->OnLogEvent(event.get(), event->GetElapsedTimestampNs());
983     }
984 
985     // Call WriteDataToDisk after 20 second because cooldown period is 15 second.
986     processor->WriteDataToDisk(DEVICE_SHUTDOWN, FAST, 20 * NS_PER_SEC, getWallClockNs());
987 
988     std::stringstream query;
989     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
990     string err;
991     std::vector<int32_t> columnTypes;
992     std::vector<string> columnNames;
993     std::vector<std::vector<std::string>> rows;
994     EXPECT_TRUE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
995     EXPECT_EQ(rows.size(), 1);
996 }
997 
TEST_F(RestrictedEventMetricE2eTest,TestFlushPeriodically)998 TEST_F(RestrictedEventMetricE2eTest, TestFlushPeriodically) {
999     std::vector<std::unique_ptr<LogEvent>> events;
1000 
1001     events.push_back(CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100));
1002     events.push_back(CreateRestrictedLogEvent(
1003             atomTag, configAddedTimeNs + StatsdStats::kMinFlushRestrictedPeriodNs + 1));
1004 
1005     // Send log events to StatsLogProcessor.
1006     for (auto& event : events) {
1007         processor->OnLogEvent(event.get(), event->GetElapsedTimestampNs());
1008     }
1009 
1010     std::stringstream query;
1011     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
1012     string err;
1013     std::vector<int32_t> columnTypes;
1014     std::vector<string> columnNames;
1015     std::vector<std::vector<std::string>> rows;
1016     EXPECT_TRUE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
1017     // Only first event is flushed when second event is logged.
1018     EXPECT_EQ(rows.size(), 1);
1019 }
1020 
TEST_F(RestrictedEventMetricE2eTest,TestOnLogEventMalformedDbNameDeleted)1021 TEST_F(RestrictedEventMetricE2eTest, TestOnLogEventMalformedDbNameDeleted) {
1022     vector<string> emptyData;
1023     string fileName = StringPrintf("%s/malformedname.db", STATS_RESTRICTED_DATA_DIR);
1024     StorageManager::writeFile(fileName.c_str(), emptyData.data(), emptyData.size());
1025     EXPECT_TRUE(StorageManager::hasFile(fileName.c_str()));
1026     int64_t originalEventElapsedTime = configAddedTimeNs + 100;
1027     // 2 hours used here because the TTL check period is 1 hour.
1028     int64_t newEventElapsedTime = configAddedTimeNs + 2 * 3600 * NS_PER_SEC + 1;  // 2 hrs later
1029     std::unique_ptr<LogEvent> event2 = CreateRestrictedLogEvent(atomTag, newEventElapsedTime);
1030     event2->setLogdWallClockTimestampNs(getWallClockNs());
1031 
1032     processor->mLastTtlTime = originalEventElapsedTime;
1033     // Send log events to StatsLogProcessor.
1034     processor->OnLogEvent(event2.get(), newEventElapsedTime);
1035 
1036     EXPECT_FALSE(StorageManager::hasFile(fileName.c_str()));
1037     StorageManager::deleteFile(fileName.c_str());
1038 }
1039 
TEST_F(RestrictedEventMetricE2eTest,TestRestrictedMetricSavesTtlToDisk)1040 TEST_F(RestrictedEventMetricE2eTest, TestRestrictedMetricSavesTtlToDisk) {
1041     metadata::StatsMetadataList result;
1042     processor->WriteMetadataToProto(getWallClockNs(), configAddedTimeNs, &result);
1043 
1044     ASSERT_EQ(result.stats_metadata_size(), 1);
1045     metadata::StatsMetadata statsMetadata = result.stats_metadata(0);
1046     EXPECT_EQ(statsMetadata.config_key().config_id(), configId);
1047     EXPECT_EQ(statsMetadata.config_key().uid(), config_app_uid);
1048 
1049     ASSERT_EQ(statsMetadata.metric_metadata_size(), 1);
1050     metadata::MetricMetadata metricMetadata = statsMetadata.metric_metadata(0);
1051     EXPECT_EQ(metricMetadata.metric_id(), restrictedMetricId);
1052     EXPECT_EQ(metricMetadata.restricted_category(), CATEGORY_UNKNOWN);
1053     result.Clear();
1054 
1055     std::unique_ptr<LogEvent> event = CreateRestrictedLogEvent(atomTag, configAddedTimeNs + 100);
1056     processor->OnLogEvent(event.get());
1057     processor->WriteMetadataToProto(getWallClockNs(), configAddedTimeNs, &result);
1058 
1059     ASSERT_EQ(result.stats_metadata_size(), 1);
1060     statsMetadata = result.stats_metadata(0);
1061     EXPECT_EQ(statsMetadata.config_key().config_id(), configId);
1062     EXPECT_EQ(statsMetadata.config_key().uid(), config_app_uid);
1063 
1064     ASSERT_EQ(statsMetadata.metric_metadata_size(), 1);
1065     metricMetadata = statsMetadata.metric_metadata(0);
1066     EXPECT_EQ(metricMetadata.metric_id(), restrictedMetricId);
1067     EXPECT_EQ(metricMetadata.restricted_category(), CATEGORY_DIAGNOSTIC);
1068 }
1069 
TEST_F(RestrictedEventMetricE2eTest,TestRestrictedMetricLoadsTtlFromDisk)1070 TEST_F(RestrictedEventMetricE2eTest, TestRestrictedMetricLoadsTtlFromDisk) {
1071     int64_t currentWallTimeNs = getWallClockNs();
1072     int64_t originalEventElapsedTime = configAddedTimeNs + 100;
1073     std::unique_ptr<LogEvent> event1 = CreateRestrictedLogEvent(atomTag, originalEventElapsedTime);
1074     event1->setLogdWallClockTimestampNs(eightDaysAgo);
1075     processor->OnLogEvent(event1.get(), originalEventElapsedTime);
1076     processor->flushRestrictedDataLocked(originalEventElapsedTime);
1077     int64_t wallClockNs = 1584991200 * NS_PER_SEC;  // random time
1078     int64_t metadataWriteTime = originalEventElapsedTime + 5000 * NS_PER_SEC;
1079     processor->SaveMetadataToDisk(wallClockNs, metadataWriteTime);
1080 
1081     std::stringstream query;
1082     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
1083     string err;
1084     std::vector<int32_t> columnTypes;
1085     std::vector<string> columnNames;
1086     std::vector<std::vector<std::string>> rows;
1087     EXPECT_TRUE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
1088     ASSERT_EQ(rows.size(), 1);
1089     EXPECT_THAT(columnNames,
1090                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
1091     EXPECT_THAT(columnTypes,
1092                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
1093     EXPECT_THAT(rows[0], ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime),
1094                                      to_string(eightDaysAgo), _));
1095 
1096     auto processor2 =
1097             CreateStatsLogProcessor(/*baseTimeNs=*/0, configAddedTimeNs, config, configKey,
1098                                     /*puller=*/nullptr, /*atomTag=*/0, uidMap);
1099     // 2 hours used here because the TTL check period is 1 hour.
1100     int64_t newEventElapsedTime = configAddedTimeNs + 2 * 3600 * NS_PER_SEC + 1;  // 2 hrs later
1101     processor2->LoadMetadataFromDisk(wallClockNs, newEventElapsedTime);
1102 
1103     // Log another event and check that the original TTL is maintained across reboot
1104     std::unique_ptr<LogEvent> event2 = CreateRestrictedLogEvent(atomTag, newEventElapsedTime);
1105     event2->setLogdWallClockTimestampNs(currentWallTimeNs);
1106     processor2->OnLogEvent(event2.get(), newEventElapsedTime);
1107     processor2->flushRestrictedDataLocked(newEventElapsedTime);
1108 
1109     columnTypes.clear();
1110     columnNames.clear();
1111     rows.clear();
1112     EXPECT_TRUE(dbutils::query(configKey, query.str(), rows, columnTypes, columnNames, err));
1113     ASSERT_EQ(rows.size(), 1);
1114     EXPECT_THAT(columnNames,
1115                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
1116     EXPECT_THAT(columnTypes,
1117                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
1118     EXPECT_THAT(rows[0], ElementsAre(to_string(atomTag), to_string(newEventElapsedTime),
1119                                      to_string(currentWallTimeNs), _));
1120 }
1121 
TEST_F(RestrictedEventMetricE2eTest,TestNewRestrictionCategoryEventDeletesTable)1122 TEST_F(RestrictedEventMetricE2eTest, TestNewRestrictionCategoryEventDeletesTable) {
1123     int64_t currentWallTimeNs = getWallClockNs();
1124     int64_t originalEventElapsedTime = configAddedTimeNs + 100;
1125     std::unique_ptr<LogEvent> event1 =
1126             CreateNonRestrictedLogEvent(atomTag, originalEventElapsedTime);
1127     processor->OnLogEvent(event1.get());
1128 
1129     std::stringstream query;
1130     query << "SELECT * FROM metric_" << dbutils::reformatMetricId(restrictedMetricId);
1131     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
1132                         /*policyConfig=*/{}, mockStatsQueryCallback,
1133                         /*configKey=*/configId, /*configPackage=*/config_package_name,
1134                         /*callingUid=*/delegate_uid);
1135     EXPECT_EQ(rowCountResult, 1);
1136     EXPECT_THAT(queryDataResult,
1137                 ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime),
1138                             _,  // wallTimestampNs
1139                             _   // field_1
1140                             ));
1141     EXPECT_THAT(columnNamesResult,
1142                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
1143     EXPECT_THAT(columnTypesResult,
1144                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
1145 
1146     // Log a second event that will go into the cache
1147     std::unique_ptr<LogEvent> event2 =
1148             CreateNonRestrictedLogEvent(atomTag, originalEventElapsedTime + 100);
1149     processor->OnLogEvent(event2.get());
1150 
1151     // Log a third event with a different category
1152     std::unique_ptr<LogEvent> event3 =
1153             CreateRestrictedLogEvent(atomTag, originalEventElapsedTime + 200);
1154     processor->OnLogEvent(event3.get());
1155 
1156     processor->querySql(query.str(), /*minSqlClientVersion=*/0,
1157                         /*policyConfig=*/{}, mockStatsQueryCallback,
1158                         /*configKey=*/configId, /*configPackage=*/config_package_name,
1159                         /*callingUid=*/delegate_uid);
1160     EXPECT_EQ(rowCountResult, 1);
1161     EXPECT_THAT(queryDataResult,
1162                 ElementsAre(to_string(atomTag), to_string(originalEventElapsedTime + 200),
1163                             _,  // wallTimestampNs
1164                             _   // field_1
1165                             ));
1166     EXPECT_THAT(columnNamesResult,
1167                 ElementsAre("atomId", "elapsedTimestampNs", "wallTimestampNs", "field_1"));
1168     EXPECT_THAT(columnTypesResult,
1169                 ElementsAre(SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER, SQLITE_INTEGER));
1170 }
1171 
TEST_F(RestrictedEventMetricE2eTest,TestDeviceInfoTableCreated)1172 TEST_F(RestrictedEventMetricE2eTest, TestDeviceInfoTableCreated) {
1173     std::string query = "SELECT * FROM device_info";
1174     processor->querySql(query.c_str(), /*minSqlClientVersion=*/0,
1175                         /*policyConfig=*/{}, mockStatsQueryCallback,
1176                         /*configKey=*/configId, /*configPackage=*/config_package_name,
1177                         /*callingUid=*/delegate_uid);
1178     EXPECT_EQ(rowCountResult, 1);
1179     EXPECT_THAT(queryDataResult, ElementsAre(_, _, _, _, _, _, _, _, _, _));
1180     EXPECT_THAT(columnNamesResult,
1181                 ElementsAre("sdkVersion", "model", "product", "hardware", "device", "osBuild",
1182                             "fingerprint", "brand", "manufacturer", "board"));
1183     EXPECT_THAT(columnTypesResult,
1184                 ElementsAre(SQLITE_INTEGER, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT,
1185                             SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT, SQLITE_TEXT));
1186 }
1187 #else
1188 GTEST_LOG_(INFO) << "This test does nothing.\n";
1189 #endif
1190 
1191 }  // namespace statsd
1192 }  // namespace os
1193 }  // namespace android
1194