• 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 <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