1 /* 2 * Copyright (C) 2016 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 <unistd.h> 19 20 #include <atomic> 21 #include <condition_variable> 22 #include <thread> 23 24 #include "adb_io.h" 25 #include "sysdeps.h" 26 #include "sysdeps/chrono.h" 27 28 static void increment_atomic_int(void* c) { 29 std::this_thread::sleep_for(1s); 30 reinterpret_cast<std::atomic<int>*>(c)->fetch_add(1); 31 } 32 33 TEST(sysdeps_thread, smoke) { 34 std::atomic<int> counter(0); 35 36 for (int i = 0; i < 100; ++i) { 37 ASSERT_TRUE(adb_thread_create(increment_atomic_int, &counter)); 38 } 39 40 std::this_thread::sleep_for(2s); 41 ASSERT_EQ(100, counter.load()); 42 } 43 44 TEST(sysdeps_thread, join) { 45 std::atomic<int> counter(0); 46 std::vector<adb_thread_t> threads(500); 47 for (size_t i = 0; i < threads.size(); ++i) { 48 ASSERT_TRUE(adb_thread_create(increment_atomic_int, &counter, &threads[i])); 49 } 50 51 int current = counter.load(); 52 ASSERT_GE(current, 0); 53 // Make sure that adb_thread_create actually creates threads, and doesn't do something silly 54 // like synchronously run the function passed in. The sleep in increment_atomic_int should be 55 // enough to keep this from being flakey. 56 ASSERT_LT(current, 500); 57 58 for (const auto& thread : threads) { 59 ASSERT_TRUE(adb_thread_join(thread)); 60 } 61 62 ASSERT_EQ(500, counter.load()); 63 } 64 65 TEST(sysdeps_thread, exit) { 66 adb_thread_t thread; 67 ASSERT_TRUE(adb_thread_create( 68 [](void*) { 69 adb_thread_exit(); 70 for (;;) continue; 71 }, 72 nullptr, &thread)); 73 ASSERT_TRUE(adb_thread_join(thread)); 74 } 75 76 TEST(sysdeps_socketpair, smoke) { 77 int fds[2]; 78 ASSERT_EQ(0, adb_socketpair(fds)) << strerror(errno); 79 ASSERT_TRUE(WriteFdExactly(fds[0], "foo", 4)); 80 ASSERT_TRUE(WriteFdExactly(fds[1], "bar", 4)); 81 82 char buf[4]; 83 ASSERT_TRUE(ReadFdExactly(fds[1], buf, 4)); 84 ASSERT_STREQ(buf, "foo"); 85 ASSERT_TRUE(ReadFdExactly(fds[0], buf, 4)); 86 ASSERT_STREQ(buf, "bar"); 87 ASSERT_EQ(0, adb_close(fds[0])); 88 ASSERT_EQ(0, adb_close(fds[1])); 89 } 90 91 TEST(sysdeps_fd, exhaustion) { 92 std::vector<int> fds; 93 int socketpair[2]; 94 95 while (adb_socketpair(socketpair) == 0) { 96 fds.push_back(socketpair[0]); 97 fds.push_back(socketpair[1]); 98 } 99 100 ASSERT_EQ(EMFILE, errno) << strerror(errno); 101 for (int fd : fds) { 102 ASSERT_EQ(0, adb_close(fd)); 103 } 104 ASSERT_EQ(0, adb_socketpair(socketpair)); 105 ASSERT_EQ(socketpair[0], fds[0]); 106 ASSERT_EQ(socketpair[1], fds[1]); 107 ASSERT_EQ(0, adb_close(socketpair[0])); 108 ASSERT_EQ(0, adb_close(socketpair[1])); 109 } 110 111 class sysdeps_poll : public ::testing::Test { 112 protected: 113 int fds[2]; 114 void SetUp() override { 115 ASSERT_EQ(0, adb_socketpair(fds)) << strerror(errno); 116 } 117 118 void TearDown() override { 119 if (fds[0] >= 0) { 120 ASSERT_EQ(0, adb_close(fds[0])); 121 } 122 if (fds[1] >= 0) { 123 ASSERT_EQ(0, adb_close(fds[1])); 124 } 125 } 126 }; 127 128 TEST_F(sysdeps_poll, smoke) { 129 adb_pollfd pfd[2] = {}; 130 pfd[0].fd = fds[0]; 131 pfd[0].events = POLLRDNORM; 132 pfd[1].fd = fds[1]; 133 pfd[1].events = POLLWRNORM; 134 135 pfd[0].revents = -1; 136 pfd[1].revents = -1; 137 EXPECT_EQ(1, adb_poll(pfd, 2, 0)); 138 EXPECT_EQ(0, pfd[0].revents); 139 EXPECT_EQ(POLLWRNORM, pfd[1].revents); 140 141 ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4)); 142 143 // Wait for the socketpair to be flushed. 144 pfd[0].revents = -1; 145 EXPECT_EQ(1, adb_poll(pfd, 1, 100)); 146 EXPECT_EQ(POLLRDNORM, pfd[0].revents); 147 pfd[0].revents = -1; 148 pfd[1].revents = -1; 149 EXPECT_EQ(2, adb_poll(pfd, 2, 0)); 150 EXPECT_EQ(POLLRDNORM, pfd[0].revents); 151 EXPECT_EQ(POLLWRNORM, pfd[1].revents); 152 } 153 154 TEST_F(sysdeps_poll, timeout) { 155 adb_pollfd pfd = {}; 156 pfd.fd = fds[0]; 157 pfd.events = POLLRDNORM; 158 159 EXPECT_EQ(0, adb_poll(&pfd, 1, 100)); 160 EXPECT_EQ(0, pfd.revents); 161 162 ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4)); 163 164 EXPECT_EQ(1, adb_poll(&pfd, 1, 100)); 165 EXPECT_EQ(POLLRDNORM, pfd.revents); 166 } 167 168 TEST_F(sysdeps_poll, invalid_fd) { 169 adb_pollfd pfd[3] = {}; 170 pfd[0].fd = fds[0]; 171 pfd[0].events = POLLRDNORM; 172 pfd[1].fd = INT_MAX; 173 pfd[1].events = POLLRDNORM; 174 pfd[2].fd = fds[1]; 175 pfd[2].events = POLLWRNORM; 176 177 ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4)); 178 179 // Wait for the socketpair to be flushed. 180 EXPECT_EQ(1, adb_poll(pfd, 1, 100)); 181 EXPECT_EQ(POLLRDNORM, pfd[0].revents); 182 183 EXPECT_EQ(3, adb_poll(pfd, 3, 0)); 184 EXPECT_EQ(POLLRDNORM, pfd[0].revents); 185 EXPECT_EQ(POLLNVAL, pfd[1].revents); 186 EXPECT_EQ(POLLWRNORM, pfd[2].revents); 187 } 188 189 TEST_F(sysdeps_poll, duplicate_fd) { 190 adb_pollfd pfd[2] = {}; 191 pfd[0].fd = fds[0]; 192 pfd[0].events = POLLRDNORM; 193 pfd[1] = pfd[0]; 194 195 EXPECT_EQ(0, adb_poll(pfd, 2, 0)); 196 EXPECT_EQ(0, pfd[0].revents); 197 EXPECT_EQ(0, pfd[1].revents); 198 199 ASSERT_TRUE(WriteFdExactly(fds[1], "foo", 4)); 200 201 EXPECT_EQ(2, adb_poll(pfd, 2, 100)); 202 EXPECT_EQ(POLLRDNORM, pfd[0].revents); 203 EXPECT_EQ(POLLRDNORM, pfd[1].revents); 204 } 205 206 TEST_F(sysdeps_poll, disconnect) { 207 adb_pollfd pfd = {}; 208 pfd.fd = fds[0]; 209 pfd.events = POLLIN; 210 211 EXPECT_EQ(0, adb_poll(&pfd, 1, 0)); 212 EXPECT_EQ(0, pfd.revents); 213 214 EXPECT_EQ(0, adb_close(fds[1])); 215 fds[1] = -1; 216 217 EXPECT_EQ(1, adb_poll(&pfd, 1, 100)); 218 219 // Linux returns POLLIN | POLLHUP, Windows returns just POLLHUP. 220 EXPECT_EQ(POLLHUP, pfd.revents & POLLHUP); 221 } 222 223 TEST_F(sysdeps_poll, fd_count) { 224 // https://code.google.com/p/android/issues/detail?id=12141 225 static constexpr int num_sockets = 256; 226 std::vector<int> sockets; 227 std::vector<adb_pollfd> pfds; 228 sockets.resize(num_sockets * 2); 229 for (int32_t i = 0; i < num_sockets; ++i) { 230 ASSERT_EQ(0, adb_socketpair(&sockets[i * 2])) << strerror(errno); 231 ASSERT_TRUE(WriteFdExactly(sockets[i * 2], &i, sizeof(i))); 232 adb_pollfd pfd; 233 pfd.events = POLLIN; 234 pfd.fd = sockets[i * 2 + 1]; 235 pfds.push_back(pfd); 236 } 237 238 ASSERT_EQ(num_sockets, adb_poll(pfds.data(), pfds.size(), 0)); 239 for (int i = 0; i < num_sockets; ++i) { 240 ASSERT_NE(0, pfds[i].revents & POLLIN); 241 242 int32_t buf[2] = { -1, -1 }; 243 ASSERT_EQ(adb_read(pfds[i].fd, buf, sizeof(buf)), static_cast<ssize_t>(sizeof(int32_t))); 244 ASSERT_EQ(i, buf[0]); 245 } 246 247 for (int fd : sockets) { 248 adb_close(fd); 249 } 250 } 251 252 TEST(sysdeps_mutex, mutex_smoke) { 253 static std::atomic<bool> finished(false); 254 static std::mutex &m = *new std::mutex(); 255 m.lock(); 256 ASSERT_FALSE(m.try_lock()); 257 adb_thread_create([](void*) { 258 ASSERT_FALSE(m.try_lock()); 259 m.lock(); 260 finished.store(true); 261 std::this_thread::sleep_for(200ms); 262 m.unlock(); 263 }, nullptr); 264 265 ASSERT_FALSE(finished.load()); 266 std::this_thread::sleep_for(100ms); 267 ASSERT_FALSE(finished.load()); 268 m.unlock(); 269 std::this_thread::sleep_for(100ms); 270 m.lock(); 271 ASSERT_TRUE(finished.load()); 272 m.unlock(); 273 } 274 275 TEST(sysdeps_mutex, recursive_mutex_smoke) { 276 static std::recursive_mutex &m = *new std::recursive_mutex(); 277 278 m.lock(); 279 ASSERT_TRUE(m.try_lock()); 280 m.unlock(); 281 282 adb_thread_create([](void*) { 283 ASSERT_FALSE(m.try_lock()); 284 m.lock(); 285 std::this_thread::sleep_for(500ms); 286 m.unlock(); 287 }, nullptr); 288 289 std::this_thread::sleep_for(100ms); 290 m.unlock(); 291 std::this_thread::sleep_for(100ms); 292 ASSERT_FALSE(m.try_lock()); 293 m.lock(); 294 m.unlock(); 295 } 296 297 TEST(sysdeps_condition_variable, smoke) { 298 static std::mutex &m = *new std::mutex; 299 static std::condition_variable &cond = *new std::condition_variable; 300 static volatile bool flag = false; 301 302 std::unique_lock<std::mutex> lock(m); 303 adb_thread_create([](void*) { 304 m.lock(); 305 flag = true; 306 cond.notify_one(); 307 m.unlock(); 308 }, nullptr); 309 310 while (!flag) { 311 cond.wait(lock); 312 } 313 } 314