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 <gtest/gtest.h>
18 #include <sys/socket.h>
19 #include <sys/types.h>
20
21 #include <future>
22
23 #include "module.h"
24 #include "os/thread.h"
25 #include "shim/dumpsys.h"
26 #include "shim/dumpsys_args.h"
27 #include "test_data/dumpsys_test_data_bin.h"
28
29 namespace testing {
30
31 using bluetooth::TestModuleRegistry;
32 using namespace bluetooth;
33
34 namespace {
35
SimpleJsonValidator(int fd,int * dumpsys_byte_cnt)36 bool SimpleJsonValidator(int fd, int* dumpsys_byte_cnt) {
37 char buf{0};
38 bool within_double_quotes{false};
39 int left_bracket{0}, right_bracket{0};
40 while (read(fd, &buf, 1) != -1) {
41 switch (buf) {
42 (*dumpsys_byte_cnt)++;
43 case '"':
44 within_double_quotes = !within_double_quotes;
45 break;
46 case '{':
47 if (!within_double_quotes) {
48 left_bracket++;
49 }
50 break;
51 case '}':
52 if (!within_double_quotes) {
53 right_bracket++;
54 }
55 break;
56 default:
57 break;
58 }
59 }
60 return left_bracket == right_bracket;
61 }
62
63 } // namespace
64
65 // To create dumpsys_test_header_bin.h:
66 // make bluetooth_flatbuffer_bundler
67 // ${ANDROID_BUILD_TOP}/out/host/linux-x86/bin/bluetooth_flatbuffer_bundler -w -m bluetooth.DumpsysData -f
68 // test_gen/dumpsys_test_data_bin -n bluetooth::test test_gen/*
69
70 class DumpsysTest : public Test {
71 protected:
SetUp()72 void SetUp() override {
73 dumpsys_module_ = new bluetooth::shim::Dumpsys(bluetooth::test::GetBundledSchemaData());
74 fake_registry_.InjectTestModule(&shim::Dumpsys::Factory, dumpsys_module_);
75 }
76
TearDown()77 void TearDown() override {
78 fake_registry_.StopAll();
79 }
80
Print()81 void Print() {
82 dumpsys_module_->Dump(0, nullptr);
83 }
84
GetSocketBufferSize(int sockfd)85 int GetSocketBufferSize(int sockfd) {
86 int socket_buffer_size;
87 socklen_t optlen = sizeof(socket_buffer_size);
88 getsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (void*)&socket_buffer_size, &optlen);
89 return socket_buffer_size;
90 }
91
SetSocketBufferSize(int sockfd,int socket_buffer_size)92 void SetSocketBufferSize(int sockfd, int socket_buffer_size) {
93 socklen_t optlen = sizeof(socket_buffer_size);
94 ASSERT_EQ(0, setsockopt(sockfd, SOL_SOCKET, SO_RCVBUF, (const void*)&socket_buffer_size, optlen));
95 }
96
97 TestModuleRegistry fake_registry_;
98 os::Thread& thread_ = fake_registry_.GetTestThread();
99 bluetooth::shim::Dumpsys* dumpsys_module_ = nullptr;
100 os::Handler* client_handler_ = nullptr;
101 };
102
TEST_F(DumpsysTest,dump_as_developer)103 TEST_F(DumpsysTest, dump_as_developer) {
104 const char* args[]{bluetooth::shim::kArgumentDeveloper, nullptr};
105
106 int sv[2];
107 ASSERT_EQ(0, socketpair(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, sv));
108 int socket_buffer_size = GetSocketBufferSize(sv[0]);
109
110 std::promise<void> promise;
111 std::future future = promise.get_future();
112 dumpsys_module_->Dump(sv[0], args, std::move(promise));
113 future.wait();
114
115 int dumpsys_byte_cnt = 0;
116 ASSERT_TRUE(SimpleJsonValidator(sv[1], &dumpsys_byte_cnt));
117 ASSERT_TRUE(dumpsys_byte_cnt < socket_buffer_size);
118 }
119
TEST_F(DumpsysTest,dump_as_user)120 TEST_F(DumpsysTest, dump_as_user) {
121 const char* args[]{"not-a-developer-option", nullptr};
122
123 int sv[2];
124 ASSERT_EQ(0, socketpair(AF_LOCAL, SOCK_STREAM | SOCK_NONBLOCK, 0, sv));
125 int socket_buffer_size = GetSocketBufferSize(sv[0]);
126
127 std::promise<void> promise;
128 std::future future = promise.get_future();
129 dumpsys_module_->Dump(sv[0], args, std::move(promise));
130 future.wait();
131
132 int dumpsys_byte_cnt = 0;
133 ASSERT_TRUE(SimpleJsonValidator(sv[1], &dumpsys_byte_cnt));
134 ASSERT_TRUE(dumpsys_byte_cnt < socket_buffer_size);
135 }
136
137 } // namespace testing
138