command_processor_unittest.cpp 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475
  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 <errno.h>
  17. #include <unistd.h>
  18. #include <algorithm>
  19. #include <cstring>
  20. #include <memory>
  21. #include <string>
  22. #include <tuple>
  23. #include <type_traits>
  24. #include <utility>
  25. #include "android-base/unique_fd.h"
  26. #include "gmock/gmock.h"
  27. #include "gtest/gtest.h"
  28. #include "wifilogd/byte_buffer.h"
  29. #include "wifilogd/local_utils.h"
  30. #include "wifilogd/protocol.h"
  31. #include "wifilogd/tests/mock_os.h"
  32. #include "wifilogd/command_processor.h"
  33. namespace android {
  34. namespace wifilogd {
  35. namespace {
  36. using ::android::base::unique_fd;
  37. using ::testing::_;
  38. using ::testing::AnyNumber;
  39. using ::testing::AtLeast;
  40. using ::testing::EndsWith;
  41. using ::testing::HasSubstr;
  42. using ::testing::Invoke;
  43. using ::testing::Return;
  44. using ::testing::StartsWith;
  45. using ::testing::StrictMock;
  46. using local_utils::GetMaxVal;
  47. // The CommandBuffer is deliberately larger than the maximal permitted
  48. // command, so that we can test the CommandProcessor's handling of oversized
  49. // inputs.
  50. using CommandBuffer = ByteBuffer<protocol::kMaxMessageSize * 2>;
  51. constexpr size_t kBufferSizeBytes = protocol::kMaxMessageSize * 16;
  52. constexpr char kLogRecordSeparator = '\n';
  53. constexpr size_t kMaxAsciiMessagePayloadLen = protocol::kMaxMessageSize -
  54. sizeof(protocol::Command) -
  55. sizeof(protocol::AsciiMessage);
  56. class CommandProcessorTest : public ::testing::Test {
  57. public:
  58. CommandProcessorTest() {
  59. os_ = new StrictMock<MockOs>();
  60. auto& accumulator = written_to_os_;
  61. ON_CALL(*os_, Write(_, _, _))
  62. .WillByDefault(Invoke(
  63. [&accumulator](int /*fd*/, const void* write_buf, size_t buflen) {
  64. accumulator.append(static_cast<const char*>(write_buf), buflen);
  65. return std::tuple<size_t, Os::Errno>(buflen, 0);
  66. }));
  67. command_processor_ = std::unique_ptr<CommandProcessor>(
  68. new CommandProcessor(kBufferSizeBytes, std::unique_ptr<Os>(os_)));
  69. }
  70. protected:
  71. CommandBuffer BuildAsciiMessageCommandWithAdjustments(
  72. const std::string& tag, const std::string& message,
  73. ssize_t command_payload_len_adjustment,
  74. ssize_t ascii_message_tag_len_adjustment,
  75. ssize_t ascii_message_data_len_adjustment) {
  76. const size_t adjusted_tag_len =
  77. tag.length() + ascii_message_tag_len_adjustment;
  78. const size_t adjusted_data_len =
  79. message.length() + ascii_message_data_len_adjustment;
  80. const auto ascii_message_header =
  81. protocol::AsciiMessage()
  82. .set_tag_len(SAFELY_CLAMP(
  83. adjusted_tag_len, uint8_t, 0,
  84. GetMaxVal<decltype(protocol::AsciiMessage::tag_len)>()))
  85. .set_data_len(SAFELY_CLAMP(
  86. adjusted_data_len, uint16_t, 0,
  87. GetMaxVal<decltype(protocol::AsciiMessage::data_len)>()))
  88. .set_severity(protocol::MessageSeverity::kError);
  89. EXPECT_EQ(adjusted_tag_len, ascii_message_header.tag_len);
  90. EXPECT_EQ(adjusted_data_len, ascii_message_header.data_len);
  91. const size_t payload_len = sizeof(ascii_message_header) + tag.length() +
  92. message.length() +
  93. command_payload_len_adjustment;
  94. const auto command =
  95. protocol::Command()
  96. .set_opcode(protocol::Opcode::kWriteAsciiMessage)
  97. .set_payload_len(SAFELY_CLAMP(
  98. payload_len, uint16_t, 0,
  99. GetMaxVal<decltype(protocol::Command::payload_len)>()));
  100. EXPECT_EQ(payload_len, command.payload_len);
  101. return CommandBuffer()
  102. .AppendOrDie(&command, sizeof(command))
  103. .AppendOrDie(&ascii_message_header, sizeof(ascii_message_header))
  104. .AppendOrDie(tag.data(), tag.length())
  105. .AppendOrDie(message.data(), message.length());
  106. }
  107. CommandBuffer BuildAsciiMessageCommand(const std::string& tag,
  108. const std::string& message) {
  109. return BuildAsciiMessageCommandWithAdjustments(tag, message, 0, 0, 0);
  110. }
  111. bool SendAsciiMessageWithAdjustments(
  112. const std::string& tag, const std::string& message,
  113. ssize_t transport_len_adjustment, ssize_t command_payload_len_adjustment,
  114. ssize_t ascii_message_tag_len_adjustment,
  115. ssize_t ascii_message_data_len_adjustment) {
  116. const CommandBuffer& command_buffer(BuildAsciiMessageCommandWithAdjustments(
  117. tag, message, command_payload_len_adjustment,
  118. ascii_message_tag_len_adjustment, ascii_message_data_len_adjustment));
  119. EXPECT_CALL(*os_, GetTimestamp(CLOCK_MONOTONIC));
  120. EXPECT_CALL(*os_, GetTimestamp(CLOCK_BOOTTIME));
  121. EXPECT_CALL(*os_, GetTimestamp(CLOCK_REALTIME));
  122. return command_processor_->ProcessCommand(
  123. command_buffer.data(), command_buffer.size() + transport_len_adjustment,
  124. Os::kInvalidFd);
  125. }
  126. bool SendAsciiMessage(const std::string& tag, const std::string& message) {
  127. return SendAsciiMessageWithAdjustments(tag, message, 0, 0, 0, 0);
  128. }
  129. bool SendDumpBuffers() {
  130. const auto command = protocol::Command()
  131. .set_opcode(protocol::Opcode::kDumpBuffers)
  132. .set_payload_len(0);
  133. const auto buf = CommandBuffer().AppendOrDie(&command, sizeof(command));
  134. constexpr int kFakeFd = 100;
  135. return command_processor_->ProcessCommand(buf.data(), buf.size(), kFakeFd);
  136. }
  137. std::string written_to_os_; // Must out-live |os_|
  138. std::unique_ptr<CommandProcessor> command_processor_;
  139. // We use a raw pointer to access the mock, since ownership passes
  140. // to |command_processor_|.
  141. StrictMock<MockOs>* os_;
  142. };
  143. } // namespace
  144. // A valid ASCII message should, of course, be processed successfully.
  145. TEST_F(CommandProcessorTest, ProcessCommandOnValidAsciiMessageSucceeds) {
  146. EXPECT_TRUE(SendAsciiMessage("tag", "message"));
  147. }
  148. // If the buffer given to ProcessCommand() is shorter than a protocol::Command,
  149. // then we discard the data.
  150. TEST_F(CommandProcessorTest,
  151. ProcessCommandOnAsciiMessageShorterThanCommandFails) {
  152. const CommandBuffer& command_buffer(
  153. BuildAsciiMessageCommand("tag", "message"));
  154. EXPECT_FALSE(command_processor_->ProcessCommand(
  155. command_buffer.data(), sizeof(protocol::Command) - 1, Os::kInvalidFd));
  156. }
  157. // In all other cases, we save the data we got, and will try to salvage the
  158. // contents when dumping.
  159. TEST_F(CommandProcessorTest, ProcessCommandOnAsciiMessageWithEmtpyTagSucceeds) {
  160. EXPECT_TRUE(SendAsciiMessage("", "message"));
  161. }
  162. TEST_F(CommandProcessorTest,
  163. ProcessCommandOnAsciiMessageWithEmptyMessageSucceeds) {
  164. EXPECT_TRUE(SendAsciiMessage("tag", ""));
  165. }
  166. TEST_F(CommandProcessorTest,
  167. ProcessCommandOnAsciiMessageWithEmptyTagAndMessageSucceeds) {
  168. EXPECT_TRUE(SendAsciiMessage("", ""));
  169. }
  170. TEST_F(CommandProcessorTest,
  171. ProcessCommandOnAsciiMessageWithBadCommandLengthSucceeds) {
  172. EXPECT_TRUE(SendAsciiMessageWithAdjustments("tag", "message", 0, 1, 0, 0));
  173. EXPECT_TRUE(SendAsciiMessageWithAdjustments("tag", "message", 0, -1, 0, 0));
  174. }
  175. TEST_F(CommandProcessorTest,
  176. ProcessCommandOnAsciiMessageWithBadTagLengthSucceeds) {
  177. EXPECT_TRUE(SendAsciiMessageWithAdjustments("tag", "message", 0, 0, 1, 0));
  178. EXPECT_TRUE(SendAsciiMessageWithAdjustments("tag", "message", 0, 0, -1, 0));
  179. }
  180. TEST_F(CommandProcessorTest,
  181. ProcessCommandOnAsciiMessageWithBadMessageLengthSucceeds) {
  182. EXPECT_TRUE(SendAsciiMessageWithAdjustments("tag", "message", 0, 0, 0, 1));
  183. EXPECT_TRUE(SendAsciiMessageWithAdjustments("tag", "message", 0, 0, 0, -1));
  184. }
  185. TEST_F(CommandProcessorTest, ProcessCommandOnOverlyLargeAsciiMessageSucceeds) {
  186. const std::string tag{"tag"};
  187. EXPECT_TRUE(SendAsciiMessage(
  188. tag, std::string(kMaxAsciiMessagePayloadLen - tag.size() + 1, '.')));
  189. }
  190. TEST_F(CommandProcessorTest, ProcessCommandInvalidOpcodeReturnsFailure) {
  191. using opcode_enum_t = decltype(protocol::Command::opcode);
  192. using opcode_integral_t = std::underlying_type<opcode_enum_t>::type;
  193. constexpr auto invalid_opcode = GetMaxVal<opcode_integral_t>();
  194. const auto command =
  195. protocol::Command()
  196. .set_opcode(local_utils::CopyFromBufferOrDie<opcode_enum_t>(
  197. &invalid_opcode, sizeof(invalid_opcode)))
  198. .set_payload_len(0);
  199. const auto buf = CommandBuffer().AppendOrDie(&command, sizeof(command));
  200. constexpr int kFakeFd = 100;
  201. EXPECT_FALSE(
  202. command_processor_->ProcessCommand(buf.data(), buf.size(), kFakeFd));
  203. }
  204. TEST_F(CommandProcessorTest, ProcessCommandSucceedsEvenAfterFillingBuffer) {
  205. const std::string tag{"tag"};
  206. const std::string message(kMaxAsciiMessagePayloadLen - tag.size(), '.');
  207. for (size_t cumulative_payload_bytes = 0;
  208. cumulative_payload_bytes <= kBufferSizeBytes;
  209. cumulative_payload_bytes += (tag.size() + message.size())) {
  210. EXPECT_TRUE(SendAsciiMessage(tag, message));
  211. }
  212. }
  213. TEST_F(CommandProcessorTest,
  214. ProcessCommandDumpBuffersOutputIncludesCorrectlyFormattedTimestamps) {
  215. const CommandBuffer& command_buf(BuildAsciiMessageCommand("tag", "message"));
  216. EXPECT_CALL(*os_, GetTimestamp(CLOCK_MONOTONIC))
  217. .WillOnce(Return(Os::Timestamp{0, 999}));
  218. EXPECT_CALL(*os_, GetTimestamp(CLOCK_BOOTTIME))
  219. .WillOnce(Return(Os::Timestamp{1, 1000}));
  220. EXPECT_CALL(*os_, GetTimestamp(CLOCK_REALTIME))
  221. .WillOnce(Return(Os::Timestamp{123456, 123456000}));
  222. EXPECT_TRUE(command_processor_->ProcessCommand(
  223. command_buf.data(), command_buf.size(), Os::kInvalidFd));
  224. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  225. EXPECT_TRUE(SendDumpBuffers());
  226. EXPECT_THAT(written_to_os_, StartsWith("0.000000 1.000001 123456.123456"));
  227. }
  228. TEST_F(CommandProcessorTest, ProcessCommandDumpBuffersSucceedsOnEmptyLog) {
  229. EXPECT_CALL(*os_, Write(_, _, _)).Times(0);
  230. EXPECT_TRUE(SendDumpBuffers());
  231. }
  232. TEST_F(CommandProcessorTest, ProcessCommandDumpBuffersIncludesAllMessages) {
  233. constexpr int kNumMessages = 5;
  234. for (size_t i = 0; i < kNumMessages; ++i) {
  235. ASSERT_TRUE(SendAsciiMessage("tag", "message"));
  236. }
  237. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  238. EXPECT_TRUE(SendDumpBuffers());
  239. EXPECT_EQ(kNumMessages,
  240. std::count(written_to_os_.begin(), written_to_os_.end(),
  241. kLogRecordSeparator));
  242. }
  243. TEST_F(CommandProcessorTest,
  244. ProcessCommandDumpBuffersAsciiMessageIncludesTagAndMessage) {
  245. ASSERT_TRUE(SendAsciiMessage("tag", "message"));
  246. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  247. ASSERT_TRUE(SendDumpBuffers());
  248. EXPECT_THAT(written_to_os_, EndsWith("tag message\n"));
  249. }
  250. TEST_F(CommandProcessorTest,
  251. ProcessCommandDumpBuffersAsciiMessageHandlesEmptyTag) {
  252. ASSERT_TRUE(SendAsciiMessage("", "message"));
  253. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  254. ASSERT_TRUE(SendDumpBuffers());
  255. EXPECT_THAT(written_to_os_, EndsWith("[empty] message\n"));
  256. }
  257. TEST_F(CommandProcessorTest,
  258. ProcessCommandDumpBuffersAsciiMessageHandlesEmptyMessage) {
  259. ASSERT_TRUE(SendAsciiMessage("tag", ""));
  260. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  261. ASSERT_TRUE(SendDumpBuffers());
  262. EXPECT_THAT(written_to_os_, EndsWith("tag [empty]\n"));
  263. }
  264. TEST_F(CommandProcessorTest,
  265. ProcessCommandDumpBuffersAsciiMessageHandlesEmptyTagAndEmptyMessage) {
  266. ASSERT_TRUE(SendAsciiMessage("", ""));
  267. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  268. ASSERT_TRUE(SendDumpBuffers());
  269. EXPECT_THAT(written_to_os_, EndsWith("[empty] [empty]\n"));
  270. }
  271. TEST_F(CommandProcessorTest,
  272. ProcessCommandDumpBuffersAsciiMessageSanitizesUnprintableChars) {
  273. ASSERT_TRUE(SendAsciiMessage("\xfftag\xff", "\xffmessage\xff"));
  274. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  275. ASSERT_TRUE(SendDumpBuffers());
  276. EXPECT_THAT(written_to_os_, EndsWith("?tag? ?message?\n"));
  277. }
  278. TEST_F(
  279. CommandProcessorTest,
  280. ProcessCommandDumpBuffersAsciiMessageHandlesMessageTooShortForAsciiMessage) { // NOLINT(whitespace/line_length)
  281. ASSERT_TRUE(SendAsciiMessageWithAdjustments("", "", -1, 0, 0, 0));
  282. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  283. ASSERT_TRUE(SendDumpBuffers());
  284. EXPECT_THAT(written_to_os_, EndsWith("[truncated-header]\n"));
  285. }
  286. TEST_F(CommandProcessorTest,
  287. ProcessCommandDumpBuffersAsciiMessageHandlesMessageTooShortForTagStart) {
  288. constexpr char kTag[] = "tag";
  289. constexpr char kMessage[] = "message";
  290. ASSERT_TRUE(SendAsciiMessageWithAdjustments(
  291. kTag, kMessage, -(std::strlen(kTag) + std::strlen(kMessage)), 0, 0, 0));
  292. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  293. ASSERT_TRUE(SendDumpBuffers());
  294. EXPECT_THAT(written_to_os_, EndsWith("[buffer-overrun] [buffer-overrun]\n"));
  295. }
  296. TEST_F(CommandProcessorTest,
  297. ProcessCommandDumpBuffersAsciiMessageHandlesMessageTooShortForTagEnd) {
  298. constexpr char kTag[] = "tag";
  299. constexpr char kMessage[] = "message";
  300. ASSERT_TRUE(SendAsciiMessageWithAdjustments(
  301. kTag, kMessage, -(1 + std::strlen(kMessage)), 0, 0, 0));
  302. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  303. ASSERT_TRUE(SendDumpBuffers());
  304. EXPECT_THAT(written_to_os_,
  305. EndsWith("ta[buffer-overrun] [buffer-overrun]\n"));
  306. }
  307. TEST_F(
  308. CommandProcessorTest,
  309. ProcessCommandDumpBuffersAsciiMessageHandlesMessageTooShortForLogMessageStart) { // NOLINT(whitespace/line_length)
  310. constexpr char kTag[] = "tag";
  311. constexpr char kMessage[] = "message";
  312. ASSERT_TRUE(SendAsciiMessageWithAdjustments(kTag, kMessage,
  313. -std::strlen(kMessage), 0, 0, 0));
  314. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  315. ASSERT_TRUE(SendDumpBuffers());
  316. EXPECT_THAT(written_to_os_, EndsWith("tag [buffer-overrun]\n"));
  317. }
  318. TEST_F(
  319. CommandProcessorTest,
  320. ProcessCommandDumpBuffersAsciiMessageHandlesMessageTooShortForLogMessageEnd) { // NOLINT(whitespace/line_length)
  321. ASSERT_TRUE(SendAsciiMessageWithAdjustments("tag", "message", -1, 0, 0, 0));
  322. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  323. ASSERT_TRUE(SendDumpBuffers());
  324. EXPECT_THAT(written_to_os_, EndsWith("tag messag[buffer-overrun]\n"));
  325. }
  326. TEST_F(CommandProcessorTest,
  327. ProcessCommandDumpBuffersAsciiMessageHandlesMessageTooLongForTag) {
  328. ASSERT_TRUE(SendAsciiMessageWithAdjustments("tag", "", 100, 0, 0, 0));
  329. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  330. ASSERT_TRUE(SendDumpBuffers());
  331. EXPECT_THAT(written_to_os_, EndsWith("tag [empty]\n"));
  332. }
  333. TEST_F(CommandProcessorTest,
  334. ProcessCommandDumpBuffersAsciiMessageHandlesMessageTooLongForMessage) {
  335. ASSERT_TRUE(SendAsciiMessageWithAdjustments("tag", "message", 100, 0, 0, 0));
  336. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  337. ASSERT_TRUE(SendDumpBuffers());
  338. EXPECT_THAT(written_to_os_, EndsWith("tag message\n"));
  339. }
  340. TEST_F(CommandProcessorTest, ProcessCommandDumpBuffersStopsAfterFirstError) {
  341. ASSERT_TRUE(SendAsciiMessage("tag", "message"));
  342. ASSERT_TRUE(SendAsciiMessage("tag", "message"));
  343. EXPECT_CALL(*os_, Write(_, _, _))
  344. .WillOnce(Return(std::tuple<size_t, Os::Errno>{-1, EBADF}));
  345. ASSERT_FALSE(SendDumpBuffers());
  346. }
  347. TEST_F(CommandProcessorTest, ProcessCommandDumpBuffersContinuesPastEintr) {
  348. constexpr int kNumMessages = 5;
  349. for (size_t i = 0; i < kNumMessages; ++i) {
  350. ASSERT_TRUE(SendAsciiMessage("tag", "message"));
  351. }
  352. std::string written_to_os;
  353. EXPECT_CALL(*os_, Write(_, _, _))
  354. .WillRepeatedly(Invoke(
  355. [&written_to_os](int /*fd*/, const void* write_buf, size_t buflen) {
  356. written_to_os.append(static_cast<const char*>(write_buf), buflen);
  357. return std::tuple<size_t, Os::Errno>{buflen / 2, EINTR};
  358. }));
  359. EXPECT_TRUE(SendDumpBuffers());
  360. EXPECT_EQ(kNumMessages, std::count(written_to_os.begin(), written_to_os.end(),
  361. kLogRecordSeparator));
  362. }
  363. TEST_F(CommandProcessorTest, ProcessCommandDumpBuffersIsIdempotent) {
  364. ASSERT_TRUE(SendAsciiMessage("tag", "message"));
  365. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  366. ASSERT_TRUE(SendDumpBuffers());
  367. ASSERT_GT(written_to_os_.size(), 0U);
  368. written_to_os_.clear();
  369. ASSERT_EQ(0U, written_to_os_.size());
  370. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  371. EXPECT_TRUE(SendDumpBuffers());
  372. EXPECT_GT(written_to_os_.size(), 0U);
  373. }
  374. TEST_F(CommandProcessorTest,
  375. ProcessCommandDumpBuffersIsIdempotentEvenWithWriteFailure) {
  376. ASSERT_TRUE(SendAsciiMessage("tag", "message"));
  377. EXPECT_CALL(*os_, Write(_, _, _))
  378. .WillOnce(Return(std::tuple<size_t, Os::Errno>{-1, EBADF}));
  379. ASSERT_FALSE(SendDumpBuffers());
  380. ASSERT_EQ(0U, written_to_os_.size());
  381. EXPECT_CALL(*os_, Write(_, _, _)).Times(AtLeast(1));
  382. EXPECT_TRUE(SendDumpBuffers());
  383. EXPECT_GT(written_to_os_.size(), 0U);
  384. }
  385. // Strictly speaking, this is not a unit test. But there's no easy way to get
  386. // unique_fd to call on an instance of our Os.
  387. TEST_F(CommandProcessorTest, ProcessCommandClosesFd) {
  388. int pipe_fds[2];
  389. ASSERT_EQ(0, pipe(pipe_fds));
  390. const unique_fd our_fd{pipe_fds[0]};
  391. const int their_fd = pipe_fds[1];
  392. const CommandBuffer& command_buffer(
  393. BuildAsciiMessageCommand("tag", "message"));
  394. EXPECT_CALL(*os_, GetTimestamp(_)).Times(AnyNumber());
  395. EXPECT_TRUE(command_processor_->ProcessCommand(
  396. command_buffer.data(), command_buffer.size(), their_fd));
  397. EXPECT_EQ(-1, close(their_fd));
  398. EXPECT_EQ(EBADF, errno);
  399. }
  400. // Strictly speaking, this is not a unit test. But there's no easy way to get
  401. // unique_fd to call on an instance of our Os.
  402. TEST_F(CommandProcessorTest, ProcessCommandClosesFdEvenOnFailure) {
  403. int pipe_fds[2];
  404. ASSERT_EQ(0, pipe(pipe_fds));
  405. const unique_fd our_fd{pipe_fds[0]};
  406. const int their_fd = pipe_fds[1];
  407. const CommandBuffer command_buffer;
  408. EXPECT_FALSE(command_processor_->ProcessCommand(
  409. command_buffer.data(), command_buffer.size(), their_fd));
  410. EXPECT_EQ(-1, close(their_fd));
  411. EXPECT_EQ(EBADF, errno);
  412. }
  413. } // namespace wifilogd
  414. } // namespace android