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 <string.h> 18 19#include <memory> 20 21#include <android-base/logging.h> 22#include <android-base/unique_fd.h> 23#include <gtest/gtest.h> 24#include <utils/Errors.h> 25#include <utils/StopWatch.h> 26 27#include "wificond/looper_backed_event_loop.h" 28 29namespace { 30 31const int kTimingToleranceMs = 25; 32 33// Adapt from libutils/tests/TestHelpers.h 34class Pipe { 35public: 36 android::base::unique_fd send_fd; 37 android::base::unique_fd receive_fd; 38 39 Pipe() { 40 int fds[2]; 41 ::pipe(fds); 42 43 receive_fd = android::base::unique_fd(fds[0]); 44 send_fd = android::base::unique_fd(fds[1]); 45 } 46 47 bool writeSignal() { 48 ssize_t n_written = ::write(send_fd, "*", 1); 49 if (n_written != 1) { 50 LOG(ERROR) << "Failed to write signal to pipe: " << strerror(errno); 51 return false; 52 } 53 return true; 54 } 55 56 bool readSignal() { 57 char buf[1]; 58 ssize_t n_read = ::read(receive_fd, buf, 1); 59 if (n_read != 1) { 60 if (n_read == 0) { 61 LOG(ERROR) << "No data from pipe"; 62 } else { 63 LOG(ERROR) << "Failed to read signal from pipe: " << strerror(errno); 64 } 65 return false; 66 } 67 return true; 68 } 69}; 70 71} // namespace 72 73namespace android { 74namespace wificond { 75 76class WificondLooperBackedEventLoopTest : public ::testing::Test { 77 protected: 78 std::unique_ptr<LooperBackedEventLoop> event_loop_; 79 80 virtual void SetUp() { 81 event_loop_.reset(new LooperBackedEventLoop()); 82 } 83}; 84 85TEST_F(WificondLooperBackedEventLoopTest, LooperBackedEventLoopPostTaskTest) { 86 bool task_executed = false; 87 event_loop_->PostTask([this, &task_executed]() mutable { 88 task_executed = true; event_loop_->TriggerExit();}); 89 EXPECT_FALSE(task_executed); 90 event_loop_->Poll(); 91 EXPECT_TRUE(task_executed); 92} 93 94TEST_F(WificondLooperBackedEventLoopTest, 95 LooperBackedEventLoopPostDelayedTaskTest) { 96 bool task_executed = false; 97 event_loop_->PostDelayedTask([this, &task_executed]() mutable { 98 task_executed = true; event_loop_->TriggerExit();}, 500); 99 EXPECT_FALSE(task_executed); 100 StopWatch stopWatch("DelayedTask"); 101 event_loop_->Poll(); 102 int32_t elapsedMillis = ns2ms(stopWatch.elapsedTime()); 103 EXPECT_NEAR(500, elapsedMillis, kTimingToleranceMs); 104 EXPECT_TRUE(task_executed); 105} 106 107TEST_F(WificondLooperBackedEventLoopTest, LooperBackedEventLoopWatchFdInputReadyTest) { 108 Pipe pipe; 109 bool read_result = false; 110 bool write_result = false; 111 event_loop_->PostTask([&write_result, &pipe]() {write_result = pipe.writeSignal();}); 112 // Read data from pipe when fd is ready for input. 113 EXPECT_TRUE(event_loop_->WatchFileDescriptor( 114 pipe.receive_fd, 115 EventLoop::kModeInput, 116 [&read_result, &pipe, this](int fd) { 117 read_result = pipe.readSignal(); 118 event_loop_->TriggerExit();})); 119 event_loop_->Poll(); 120 EXPECT_EQ(true, read_result); 121 EXPECT_EQ(true, write_result); 122} 123 124TEST_F(WificondLooperBackedEventLoopTest, LooperBackedEventLoopWatchFdOutputReadyTest) { 125 Pipe pipe; 126 bool write_result = false; 127 // Write data to pipe when fd is ready for output. 128 EXPECT_TRUE(event_loop_->WatchFileDescriptor( 129 pipe.send_fd, 130 EventLoop::kModeOutput, 131 [&write_result, &pipe, this](int fd) { 132 write_result = pipe.writeSignal(); 133 event_loop_->TriggerExit();})); 134 event_loop_->Poll(); 135 EXPECT_EQ(true, write_result); 136 EXPECT_EQ(true, pipe.readSignal()); 137} 138 139TEST_F(WificondLooperBackedEventLoopTest, LooperBackedEventLoopStopWatchFdTest) { 140 Pipe pipe; 141 bool read_result = false; 142 bool write_result = false; 143 event_loop_->PostTask([&write_result, &pipe]() {write_result = pipe.writeSignal();}); 144 // Read data from pipe when fd is ready for input. 145 EXPECT_TRUE(event_loop_->WatchFileDescriptor( 146 pipe.receive_fd, 147 EventLoop::kModeInput, 148 [&read_result, &pipe, this](int fd) { 149 read_result = pipe.readSignal(); 150 event_loop_->TriggerExit();})); 151 // Stop watching the file descriptor. 152 EXPECT_TRUE(event_loop_->StopWatchFileDescriptor(pipe.receive_fd)); 153 event_loop_->Poll(); 154 // We wrote to pipe successfully. 155 EXPECT_EQ(true, write_result); 156 // No data was read from the pipe because we stopped watching the file 157 // descriptor. |read_result| is not set to true; 158 EXPECT_EQ(false, read_result); 159} 160 161} // namespace wificond 162} // namespace android 163