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