os_unittest.cpp 12 KB

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