1 /*
2 * Copyright 2020 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "dumpsys/internal/filter_internal.h"
18
19 #include <gmock/gmock.h>
20 #include <gtest/gtest.h>
21
22 #include "dumpsys/internal/test_data/float_bfbs.h"
23 #include "dumpsys/internal/test_data/float_generated.h"
24 #include "dumpsys/internal/test_data/integer_bfbs.h"
25 #include "dumpsys/internal/test_data/integer_generated.h"
26 #include "dumpsys/internal/test_data/string_bfbs.h"
27 #include "dumpsys/internal/test_data/string_generated.h"
28 #include "dumpsys/internal/test_data/struct_bfbs.h"
29 #include "dumpsys/internal/test_data/struct_generated.h"
30 #include "os/log.h"
31
32 namespace testing {
33
34 class DumpsysFilterInternalTest : public Test {
35 protected:
SetUp()36 void SetUp() override {}
TearDown()37 void TearDown() override {}
38
GetMutableTable() const39 flatbuffers::Table* GetMutableTable() const {
40 return flatbuffers::GetMutableRoot<flatbuffers::Table>(fb_builder_.GetBufferPointer());
41 }
42
ParseReflectionSchema(unsigned char * bfbs,unsigned int bfbs_len)43 void ParseReflectionSchema(unsigned char* bfbs, unsigned int bfbs_len) {
44 ASSERT_TRUE(reflection_schema_.empty());
45 reflection_schema_ = std::move(std::vector<const uint8_t>(bfbs, bfbs + bfbs_len));
46 flatbuffers::Verifier verifier(reflection_schema_.data(), reflection_schema_.size());
47 ASSERT_TRUE(reflection::VerifySchemaBuffer(verifier));
48 schema_ = reflection::GetSchema(reflection_schema_.data());
49 ASSERT_TRUE(schema_ != nullptr);
50 }
51
52 const reflection::Schema* schema_{nullptr};
53 flatbuffers::FlatBufferBuilder fb_builder_ = std::move(flatbuffers::FlatBufferBuilder(1024));
54
55 private:
56 std::vector<const uint8_t> reflection_schema_;
57 };
58
59 class DumpsysFilterInternalIntegerTest : public DumpsysFilterInternalTest {
60 protected:
SetUp()61 void SetUp() override {
62 this->ParseReflectionSchema(integer_bfbs, integer_bfbs_len);
63 }
64
CreateInteger(int32_t value)65 const testing::TestTableInteger* CreateInteger(int32_t value) {
66 TestTableIntegerBuilder builder(fb_builder_);
67 builder.add_test_int(value);
68 fb_builder_.Finish(builder.Finish());
69 return GetTestTableInteger(fb_builder_.GetBufferPointer());
70 }
71 };
72
73 class DumpsysFilterInternalFloatTest : public DumpsysFilterInternalTest {
74 protected:
SetUp()75 void SetUp() override {
76 this->ParseReflectionSchema(float_bfbs, float_bfbs_len);
77 }
78
CreateFloat(double value)79 const testing::TestTableFloat* CreateFloat(double value) {
80 TestTableFloatBuilder builder(fb_builder_);
81 builder.add_test_float(value);
82 fb_builder_.Finish(builder.Finish());
83 return GetTestTableFloat(fb_builder_.GetBufferPointer());
84 }
85 };
86
87 class DumpsysFilterInternalStringTest : public DumpsysFilterInternalTest {
88 protected:
SetUp()89 void SetUp() override {
90 this->ParseReflectionSchema(string_bfbs, string_bfbs_len);
91 }
92
CreateString(std::string string)93 const testing::TestTableString* CreateString(std::string string) {
94 auto test_string = fb_builder_.CreateString(string);
95 TestTableStringBuilder builder(fb_builder_);
96 builder.add_test_string(test_string);
97 fb_builder_.Finish(builder.Finish());
98 return GetTestTableString(fb_builder_.GetBufferPointer());
99 }
100 };
101
102 class DumpsysFilterInternalStructTest : public DumpsysFilterInternalTest {
103 protected:
SetUp()104 void SetUp() override {
105 this->ParseReflectionSchema(struct_bfbs, struct_bfbs_len);
106 }
107
CreateSubTable(int val)108 flatbuffers::Offset<TestSubTable> CreateSubTable(int val) {
109 TestSubTableBuilder builder(fb_builder_);
110 builder.add_placeholder(val);
111 return builder.Finish();
112 }
113
CreateStruct(int val)114 const testing::TestTableStruct* CreateStruct(int val) {
115 auto sub_table = CreateSubTable(val);
116
117 TestTableStructBuilder builder(fb_builder_);
118 builder.add_sub_table(sub_table);
119 fb_builder_.Finish(builder.Finish());
120 return GetTestTableStruct(fb_builder_.GetBufferPointer());
121 }
122 };
123
TEST_F(DumpsysFilterInternalIntegerTest,filter_type_integer_any)124 TEST_F(DumpsysFilterInternalIntegerTest, filter_type_integer_any) {
125 const testing::TestTableInteger* test_table = CreateInteger(123);
126 ASSERT_EQ(123, test_table->test_int());
127
128 flatbuffers::Table* table = GetMutableTable();
129
130 const reflection::Object* object = schema_->root_table();
131 ASSERT_TRUE(object != nullptr);
132
133 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
134 bluetooth::dumpsys::internal::FilterTypeInteger(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAny);
135 }
136 ASSERT_EQ(123, test_table->test_int());
137 }
138
TEST_F(DumpsysFilterInternalIntegerTest,filter_type_integer_anonymized)139 TEST_F(DumpsysFilterInternalIntegerTest, filter_type_integer_anonymized) {
140 const testing::TestTableInteger* test_table = CreateInteger(123);
141 ASSERT_EQ(123, test_table->test_int());
142
143 flatbuffers::Table* table = GetMutableTable();
144
145 const reflection::Object* object = schema_->root_table();
146 ASSERT_TRUE(object != nullptr);
147
148 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
149 bluetooth::dumpsys::internal::FilterTypeInteger(
150 **it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAnonymized);
151 }
152 ASSERT_NE(123, test_table->test_int());
153 }
154
TEST_F(DumpsysFilterInternalIntegerTest,filter_type_integer_opaque)155 TEST_F(DumpsysFilterInternalIntegerTest, filter_type_integer_opaque) {
156 const testing::TestTableInteger* test_table = CreateInteger(123);
157 ASSERT_EQ(123, test_table->test_int());
158
159 flatbuffers::Table* table = GetMutableTable();
160
161 const reflection::Object* object = schema_->root_table();
162 ASSERT_TRUE(object != nullptr);
163
164 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
165 bluetooth::dumpsys::internal::FilterTypeInteger(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kOpaque);
166 }
167 ASSERT_EQ(0, test_table->test_int());
168 }
169
TEST_F(DumpsysFilterInternalIntegerTest,filter_type_integer_privacy)170 TEST_F(DumpsysFilterInternalIntegerTest, filter_type_integer_privacy) {
171 const testing::TestTableInteger* test_table = CreateInteger(123);
172 ASSERT_EQ(123, test_table->test_int());
173
174 flatbuffers::Table* table = GetMutableTable();
175
176 const reflection::Object* object = schema_->root_table();
177 ASSERT_TRUE(object != nullptr);
178
179 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
180 bluetooth::dumpsys::internal::FilterTypeInteger(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kPrivate);
181 }
182 ASSERT_EQ(0, test_table->test_int());
183 }
184
TEST_F(DumpsysFilterInternalFloatTest,filter_type_float_any)185 TEST_F(DumpsysFilterInternalFloatTest, filter_type_float_any) {
186 const testing::TestTableFloat* test_table = CreateFloat(1.23);
187 ASSERT_FLOAT_EQ(1.23, test_table->test_float());
188
189 flatbuffers::Table* table = GetMutableTable();
190
191 const reflection::Object* object = schema_->root_table();
192 ASSERT_TRUE(object != nullptr);
193
194 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
195 bluetooth::dumpsys::internal::FilterTypeFloat(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAny);
196 }
197 ASSERT_FLOAT_EQ(1.23, test_table->test_float());
198 }
199
TEST_F(DumpsysFilterInternalFloatTest,filter_type_float_anonymized)200 TEST_F(DumpsysFilterInternalFloatTest, filter_type_float_anonymized) {
201 const testing::TestTableFloat* test_table = CreateFloat(1.23);
202 ASSERT_FLOAT_EQ(1.23, test_table->test_float());
203
204 flatbuffers::Table* table = GetMutableTable();
205
206 const reflection::Object* object = schema_->root_table();
207 ASSERT_TRUE(object != nullptr);
208
209 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
210 bluetooth::dumpsys::internal::FilterTypeFloat(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAnonymized);
211 }
212 ASSERT_THAT(test_table->test_float(), Not(FloatEq(1.23)));
213 }
214
TEST_F(DumpsysFilterInternalFloatTest,filter_type_float_opaque)215 TEST_F(DumpsysFilterInternalFloatTest, filter_type_float_opaque) {
216 const testing::TestTableFloat* test_table = CreateFloat(1.23);
217 ASSERT_FLOAT_EQ(1.23, test_table->test_float());
218
219 flatbuffers::Table* table = GetMutableTable();
220
221 const reflection::Object* object = schema_->root_table();
222 ASSERT_TRUE(object != nullptr);
223
224 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
225 bluetooth::dumpsys::internal::FilterTypeFloat(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kOpaque);
226 }
227 ASSERT_FLOAT_EQ(0.0, test_table->test_float());
228 }
229
TEST_F(DumpsysFilterInternalFloatTest,filter_type_float_private)230 TEST_F(DumpsysFilterInternalFloatTest, filter_type_float_private) {
231 const testing::TestTableFloat* test_table = CreateFloat(1.23);
232 ASSERT_FLOAT_EQ(1.23, test_table->test_float());
233
234 flatbuffers::Table* table = GetMutableTable();
235
236 const reflection::Object* object = schema_->root_table();
237 ASSERT_TRUE(object != nullptr);
238
239 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
240 bluetooth::dumpsys::internal::FilterTypeFloat(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kPrivate);
241 }
242 ASSERT_FLOAT_EQ(0.0, test_table->test_float());
243 }
244
TEST_F(DumpsysFilterInternalStringTest,filter_type_string_any)245 TEST_F(DumpsysFilterInternalStringTest, filter_type_string_any) {
246 const testing::TestTableString* test_table = CreateString("This is a string");
247 ASSERT_STREQ("This is a string", test_table->test_string()->c_str());
248
249 flatbuffers::Table* table = GetMutableTable();
250
251 const reflection::Object* object = schema_->root_table();
252 ASSERT_TRUE(object != nullptr);
253
254 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
255 bluetooth::dumpsys::internal::FilterTypeString(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAny);
256 }
257 ASSERT_STREQ("This is a string", test_table->test_string()->c_str());
258 }
259
TEST_F(DumpsysFilterInternalStringTest,filter_type_string_anonymous)260 TEST_F(DumpsysFilterInternalStringTest, filter_type_string_anonymous) {
261 const testing::TestTableString* test_table = CreateString("This is a string");
262 ASSERT_STREQ("This is a string", test_table->test_string()->c_str());
263
264 flatbuffers::Table* table = GetMutableTable();
265
266 const reflection::Object* object = schema_->root_table();
267 ASSERT_TRUE(object != nullptr);
268
269 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
270 bluetooth::dumpsys::internal::FilterTypeString(
271 **it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAnonymized);
272 }
273 ASSERT_NE("This is a string", test_table->test_string()->c_str());
274 }
275
TEST_F(DumpsysFilterInternalStringTest,filter_type_string_anonymous_small)276 TEST_F(DumpsysFilterInternalStringTest, filter_type_string_anonymous_small) {
277 const testing::TestTableString* test_table = CreateString("A");
278 ASSERT_STREQ("A", test_table->test_string()->c_str());
279
280 flatbuffers::Table* table = GetMutableTable();
281
282 const reflection::Object* object = schema_->root_table();
283 ASSERT_TRUE(object != nullptr);
284
285 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
286 bluetooth::dumpsys::internal::FilterTypeString(
287 **it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAnonymized);
288 }
289 ASSERT_NE("A", test_table->test_string()->c_str());
290 }
291
TEST_F(DumpsysFilterInternalStringTest,filter_type_string_anonymous_large)292 TEST_F(DumpsysFilterInternalStringTest, filter_type_string_anonymous_large) {
293 const testing::TestTableString* test_table = CreateString("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz");
294 ASSERT_STREQ("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", test_table->test_string()->c_str());
295
296 flatbuffers::Table* table = GetMutableTable();
297
298 const reflection::Object* object = schema_->root_table();
299 ASSERT_TRUE(object != nullptr);
300
301 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
302 bluetooth::dumpsys::internal::FilterTypeString(
303 **it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAnonymized);
304 }
305 ASSERT_NE("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz", test_table->test_string()->c_str());
306 }
307
TEST_F(DumpsysFilterInternalStringTest,filter_type_string_opaque)308 TEST_F(DumpsysFilterInternalStringTest, filter_type_string_opaque) {
309 const testing::TestTableString* test_table = CreateString("This is a string");
310 ASSERT_STREQ("This is a string", test_table->test_string()->c_str());
311
312 flatbuffers::Table* table = GetMutableTable();
313
314 const reflection::Object* object = schema_->root_table();
315 ASSERT_TRUE(object != nullptr);
316
317 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
318 bluetooth::dumpsys::internal::FilterTypeString(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kOpaque);
319 }
320
321 std::string opaque_expected(strlen("This is a string"), '*');
322 ASSERT_STREQ(opaque_expected.c_str(), test_table->test_string()->c_str());
323 }
324
TEST_F(DumpsysFilterInternalStringTest,filter_type_string_private)325 TEST_F(DumpsysFilterInternalStringTest, filter_type_string_private) {
326 const testing::TestTableString* test_table = CreateString("This is a string");
327 ASSERT_STREQ("This is a string", test_table->test_string()->c_str());
328
329 flatbuffers::Table* table = GetMutableTable();
330
331 const reflection::Object* object = schema_->root_table();
332 ASSERT_TRUE(object != nullptr);
333
334 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
335 bluetooth::dumpsys::internal::FilterTypeString(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kPrivate);
336 }
337 ASSERT_EQ(nullptr, test_table->test_string());
338 }
339
TEST_F(DumpsysFilterInternalStringTest,filter_type_string_private_small)340 TEST_F(DumpsysFilterInternalStringTest, filter_type_string_private_small) {
341 const testing::TestTableString* test_table = CreateString("A");
342 ASSERT_STREQ("A", test_table->test_string()->c_str());
343
344 flatbuffers::Table* table = GetMutableTable();
345
346 const reflection::Object* object = schema_->root_table();
347 ASSERT_TRUE(object != nullptr);
348
349 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
350 bluetooth::dumpsys::internal::FilterTypeString(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kPrivate);
351 }
352 ASSERT_EQ(nullptr, test_table->test_string());
353 }
354
TEST_F(DumpsysFilterInternalStructTest,filter_type_struct_any)355 TEST_F(DumpsysFilterInternalStructTest, filter_type_struct_any) {
356 const testing::TestTableStruct* test_table = CreateStruct(456);
357 ASSERT_EQ(456, test_table->sub_table()->placeholder());
358
359 flatbuffers::Table* table = GetMutableTable();
360
361 const reflection::Object* object = schema_->root_table();
362 ASSERT_TRUE(object != nullptr);
363
364 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
365 bluetooth::dumpsys::internal::FilterTypeStruct(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAny);
366 }
367 ASSERT_EQ(456, test_table->sub_table()->placeholder());
368 }
369
TEST_F(DumpsysFilterInternalStructTest,filter_type_struct_anonymous)370 TEST_F(DumpsysFilterInternalStructTest, filter_type_struct_anonymous) {
371 const testing::TestTableStruct* test_table = CreateStruct(456);
372 ASSERT_EQ(456, test_table->sub_table()->placeholder());
373
374 flatbuffers::Table* table = GetMutableTable();
375
376 const reflection::Object* object = schema_->root_table();
377 ASSERT_TRUE(object != nullptr);
378
379 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
380 bluetooth::dumpsys::internal::FilterTypeStruct(
381 **it, table, bluetooth::dumpsys::internal::PrivacyLevel::kAnonymized);
382 }
383 ASSERT_EQ(nullptr, test_table->sub_table());
384 }
385
TEST_F(DumpsysFilterInternalStructTest,filter_type_struct_opaque)386 TEST_F(DumpsysFilterInternalStructTest, filter_type_struct_opaque) {
387 const testing::TestTableStruct* test_table = CreateStruct(456);
388 ASSERT_EQ(456, test_table->sub_table()->placeholder());
389
390 flatbuffers::Table* table = GetMutableTable();
391
392 const reflection::Object* object = schema_->root_table();
393 ASSERT_TRUE(object != nullptr);
394
395 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
396 bluetooth::dumpsys::internal::FilterTypeStruct(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kOpaque);
397 }
398 ASSERT_EQ(nullptr, test_table->sub_table());
399 }
400
TEST_F(DumpsysFilterInternalStructTest,filter_type_struct_private)401 TEST_F(DumpsysFilterInternalStructTest, filter_type_struct_private) {
402 const testing::TestTableStruct* test_table = CreateStruct(456);
403 ASSERT_EQ(456, test_table->sub_table()->placeholder());
404
405 flatbuffers::Table* table = GetMutableTable();
406
407 const reflection::Object* object = schema_->root_table();
408 ASSERT_TRUE(object != nullptr);
409
410 for (auto it = object->fields()->cbegin(); it != object->fields()->cend(); ++it) {
411 bluetooth::dumpsys::internal::FilterTypeStruct(**it, table, bluetooth::dumpsys::internal::PrivacyLevel::kPrivate);
412 }
413 ASSERT_EQ(nullptr, test_table->sub_table());
414 }
415
416 } // namespace testing
417