fake_file_operations.cc 9.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283
  1. // Copyright 2018 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/fake_file_operations.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/bind.h"
  9. #include "base/memory/raw_ptr.h"
  10. #include "base/memory/weak_ptr.h"
  11. #include "base/threading/sequenced_task_runner_handle.h"
  12. namespace remoting {
  13. class FakeFileOperations::FakeFileReader : public FileOperations::Reader {
  14. public:
  15. FakeFileReader(TestIo* test_io);
  16. ~FakeFileReader() override;
  17. void Open(OpenCallback callback) override;
  18. void ReadChunk(std::size_t size, ReadCallback callback) override;
  19. const base::FilePath& filename() const override;
  20. std::uint64_t size() const override;
  21. State state() const override;
  22. private:
  23. void DoOpen(OpenCallback callback);
  24. void DoReadChunk(std::size_t size, ReadCallback callback);
  25. FileOperations::State state_ = FileOperations::kCreated;
  26. raw_ptr<TestIo> test_io_;
  27. protocol::FileTransferResult<InputFile> input_file_;
  28. base::FilePath filename_;
  29. std::size_t filesize_ = 0;
  30. std::size_t read_offset_ = 0;
  31. base::WeakPtrFactory<FakeFileReader> weak_ptr_factory_{this};
  32. };
  33. class FakeFileOperations::FakeFileWriter : public FileOperations::Writer {
  34. public:
  35. FakeFileWriter(TestIo* test_io);
  36. ~FakeFileWriter() override;
  37. void Open(const base::FilePath& filename, Callback callback) override;
  38. void WriteChunk(std::vector<std::uint8_t> data, Callback callback) override;
  39. void Close(Callback callback) override;
  40. FileOperations::State state() const override;
  41. private:
  42. void DoOpen(Callback callback);
  43. void DoWrite(std::vector<std::uint8_t> data, Callback callback);
  44. void DoClose(Callback callback);
  45. FileOperations::State state_ = FileOperations::kCreated;
  46. raw_ptr<TestIo> test_io_;
  47. base::FilePath filename_;
  48. std::vector<std::vector<std::uint8_t>> chunks_;
  49. base::WeakPtrFactory<FakeFileWriter> weak_ptr_factory_{this};
  50. };
  51. std::unique_ptr<FileOperations::Reader> FakeFileOperations::CreateReader() {
  52. return std::make_unique<FakeFileReader>(test_io_);
  53. }
  54. std::unique_ptr<FileOperations::Writer> FakeFileOperations::CreateWriter() {
  55. return std::make_unique<FakeFileWriter>(test_io_);
  56. }
  57. FakeFileOperations::FakeFileOperations(FakeFileOperations::TestIo* test_io)
  58. : test_io_(test_io) {}
  59. FakeFileOperations::~FakeFileOperations() = default;
  60. FakeFileOperations::OutputFile::OutputFile(
  61. base::FilePath filename,
  62. bool failed,
  63. std::vector<std::vector<std::uint8_t>> chunks)
  64. : filename(std::move(filename)),
  65. failed(failed),
  66. chunks(std::move(chunks)) {}
  67. FakeFileOperations::OutputFile::OutputFile(const OutputFile& other) = default;
  68. FakeFileOperations::OutputFile::OutputFile(OutputFile&& other) = default;
  69. FakeFileOperations::OutputFile& FakeFileOperations::OutputFile::operator=(
  70. const OutputFile&) = default;
  71. FakeFileOperations::OutputFile& FakeFileOperations::OutputFile::operator=(
  72. OutputFile&&) = default;
  73. FakeFileOperations::OutputFile::~OutputFile() = default;
  74. FakeFileOperations::InputFile::InputFile(
  75. base::FilePath filename,
  76. std::vector<std::uint8_t> data,
  77. absl::optional<protocol::FileTransfer_Error> io_error)
  78. : filename(std::move(filename)),
  79. data(std::move(data)),
  80. io_error(std::move(io_error)) {}
  81. FakeFileOperations::InputFile::InputFile() = default;
  82. FakeFileOperations::InputFile::InputFile(const InputFile&) = default;
  83. FakeFileOperations::InputFile::InputFile(InputFile&&) = default;
  84. FakeFileOperations::InputFile& FakeFileOperations::InputFile::operator=(
  85. const InputFile&) = default;
  86. FakeFileOperations::InputFile& FakeFileOperations::InputFile::operator=(
  87. InputFile&&) = default;
  88. FakeFileOperations::InputFile::~InputFile() = default;
  89. FakeFileOperations::TestIo::TestIo() = default;
  90. FakeFileOperations::TestIo::TestIo(const TestIo& other) = default;
  91. FakeFileOperations::TestIo::~TestIo() = default;
  92. FakeFileOperations::FakeFileReader::FakeFileReader(TestIo* test_io)
  93. : test_io_(test_io) {}
  94. FakeFileOperations::FakeFileReader::~FakeFileReader() = default;
  95. void FakeFileOperations::FakeFileReader::Open(
  96. FileOperations::Reader::OpenCallback callback) {
  97. CHECK_EQ(kCreated, state_) << "Open called twice";
  98. state_ = kBusy;
  99. input_file_ = test_io_->input_file;
  100. base::SequencedTaskRunnerHandle::Get()->PostTask(
  101. FROM_HERE,
  102. base::BindOnce(&FakeFileReader::DoOpen, weak_ptr_factory_.GetWeakPtr(),
  103. std::move(callback)));
  104. }
  105. void FakeFileOperations::FakeFileReader::ReadChunk(
  106. std::size_t size,
  107. FileOperations::Reader::ReadCallback callback) {
  108. CHECK_EQ(kReady, state_) << "ReadChunk called when writer not ready";
  109. state_ = kBusy;
  110. base::SequencedTaskRunnerHandle::Get()->PostTask(
  111. FROM_HERE, base::BindOnce(&FakeFileReader::DoReadChunk,
  112. weak_ptr_factory_.GetWeakPtr(), size,
  113. std::move(callback)));
  114. }
  115. const base::FilePath& FakeFileOperations::FakeFileReader::filename() const {
  116. return filename_;
  117. }
  118. std::uint64_t FakeFileOperations::FakeFileReader::size() const {
  119. return filesize_;
  120. }
  121. FileOperations::State FakeFileOperations::FakeFileReader::state() const {
  122. return state_;
  123. }
  124. void FakeFileOperations::FakeFileReader::DoOpen(
  125. FileOperations::Reader::OpenCallback callback) {
  126. if (input_file_) {
  127. filename_ = input_file_->filename;
  128. filesize_ = input_file_->data.size();
  129. state_ = kReady;
  130. std::move(callback).Run(kSuccessTag);
  131. } else {
  132. state_ = kFailed;
  133. std::move(callback).Run(input_file_.error());
  134. }
  135. }
  136. void FakeFileOperations::FakeFileReader::DoReadChunk(
  137. std::size_t size,
  138. FileOperations::Reader::ReadCallback callback) {
  139. if (size == 0) {
  140. state_ = kReady;
  141. std::move(callback).Run(std::vector<std::uint8_t>());
  142. return;
  143. }
  144. std::size_t remaining_data = input_file_->data.size() - read_offset_;
  145. if (remaining_data == 0) {
  146. if (input_file_->io_error) {
  147. state_ = kFailed;
  148. std::move(callback).Run(*input_file_->io_error);
  149. } else {
  150. state_ = kComplete;
  151. std::move(callback).Run(std::vector<std::uint8_t>());
  152. }
  153. return;
  154. }
  155. std::size_t read_size = std::min(size, remaining_data);
  156. state_ = kReady;
  157. std::move(callback).Run(std::vector<std::uint8_t>(
  158. input_file_->data.begin() + read_offset_,
  159. input_file_->data.begin() + read_offset_ + read_size));
  160. read_offset_ += read_size;
  161. }
  162. FakeFileOperations::FakeFileWriter::FakeFileWriter(TestIo* test_io)
  163. : test_io_(test_io) {}
  164. FakeFileOperations::FakeFileWriter::~FakeFileWriter() {
  165. if (state_ == FileOperations::kCreated ||
  166. state_ == FileOperations::kComplete ||
  167. state_ == FileOperations::kFailed) {
  168. return;
  169. }
  170. test_io_->files_written.push_back(
  171. OutputFile(filename_, true /* failed */, std::move(chunks_)));
  172. }
  173. void FakeFileOperations::FakeFileWriter::Open(const base::FilePath& filename,
  174. Callback callback) {
  175. CHECK_EQ(kCreated, state_) << "Open called twice";
  176. state_ = kBusy;
  177. filename_ = filename;
  178. base::SequencedTaskRunnerHandle::Get()->PostTask(
  179. FROM_HERE,
  180. base::BindOnce(&FakeFileWriter::DoOpen, weak_ptr_factory_.GetWeakPtr(),
  181. std::move(callback)));
  182. }
  183. void FakeFileOperations::FakeFileWriter::WriteChunk(
  184. std::vector<std::uint8_t> data,
  185. Callback callback) {
  186. CHECK_EQ(kReady, state_) << "WriteChunk called when writer not ready";
  187. state_ = kBusy;
  188. base::SequencedTaskRunnerHandle::Get()->PostTask(
  189. FROM_HERE,
  190. base::BindOnce(&FakeFileWriter::DoWrite, weak_ptr_factory_.GetWeakPtr(),
  191. std::move(data), std::move(callback)));
  192. }
  193. void FakeFileOperations::FakeFileWriter::Close(Callback callback) {
  194. CHECK_EQ(kReady, state_) << "Close called when writer not ready";
  195. state_ = kBusy;
  196. base::SequencedTaskRunnerHandle::Get()->PostTask(
  197. FROM_HERE,
  198. base::BindOnce(&FakeFileWriter::DoClose, weak_ptr_factory_.GetWeakPtr(),
  199. std::move(callback)));
  200. }
  201. FileOperations::State FakeFileOperations::FakeFileWriter::state() const {
  202. return state_;
  203. }
  204. void FakeFileOperations::FakeFileWriter::DoOpen(Callback callback) {
  205. if (!test_io_->io_error) {
  206. state_ = kReady;
  207. std::move(callback).Run(kSuccessTag);
  208. } else {
  209. state_ = kFailed;
  210. std::move(callback).Run(*test_io_->io_error);
  211. }
  212. }
  213. void FakeFileOperations::FakeFileWriter::DoWrite(std::vector<std::uint8_t> data,
  214. Callback callback) {
  215. if (!test_io_->io_error) {
  216. chunks_.push_back(std::move(data));
  217. state_ = kReady;
  218. std::move(callback).Run(kSuccessTag);
  219. } else {
  220. state_ = kFailed;
  221. test_io_->files_written.push_back(
  222. OutputFile(filename_, true /* failed */, std::move(chunks_)));
  223. std::move(callback).Run(*test_io_->io_error);
  224. }
  225. }
  226. void FakeFileOperations::FakeFileWriter::DoClose(Callback callback) {
  227. if (!test_io_->io_error) {
  228. test_io_->files_written.push_back(
  229. OutputFile(filename_, false /* failed */, std::move(chunks_)));
  230. state_ = kComplete;
  231. std::move(callback).Run(kSuccessTag);
  232. } else {
  233. state_ = kFailed;
  234. test_io_->files_written.push_back(
  235. OutputFile(filename_, true /* failed */, std::move(chunks_)));
  236. std::move(callback).Run(*test_io_->io_error);
  237. }
  238. }
  239. } // namespace remoting