Home | History | Annotate | Download | only in streams
      1 // Copyright 2015 The Chromium OS 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 
      5 #include <brillo/streams/file_stream.h>
      6 
      7 #include <limits>
      8 #include <numeric>
      9 #include <string>
     10 #include <sys/stat.h>
     11 #include <vector>
     12 
     13 #include <base/files/file_util.h>
     14 #include <base/files/scoped_temp_dir.h>
     15 #include <base/message_loop/message_loop.h>
     16 #include <base/rand_util.h>
     17 #include <base/run_loop.h>
     18 #include <brillo/bind_lambda.h>
     19 #include <brillo/errors/error_codes.h>
     20 #include <brillo/message_loops/base_message_loop.h>
     21 #include <brillo/message_loops/message_loop_utils.h>
     22 #include <brillo/streams/stream_errors.h>
     23 #include <gmock/gmock.h>
     24 #include <gtest/gtest.h>
     25 
     26 using testing::InSequence;
     27 using testing::Return;
     28 using testing::ReturnArg;
     29 using testing::SaveArg;
     30 using testing::SetErrnoAndReturn;
     31 using testing::_;
     32 
     33 namespace brillo {
     34 
     35 namespace {
     36 
     37 // gmock action that would return a blocking situation from a read() or write().
     38 ACTION(ReturnWouldBlock) {
     39   errno = EWOULDBLOCK;
     40   return -1;
     41 }
     42 
     43 // Helper function to read one byte from the stream.
     44 inline int ReadByte(Stream* stream) {
     45   uint8_t byte = 0;
     46   return stream->ReadAllBlocking(&byte, sizeof(byte), nullptr) ? byte : -1;
     47 }
     48 
     49 // Helper function to write one byte from the stream.
     50 inline bool WriteByte(Stream* stream, uint8_t byte) {
     51   return stream->WriteAllBlocking(&byte, sizeof(byte), nullptr);
     52 }
     53 
     54 // Helper function to test file stream workflow on newly created file.
     55 void TestCreateFile(Stream* stream) {
     56   ASSERT_TRUE(stream->IsOpen());
     57 
     58   // Set up a sample data buffer.
     59   std::vector<uint8_t> in_buffer(256);
     60   std::iota(in_buffer.begin(), in_buffer.end(), 0);
     61 
     62   // Initial assumptions about empty file stream.
     63   EXPECT_TRUE(stream->CanRead());
     64   EXPECT_TRUE(stream->CanWrite());
     65   EXPECT_TRUE(stream->CanSeek());
     66   EXPECT_TRUE(stream->CanGetSize());
     67   EXPECT_EQ(0, stream->GetPosition());
     68   EXPECT_EQ(0, stream->GetSize());
     69 
     70   // Write sample data.
     71   EXPECT_TRUE(stream->WriteAllBlocking(in_buffer.data(), in_buffer.size(),
     72                                        nullptr));
     73   EXPECT_EQ(in_buffer.size(), stream->GetPosition());
     74   EXPECT_EQ(in_buffer.size(), stream->GetSize());
     75 
     76   // Rewind the stream to the beginning.
     77   uint64_t pos = 0;
     78   EXPECT_TRUE(stream->Seek(0, Stream::Whence::FROM_BEGIN, &pos, nullptr));
     79   EXPECT_EQ(0, pos);
     80   EXPECT_EQ(0, stream->GetPosition());
     81   EXPECT_EQ(in_buffer.size(), stream->GetSize());
     82 
     83   // Read the file contents back.
     84   std::vector<uint8_t> out_buffer(256);
     85   EXPECT_TRUE(stream->ReadAllBlocking(out_buffer.data(), out_buffer.size(),
     86                                       nullptr));
     87   EXPECT_EQ(out_buffer.size(), stream->GetPosition());
     88   EXPECT_EQ(out_buffer.size(), stream->GetSize());
     89 
     90   // Make sure the data read matches those written.
     91   EXPECT_EQ(in_buffer, out_buffer);
     92 
     93   // Random read/write
     94   EXPECT_TRUE(stream->Seek(10, Stream::Whence::FROM_BEGIN, &pos, nullptr));
     95   EXPECT_EQ(10, pos);
     96 
     97   // Since our data buffer contained values from 0 to 255, the byte at position
     98   // 10 will contain the value of 10.
     99   EXPECT_EQ(10, ReadByte(stream));
    100   EXPECT_EQ(11, ReadByte(stream));
    101   EXPECT_EQ(12, ReadByte(stream));
    102   EXPECT_TRUE(stream->Seek(7, Stream::Whence::FROM_CURRENT, nullptr, nullptr));
    103   EXPECT_EQ(20, ReadByte(stream));
    104 
    105   EXPECT_EQ(21, stream->GetPosition());
    106   EXPECT_TRUE(stream->Seek(-2, Stream::Whence::FROM_CURRENT, &pos, nullptr));
    107   EXPECT_EQ(19, pos);
    108   EXPECT_TRUE(WriteByte(stream, 100));
    109   EXPECT_EQ(20, ReadByte(stream));
    110   EXPECT_TRUE(stream->Seek(-2, Stream::Whence::FROM_CURRENT, nullptr, nullptr));
    111   EXPECT_EQ(100, ReadByte(stream));
    112   EXPECT_EQ(20, ReadByte(stream));
    113   EXPECT_TRUE(stream->Seek(-1, Stream::Whence::FROM_END, &pos, nullptr));
    114   EXPECT_EQ(255, pos);
    115   EXPECT_EQ(255, ReadByte(stream));
    116   EXPECT_EQ(-1, ReadByte(stream));
    117 }
    118 
    119 }  // anonymous namespace
    120 
    121 // A mock file descriptor wrapper to test low-level file API used by FileStream.
    122 class MockFileDescriptor : public FileStream::FileDescriptorInterface {
    123  public:
    124   MOCK_CONST_METHOD0(IsOpen, bool());
    125   MOCK_METHOD2(Read, ssize_t(void*, size_t));
    126   MOCK_METHOD2(Write, ssize_t(const void*, size_t));
    127   MOCK_METHOD2(Seek, off64_t(off64_t, int));
    128   MOCK_CONST_METHOD0(GetFileMode, mode_t());
    129   MOCK_CONST_METHOD0(GetSize, uint64_t());
    130   MOCK_CONST_METHOD1(Truncate, int(off64_t));
    131   MOCK_METHOD0(Flush, int());
    132   MOCK_METHOD0(Close, int());
    133   MOCK_METHOD3(WaitForData,
    134                bool(Stream::AccessMode, const DataCallback&, ErrorPtr*));
    135   MOCK_METHOD3(WaitForDataBlocking,
    136                int(Stream::AccessMode, base::TimeDelta, Stream::AccessMode*));
    137   MOCK_METHOD0(CancelPendingAsyncOperations, void());
    138 };
    139 
    140 class FileStreamTest : public testing::Test {
    141  public:
    142   void SetUp() override {
    143     CreateStream(S_IFREG, Stream::AccessMode::READ_WRITE);
    144   }
    145 
    146   MockFileDescriptor& fd_mock() {
    147     return *static_cast<MockFileDescriptor*>(stream_->fd_interface_.get());
    148   }
    149 
    150   void CreateStream(mode_t file_mode, Stream::AccessMode access_mode) {
    151     std::unique_ptr<MockFileDescriptor> fd{new MockFileDescriptor{}};
    152     EXPECT_CALL(*fd, GetFileMode()).WillOnce(Return(file_mode));
    153     stream_.reset(new FileStream(std::move(fd), access_mode));
    154     EXPECT_CALL(fd_mock(), IsOpen()).WillRepeatedly(Return(true));
    155   }
    156 
    157   void ExpectStreamClosed(const ErrorPtr& error) const {
    158     EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
    159     EXPECT_EQ(errors::stream::kStreamClosed, error->GetCode());
    160     EXPECT_EQ("Stream is closed", error->GetMessage());
    161   }
    162 
    163   void ExpectStreamOffsetTooLarge(const ErrorPtr& error) const {
    164     EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
    165     EXPECT_EQ(errors::stream::kInvalidParameter, error->GetCode());
    166     EXPECT_EQ("The stream offset value is out of range", error->GetMessage());
    167   }
    168 
    169   inline static char* IntToPtr(int addr) {
    170     return reinterpret_cast<char*>(addr);
    171   }
    172 
    173   inline static const char* IntToConstPtr(int addr) {
    174     return reinterpret_cast<const char*>(addr);
    175   }
    176 
    177   bool CallWaitForData(Stream::AccessMode mode, ErrorPtr* error) {
    178     return stream_->WaitForData(mode, {}, error);
    179   }
    180 
    181   std::unique_ptr<FileStream> stream_;
    182 
    183   const uint64_t kMaxSize = std::numeric_limits<int64_t>::max();
    184   const uint64_t kTooLargeSize = std::numeric_limits<uint64_t>::max();
    185 
    186   // Dummy buffer pointer values to make sure that input pointer values
    187   // are delegated to the file interface without a change.
    188   char* const test_read_buffer_ = IntToPtr(12345);
    189   const char* const test_write_buffer_ = IntToConstPtr(67890);
    190 };
    191 
    192 TEST_F(FileStreamTest, IsOpen) {
    193   EXPECT_TRUE(stream_->IsOpen());
    194   EXPECT_CALL(fd_mock(), IsOpen()).WillOnce(Return(false));
    195   EXPECT_FALSE(stream_->IsOpen());
    196 }
    197 
    198 TEST_F(FileStreamTest, CanRead) {
    199   CreateStream(S_IFREG, Stream::AccessMode::READ_WRITE);
    200   EXPECT_TRUE(stream_->CanRead());
    201   EXPECT_CALL(fd_mock(), IsOpen()).WillRepeatedly(Return(false));
    202   EXPECT_FALSE(stream_->CanRead());
    203   CreateStream(S_IFREG, Stream::AccessMode::READ);
    204   EXPECT_TRUE(stream_->CanRead());
    205   CreateStream(S_IFREG, Stream::AccessMode::WRITE);
    206   EXPECT_FALSE(stream_->CanRead());
    207 }
    208 
    209 TEST_F(FileStreamTest, CanWrite) {
    210   CreateStream(S_IFREG, Stream::AccessMode::READ_WRITE);
    211   EXPECT_TRUE(stream_->CanWrite());
    212   EXPECT_CALL(fd_mock(), IsOpen()).WillRepeatedly(Return(false));
    213   EXPECT_FALSE(stream_->CanWrite());
    214   CreateStream(S_IFREG, Stream::AccessMode::READ);
    215   EXPECT_FALSE(stream_->CanWrite());
    216   CreateStream(S_IFREG, Stream::AccessMode::WRITE);
    217   EXPECT_TRUE(stream_->CanWrite());
    218 }
    219 
    220 TEST_F(FileStreamTest, CanSeek) {
    221   CreateStream(S_IFBLK, Stream::AccessMode::READ_WRITE);
    222   EXPECT_TRUE(stream_->CanSeek());
    223   CreateStream(S_IFDIR, Stream::AccessMode::READ_WRITE);
    224   EXPECT_TRUE(stream_->CanSeek());
    225   CreateStream(S_IFREG, Stream::AccessMode::READ_WRITE);
    226   EXPECT_TRUE(stream_->CanSeek());
    227   CreateStream(S_IFLNK, Stream::AccessMode::READ_WRITE);
    228   EXPECT_TRUE(stream_->CanSeek());
    229   CreateStream(S_IFCHR, Stream::AccessMode::READ_WRITE);
    230   EXPECT_FALSE(stream_->CanSeek());
    231   CreateStream(S_IFSOCK, Stream::AccessMode::READ_WRITE);
    232   EXPECT_FALSE(stream_->CanSeek());
    233   CreateStream(S_IFIFO, Stream::AccessMode::READ_WRITE);
    234   EXPECT_FALSE(stream_->CanSeek());
    235 
    236   CreateStream(S_IFREG, Stream::AccessMode::READ);
    237   EXPECT_TRUE(stream_->CanSeek());
    238   CreateStream(S_IFREG, Stream::AccessMode::WRITE);
    239   EXPECT_TRUE(stream_->CanSeek());
    240 }
    241 
    242 TEST_F(FileStreamTest, CanGetSize) {
    243   CreateStream(S_IFBLK, Stream::AccessMode::READ_WRITE);
    244   EXPECT_TRUE(stream_->CanGetSize());
    245   CreateStream(S_IFDIR, Stream::AccessMode::READ_WRITE);
    246   EXPECT_TRUE(stream_->CanGetSize());
    247   CreateStream(S_IFREG, Stream::AccessMode::READ_WRITE);
    248   EXPECT_TRUE(stream_->CanGetSize());
    249   CreateStream(S_IFLNK, Stream::AccessMode::READ_WRITE);
    250   EXPECT_TRUE(stream_->CanGetSize());
    251   CreateStream(S_IFCHR, Stream::AccessMode::READ_WRITE);
    252   EXPECT_FALSE(stream_->CanGetSize());
    253   CreateStream(S_IFSOCK, Stream::AccessMode::READ_WRITE);
    254   EXPECT_FALSE(stream_->CanGetSize());
    255   CreateStream(S_IFIFO, Stream::AccessMode::READ_WRITE);
    256   EXPECT_FALSE(stream_->CanGetSize());
    257 
    258   CreateStream(S_IFREG, Stream::AccessMode::READ);
    259   EXPECT_TRUE(stream_->CanGetSize());
    260   CreateStream(S_IFREG, Stream::AccessMode::WRITE);
    261   EXPECT_TRUE(stream_->CanGetSize());
    262 }
    263 
    264 TEST_F(FileStreamTest, GetSize) {
    265   EXPECT_CALL(fd_mock(), GetSize()).WillRepeatedly(Return(12345));
    266   EXPECT_EQ(12345u, stream_->GetSize());
    267   EXPECT_CALL(fd_mock(), IsOpen()).WillOnce(Return(false));
    268   EXPECT_EQ(0u, stream_->GetSize());
    269 }
    270 
    271 TEST_F(FileStreamTest, SetSizeBlocking) {
    272   EXPECT_CALL(fd_mock(), Truncate(0)).WillOnce(Return(0));
    273   EXPECT_TRUE(stream_->SetSizeBlocking(0, nullptr));
    274 
    275   EXPECT_CALL(fd_mock(), Truncate(123)).WillOnce(Return(0));
    276   EXPECT_TRUE(stream_->SetSizeBlocking(123, nullptr));
    277 
    278   EXPECT_CALL(fd_mock(), Truncate(kMaxSize)).WillOnce(Return(0));
    279   EXPECT_TRUE(stream_->SetSizeBlocking(kMaxSize, nullptr));
    280 }
    281 
    282 TEST_F(FileStreamTest, SetSizeBlocking_Fail) {
    283   brillo::ErrorPtr error;
    284 
    285   EXPECT_CALL(fd_mock(), Truncate(1235)).WillOnce(SetErrnoAndReturn(EIO, -1));
    286   EXPECT_FALSE(stream_->SetSizeBlocking(1235, &error));
    287   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    288   EXPECT_EQ("EIO", error->GetCode());
    289 
    290   error.reset();
    291   EXPECT_FALSE(stream_->SetSizeBlocking(kTooLargeSize, &error));
    292   ExpectStreamOffsetTooLarge(error);
    293 
    294   error.reset();
    295   EXPECT_CALL(fd_mock(), IsOpen()).WillOnce(Return(false));
    296   EXPECT_FALSE(stream_->SetSizeBlocking(1235, &error));
    297   ExpectStreamClosed(error);
    298 }
    299 
    300 TEST_F(FileStreamTest, GetRemainingSize) {
    301   EXPECT_CALL(fd_mock(), Seek(0, SEEK_CUR)).WillOnce(Return(234));
    302   EXPECT_CALL(fd_mock(), GetSize()).WillOnce(Return(1234));
    303   EXPECT_EQ(1000u, stream_->GetRemainingSize());
    304 
    305   EXPECT_CALL(fd_mock(), Seek(0, SEEK_CUR)).WillOnce(Return(1234));
    306   EXPECT_CALL(fd_mock(), GetSize()).WillOnce(Return(1000));
    307   EXPECT_EQ(0u, stream_->GetRemainingSize());
    308 }
    309 
    310 TEST_F(FileStreamTest, Seek_Set) {
    311   uint64_t pos = 0;
    312 
    313   EXPECT_CALL(fd_mock(), Seek(0, SEEK_SET)).WillOnce(Return(0));
    314   EXPECT_TRUE(stream_->Seek(0, Stream::Whence::FROM_BEGIN, &pos, nullptr));
    315   EXPECT_EQ(0u, pos);
    316 
    317   EXPECT_CALL(fd_mock(), Seek(123456, SEEK_SET)).WillOnce(Return(123456));
    318   EXPECT_TRUE(stream_->Seek(123456, Stream::Whence::FROM_BEGIN, &pos, nullptr));
    319   EXPECT_EQ(123456u, pos);
    320 
    321   EXPECT_CALL(fd_mock(), Seek(kMaxSize, SEEK_SET))
    322       .WillRepeatedly(Return(kMaxSize));
    323   EXPECT_TRUE(stream_->Seek(kMaxSize, Stream::Whence::FROM_BEGIN, &pos,
    324               nullptr));
    325   EXPECT_EQ(kMaxSize, pos);
    326   EXPECT_TRUE(stream_->Seek(kMaxSize, Stream::Whence::FROM_BEGIN, nullptr,
    327               nullptr));
    328 }
    329 
    330 TEST_F(FileStreamTest, Seek_Cur) {
    331   uint64_t pos = 0;
    332 
    333   EXPECT_CALL(fd_mock(), Seek(0, SEEK_CUR)).WillOnce(Return(100));
    334   EXPECT_TRUE(stream_->Seek(0, Stream::Whence::FROM_CURRENT, &pos, nullptr));
    335   EXPECT_EQ(100u, pos);
    336 
    337   EXPECT_CALL(fd_mock(), Seek(234, SEEK_CUR)).WillOnce(Return(1234));
    338   EXPECT_TRUE(stream_->Seek(234, Stream::Whence::FROM_CURRENT, &pos, nullptr));
    339   EXPECT_EQ(1234u, pos);
    340 
    341   EXPECT_CALL(fd_mock(), Seek(-100, SEEK_CUR)).WillOnce(Return(900));
    342   EXPECT_TRUE(stream_->Seek(-100, Stream::Whence::FROM_CURRENT, &pos, nullptr));
    343   EXPECT_EQ(900u, pos);
    344 }
    345 
    346 TEST_F(FileStreamTest, Seek_End) {
    347   uint64_t pos = 0;
    348 
    349   EXPECT_CALL(fd_mock(), Seek(0, SEEK_END)).WillOnce(Return(1000));
    350   EXPECT_TRUE(stream_->Seek(0, Stream::Whence::FROM_END, &pos, nullptr));
    351   EXPECT_EQ(1000u, pos);
    352 
    353   EXPECT_CALL(fd_mock(), Seek(234, SEEK_END)).WillOnce(Return(10234));
    354   EXPECT_TRUE(stream_->Seek(234, Stream::Whence::FROM_END, &pos, nullptr));
    355   EXPECT_EQ(10234u, pos);
    356 
    357   EXPECT_CALL(fd_mock(), Seek(-100, SEEK_END)).WillOnce(Return(9900));
    358   EXPECT_TRUE(stream_->Seek(-100, Stream::Whence::FROM_END, &pos, nullptr));
    359   EXPECT_EQ(9900u, pos);
    360 }
    361 
    362 TEST_F(FileStreamTest, Seek_Fail) {
    363   brillo::ErrorPtr error;
    364   EXPECT_CALL(fd_mock(), Seek(0, SEEK_SET))
    365       .WillOnce(SetErrnoAndReturn(EPIPE, -1));
    366   EXPECT_FALSE(stream_->Seek(0, Stream::Whence::FROM_BEGIN, nullptr, &error));
    367   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    368   EXPECT_EQ("EPIPE", error->GetCode());
    369 }
    370 
    371 TEST_F(FileStreamTest, ReadAsync) {
    372   size_t read_size = 0;
    373   bool failed = false;
    374   auto success_callback = [](size_t* read_size, size_t size) {
    375     *read_size = size;
    376   };
    377   auto error_callback = [](bool* failed, const Error* /* error */) {
    378     *failed = true;
    379   };
    380   FileStream::FileDescriptorInterface::DataCallback data_callback;
    381 
    382   EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 100))
    383       .WillOnce(ReturnWouldBlock());
    384   EXPECT_CALL(fd_mock(), WaitForData(Stream::AccessMode::READ, _, _))
    385       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
    386   EXPECT_TRUE(stream_->ReadAsync(
    387       test_read_buffer_,
    388       100,
    389       base::Bind(success_callback, base::Unretained(&read_size)),
    390       base::Bind(error_callback, base::Unretained(&failed)),
    391       nullptr));
    392   EXPECT_EQ(0u, read_size);
    393   EXPECT_FALSE(failed);
    394 
    395   EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 100)).WillOnce(Return(83));
    396   data_callback.Run(Stream::AccessMode::READ);
    397   EXPECT_EQ(83u, read_size);
    398   EXPECT_FALSE(failed);
    399 }
    400 
    401 TEST_F(FileStreamTest, ReadNonBlocking) {
    402   size_t size = 0;
    403   bool eos = false;
    404   EXPECT_CALL(fd_mock(), Read(test_read_buffer_, _))
    405       .WillRepeatedly(ReturnArg<1>());
    406   EXPECT_TRUE(stream_->ReadNonBlocking(test_read_buffer_, 100, &size, &eos,
    407                                        nullptr));
    408   EXPECT_EQ(100u, size);
    409   EXPECT_FALSE(eos);
    410 
    411   EXPECT_TRUE(stream_->ReadNonBlocking(test_read_buffer_, 0, &size, &eos,
    412                                        nullptr));
    413   EXPECT_EQ(0u, size);
    414   EXPECT_FALSE(eos);
    415 
    416   EXPECT_CALL(fd_mock(), Read(test_read_buffer_, _)).WillOnce(Return(0));
    417   EXPECT_TRUE(stream_->ReadNonBlocking(test_read_buffer_, 100, &size, &eos,
    418                                        nullptr));
    419   EXPECT_EQ(0u, size);
    420   EXPECT_TRUE(eos);
    421 
    422   EXPECT_CALL(fd_mock(), Read(test_read_buffer_, _))
    423       .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    424   EXPECT_TRUE(stream_->ReadNonBlocking(test_read_buffer_, 100, &size, &eos,
    425                                        nullptr));
    426   EXPECT_EQ(0u, size);
    427   EXPECT_FALSE(eos);
    428 }
    429 
    430 TEST_F(FileStreamTest, ReadNonBlocking_Fail) {
    431   size_t size = 0;
    432   brillo::ErrorPtr error;
    433   EXPECT_CALL(fd_mock(), Read(test_read_buffer_, _))
    434       .WillOnce(SetErrnoAndReturn(EACCES, -1));
    435   EXPECT_FALSE(stream_->ReadNonBlocking(test_read_buffer_, 100, &size, nullptr,
    436                                         &error));
    437   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    438   EXPECT_EQ("EACCES", error->GetCode());
    439 }
    440 
    441 TEST_F(FileStreamTest, ReadBlocking) {
    442   size_t size = 0;
    443   EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 100)).WillOnce(Return(20));
    444   EXPECT_TRUE(stream_->ReadBlocking(test_read_buffer_, 100, &size, nullptr));
    445   EXPECT_EQ(20u, size);
    446 
    447   {
    448     InSequence seq;
    449     EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 80))
    450         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    451     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::READ, _, _))
    452         .WillOnce(Return(1));
    453     EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 80)).WillOnce(Return(45));
    454   }
    455   EXPECT_TRUE(stream_->ReadBlocking(test_read_buffer_, 80, &size, nullptr));
    456   EXPECT_EQ(45u, size);
    457 
    458   EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 50)).WillOnce(Return(0));
    459   EXPECT_TRUE(stream_->ReadBlocking(test_read_buffer_, 50, &size, nullptr));
    460   EXPECT_EQ(0u, size);
    461 }
    462 
    463 TEST_F(FileStreamTest, ReadBlocking_Fail) {
    464   {
    465     InSequence seq;
    466     EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 80))
    467         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    468     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::READ, _, _))
    469         .WillOnce(SetErrnoAndReturn(EBADF, -1));
    470   }
    471   brillo::ErrorPtr error;
    472   size_t size = 0;
    473   EXPECT_FALSE(stream_->ReadBlocking(test_read_buffer_, 80, &size, &error));
    474   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    475   EXPECT_EQ("EBADF", error->GetCode());
    476 }
    477 
    478 TEST_F(FileStreamTest, ReadAllBlocking) {
    479   {
    480     InSequence seq;
    481     EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 100)).WillOnce(Return(20));
    482     EXPECT_CALL(fd_mock(), Read(test_read_buffer_ + 20, 80))
    483         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    484     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::READ, _, _))
    485         .WillOnce(Return(1));
    486     EXPECT_CALL(fd_mock(), Read(test_read_buffer_ + 20, 80))
    487         .WillOnce(Return(45));
    488     EXPECT_CALL(fd_mock(), Read(test_read_buffer_ + 65, 35))
    489         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    490     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::READ, _, _))
    491         .WillOnce(Return(1));
    492     EXPECT_CALL(fd_mock(), Read(test_read_buffer_ + 65, 35))
    493         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    494     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::READ, _, _))
    495         .WillOnce(Return(1));
    496     EXPECT_CALL(fd_mock(), Read(test_read_buffer_ + 65, 35))
    497         .WillOnce(Return(35));
    498   }
    499   EXPECT_TRUE(stream_->ReadAllBlocking(test_read_buffer_, 100, nullptr));
    500 }
    501 
    502 TEST_F(FileStreamTest, ReadAllBlocking_Fail) {
    503   {
    504     InSequence seq;
    505     EXPECT_CALL(fd_mock(), Read(test_read_buffer_, 100)).WillOnce(Return(20));
    506     EXPECT_CALL(fd_mock(), Read(test_read_buffer_ + 20, 80))
    507         .WillOnce(Return(0));
    508   }
    509   brillo::ErrorPtr error;
    510   EXPECT_FALSE(stream_->ReadAllBlocking(test_read_buffer_, 100, &error));
    511   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
    512   EXPECT_EQ(errors::stream::kPartialData, error->GetCode());
    513   EXPECT_EQ("Reading past the end of stream", error->GetMessage());
    514 }
    515 
    516 TEST_F(FileStreamTest, WriteAsync) {
    517   size_t write_size = 0;
    518   bool failed = false;
    519   auto success_callback = [](size_t* write_size, size_t size) {
    520     *write_size = size;
    521   };
    522   auto error_callback = [](bool* failed, const Error* /* error */) {
    523     *failed = true;
    524   };
    525   FileStream::FileDescriptorInterface::DataCallback data_callback;
    526 
    527   EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 100))
    528       .WillOnce(ReturnWouldBlock());
    529   EXPECT_CALL(fd_mock(), WaitForData(Stream::AccessMode::WRITE, _, _))
    530       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
    531   EXPECT_TRUE(stream_->WriteAsync(
    532       test_write_buffer_,
    533       100,
    534       base::Bind(success_callback, base::Unretained(&write_size)),
    535       base::Bind(error_callback, base::Unretained(&failed)),
    536       nullptr));
    537   EXPECT_EQ(0u, write_size);
    538   EXPECT_FALSE(failed);
    539 
    540   EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 100)).WillOnce(Return(87));
    541   data_callback.Run(Stream::AccessMode::WRITE);
    542   EXPECT_EQ(87u, write_size);
    543   EXPECT_FALSE(failed);
    544 }
    545 
    546 TEST_F(FileStreamTest, WriteNonBlocking) {
    547   size_t size = 0;
    548   EXPECT_CALL(fd_mock(), Write(test_write_buffer_, _))
    549       .WillRepeatedly(ReturnArg<1>());
    550   EXPECT_TRUE(stream_->WriteNonBlocking(test_write_buffer_, 100, &size,
    551                                         nullptr));
    552   EXPECT_EQ(100u, size);
    553 
    554   EXPECT_TRUE(stream_->WriteNonBlocking(test_write_buffer_, 0, &size, nullptr));
    555   EXPECT_EQ(0u, size);
    556 
    557   EXPECT_CALL(fd_mock(), Write(test_write_buffer_, _)).WillOnce(Return(0));
    558   EXPECT_TRUE(stream_->WriteNonBlocking(test_write_buffer_, 100, &size,
    559                                         nullptr));
    560   EXPECT_EQ(0u, size);
    561 
    562   EXPECT_CALL(fd_mock(), Write(test_write_buffer_, _))
    563       .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    564   EXPECT_TRUE(stream_->WriteNonBlocking(test_write_buffer_, 100, &size,
    565                                         nullptr));
    566   EXPECT_EQ(0u, size);
    567 }
    568 
    569 TEST_F(FileStreamTest, WriteNonBlocking_Fail) {
    570   size_t size = 0;
    571   brillo::ErrorPtr error;
    572   EXPECT_CALL(fd_mock(), Write(test_write_buffer_, _))
    573       .WillOnce(SetErrnoAndReturn(EACCES, -1));
    574   EXPECT_FALSE(stream_->WriteNonBlocking(test_write_buffer_, 100, &size,
    575                                          &error));
    576   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    577   EXPECT_EQ("EACCES", error->GetCode());
    578 }
    579 
    580 TEST_F(FileStreamTest, WriteBlocking) {
    581   size_t size = 0;
    582   EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 100)).WillOnce(Return(20));
    583   EXPECT_TRUE(stream_->WriteBlocking(test_write_buffer_, 100, &size, nullptr));
    584   EXPECT_EQ(20u, size);
    585 
    586   {
    587     InSequence seq;
    588     EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 80))
    589         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    590     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::WRITE, _, _))
    591         .WillOnce(Return(1));
    592     EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 80)).WillOnce(Return(45));
    593   }
    594   EXPECT_TRUE(stream_->WriteBlocking(test_write_buffer_, 80, &size, nullptr));
    595   EXPECT_EQ(45u, size);
    596 
    597   {
    598     InSequence seq;
    599     EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 50)).WillOnce(Return(0));
    600     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::WRITE, _, _))
    601         .WillOnce(Return(1));
    602     EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 50)).WillOnce(Return(1));
    603   }
    604   EXPECT_TRUE(stream_->WriteBlocking(test_write_buffer_, 50, &size, nullptr));
    605   EXPECT_EQ(1u, size);
    606 }
    607 
    608 TEST_F(FileStreamTest, WriteBlocking_Fail) {
    609   {
    610     InSequence seq;
    611     EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 80))
    612         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    613     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::WRITE, _, _))
    614         .WillOnce(SetErrnoAndReturn(EBADF, -1));
    615   }
    616   brillo::ErrorPtr error;
    617   size_t size = 0;
    618   EXPECT_FALSE(stream_->WriteBlocking(test_write_buffer_, 80, &size, &error));
    619   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    620   EXPECT_EQ("EBADF", error->GetCode());
    621 }
    622 
    623 TEST_F(FileStreamTest, WriteAllBlocking) {
    624   {
    625     InSequence seq;
    626     EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 100)).WillOnce(Return(20));
    627     EXPECT_CALL(fd_mock(), Write(test_write_buffer_ + 20, 80))
    628         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    629     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::WRITE, _, _))
    630         .WillOnce(Return(1));
    631     EXPECT_CALL(fd_mock(), Write(test_write_buffer_ + 20, 80))
    632         .WillOnce(Return(45));
    633     EXPECT_CALL(fd_mock(), Write(test_write_buffer_ + 65, 35))
    634         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    635     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::WRITE, _, _))
    636         .WillOnce(Return(1));
    637     EXPECT_CALL(fd_mock(), Write(test_write_buffer_ + 65, 35))
    638         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    639     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::WRITE, _, _))
    640         .WillOnce(Return(1));
    641     EXPECT_CALL(fd_mock(), Write(test_write_buffer_ + 65, 35))
    642         .WillOnce(Return(35));
    643   }
    644   EXPECT_TRUE(stream_->WriteAllBlocking(test_write_buffer_, 100, nullptr));
    645 }
    646 
    647 TEST_F(FileStreamTest, WriteAllBlocking_Fail) {
    648   {
    649     InSequence seq;
    650     EXPECT_CALL(fd_mock(), Write(test_write_buffer_, 80))
    651         .WillOnce(SetErrnoAndReturn(EAGAIN, -1));
    652     EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::WRITE, _, _))
    653         .WillOnce(SetErrnoAndReturn(EBADF, -1));
    654   }
    655   brillo::ErrorPtr error;
    656   EXPECT_FALSE(stream_->WriteAllBlocking(test_write_buffer_, 80, &error));
    657   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    658   EXPECT_EQ("EBADF", error->GetCode());
    659 }
    660 
    661 TEST_F(FileStreamTest, WaitForDataBlocking_Timeout) {
    662   EXPECT_CALL(fd_mock(), WaitForDataBlocking(Stream::AccessMode::WRITE, _, _))
    663       .WillOnce(Return(0));
    664   brillo::ErrorPtr error;
    665   EXPECT_FALSE(stream_->WaitForDataBlocking(Stream::AccessMode::WRITE, {},
    666                                             nullptr, &error));
    667   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
    668   EXPECT_EQ(errors::stream::kTimeout, error->GetCode());
    669 }
    670 
    671 TEST_F(FileStreamTest, FlushBlocking) {
    672   EXPECT_TRUE(stream_->FlushBlocking(nullptr));
    673 }
    674 
    675 TEST_F(FileStreamTest, CloseBlocking) {
    676   EXPECT_CALL(fd_mock(), Close()).WillOnce(Return(0));
    677   EXPECT_TRUE(stream_->CloseBlocking(nullptr));
    678 
    679   EXPECT_CALL(fd_mock(), IsOpen()).WillOnce(Return(false));
    680   EXPECT_TRUE(stream_->CloseBlocking(nullptr));
    681 }
    682 
    683 TEST_F(FileStreamTest, CloseBlocking_Fail) {
    684   brillo::ErrorPtr error;
    685   EXPECT_CALL(fd_mock(), Close()).WillOnce(SetErrnoAndReturn(EFBIG, -1));
    686   EXPECT_FALSE(stream_->CloseBlocking(&error));
    687   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    688   EXPECT_EQ("EFBIG", error->GetCode());
    689 }
    690 
    691 TEST_F(FileStreamTest, WaitForData) {
    692   EXPECT_CALL(fd_mock(), WaitForData(Stream::AccessMode::READ, _, _))
    693       .WillOnce(Return(true));
    694   EXPECT_TRUE(CallWaitForData(Stream::AccessMode::READ, nullptr));
    695 
    696   EXPECT_CALL(fd_mock(), WaitForData(Stream::AccessMode::WRITE, _, _))
    697       .WillOnce(Return(true));
    698   EXPECT_TRUE(CallWaitForData(Stream::AccessMode::WRITE, nullptr));
    699 
    700   EXPECT_CALL(fd_mock(), WaitForData(Stream::AccessMode::READ_WRITE, _, _))
    701       .WillOnce(Return(true));
    702   EXPECT_TRUE(CallWaitForData(Stream::AccessMode::READ_WRITE, nullptr));
    703 
    704   EXPECT_CALL(fd_mock(), WaitForData(Stream::AccessMode::READ_WRITE, _, _))
    705       .WillOnce(Return(false));
    706   EXPECT_FALSE(CallWaitForData(Stream::AccessMode::READ_WRITE, nullptr));
    707 }
    708 
    709 TEST_F(FileStreamTest, CreateTemporary) {
    710   StreamPtr stream = FileStream::CreateTemporary(nullptr);
    711   ASSERT_NE(nullptr, stream.get());
    712   TestCreateFile(stream.get());
    713 }
    714 
    715 TEST_F(FileStreamTest, OpenRead) {
    716   base::ScopedTempDir temp_dir;
    717   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    718   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    719   std::vector<char> buffer(1024 * 1024);
    720   base::RandBytes(buffer.data(), buffer.size());
    721   int file_size = buffer.size();  // Stupid base::WriteFile taking "int" size.
    722   ASSERT_EQ(file_size, base::WriteFile(path, buffer.data(), file_size));
    723 
    724   StreamPtr stream = FileStream::Open(path,
    725                                       Stream::AccessMode::READ,
    726                                       FileStream::Disposition::OPEN_EXISTING,
    727                                       nullptr);
    728   ASSERT_NE(nullptr, stream.get());
    729   ASSERT_TRUE(stream->IsOpen());
    730   EXPECT_TRUE(stream->CanRead());
    731   EXPECT_FALSE(stream->CanWrite());
    732   EXPECT_TRUE(stream->CanSeek());
    733   EXPECT_TRUE(stream->CanGetSize());
    734   EXPECT_EQ(0u, stream->GetPosition());
    735   EXPECT_EQ(buffer.size(), stream->GetSize());
    736 
    737   std::vector<char> buffer2(buffer.size());
    738   EXPECT_TRUE(stream->ReadAllBlocking(buffer2.data(), buffer2.size(), nullptr));
    739   EXPECT_EQ(buffer2, buffer);
    740   EXPECT_TRUE(stream->CloseBlocking(nullptr));
    741 }
    742 
    743 TEST_F(FileStreamTest, OpenWrite) {
    744   base::ScopedTempDir temp_dir;
    745   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    746   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    747   std::vector<char> buffer(1024 * 1024);
    748   base::RandBytes(buffer.data(), buffer.size());
    749 
    750   StreamPtr stream = FileStream::Open(path,
    751                                       Stream::AccessMode::WRITE,
    752                                       FileStream::Disposition::CREATE_ALWAYS,
    753                                       nullptr);
    754   ASSERT_NE(nullptr, stream.get());
    755   ASSERT_TRUE(stream->IsOpen());
    756   EXPECT_FALSE(stream->CanRead());
    757   EXPECT_TRUE(stream->CanWrite());
    758   EXPECT_TRUE(stream->CanSeek());
    759   EXPECT_TRUE(stream->CanGetSize());
    760   EXPECT_EQ(0u, stream->GetPosition());
    761   EXPECT_EQ(0u, stream->GetSize());
    762 
    763   EXPECT_TRUE(stream->WriteAllBlocking(buffer.data(), buffer.size(), nullptr));
    764   EXPECT_TRUE(stream->CloseBlocking(nullptr));
    765 
    766   std::vector<char> buffer2(buffer.size());
    767   int file_size = buffer2.size();  // Stupid base::ReadFile taking "int" size.
    768   ASSERT_EQ(file_size, base::ReadFile(path, buffer2.data(), file_size));
    769   EXPECT_EQ(buffer2, buffer);
    770 }
    771 
    772 TEST_F(FileStreamTest, Open_OpenExisting) {
    773   base::ScopedTempDir temp_dir;
    774   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    775   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    776   std::string data{"Lorem ipsum dolor sit amet ..."};
    777   int data_size = data.size();  // I hate ints for data size...
    778   ASSERT_EQ(data_size, base::WriteFile(path, data.data(), data_size));
    779 
    780   StreamPtr stream = FileStream::Open(path,
    781                                       Stream::AccessMode::READ_WRITE,
    782                                       FileStream::Disposition::OPEN_EXISTING,
    783                                       nullptr);
    784   ASSERT_NE(nullptr, stream.get());
    785   EXPECT_TRUE(stream->CanRead());
    786   EXPECT_TRUE(stream->CanWrite());
    787   EXPECT_TRUE(stream->CanSeek());
    788   EXPECT_TRUE(stream->CanGetSize());
    789   EXPECT_EQ(0u, stream->GetPosition());
    790   EXPECT_EQ(data.size(), stream->GetSize());
    791   EXPECT_TRUE(stream->CloseBlocking(nullptr));
    792 }
    793 
    794 TEST_F(FileStreamTest, Open_OpenExisting_Fail) {
    795   base::ScopedTempDir temp_dir;
    796   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    797   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    798 
    799   ErrorPtr error;
    800   StreamPtr stream = FileStream::Open(path,
    801                                       Stream::AccessMode::READ_WRITE,
    802                                       FileStream::Disposition::OPEN_EXISTING,
    803                                       &error);
    804   ASSERT_EQ(nullptr, stream.get());
    805   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    806   EXPECT_EQ("ENOENT", error->GetCode());
    807 }
    808 
    809 TEST_F(FileStreamTest, Open_CreateAlways_New) {
    810   base::ScopedTempDir temp_dir;
    811   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    812   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    813 
    814   StreamPtr stream = FileStream::Open(path,
    815                                       Stream::AccessMode::READ_WRITE,
    816                                       FileStream::Disposition::CREATE_ALWAYS,
    817                                       nullptr);
    818   ASSERT_NE(nullptr, stream.get());
    819   EXPECT_TRUE(stream->CanRead());
    820   EXPECT_TRUE(stream->CanWrite());
    821   EXPECT_TRUE(stream->CanSeek());
    822   EXPECT_TRUE(stream->CanGetSize());
    823   EXPECT_EQ(0u, stream->GetPosition());
    824   EXPECT_EQ(0u, stream->GetSize());
    825   EXPECT_TRUE(stream->CloseBlocking(nullptr));
    826 }
    827 
    828 TEST_F(FileStreamTest, Open_CreateAlways_Existing) {
    829   base::ScopedTempDir temp_dir;
    830   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    831   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    832   std::string data{"Lorem ipsum dolor sit amet ..."};
    833   int data_size = data.size();  // I hate ints for data size...
    834   ASSERT_EQ(data_size, base::WriteFile(path, data.data(), data_size));
    835 
    836   StreamPtr stream = FileStream::Open(path,
    837                                       Stream::AccessMode::READ_WRITE,
    838                                       FileStream::Disposition::CREATE_ALWAYS,
    839                                       nullptr);
    840   ASSERT_NE(nullptr, stream.get());
    841   EXPECT_TRUE(stream->CanRead());
    842   EXPECT_TRUE(stream->CanWrite());
    843   EXPECT_TRUE(stream->CanSeek());
    844   EXPECT_TRUE(stream->CanGetSize());
    845   EXPECT_EQ(0u, stream->GetPosition());
    846   EXPECT_EQ(0u, stream->GetSize());
    847   EXPECT_TRUE(stream->CloseBlocking(nullptr));
    848 }
    849 
    850 TEST_F(FileStreamTest, Open_CreateNewOnly_New) {
    851   base::ScopedTempDir temp_dir;
    852   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    853   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    854 
    855   StreamPtr stream = FileStream::Open(path,
    856                                       Stream::AccessMode::READ_WRITE,
    857                                       FileStream::Disposition::CREATE_NEW_ONLY,
    858                                       nullptr);
    859   ASSERT_NE(nullptr, stream.get());
    860   EXPECT_TRUE(stream->CanRead());
    861   EXPECT_TRUE(stream->CanWrite());
    862   EXPECT_TRUE(stream->CanSeek());
    863   EXPECT_TRUE(stream->CanGetSize());
    864   EXPECT_EQ(0u, stream->GetPosition());
    865   EXPECT_EQ(0u, stream->GetSize());
    866   EXPECT_TRUE(stream->CloseBlocking(nullptr));
    867 }
    868 
    869 TEST_F(FileStreamTest, Open_CreateNewOnly_Existing) {
    870   base::ScopedTempDir temp_dir;
    871   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    872   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    873   std::string data{"Lorem ipsum dolor sit amet ..."};
    874   int data_size = data.size();  // I hate ints for data size...
    875   ASSERT_EQ(data_size, base::WriteFile(path, data.data(), data_size));
    876 
    877   ErrorPtr error;
    878   StreamPtr stream = FileStream::Open(path,
    879                                       Stream::AccessMode::READ_WRITE,
    880                                       FileStream::Disposition::CREATE_NEW_ONLY,
    881                                       &error);
    882   ASSERT_EQ(nullptr, stream.get());
    883   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    884   EXPECT_EQ("EEXIST", error->GetCode());
    885 }
    886 
    887 TEST_F(FileStreamTest, Open_TruncateExisting_New) {
    888   base::ScopedTempDir temp_dir;
    889   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    890   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    891 
    892   ErrorPtr error;
    893   StreamPtr stream = FileStream::Open(
    894       path,
    895       Stream::AccessMode::READ_WRITE,
    896       FileStream::Disposition::TRUNCATE_EXISTING,
    897       &error);
    898   ASSERT_EQ(nullptr, stream.get());
    899   EXPECT_EQ(errors::system::kDomain, error->GetDomain());
    900   EXPECT_EQ("ENOENT", error->GetCode());
    901 }
    902 
    903 TEST_F(FileStreamTest, Open_TruncateExisting_Existing) {
    904   base::ScopedTempDir temp_dir;
    905   ASSERT_TRUE(temp_dir.CreateUniqueTempDir());
    906   base::FilePath path = temp_dir.path().Append(base::FilePath{"test.dat"});
    907   std::string data{"Lorem ipsum dolor sit amet ..."};
    908   int data_size = data.size();  // I hate ints for data size...
    909   ASSERT_EQ(data_size, base::WriteFile(path, data.data(), data_size));
    910 
    911   StreamPtr stream = FileStream::Open(
    912       path,
    913       Stream::AccessMode::READ_WRITE,
    914       FileStream::Disposition::TRUNCATE_EXISTING,
    915       nullptr);
    916   ASSERT_NE(nullptr, stream.get());
    917   EXPECT_TRUE(stream->CanRead());
    918   EXPECT_TRUE(stream->CanWrite());
    919   EXPECT_TRUE(stream->CanSeek());
    920   EXPECT_TRUE(stream->CanGetSize());
    921   EXPECT_EQ(0u, stream->GetPosition());
    922   EXPECT_EQ(0u, stream->GetSize());
    923   EXPECT_TRUE(stream->CloseBlocking(nullptr));
    924 }
    925 
    926 TEST_F(FileStreamTest, FromFileDescriptor_StdIn) {
    927   StreamPtr stream =
    928       FileStream::FromFileDescriptor(STDIN_FILENO, false, nullptr);
    929   ASSERT_NE(nullptr, stream.get());
    930   EXPECT_TRUE(stream->IsOpen());
    931   EXPECT_TRUE(stream->CanRead());
    932   EXPECT_FALSE(stream->CanSeek());
    933   EXPECT_FALSE(stream->CanGetSize());
    934 }
    935 
    936 TEST_F(FileStreamTest, FromFileDescriptor_StdOut) {
    937   StreamPtr stream =
    938       FileStream::FromFileDescriptor(STDOUT_FILENO, false, nullptr);
    939   ASSERT_NE(nullptr, stream.get());
    940   EXPECT_TRUE(stream->IsOpen());
    941   EXPECT_TRUE(stream->CanWrite());
    942   EXPECT_FALSE(stream->CanSeek());
    943   EXPECT_FALSE(stream->CanGetSize());
    944 }
    945 
    946 TEST_F(FileStreamTest, FromFileDescriptor_StdErr) {
    947   StreamPtr stream =
    948       FileStream::FromFileDescriptor(STDERR_FILENO, false, nullptr);
    949   ASSERT_NE(nullptr, stream.get());
    950   EXPECT_TRUE(stream->IsOpen());
    951   EXPECT_TRUE(stream->CanWrite());
    952   EXPECT_FALSE(stream->CanSeek());
    953   EXPECT_FALSE(stream->CanGetSize());
    954 }
    955 
    956 TEST_F(FileStreamTest, FromFileDescriptor_ReadNonBlocking) {
    957   int fds[2] = {-1, -1};
    958   ASSERT_EQ(0, pipe(fds));
    959 
    960   StreamPtr stream = FileStream::FromFileDescriptor(fds[0], true, nullptr);
    961   ASSERT_NE(nullptr, stream.get());
    962   EXPECT_TRUE(stream->IsOpen());
    963   EXPECT_TRUE(stream->CanRead());
    964   EXPECT_FALSE(stream->CanWrite());
    965   EXPECT_FALSE(stream->CanSeek());
    966   EXPECT_FALSE(stream->CanGetSize());
    967 
    968   char buf[10];
    969   size_t read = 0;
    970   bool eos = true;
    971   EXPECT_TRUE(stream->ReadNonBlocking(buf, sizeof(buf), &read, &eos, nullptr));
    972   EXPECT_EQ(0, read);
    973   EXPECT_FALSE(eos);
    974 
    975   std::string data{"foo_bar"};
    976   EXPECT_TRUE(base::WriteFileDescriptor(fds[1], data.data(), data.size()));
    977   EXPECT_TRUE(stream->ReadNonBlocking(buf, sizeof(buf), &read, &eos, nullptr));
    978   EXPECT_EQ(data.size(), read);
    979   EXPECT_FALSE(eos);
    980   EXPECT_EQ(data, (std::string{buf, read}));
    981 
    982   EXPECT_TRUE(stream->ReadNonBlocking(buf, sizeof(buf), &read, &eos, nullptr));
    983   EXPECT_EQ(0, read);
    984   EXPECT_FALSE(eos);
    985 
    986   close(fds[1]);
    987 
    988   EXPECT_TRUE(stream->ReadNonBlocking(buf, sizeof(buf), &read, &eos, nullptr));
    989   EXPECT_EQ(0, read);
    990   EXPECT_TRUE(eos);
    991 
    992   EXPECT_TRUE(stream->CloseBlocking(nullptr));
    993 }
    994 
    995 TEST_F(FileStreamTest, FromFileDescriptor_WriteNonBlocking) {
    996   int fds[2] = {-1, -1};
    997   ASSERT_EQ(0, pipe(fds));
    998 
    999   StreamPtr stream = FileStream::FromFileDescriptor(fds[1], true, nullptr);
   1000   ASSERT_NE(nullptr, stream.get());
   1001   EXPECT_TRUE(stream->IsOpen());
   1002   EXPECT_FALSE(stream->CanRead());
   1003   EXPECT_TRUE(stream->CanWrite());
   1004   EXPECT_FALSE(stream->CanSeek());
   1005   EXPECT_FALSE(stream->CanGetSize());
   1006 
   1007   // Pipe buffer is generally 64K, so 128K should be more than enough.
   1008   std::vector<char> buffer(128 * 1024);
   1009   base::RandBytes(buffer.data(), buffer.size());
   1010   size_t written = 0;
   1011   size_t total_size = 0;
   1012 
   1013   // Fill the output buffer of the pipe until we can no longer write any data
   1014   // to it.
   1015   do {
   1016     ASSERT_TRUE(stream->WriteNonBlocking(buffer.data(), buffer.size(), &written,
   1017                                          nullptr));
   1018     total_size += written;
   1019   } while (written == buffer.size());
   1020 
   1021   EXPECT_TRUE(stream->WriteNonBlocking(buffer.data(), buffer.size(), &written,
   1022                                        nullptr));
   1023   EXPECT_EQ(0, written);
   1024 
   1025   std::vector<char> out_buffer(total_size);
   1026   EXPECT_TRUE(base::ReadFromFD(fds[0], out_buffer.data(), out_buffer.size()));
   1027 
   1028   EXPECT_TRUE(stream->WriteNonBlocking(buffer.data(), buffer.size(), &written,
   1029                                        nullptr));
   1030   EXPECT_GT(written, 0);
   1031   out_buffer.resize(written);
   1032   EXPECT_TRUE(base::ReadFromFD(fds[0], out_buffer.data(), out_buffer.size()));
   1033   EXPECT_TRUE(std::equal(out_buffer.begin(), out_buffer.end(), buffer.begin()));
   1034 
   1035   close(fds[0]);
   1036   EXPECT_TRUE(stream->CloseBlocking(nullptr));
   1037 }
   1038 
   1039 TEST_F(FileStreamTest, FromFileDescriptor_ReadAsync) {
   1040   int fds[2] = {-1, -1};
   1041   bool succeeded = false;
   1042   bool failed = false;
   1043   char buffer[100];
   1044   base::MessageLoopForIO base_loop;
   1045   BaseMessageLoop brillo_loop{&base_loop};
   1046   brillo_loop.SetAsCurrent();
   1047 
   1048   auto success_callback = [](bool* succeeded, char* buffer, size_t size) {
   1049     std::string data{buffer, buffer + size};
   1050     ASSERT_EQ("abracadabra", data);
   1051     *succeeded = true;
   1052   };
   1053 
   1054   auto error_callback = [](bool* failed, const Error* /* error */) {
   1055     *failed = true;
   1056   };
   1057 
   1058   auto write_data_callback = [](int write_fd) {
   1059     std::string data{"abracadabra"};
   1060     EXPECT_TRUE(base::WriteFileDescriptor(write_fd, data.data(), data.size()));
   1061   };
   1062 
   1063   ASSERT_EQ(0, pipe(fds));
   1064 
   1065   StreamPtr stream = FileStream::FromFileDescriptor(fds[0], true, nullptr);
   1066 
   1067   // Write to the pipe with a bit of delay.
   1068   brillo_loop.PostDelayedTask(
   1069       FROM_HERE,
   1070       base::Bind(write_data_callback, fds[1]),
   1071       base::TimeDelta::FromMilliseconds(10));
   1072 
   1073   EXPECT_TRUE(
   1074       stream->ReadAsync(buffer,
   1075                         100,
   1076                         base::Bind(success_callback,
   1077                                    base::Unretained(&succeeded),
   1078                                    base::Unretained(buffer)),
   1079                         base::Bind(error_callback, base::Unretained(&failed)),
   1080                         nullptr));
   1081 
   1082   auto end_condition = [](bool* failed, bool* succeeded) {
   1083     return *failed || *succeeded;
   1084   };
   1085   MessageLoopRunUntil(&brillo_loop,
   1086                       base::TimeDelta::FromSeconds(1),
   1087                       base::Bind(end_condition,
   1088                                  base::Unretained(&failed),
   1089                                  base::Unretained(&succeeded)));
   1090 
   1091   EXPECT_TRUE(succeeded);
   1092   EXPECT_FALSE(failed);
   1093 
   1094   close(fds[1]);
   1095   EXPECT_TRUE(stream->CloseBlocking(nullptr));
   1096 }
   1097 
   1098 TEST_F(FileStreamTest, FromFileDescriptor_WriteAsync) {
   1099   int fds[2] = {-1, -1};
   1100   bool succeeded = false;
   1101   bool failed = false;
   1102   const std::string data{"abracadabra"};
   1103   base::MessageLoopForIO base_loop;
   1104   BaseMessageLoop brillo_loop{&base_loop};
   1105   brillo_loop.SetAsCurrent();
   1106 
   1107   ASSERT_EQ(0, pipe(fds));
   1108 
   1109   auto success_callback = [](bool* succeeded,
   1110                              const std::string& data,
   1111                              int read_fd,
   1112                              size_t /* size */) {
   1113     char buffer[100];
   1114     EXPECT_TRUE(base::ReadFromFD(read_fd, buffer, data.size()));
   1115     EXPECT_EQ(data, (std::string{buffer, buffer + data.size()}));
   1116     *succeeded = true;
   1117   };
   1118 
   1119   auto error_callback = [](bool* failed, const Error* /* error */) {
   1120     *failed = true;
   1121   };
   1122 
   1123   StreamPtr stream = FileStream::FromFileDescriptor(fds[1], true, nullptr);
   1124 
   1125   EXPECT_TRUE(stream->WriteAsync(
   1126       data.data(),
   1127       data.size(),
   1128       base::Bind(success_callback, base::Unretained(&succeeded), data, fds[0]),
   1129       base::Bind(error_callback, base::Unretained(&failed)),
   1130       nullptr));
   1131 
   1132   auto end_condition = [](bool* failed, bool* succeeded) {
   1133     return *failed || *succeeded;
   1134   };
   1135   MessageLoopRunUntil(&brillo_loop,
   1136                       base::TimeDelta::FromSeconds(1),
   1137                       base::Bind(end_condition,
   1138                                  base::Unretained(&failed),
   1139                                  base::Unretained(&succeeded)));
   1140 
   1141   EXPECT_TRUE(succeeded);
   1142   EXPECT_FALSE(failed);
   1143 
   1144   close(fds[0]);
   1145   EXPECT_TRUE(stream->CloseBlocking(nullptr));
   1146 }
   1147 
   1148 }  // namespace brillo
   1149