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 <list>
18 #include <queue>
19 
20 #include "dumpsys/filter.h"
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 
25 #include "test_data/bar.h"
26 #include "test_data/baz.h"
27 #include "test_data/foo.h"
28 #include "test_data/qux.h"
29 #include "test_data/root.h"
30 
31 // TODO(cmanton) fix bundler to split header/code
32 //#include "generated_dumpsys_bundled_test_schema.h"
33 namespace testing {
34 extern const unsigned char* data;
35 extern const size_t data_size;
36 const std::string& GetBundledSchemaData();
37 }  // namespace testing
38 
39 namespace testing {
40 
41 using namespace bluetooth;
42 
43 class DumpsysFilterTest : public Test {
44  protected:
SetUp()45   void SetUp() override {
46     test_data_classes_.push_back(std::make_unique<BarTestDataClass>());
47     test_data_classes_.push_back(std::make_unique<BazTestDataClass>());
48     test_data_classes_.push_back(std::make_unique<FooTestDataClass>());
49     test_data_classes_.push_back(std::make_unique<QuxTestDataClass>());
50   }
51 
TearDown()52   void TearDown() override {}
53 
54   std::list<std::unique_ptr<DumpsysTestDataClass>> test_data_classes_;
55 
56   std::string PopulateTestSchema();
57 };
58 
PopulateTestSchema()59 std::string DumpsysFilterTest::PopulateTestSchema() {
60   flatbuffers::FlatBufferBuilder fb_builder(1024);
61 
62   auto string_private = fb_builder.CreateString("String private");
63   auto string_opaque = fb_builder.CreateString("String opaque");
64   auto string_anonymized = fb_builder.CreateString("String anonymized");
65   auto string_any = fb_builder.CreateString("String any");
66 
67   std::queue<TableAddFunction> queue;
68   for (auto& test_data_class : test_data_classes_) {
69     queue.push(test_data_class->GetTable(fb_builder));
70   }
71 
72   testing::DumpsysTestDataRootBuilder builder(fb_builder);
73 
74   builder.add_string_private(string_private);
75   builder.add_string_opaque(string_opaque);
76   builder.add_string_anonymized(string_anonymized);
77   builder.add_string_any(string_any);
78 
79   builder.add_int_private(123);
80   builder.add_int_opaque(456);
81   builder.add_int_anonymized(789);
82   builder.add_int_any(0xabc);
83 
84   while (!queue.empty()) {
85     queue.front()(&builder);
86     queue.pop();
87   }
88   fb_builder.Finish(builder.Finish());
89 
90   return std::string(fb_builder.GetBufferPointer(), fb_builder.GetBufferPointer() + fb_builder.GetSize());
91 }
92 
TEST_F(DumpsysFilterTest,filter_as_developer)93 TEST_F(DumpsysFilterTest, filter_as_developer) {
94   std::string dumpsys_data = PopulateTestSchema();
95   dumpsys::ReflectionSchema reflection_schema(testing::GetBundledSchemaData());
96 
97   dumpsys::FilterInPlace(dumpsys::FilterType::AS_DEVELOPER, reflection_schema, &dumpsys_data);
98 
99   const testing::DumpsysTestDataRoot* data_root = GetDumpsysTestDataRoot(dumpsys_data.data());
100 
101   ASSERT_TRUE(data_root->string_private()->str() == "String private");
102   ASSERT_TRUE(data_root->string_opaque()->str() == "String opaque");
103   ASSERT_TRUE(data_root->string_anonymized()->str() == "String anonymized");
104   ASSERT_TRUE(data_root->string_any()->str() == "String any");
105 
106   ASSERT_TRUE(data_root->int_private() == 123);
107   ASSERT_TRUE(data_root->int_opaque() == 456);
108   ASSERT_TRUE(data_root->int_anonymized() == 789);
109   ASSERT_TRUE(data_root->int_any() == 0xabc);
110 
111   ASSERT_EQ(nullptr, data_root->bar_module_data());
112 
113   const testing::FooTestSchema* foo = data_root->foo_module_data();
114 
115   ASSERT_EQ(123, foo->foo_int_private());
116   ASSERT_EQ(123, foo->foo_int_opaque());
117   ASSERT_EQ(123, foo->foo_int_anonymized());
118   ASSERT_EQ(123, foo->foo_int_any());
119   ASSERT_STREQ("123", foo->foo_int_string()->c_str());
120 
121   ASSERT_FLOAT_EQ(123.456, foo->foo_float_private());
122   ASSERT_FLOAT_EQ(123.456, foo->foo_float_opaque());
123   ASSERT_FLOAT_EQ(123.456, foo->foo_float_anonymized());
124   ASSERT_FLOAT_EQ(123.456, foo->foo_float_any());
125   ASSERT_STREQ("123.456", foo->foo_float_string()->c_str());
126 }
127 
TEST_F(DumpsysFilterTest,filter_as_user)128 TEST_F(DumpsysFilterTest, filter_as_user) {
129   std::string dumpsys_data = PopulateTestSchema();
130   dumpsys::ReflectionSchema reflection_schema(testing::GetBundledSchemaData());
131 
132   dumpsys::FilterInPlace(dumpsys::FilterType::AS_USER, reflection_schema, &dumpsys_data);
133 
134   [[maybe_unused]] const testing::DumpsysTestDataRoot* data_root = GetDumpsysTestDataRoot(dumpsys_data.data());
135 
136   ASSERT_TRUE(data_root->string_private() == nullptr);
137   ASSERT_TRUE(data_root->string_opaque()->str() == "*************");
138   ASSERT_TRUE(data_root->string_anonymized()->str() != "String anonymized");
139   ASSERT_TRUE(data_root->string_any()->str() == "String any");
140 
141   ASSERT_TRUE(data_root->int_private() == 0);
142   ASSERT_TRUE(data_root->int_opaque() == 0);
143   ASSERT_TRUE(data_root->int_anonymized() != 789);
144   ASSERT_TRUE(data_root->int_any() == 0xabc);
145 
146   // bar
147   ASSERT_EQ(nullptr, data_root->bar_module_data());
148 
149   // baz
150   const testing::BazTestSchema* baz = data_root->baz_module_data();
151   ASSERT_NE(nullptr, baz);
152 
153   const testing::BazSubTableAny* baz_any = baz->sub_table_any();
154   ASSERT_NE(nullptr, baz_any);
155   ASSERT_EQ(nullptr, baz->sub_table_anonymized());
156   ASSERT_EQ(nullptr, baz->sub_table_opaque());
157   ASSERT_EQ(nullptr, baz->sub_table_private());
158 
159   ASSERT_EQ(0, baz_any->subtable_int_private());     // 1
160   ASSERT_EQ(0, baz_any->subtable_int_opaque());      // 2
161   ASSERT_NE(3, baz_any->subtable_int_anonymized());  // 3
162   ASSERT_EQ(4, baz_any->subtable_int_any());         // 4
163   ASSERT_STREQ("Baz Subtable Any", baz_any->subtable_string_any()->c_str());
164 
165   // foo
166   const testing::FooTestSchema* foo = data_root->foo_module_data();
167   ASSERT_EQ(0, foo->foo_int_private());
168   ASSERT_EQ(0, foo->foo_int_opaque());
169   ASSERT_NE(123, foo->foo_int_anonymized());
170   ASSERT_EQ(123, foo->foo_int_any());
171   ASSERT_STREQ("123", foo->foo_int_string()->c_str());
172   ASSERT_FLOAT_EQ(0.0, foo->foo_float_private());
173   ASSERT_FLOAT_EQ(0.0, foo->foo_float_opaque());
174   ASSERT_THAT(foo->foo_float_anonymized(), Not(FloatEq(123.456)));
175   ASSERT_FLOAT_EQ(123.456, foo->foo_float_any());
176   ASSERT_STREQ("123.456", foo->foo_float_string()->c_str());
177 
178   // qux
179   const testing::QuxTestSchema* qux = data_root->qux_module_data();
180   ASSERT_EQ(0, qux->qux_int_private());
181   ASSERT_EQ(0, qux->qux_int_opaque());
182   ASSERT_NE(789, qux->qux_int_anonymized());
183   ASSERT_EQ(0xabc, qux->qux_int_any());
184   ASSERT_STREQ("Qux Module String", qux->qux_string_name()->c_str());
185 }
186 
187 }  // namespace testing
188