• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
29 namespace {
30 
31 const int kTimingToleranceMs = 25;
32 
33 // Adapt from libutils/tests/TestHelpers.h
34 class Pipe {
35 public:
36   android::base::unique_fd send_fd;
37   android::base::unique_fd receive_fd;
38 
Pipe()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 
writeSignal()47   bool writeSignal() {
48     ssize_t n_written = ::write(send_fd, "*", 1);
49     if (n_written != 1) {
50       PLOG(ERROR) << "Failed to write signal to pipe";
51       return false;
52     }
53     return true;
54   }
55 
readSignal()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         PLOG(ERROR) << "Failed to read signal from pipe";
64       }
65       return false;
66     }
67     return true;
68   }
69 };
70 
71 }  // namespace
72 
73 namespace android {
74 namespace wificond {
75 
76 class WificondLooperBackedEventLoopTest : public ::testing::Test {
77  protected:
78   std::unique_ptr<LooperBackedEventLoop> event_loop_;
79 
SetUp()80   virtual void SetUp() {
81     event_loop_.reset(new LooperBackedEventLoop());
82   }
83 };
84 
TEST_F(WificondLooperBackedEventLoopTest,LooperBackedEventLoopPostTaskTest)85 TEST_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 
TEST_F(WificondLooperBackedEventLoopTest,LooperBackedEventLoopPostDelayedTaskTest)94 TEST_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 
TEST_F(WificondLooperBackedEventLoopTest,LooperBackedEventLoopWatchFdInputReadyTest)107 TEST_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 
TEST_F(WificondLooperBackedEventLoopTest,LooperBackedEventLoopWatchFdOutputReadyTest)124 TEST_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   EXPECT_TRUE(event_loop_->StopWatchFileDescriptor(pipe.send_fd));
138 }
139 
TEST_F(WificondLooperBackedEventLoopTest,LooperBackedEventLoopStopWatchFdTest)140 TEST_F(WificondLooperBackedEventLoopTest, LooperBackedEventLoopStopWatchFdTest) {
141   Pipe pipe;
142   bool read_result = false;
143   bool write_result = false;
144   event_loop_->PostTask([&write_result, &pipe]() {write_result = pipe.writeSignal();});
145   // Read data from pipe when fd is ready for input.
146   EXPECT_TRUE(event_loop_->WatchFileDescriptor(
147       pipe.receive_fd,
148       EventLoop::kModeInput,
149       [&read_result, &pipe, this](int fd) {
150           read_result = pipe.readSignal();
151           event_loop_->TriggerExit();}));
152   // Stop watching the file descriptor.
153   EXPECT_TRUE(event_loop_->StopWatchFileDescriptor(pipe.receive_fd));
154   // If the lambda for |WatchFileDescriptor| is not triggered, we need this to
155   // terminate the event loop.
156   event_loop_->PostDelayedTask([this]() { event_loop_->TriggerExit();}, 500);
157   event_loop_->Poll();
158   // We wrote to pipe successfully.
159   EXPECT_EQ(true, write_result);
160   // No data was read from the pipe because we stopped watching the file
161   // descriptor. |read_result| is not set to true;
162   EXPECT_EQ(false, read_result);
163 }
164 
165 }  // namespace wificond
166 }  // namespace android
167