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 <array>
18 #include <iostream>
19 #include <memory>
20 #include <tuple>
21
22 #include "gmock/gmock.h"
23 #include "gtest/gtest.h"
24
25 #include "wifilogd/local_utils.h"
26 #include "wifilogd/os.h"
27 #include "wifilogd/tests/mock_raw_os.h"
28
29 // This function must be defined in the same namespace as |timespec|. Hence the
30 // placement of this function at the top level.
PrintTo(const timespec & ts,::std::ostream * os)31 inline void PrintTo(const timespec& ts, ::std::ostream* os) {
32 *os << "[secs:" << ts.tv_sec << " "
33 << "nsecs:" << ts.tv_nsec << "]";
34 }
35
36 namespace android {
37 namespace wifilogd {
38 namespace {
39
40 using ::testing::_;
41 using ::testing::DoAll;
42 using ::testing::InSequence;
43 using ::testing::Invoke;
44 using ::testing::Matcher;
45 using ::testing::MatcherInterface;
46 using ::testing::MatchResultListener;
47 using ::testing::NotNull;
48 using ::testing::Pointee;
49 using ::testing::Return;
50 using ::testing::SetArgumentPointee;
51 using ::testing::SetErrnoAndReturn;
52 using ::testing::StrEq;
53 using ::testing::StrictMock;
54
55 using local_utils::GetMaxVal;
56
57 class OsTest : public ::testing::Test {
58 public:
OsTest()59 OsTest() {
60 raw_os_ = new StrictMock<MockRawOs>();
61 os_ = std::unique_ptr<Os>(new Os(std::unique_ptr<RawOs>(raw_os_)));
62 }
63
64 protected:
65 std::unique_ptr<Os> os_;
66 // We use a raw pointer to access the mock, since ownership passes
67 // to |os_|.
68 MockRawOs* raw_os_;
69 };
70
71 class TimespecMatcher : public MatcherInterface<const timespec&> {
72 public:
TimespecMatcher(const timespec & expected)73 explicit TimespecMatcher(const timespec& expected) : expected_(expected) {}
74
DescribeTo(::std::ostream * os) const75 virtual void DescribeTo(::std::ostream* os) const {
76 *os << "equals ";
77 PrintTo(expected_, os);
78 }
79
MatchAndExplain(const timespec & actual,MatchResultListener *) const80 virtual bool MatchAndExplain(const timespec& actual,
81 MatchResultListener* /* listener */) const {
82 return actual.tv_sec == expected_.tv_sec &&
83 actual.tv_nsec == expected_.tv_nsec;
84 }
85
86 private:
87 const timespec& expected_;
88 };
89
EqualsTimespec(const timespec & expected)90 Matcher<const timespec&> EqualsTimespec(const timespec& expected) {
91 return MakeMatcher(new TimespecMatcher(expected));
92 }
93
94 } // namespace
95
TEST_F(OsTest,GetControlSocketReturnsFdAndZeroOnSuccess)96 TEST_F(OsTest, GetControlSocketReturnsFdAndZeroOnSuccess) {
97 constexpr char kSocketName[] = "fake-daemon";
98 constexpr int kFakeValidFd = 100;
99 EXPECT_CALL(*raw_os_, GetControlSocket(StrEq(kSocketName)))
100 .WillOnce(Return(kFakeValidFd));
101
102 constexpr std::tuple<int, Os::Errno> kExpectedResult{kFakeValidFd, 0};
103 EXPECT_EQ(kExpectedResult, os_->GetControlSocket(kSocketName));
104 }
105
TEST_F(OsTest,GetControlSocketReturnsInvalidFdAndErrorOnFailure)106 TEST_F(OsTest, GetControlSocketReturnsInvalidFdAndErrorOnFailure) {
107 constexpr char kSocketName[] = "fake-daemon";
108 constexpr Os::Errno kError = EINVAL;
109 EXPECT_CALL(*raw_os_, GetControlSocket(StrEq(kSocketName)))
110 .WillOnce(SetErrnoAndReturn(kError, -1));
111
112 constexpr std::tuple<int, Os::Errno> kExpectedResult{Os::kInvalidFd, kError};
113 EXPECT_EQ(kExpectedResult, os_->GetControlSocket(kSocketName));
114 }
115
TEST_F(OsTest,GetTimestampSucceeds)116 TEST_F(OsTest, GetTimestampSucceeds) {
117 constexpr auto kFakeSecs = 1U;
118 constexpr auto kFakeNsecs = 2U;
119 constexpr struct timespec fake_time { kFakeSecs, kFakeNsecs };
120 EXPECT_CALL(*raw_os_, ClockGettime(_, _))
121 .WillOnce(DoAll(SetArgumentPointee<1>(fake_time), Return(0)));
122
123 const Os::Timestamp received = os_->GetTimestamp(CLOCK_REALTIME);
124 EXPECT_EQ(kFakeSecs, received.secs);
125 EXPECT_EQ(kFakeNsecs, received.nsecs);
126 }
127
TEST_F(OsTest,NanosleepPassesNormalValueToSyscall)128 TEST_F(OsTest, NanosleepPassesNormalValueToSyscall) {
129 constexpr auto kSleepTimeNsec = 100;
130 EXPECT_CALL(*raw_os_,
131 Nanosleep(Pointee(EqualsTimespec({0, kSleepTimeNsec})), _));
132 os_->Nanosleep(kSleepTimeNsec);
133 }
134
TEST_F(OsTest,NanosleepPassesMaxmimalValueToSyscall)135 TEST_F(OsTest, NanosleepPassesMaxmimalValueToSyscall) {
136 EXPECT_CALL(*raw_os_,
137 Nanosleep(Pointee(EqualsTimespec({0, Os::kMaxNanos})), _));
138 os_->Nanosleep(Os::kMaxNanos);
139 }
140
TEST_F(OsTest,NanosleepPassesZeroValueToSyscall)141 TEST_F(OsTest, NanosleepPassesZeroValueToSyscall) {
142 EXPECT_CALL(*raw_os_, Nanosleep(Pointee(EqualsTimespec({0, 0})), _));
143 os_->Nanosleep(0);
144 }
145
TEST_F(OsTest,NanosleepClampsOverlyLargeValue)146 TEST_F(OsTest, NanosleepClampsOverlyLargeValue) {
147 EXPECT_CALL(*raw_os_,
148 Nanosleep(Pointee(EqualsTimespec({0, Os::kMaxNanos})), _));
149 os_->Nanosleep(Os::kMaxNanos + 1);
150 }
151
TEST_F(OsTest,NanosleepRetriesOnInterruptedCall)152 TEST_F(OsTest, NanosleepRetriesOnInterruptedCall) {
153 InSequence seq;
154 EXPECT_CALL(*raw_os_, Nanosleep(_, NotNull()))
155 .WillOnce(Invoke([](const timespec* /* desired */, timespec* remaining) {
156 *remaining = {0, 100};
157 errno = EINTR;
158 return -1;
159 }));
160 EXPECT_CALL(*raw_os_, Nanosleep(Pointee(EqualsTimespec({0, 100})), _));
161 os_->Nanosleep(Os::kMaxNanos);
162 }
163
TEST_F(OsTest,NanosleepRetriesMultipleTimesIfNecessary)164 TEST_F(OsTest, NanosleepRetriesMultipleTimesIfNecessary) {
165 InSequence seq;
166 EXPECT_CALL(*raw_os_, Nanosleep(_, NotNull()))
167 .WillOnce(Invoke([](const timespec* /* desired */, timespec* remaining) {
168 *remaining = {0, 100};
169 errno = EINTR;
170 return -1;
171 }));
172 EXPECT_CALL(*raw_os_, Nanosleep(_, NotNull()))
173 .WillOnce(Invoke([](const timespec* /* desired */, timespec* remaining) {
174 *remaining = {0, 50};
175 errno = EINTR;
176 return -1;
177 }));
178 EXPECT_CALL(*raw_os_, Nanosleep(Pointee(EqualsTimespec({0, 50})), _));
179 os_->Nanosleep(Os::kMaxNanos);
180 }
181
TEST_F(OsTest,NanosleepIgnoresEintrWithZeroTimeRemaining)182 TEST_F(OsTest, NanosleepIgnoresEintrWithZeroTimeRemaining) {
183 InSequence seq;
184 EXPECT_CALL(*raw_os_, Nanosleep(_, NotNull()))
185 .WillOnce(Invoke([](const timespec* /* desired */, timespec* remaining) {
186 *remaining = {0, 0};
187 errno = EINTR;
188 return -1;
189 }));
190 EXPECT_CALL(*raw_os_, Nanosleep(_, _)).Times(0);
191 os_->Nanosleep(Os::kMaxNanos);
192 }
193
TEST_F(OsTest,ReceiveDatagramReturnsCorrectValueForMaxSizedDatagram)194 TEST_F(OsTest, ReceiveDatagramReturnsCorrectValueForMaxSizedDatagram) {
195 constexpr int kFakeFd = 100;
196 std::array<uint8_t, 8192> buffer{};
197 EXPECT_CALL(*raw_os_, Recv(kFakeFd, buffer.data(), buffer.size(), MSG_TRUNC))
198 .WillOnce(Return(buffer.size()));
199
200 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{buffer.size(), 0};
201 EXPECT_EQ(kExpectedResult,
202 os_->ReceiveDatagram(kFakeFd, buffer.data(), buffer.size()));
203 }
204
TEST_F(OsTest,ReceieveDatagramReturnsCorrectValueForRegularSizedDatagram)205 TEST_F(OsTest, ReceieveDatagramReturnsCorrectValueForRegularSizedDatagram) {
206 constexpr int kFakeFd = 100;
207 constexpr auto kReadBufferSize = 8192;
208 constexpr auto kDatagramSize = kReadBufferSize / 2;
209 std::array<uint8_t, kReadBufferSize> buffer{};
210 EXPECT_CALL(*raw_os_, Recv(kFakeFd, buffer.data(), buffer.size(), MSG_TRUNC))
211 .WillOnce(Return(kDatagramSize));
212
213 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{kDatagramSize, 0};
214 EXPECT_EQ(kExpectedResult,
215 os_->ReceiveDatagram(kFakeFd, buffer.data(), buffer.size()));
216 }
217
TEST_F(OsTest,ReceieveDatagramReturnsCorrectValueForOversizedDatagram)218 TEST_F(OsTest, ReceieveDatagramReturnsCorrectValueForOversizedDatagram) {
219 constexpr int kFakeFd = 100;
220 constexpr auto kReadBufferSize = 8192;
221 constexpr auto kDatagramSize = kReadBufferSize * 2;
222 std::array<uint8_t, kReadBufferSize> buffer{};
223 EXPECT_CALL(*raw_os_, Recv(kFakeFd, buffer.data(), buffer.size(), MSG_TRUNC))
224 .WillOnce(Return(kDatagramSize));
225
226 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{kDatagramSize, 0};
227 EXPECT_EQ(kExpectedResult,
228 os_->ReceiveDatagram(kFakeFd, buffer.data(), buffer.size()));
229 }
230
TEST_F(OsTest,ReceieveDatagramReturnsCorrectValueForZeroByteDatagram)231 TEST_F(OsTest, ReceieveDatagramReturnsCorrectValueForZeroByteDatagram) {
232 constexpr int kFakeFd = 100;
233 std::array<uint8_t, 8192> buffer{};
234 EXPECT_CALL(*raw_os_, Recv(kFakeFd, buffer.data(), buffer.size(), MSG_TRUNC))
235 .WillOnce(Return(0));
236
237 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{0, 0};
238 EXPECT_EQ(kExpectedResult,
239 os_->ReceiveDatagram(kFakeFd, buffer.data(), buffer.size()));
240 }
241
TEST_F(OsTest,ReceieveDatagramReturnsCorrectValueOnFailure)242 TEST_F(OsTest, ReceieveDatagramReturnsCorrectValueOnFailure) {
243 constexpr int kFakeFd = 100;
244 constexpr Os::Errno kError = EBADF;
245 std::array<uint8_t, 8192> buffer{};
246 EXPECT_CALL(*raw_os_, Recv(kFakeFd, buffer.data(), buffer.size(), MSG_TRUNC))
247 .WillOnce(SetErrnoAndReturn(kError, -1));
248
249 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{0, kError};
250 EXPECT_EQ(kExpectedResult,
251 os_->ReceiveDatagram(kFakeFd, buffer.data(), buffer.size()));
252 }
253
TEST_F(OsTest,WriteReturnsCorrectValueForSuccessfulWrite)254 TEST_F(OsTest, WriteReturnsCorrectValueForSuccessfulWrite) {
255 constexpr int kFakeFd = 100;
256 constexpr std::array<uint8_t, 8192> buffer{};
257 EXPECT_CALL(*raw_os_, Write(kFakeFd, buffer.data(), buffer.size()))
258 .WillOnce(Return(buffer.size()));
259
260 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{buffer.size(), 0};
261 EXPECT_EQ(kExpectedResult, os_->Write(kFakeFd, buffer.data(), buffer.size()));
262 }
263
TEST_F(OsTest,WriteReturnsCorrectValueForTruncatedWrite)264 TEST_F(OsTest, WriteReturnsCorrectValueForTruncatedWrite) {
265 constexpr int kFakeFd = 100;
266 constexpr int kBytesWritten = 4096;
267 constexpr std::array<uint8_t, 8192> buffer{};
268 EXPECT_CALL(*raw_os_, Write(kFakeFd, buffer.data(), buffer.size()))
269 .WillOnce(Return(kBytesWritten));
270
271 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{kBytesWritten, 0};
272 EXPECT_EQ(kExpectedResult, os_->Write(kFakeFd, buffer.data(), buffer.size()));
273 }
274
TEST_F(OsTest,WriteReturnsCorrectValueForSuccessfulZeroByteWrite)275 TEST_F(OsTest, WriteReturnsCorrectValueForSuccessfulZeroByteWrite) {
276 constexpr int kFakeFd = 100;
277 constexpr std::array<uint8_t, 0> buffer{};
278 EXPECT_CALL(*raw_os_, Write(kFakeFd, buffer.data(), 0)).WillOnce(Return(0));
279
280 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{0, 0};
281 EXPECT_EQ(kExpectedResult, os_->Write(kFakeFd, buffer.data(), buffer.size()));
282 }
283
TEST_F(OsTest,WriteReturnsCorrectValueForFailedWrite)284 TEST_F(OsTest, WriteReturnsCorrectValueForFailedWrite) {
285 constexpr int kFakeFd = 100;
286 constexpr Os::Errno kError = EBADF;
287 constexpr std::array<uint8_t, 8192> buffer{};
288 EXPECT_CALL(*raw_os_, Write(kFakeFd, buffer.data(), buffer.size()))
289 .WillOnce(SetErrnoAndReturn(kError, -1));
290
291 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{0, kError};
292 EXPECT_EQ(kExpectedResult, os_->Write(kFakeFd, buffer.data(), buffer.size()));
293 }
294
TEST_F(OsTest,WriteReturnsCorrectValueForFailedZeroByteWrite)295 TEST_F(OsTest, WriteReturnsCorrectValueForFailedZeroByteWrite) {
296 constexpr int kFakeFd = 100;
297 constexpr Os::Errno kError = EBADF;
298 constexpr std::array<uint8_t, 0> buffer{};
299 EXPECT_CALL(*raw_os_, Write(kFakeFd, buffer.data(), 0))
300 .WillOnce(SetErrnoAndReturn(kError, -1));
301
302 constexpr std::tuple<size_t, Os::Errno> kExpectedResult{0, kError};
303 EXPECT_EQ(kExpectedResult, os_->Write(kFakeFd, buffer.data(), buffer.size()));
304 }
305
306 // Per
307 // github.com/google/googletest/blob/master/googletest/docs/AdvancedGuide.md#death-tests,
308 // death tests should be specially named.
309 using OsDeathTest = OsTest;
310
TEST_F(OsDeathTest,GetTimestampOverlyLargeNsecsCausesDeath)311 TEST_F(OsDeathTest, GetTimestampOverlyLargeNsecsCausesDeath) {
312 constexpr auto kFakeSecs = 1U;
313 constexpr auto kFakeNsecs = 1000 * 1000 * 1000;
314 constexpr struct timespec fake_time { kFakeSecs, kFakeNsecs };
315 ON_CALL(*raw_os_, ClockGettime(_, _))
316 .WillByDefault(DoAll(SetArgumentPointee<1>(fake_time), Return(0)));
317 EXPECT_DEATH(os_->GetTimestamp(CLOCK_REALTIME), "Check failed");
318 }
319
TEST_F(OsDeathTest,GetTimestampRawOsErrorCausesDeath)320 TEST_F(OsDeathTest, GetTimestampRawOsErrorCausesDeath) {
321 ON_CALL(*raw_os_, ClockGettime(_, _)).WillByDefault(Return(-1));
322 EXPECT_DEATH(os_->GetTimestamp(CLOCK_REALTIME), "Unexpected error");
323 }
324
TEST_F(OsDeathTest,NanosleepUnexpectedErrorCausesDeath)325 TEST_F(OsDeathTest, NanosleepUnexpectedErrorCausesDeath) {
326 ON_CALL(*raw_os_, Nanosleep(Pointee(EqualsTimespec({0, Os::kMaxNanos})), _))
327 .WillByDefault(SetErrnoAndReturn(EFAULT, -1));
328 EXPECT_DEATH(os_->Nanosleep(Os::kMaxNanos), "Unexpected error");
329 }
330
TEST_F(OsDeathTest,ReceiveDatagramWithOverlyLargeBufferCausesDeath)331 TEST_F(OsDeathTest, ReceiveDatagramWithOverlyLargeBufferCausesDeath) {
332 constexpr int kFakeFd = 100;
333 std::array<uint8_t, 8192> buffer{};
334 EXPECT_DEATH(
335 os_->ReceiveDatagram(kFakeFd, buffer.data(), GetMaxVal<size_t>()),
336 "Check failed");
337 }
338
TEST_F(OsDeathTest,WriteWithOverlyLargeBufferCausesDeath)339 TEST_F(OsDeathTest, WriteWithOverlyLargeBufferCausesDeath) {
340 constexpr int kFakeFd = 100;
341 constexpr std::array<uint8_t, 8192> buffer{};
342 EXPECT_DEATH(os_->Write(kFakeFd, buffer.data(), GetMaxVal<size_t>()),
343 "Check failed");
344 }
345
TEST_F(OsDeathTest,WriteWithOverrunCausesDeath)346 TEST_F(OsDeathTest, WriteWithOverrunCausesDeath) {
347 constexpr int kFakeFd = 100;
348 constexpr std::array<uint8_t, 8192> buffer{};
349 ON_CALL(*raw_os_, Write(kFakeFd, buffer.data(), buffer.size()))
350 .WillByDefault(Return(buffer.size() + 1));
351 EXPECT_DEATH(os_->Write(kFakeFd, buffer.data(), buffer.size()),
352 "Check failed");
353 }
354
355 } // namespace wifilogd
356 } // namespace android
357