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