file_transfer_message_handler_unittest.cc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441
  1. // Copyright 2017 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "remoting/host/file_transfer/file_transfer_message_handler.h"
  5. #include <memory>
  6. #include <string>
  7. #include <utility>
  8. #include <vector>
  9. #include "base/bind.h"
  10. #include "base/containers/queue.h"
  11. #include "base/memory/ptr_util.h"
  12. #include "base/test/task_environment.h"
  13. #include "base/threading/sequenced_task_runner_handle.h"
  14. #include "net/base/io_buffer.h"
  15. #include "remoting/base/compound_buffer.h"
  16. #include "remoting/host/file_transfer/fake_file_operations.h"
  17. #include "remoting/host/file_transfer/test_byte_vector_utils.h"
  18. #include "remoting/protocol/fake_message_pipe.h"
  19. #include "remoting/protocol/fake_message_pipe_wrapper.h"
  20. #include "remoting/protocol/file_transfer_helpers.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. namespace {
  23. constexpr char kTestDatachannelName[] = "filetransfer-test";
  24. constexpr char kTestFilename[] = "test-file.txt";
  25. std::unique_ptr<remoting::CompoundBuffer> StringToBuffer(
  26. const std::string& data) {
  27. std::unique_ptr<remoting::CompoundBuffer> buffer =
  28. std::make_unique<remoting::CompoundBuffer>();
  29. buffer->Append(base::MakeRefCounted<net::StringIOBuffer>(data.data()),
  30. data.size());
  31. return buffer;
  32. }
  33. std::unique_ptr<remoting::CompoundBuffer> MessageToBuffer(
  34. const remoting::protocol::FileTransfer& message) {
  35. return StringToBuffer(message.SerializeAsString());
  36. }
  37. std::unique_ptr<remoting::CompoundBuffer> DataToBuffer(
  38. const std::vector<std::uint8_t>& data) {
  39. remoting::protocol::FileTransfer message;
  40. message.mutable_data()->set_data(std::string(data.begin(), data.end()));
  41. return MessageToBuffer(message);
  42. }
  43. // base::queue doesn't provide operator==.
  44. template <typename T>
  45. bool QueuesEqual(const base::queue<T>& a, const base::queue<T>& b) {
  46. if (a.size() != b.size())
  47. return false;
  48. auto a_copy = a;
  49. auto b_copy = b;
  50. while (!a_copy.empty()) {
  51. if (a_copy.front() != b_copy.front())
  52. return false;
  53. a_copy.pop();
  54. b_copy.pop();
  55. }
  56. return true;
  57. }
  58. } // namespace
  59. namespace remoting {
  60. class FileTransferMessageHandlerTest : public testing::Test {
  61. public:
  62. FileTransferMessageHandlerTest();
  63. ~FileTransferMessageHandlerTest() override;
  64. // testing::Test implementation.
  65. void SetUp() override;
  66. void TearDown() override;
  67. protected:
  68. const std::vector<std::uint8_t> kTestDataOne =
  69. ByteArrayFrom("this is the first test string");
  70. const std::vector<std::uint8_t> kTestDataTwo =
  71. ByteArrayFrom("this is the second test string");
  72. const std::vector<std::uint8_t> kTestDataThree =
  73. ByteArrayFrom("this is the third test string");
  74. base::test::TaskEnvironment task_environment_;
  75. std::unique_ptr<protocol::FakeMessagePipe> fake_pipe_;
  76. protocol::FileTransfer fake_metadata_;
  77. protocol::FileTransfer fake_end_;
  78. protocol::FileTransfer fake_request_transfer_;
  79. protocol::FileTransfer fake_success_;
  80. };
  81. FileTransferMessageHandlerTest::FileTransferMessageHandlerTest()
  82. : task_environment_(
  83. base::test::TaskEnvironment::MainThreadType::DEFAULT,
  84. base::test::TaskEnvironment::ThreadPoolExecutionMode::QUEUED) {}
  85. FileTransferMessageHandlerTest::~FileTransferMessageHandlerTest() = default;
  86. void FileTransferMessageHandlerTest::SetUp() {
  87. fake_pipe_ =
  88. base::WrapUnique(new protocol::FakeMessagePipe(false /* asynchronous */));
  89. fake_metadata_.mutable_metadata()->set_filename(kTestFilename);
  90. fake_metadata_.mutable_metadata()->set_size(
  91. kTestDataOne.size() + kTestDataTwo.size() + kTestDataThree.size());
  92. fake_end_.mutable_end();
  93. fake_request_transfer_.mutable_request_transfer();
  94. fake_success_.mutable_success();
  95. }
  96. void FileTransferMessageHandlerTest::TearDown() {}
  97. // Upload tests.
  98. // Verifies that the message handler creates, writes to, and closes a
  99. // FileOperations::Writer without errors when given valid input.
  100. TEST_F(FileTransferMessageHandlerTest, WritesThreeChunks) {
  101. FakeFileOperations::TestIo test_io;
  102. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  103. // This will delete itself when fake_pipe_->ClosePipe() is called.
  104. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  105. std::move(file_operations));
  106. fake_pipe_->OpenPipe();
  107. fake_pipe_->Receive(MessageToBuffer(fake_metadata_));
  108. fake_pipe_->Receive(DataToBuffer(kTestDataOne));
  109. fake_pipe_->Receive(DataToBuffer(kTestDataTwo));
  110. fake_pipe_->Receive(DataToBuffer(kTestDataThree));
  111. fake_pipe_->Receive(MessageToBuffer(fake_end_));
  112. task_environment_.RunUntilIdle();
  113. fake_pipe_->ClosePipe();
  114. ASSERT_EQ(1ul, test_io.files_written.size());
  115. ASSERT_EQ(false, test_io.files_written[0].failed);
  116. std::vector<std::vector<std::uint8_t>> expected_chunks = {
  117. kTestDataOne, kTestDataTwo, kTestDataThree};
  118. ASSERT_EQ(expected_chunks, test_io.files_written[0].chunks);
  119. const base::queue<std::string>& actual_sent_messages =
  120. fake_pipe_->sent_messages();
  121. base::queue<std::string> expected_sent_messages;
  122. expected_sent_messages.push(fake_success_.SerializeAsString());
  123. ASSERT_TRUE(QueuesEqual(expected_sent_messages, actual_sent_messages));
  124. }
  125. // Verifies that the message handler sends an error protobuf when
  126. // FileOperations::Writer returns an error.
  127. TEST_F(FileTransferMessageHandlerTest, HandlesWriteError) {
  128. FakeFileOperations::TestIo test_io;
  129. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  130. protocol::FileTransfer_Error fake_error = protocol::MakeFileTransferError(
  131. FROM_HERE, protocol::FileTransfer_Error_Type_IO_ERROR);
  132. // This will delete itself when fake_pipe_->ClosePipe() is called.
  133. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  134. std::move(file_operations));
  135. fake_pipe_->OpenPipe();
  136. fake_pipe_->Receive(MessageToBuffer(fake_metadata_));
  137. fake_pipe_->Receive(DataToBuffer(kTestDataOne));
  138. fake_pipe_->Receive(DataToBuffer(kTestDataTwo));
  139. task_environment_.RunUntilIdle();
  140. test_io.io_error = fake_error;
  141. fake_pipe_->Receive(DataToBuffer(kTestDataTwo));
  142. fake_pipe_->Receive(MessageToBuffer(fake_end_));
  143. task_environment_.RunUntilIdle();
  144. fake_pipe_->ClosePipe();
  145. const base::queue<std::string>& actual_sent_messages =
  146. fake_pipe_->sent_messages();
  147. protocol::FileTransfer expected_response;
  148. *expected_response.mutable_error() = fake_error;
  149. base::queue<std::string> expected_sent_messages;
  150. expected_sent_messages.push(expected_response.SerializeAsString());
  151. ASSERT_TRUE(QueuesEqual(expected_sent_messages, actual_sent_messages));
  152. }
  153. // Verifies that the message handler cancels the write if an error is received
  154. // from the sender.
  155. TEST_F(FileTransferMessageHandlerTest, HandlesErrorMessage) {
  156. FakeFileOperations::TestIo test_io;
  157. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  158. // This will delete itself when fake_pipe_->ClosePipe() is called.
  159. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  160. std::move(file_operations));
  161. protocol::FileTransfer fake_error_message;
  162. *fake_error_message.mutable_error() = protocol::MakeFileTransferError(
  163. FROM_HERE, protocol::FileTransfer_Error_Type_IO_ERROR);
  164. fake_pipe_->OpenPipe();
  165. fake_pipe_->Receive(MessageToBuffer(fake_metadata_));
  166. fake_pipe_->Receive(DataToBuffer(kTestDataOne));
  167. fake_pipe_->Receive(DataToBuffer(kTestDataTwo));
  168. task_environment_.RunUntilIdle();
  169. fake_pipe_->Receive(MessageToBuffer(fake_error_message));
  170. task_environment_.RunUntilIdle();
  171. fake_pipe_->ClosePipe();
  172. ASSERT_EQ(1ul, test_io.files_written.size());
  173. ASSERT_EQ(true, test_io.files_written[0].failed);
  174. std::vector<std::vector<std::uint8_t>> expected_chunks = {kTestDataOne,
  175. kTestDataTwo};
  176. ASSERT_EQ(expected_chunks, test_io.files_written[0].chunks);
  177. const base::queue<std::string>& actual_sent_messages =
  178. fake_pipe_->sent_messages();
  179. // No messages
  180. base::queue<std::string> expected_sent_messages;
  181. ASSERT_TRUE(QueuesEqual(expected_sent_messages, actual_sent_messages));
  182. }
  183. // Verifies that the message handler cancels the write if the connection is
  184. // closed prematurely.
  185. TEST_F(FileTransferMessageHandlerTest, HandlesPrematureClose) {
  186. FakeFileOperations::TestIo test_io;
  187. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  188. // This will delete itself when fake_pipe_->ClosePipe() is called.
  189. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  190. std::move(file_operations));
  191. fake_pipe_->OpenPipe();
  192. fake_pipe_->Receive(MessageToBuffer(fake_metadata_));
  193. fake_pipe_->Receive(DataToBuffer(kTestDataOne));
  194. fake_pipe_->Receive(DataToBuffer(kTestDataTwo));
  195. task_environment_.RunUntilIdle();
  196. fake_pipe_->ClosePipe();
  197. ASSERT_EQ(1ul, test_io.files_written.size());
  198. ASSERT_EQ(true, test_io.files_written[0].failed);
  199. std::vector<std::vector<std::uint8_t>> expected_chunks = {kTestDataOne,
  200. kTestDataTwo};
  201. ASSERT_EQ(expected_chunks, test_io.files_written[0].chunks);
  202. }
  203. // Verifies that an error is sent if data is sent before/without metadata.
  204. TEST_F(FileTransferMessageHandlerTest, ErrorsOnMissingMetadata) {
  205. FakeFileOperations::TestIo test_io;
  206. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  207. // This will delete itself when fake_pipe_->ClosePipe() is called.
  208. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  209. std::move(file_operations));
  210. fake_pipe_->OpenPipe();
  211. fake_pipe_->Receive(DataToBuffer(kTestDataOne));
  212. fake_pipe_->Receive(DataToBuffer(kTestDataTwo));
  213. fake_pipe_->Receive(DataToBuffer(kTestDataThree));
  214. fake_pipe_->Receive(MessageToBuffer(fake_end_));
  215. task_environment_.RunUntilIdle();
  216. fake_pipe_->ClosePipe();
  217. ASSERT_EQ(0ul, test_io.files_written.size());
  218. const base::queue<std::string>& sent_messages = fake_pipe_->sent_messages();
  219. ASSERT_EQ(1ul, sent_messages.size());
  220. protocol::FileTransfer response;
  221. response.ParseFromString(sent_messages.front());
  222. ASSERT_EQ(protocol::FileTransfer::kError, response.message_case());
  223. ASSERT_EQ(protocol::FileTransfer_Error_Type_PROTOCOL_ERROR,
  224. response.error().type());
  225. }
  226. // Verifies that an error is sent if another metadata message is sent.
  227. TEST_F(FileTransferMessageHandlerTest, ErrorsOnNewMetadata) {
  228. FakeFileOperations::TestIo test_io;
  229. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  230. // This will delete itself when fake_pipe_->ClosePipe() is called.
  231. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  232. std::move(file_operations));
  233. fake_pipe_->OpenPipe();
  234. fake_pipe_->Receive(MessageToBuffer(fake_metadata_));
  235. fake_pipe_->Receive(DataToBuffer(kTestDataOne));
  236. fake_pipe_->Receive(DataToBuffer(kTestDataTwo));
  237. fake_pipe_->Receive(DataToBuffer(kTestDataThree));
  238. fake_pipe_->Receive(MessageToBuffer(fake_end_));
  239. task_environment_.RunUntilIdle();
  240. fake_pipe_->Receive(MessageToBuffer(fake_metadata_));
  241. fake_pipe_->ClosePipe();
  242. const base::queue<std::string>& sent_messages = fake_pipe_->sent_messages();
  243. // First is the success message, second should be a protocol error.
  244. ASSERT_EQ(2ul, sent_messages.size());
  245. protocol::FileTransfer response;
  246. response.ParseFromString(sent_messages.back());
  247. ASSERT_EQ(protocol::FileTransfer::kError, response.message_case());
  248. ASSERT_EQ(protocol::FileTransfer_Error_Type_PROTOCOL_ERROR,
  249. response.error().type());
  250. }
  251. // Verifies that an error is sent if more data is sent after Close.
  252. TEST_F(FileTransferMessageHandlerTest, ErrorsOnDataAfterClose) {
  253. FakeFileOperations::TestIo test_io;
  254. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  255. // This will delete itself when fake_pipe_->ClosePipe() is called.
  256. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  257. std::move(file_operations));
  258. fake_pipe_->OpenPipe();
  259. fake_pipe_->Receive(MessageToBuffer(fake_metadata_));
  260. fake_pipe_->Receive(DataToBuffer(kTestDataOne));
  261. fake_pipe_->Receive(DataToBuffer(kTestDataTwo));
  262. fake_pipe_->Receive(DataToBuffer(kTestDataThree));
  263. fake_pipe_->Receive(MessageToBuffer(fake_end_));
  264. fake_pipe_->Receive(DataToBuffer(kTestDataOne));
  265. task_environment_.RunUntilIdle();
  266. fake_pipe_->ClosePipe();
  267. ASSERT_EQ(1ul, test_io.files_written.size());
  268. ASSERT_EQ(true, test_io.files_written[0].failed);
  269. const base::queue<std::string>& sent_messages = fake_pipe_->sent_messages();
  270. // Because the error is triggered before RunUntilIdle is called, there should
  271. // be no complete message this time.
  272. ASSERT_EQ(1ul, sent_messages.size());
  273. protocol::FileTransfer response;
  274. response.ParseFromString(sent_messages.front());
  275. ASSERT_EQ(protocol::FileTransfer::kError, response.message_case());
  276. ASSERT_EQ(protocol::FileTransfer_Error_Type_PROTOCOL_ERROR,
  277. response.error().type());
  278. }
  279. // Download tests.
  280. // Verifies that the message handler will read and respond with a file when a
  281. // RequestTransfer message is received.
  282. TEST_F(FileTransferMessageHandlerTest, ReadsFile) {
  283. FakeFileOperations::TestIo test_io;
  284. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  285. test_io.input_file = FakeFileOperations::InputFile(
  286. base::FilePath::FromASCII(kTestFilename),
  287. ByteArrayFrom(kTestDataOne, kTestDataTwo, kTestDataThree), absl::nullopt);
  288. // This will delete itself when fake_pipe_->ClosePipe() is called.
  289. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  290. std::move(file_operations));
  291. fake_pipe_->OpenPipe();
  292. fake_pipe_->Receive(MessageToBuffer(fake_request_transfer_));
  293. task_environment_.RunUntilIdle();
  294. fake_pipe_->Receive(MessageToBuffer(fake_success_));
  295. task_environment_.RunUntilIdle();
  296. fake_pipe_->ClosePipe();
  297. const base::queue<std::string>& actual_sent_messages =
  298. fake_pipe_->sent_messages();
  299. base::queue<std::string> expected_sent_messages;
  300. expected_sent_messages.push(fake_metadata_.SerializeAsString());
  301. protocol::FileTransfer data;
  302. data.mutable_data()->set_data(std::string(test_io.input_file->data.begin(),
  303. test_io.input_file->data.end()));
  304. expected_sent_messages.push(data.SerializeAsString());
  305. expected_sent_messages.push(fake_end_.SerializeAsString());
  306. ASSERT_TRUE(QueuesEqual(expected_sent_messages, actual_sent_messages));
  307. }
  308. // Verifies that the message handler forwards errors from opening a file with
  309. // the reader.
  310. TEST_F(FileTransferMessageHandlerTest, ForwardsReaderOpenError) {
  311. FakeFileOperations::TestIo test_io;
  312. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  313. test_io.input_file = protocol::MakeFileTransferError(
  314. FROM_HERE, protocol::FileTransfer_Error_Type_CANCELED);
  315. // This will delete itself when fake_pipe_->ClosePipe() is called.
  316. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  317. std::move(file_operations));
  318. fake_pipe_->OpenPipe();
  319. fake_pipe_->Receive(MessageToBuffer(fake_request_transfer_));
  320. task_environment_.RunUntilIdle();
  321. fake_pipe_->ClosePipe();
  322. const base::queue<std::string>& actual_sent_messages =
  323. fake_pipe_->sent_messages();
  324. base::queue<std::string> expected_sent_messages;
  325. protocol::FileTransfer error;
  326. *error.mutable_error() = test_io.input_file.error();
  327. expected_sent_messages.push(error.SerializeAsString());
  328. ASSERT_TRUE(QueuesEqual(expected_sent_messages, actual_sent_messages));
  329. }
  330. // Verifies that the message handler forwards errors from reading a file.
  331. TEST_F(FileTransferMessageHandlerTest, ForwardsReadError) {
  332. FakeFileOperations::TestIo test_io;
  333. auto file_operations = std::make_unique<FakeFileOperations>(&test_io);
  334. test_io.input_file = FakeFileOperations::InputFile(
  335. base::FilePath::FromASCII(kTestFilename),
  336. ByteArrayFrom(kTestDataOne, kTestDataTwo, kTestDataThree),
  337. protocol::MakeFileTransferError(
  338. FROM_HERE, protocol::FileTransfer_Error_Type_IO_ERROR));
  339. // This will delete itself when fake_pipe_->ClosePipe() is called.
  340. new FileTransferMessageHandler(kTestDatachannelName, fake_pipe_->Wrap(),
  341. std::move(file_operations));
  342. fake_pipe_->OpenPipe();
  343. fake_pipe_->Receive(MessageToBuffer(fake_request_transfer_));
  344. task_environment_.RunUntilIdle();
  345. fake_pipe_->ClosePipe();
  346. const base::queue<std::string>& actual_sent_messages =
  347. fake_pipe_->sent_messages();
  348. base::queue<std::string> expected_sent_messages;
  349. expected_sent_messages.push(fake_metadata_.SerializeAsString());
  350. protocol::FileTransfer data;
  351. data.mutable_data()->set_data(std::string(test_io.input_file->data.begin(),
  352. test_io.input_file->data.end()));
  353. expected_sent_messages.push(data.SerializeAsString());
  354. protocol::FileTransfer error;
  355. *error.mutable_error() = *test_io.input_file->io_error;
  356. expected_sent_messages.push(error.SerializeAsString());
  357. ASSERT_TRUE(QueuesEqual(expected_sent_messages, actual_sent_messages));
  358. }
  359. } // namespace remoting