blob: 7458cbf9e9a1678596562190c7aa275f78197cc1 [file] [log] [blame]
Yangster-mac20877162017-12-22 17:19:39 -08001// Copyright (C) 2017 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
Yao Chen8c433862018-10-24 14:09:20 -070015#include "src/logd/LogEvent.h"
Yangster-mac20877162017-12-22 17:19:39 -080016#include <gtest/gtest.h>
17#include <log/log_event_list.h>
Yao Chen8c433862018-10-24 14:09:20 -070018#include "frameworks/base/cmds/statsd/src/atoms.pb.h"
19#include "frameworks/base/core/proto/android/stats/launcher/launcher.pb.h"
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080020#include <stats_event.h>
21
Yangster-mac20877162017-12-22 17:19:39 -080022
23#ifdef __ANDROID__
24
25namespace android {
26namespace os {
27namespace statsd {
28
Yao Chen8c433862018-10-24 14:09:20 -070029using std::string;
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080030using std::vector;
Yao Chen8c433862018-10-24 14:09:20 -070031using util::ProtoOutputStream;
Joe Onorato99598ee2019-02-11 15:55:13 +000032using util::ProtoReader;
Yao Chen8c433862018-10-24 14:09:20 -070033
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080034Field getField(int32_t tag, const vector<int32_t>& pos, int32_t depth, const vector<bool>& last) {
35 Field f(tag, (int32_t*)pos.data(), depth);
36
37 // For loop starts at 1 because the last field at depth 0 is not decorated.
38 for (int i = 1; i < depth; i++) {
39 if (last[i]) f.decorateLastPos(i);
40 }
41
42 return f;
43}
44
45TEST(LogEventTest, TestPrimitiveParsing) {
Tej Singhb26d0442020-01-31 16:18:21 -080046 AStatsEvent* event = AStatsEvent_obtain();
47 AStatsEvent_setAtomId(event, 100);
48 AStatsEvent_writeInt32(event, 10);
49 AStatsEvent_writeInt64(event, 0x123456789);
50 AStatsEvent_writeFloat(event, 2.0);
51 AStatsEvent_writeBool(event, true);
52 AStatsEvent_build(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080053
54 size_t size;
Tej Singhb26d0442020-01-31 16:18:21 -080055 uint8_t* buf = AStatsEvent_getBuffer(event, &size);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080056
Ruchir Rastogidfd63d42020-02-20 17:54:13 -080057 LogEvent logEvent(/*uid=*/1000, /*pid=*/1001);
58 EXPECT_TRUE(logEvent.parseBuffer(buf, size));
59
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080060 EXPECT_EQ(100, logEvent.GetTagId());
Ruchir Rastogiab71ef02020-01-30 01:24:50 -080061 EXPECT_EQ(1000, logEvent.GetUid());
62 EXPECT_EQ(1001, logEvent.GetPid());
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080063
64 const vector<FieldValue>& values = logEvent.getValues();
65 EXPECT_EQ(4, values.size());
66
67 const FieldValue& int32Item = values[0];
68 Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
69 EXPECT_EQ(expectedField, int32Item.mField);
70 EXPECT_EQ(Type::INT, int32Item.mValue.getType());
71 EXPECT_EQ(10, int32Item.mValue.int_value);
72
73 const FieldValue& int64Item = values[1];
74 expectedField = getField(100, {2, 1, 1}, 0, {false, false, false});
75 EXPECT_EQ(expectedField, int64Item.mField);
76 EXPECT_EQ(Type::LONG, int64Item.mValue.getType());
77 EXPECT_EQ(0x123456789, int64Item.mValue.long_value);
78
79 const FieldValue& floatItem = values[2];
80 expectedField = getField(100, {3, 1, 1}, 0, {false, false, false});
81 EXPECT_EQ(expectedField, floatItem.mField);
82 EXPECT_EQ(Type::FLOAT, floatItem.mValue.getType());
83 EXPECT_EQ(2.0, floatItem.mValue.float_value);
84
85 const FieldValue& boolItem = values[3];
86 expectedField = getField(100, {4, 1, 1}, 0, {true, false, false});
87 EXPECT_EQ(expectedField, boolItem.mField);
88 EXPECT_EQ(Type::INT, boolItem.mValue.getType()); // FieldValue does not support boolean type
89 EXPECT_EQ(1, boolItem.mValue.int_value);
90
Tej Singhb26d0442020-01-31 16:18:21 -080091 AStatsEvent_release(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080092}
93
94
95TEST(LogEventTest, TestStringAndByteArrayParsing) {
Tej Singhb26d0442020-01-31 16:18:21 -080096 AStatsEvent* event = AStatsEvent_obtain();
97 AStatsEvent_setAtomId(event, 100);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -080098 string str = "test";
Tej Singhb26d0442020-01-31 16:18:21 -080099 AStatsEvent_writeString(event, str.c_str());
100 AStatsEvent_writeByteArray(event, (uint8_t*)str.c_str(), str.length());
101 AStatsEvent_build(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800102
103 size_t size;
Tej Singhb26d0442020-01-31 16:18:21 -0800104 uint8_t* buf = AStatsEvent_getBuffer(event, &size);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800105
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800106 LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001);
107 EXPECT_TRUE(logEvent.parseBuffer(buf, size));
108
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800109 EXPECT_EQ(100, logEvent.GetTagId());
Ruchir Rastogiab71ef02020-01-30 01:24:50 -0800110 EXPECT_EQ(1000, logEvent.GetUid());
111 EXPECT_EQ(1001, logEvent.GetPid());
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800112
113 const vector<FieldValue>& values = logEvent.getValues();
114 EXPECT_EQ(2, values.size());
115
116 const FieldValue& stringItem = values[0];
117 Field expectedField = getField(100, {1, 1, 1}, 0, {false, false, false});
118 EXPECT_EQ(expectedField, stringItem.mField);
119 EXPECT_EQ(Type::STRING, stringItem.mValue.getType());
120 EXPECT_EQ(str, stringItem.mValue.str_value);
121
122 const FieldValue& storageItem = values[1];
123 expectedField = getField(100, {2, 1, 1}, 0, {true, false, false});
124 EXPECT_EQ(expectedField, storageItem.mField);
125 EXPECT_EQ(Type::STORAGE, storageItem.mValue.getType());
126 vector<uint8_t> expectedValue = {'t', 'e', 's', 't'};
127 EXPECT_EQ(expectedValue, storageItem.mValue.storage_value);
128
Tej Singhb26d0442020-01-31 16:18:21 -0800129 AStatsEvent_release(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800130}
131
132TEST(LogEventTest, TestEmptyString) {
Tej Singhb26d0442020-01-31 16:18:21 -0800133 AStatsEvent* event = AStatsEvent_obtain();
134 AStatsEvent_setAtomId(event, 100);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800135 string empty = "";
Tej Singhb26d0442020-01-31 16:18:21 -0800136 AStatsEvent_writeString(event, empty.c_str());
137 AStatsEvent_build(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800138
139 size_t size;
Tej Singhb26d0442020-01-31 16:18:21 -0800140 uint8_t* buf = AStatsEvent_getBuffer(event, &size);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800141
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800142 LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001);
143 EXPECT_TRUE(logEvent.parseBuffer(buf, size));
144
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800145 EXPECT_EQ(100, logEvent.GetTagId());
Ruchir Rastogiab71ef02020-01-30 01:24:50 -0800146 EXPECT_EQ(1000, logEvent.GetUid());
147 EXPECT_EQ(1001, logEvent.GetPid());
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800148
149 const vector<FieldValue>& values = logEvent.getValues();
150 EXPECT_EQ(1, values.size());
151
152 const FieldValue& item = values[0];
153 Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
154 EXPECT_EQ(expectedField, item.mField);
155 EXPECT_EQ(Type::STRING, item.mValue.getType());
156 EXPECT_EQ(empty, item.mValue.str_value);
157
Tej Singhb26d0442020-01-31 16:18:21 -0800158 AStatsEvent_release(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800159}
160
161TEST(LogEventTest, TestByteArrayWithNullCharacter) {
Tej Singhb26d0442020-01-31 16:18:21 -0800162 AStatsEvent* event = AStatsEvent_obtain();
163 AStatsEvent_setAtomId(event, 100);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800164 uint8_t message[] = {'\t', 'e', '\0', 's', 't'};
Tej Singhb26d0442020-01-31 16:18:21 -0800165 AStatsEvent_writeByteArray(event, message, 5);
166 AStatsEvent_build(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800167
168 size_t size;
Tej Singhb26d0442020-01-31 16:18:21 -0800169 uint8_t* buf = AStatsEvent_getBuffer(event, &size);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800170
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800171 LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001);
172 EXPECT_TRUE(logEvent.parseBuffer(buf, size));
173
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800174 EXPECT_EQ(100, logEvent.GetTagId());
Ruchir Rastogiab71ef02020-01-30 01:24:50 -0800175 EXPECT_EQ(1000, logEvent.GetUid());
176 EXPECT_EQ(1001, logEvent.GetPid());
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800177
178 const vector<FieldValue>& values = logEvent.getValues();
179 EXPECT_EQ(1, values.size());
180
181 const FieldValue& item = values[0];
182 Field expectedField = getField(100, {1, 1, 1}, 0, {true, false, false});
183 EXPECT_EQ(expectedField, item.mField);
184 EXPECT_EQ(Type::STORAGE, item.mValue.getType());
185 vector<uint8_t> expectedValue(message, message + 5);
186 EXPECT_EQ(expectedValue, item.mValue.storage_value);
187
Tej Singhb26d0442020-01-31 16:18:21 -0800188 AStatsEvent_release(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800189}
190
191TEST(LogEventTest, TestAttributionChain) {
Tej Singhb26d0442020-01-31 16:18:21 -0800192 AStatsEvent* event = AStatsEvent_obtain();
193 AStatsEvent_setAtomId(event, 100);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800194
195 string tag1 = "tag1";
196 string tag2 = "tag2";
197
198 uint32_t uids[] = {1001, 1002};
199 const char* tags[] = {tag1.c_str(), tag2.c_str()};
200
Tej Singhb26d0442020-01-31 16:18:21 -0800201 AStatsEvent_writeAttributionChain(event, uids, tags, 2);
202 AStatsEvent_build(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800203
204 size_t size;
Tej Singhb26d0442020-01-31 16:18:21 -0800205 uint8_t* buf = AStatsEvent_getBuffer(event, &size);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800206
Ruchir Rastogidfd63d42020-02-20 17:54:13 -0800207 LogEvent logEvent(/*uid=*/ 1000, /*pid=*/ 1001);
208 EXPECT_TRUE(logEvent.parseBuffer(buf, size));
209
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800210 EXPECT_EQ(100, logEvent.GetTagId());
Ruchir Rastogiab71ef02020-01-30 01:24:50 -0800211 EXPECT_EQ(1000, logEvent.GetUid());
212 EXPECT_EQ(1001, logEvent.GetPid());
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800213
214 const vector<FieldValue>& values = logEvent.getValues();
215 EXPECT_EQ(4, values.size()); // 2 per attribution node
216
217 // Check first attribution node
218 const FieldValue& uid1Item = values[0];
219 Field expectedField = getField(100, {1, 1, 1}, 2, {true, false, false});
220 EXPECT_EQ(expectedField, uid1Item.mField);
221 EXPECT_EQ(Type::INT, uid1Item.mValue.getType());
222 EXPECT_EQ(1001, uid1Item.mValue.int_value);
223
224 const FieldValue& tag1Item = values[1];
225 expectedField = getField(100, {1, 1, 2}, 2, {true, false, true});
226 EXPECT_EQ(expectedField, tag1Item.mField);
227 EXPECT_EQ(Type::STRING, tag1Item.mValue.getType());
228 EXPECT_EQ(tag1, tag1Item.mValue.str_value);
229
230 // Check second attribution nodes
231 const FieldValue& uid2Item = values[2];
232 expectedField = getField(100, {1, 2, 1}, 2, {true, true, false});
233 EXPECT_EQ(expectedField, uid2Item.mField);
234 EXPECT_EQ(Type::INT, uid2Item.mValue.getType());
235 EXPECT_EQ(1002, uid2Item.mValue.int_value);
236
237 const FieldValue& tag2Item = values[3];
238 expectedField = getField(100, {1, 2, 2}, 2, {true, true, true});
239 EXPECT_EQ(expectedField, tag2Item.mField);
240 EXPECT_EQ(Type::STRING, tag2Item.mValue.getType());
241 EXPECT_EQ(tag2, tag2Item.mValue.str_value);
242
Tej Singhb26d0442020-01-31 16:18:21 -0800243 AStatsEvent_release(event);
Ruchir Rastogi1fb525e2019-11-07 14:08:24 -0800244}
245
Yangster-mac20877162017-12-22 17:19:39 -0800246} // namespace statsd
247} // namespace os
248} // namespace android
249#else
250GTEST_LOG_(INFO) << "This test does nothing.\n";
Howard Ro4078dd42018-09-27 17:41:08 -0700251#endif