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