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