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/fake_stream.h>
      6 
      7 #include <vector>
      8 
      9 #include <base/callback.h>
     10 #include <base/test/simple_test_clock.h>
     11 #include <brillo/bind_lambda.h>
     12 #include <brillo/message_loops/mock_message_loop.h>
     13 #include <gmock/gmock.h>
     14 #include <gtest/gtest.h>
     15 
     16 using testing::AnyNumber;
     17 using testing::InSequence;
     18 using testing::_;
     19 
     20 namespace brillo {
     21 
     22 class FakeStreamTest : public testing::Test {
     23  public:
     24   void SetUp() override {
     25     mock_loop_.SetAsCurrent();
     26     // Ignore calls to RunOnce().
     27     EXPECT_CALL(mock_loop_, RunOnce(true)).Times(AnyNumber());
     28   }
     29 
     30   void CreateStream(Stream::AccessMode mode) {
     31     stream_.reset(new FakeStream{mode, &clock_});
     32   }
     33 
     34   // Performs non-blocking read on the stream and returns the read data
     35   // as a string in |out_buffer|. Returns true if the read was successful or
     36   // false when an error occurs. |*eos| is set to true when end of stream is
     37   // reached.
     38   bool ReadString(size_t size_to_read, std::string* out_buffer, bool* eos) {
     39     std::vector<char> data;
     40     data.resize(size_to_read);
     41     size_t size_read = 0;
     42     bool ok = stream_->ReadNonBlocking(data.data(), data.size(), &size_read,
     43                                        eos, nullptr);
     44     if (ok) {
     45       out_buffer->assign(data.data(), data.data() + size_read);
     46     } else {
     47       out_buffer->clear();
     48     }
     49     return ok;
     50   }
     51 
     52   // Writes a string to a stream. Returns the number of bytes written or -1
     53   // in case an error occurred.
     54   int WriteString(const std::string& data) {
     55     size_t written = 0;
     56     if (!stream_->WriteNonBlocking(data.data(), data.size(), &written, nullptr))
     57       return -1;
     58     return static_cast<int>(written);
     59   }
     60 
     61  protected:
     62   base::SimpleTestClock clock_;
     63   MockMessageLoop mock_loop_{&clock_};
     64   std::unique_ptr<FakeStream> stream_;
     65   const base::TimeDelta zero_delay;
     66 };
     67 
     68 TEST_F(FakeStreamTest, InitReadOnly) {
     69   CreateStream(Stream::AccessMode::READ);
     70   EXPECT_TRUE(stream_->IsOpen());
     71   EXPECT_TRUE(stream_->CanRead());
     72   EXPECT_FALSE(stream_->CanWrite());
     73   EXPECT_FALSE(stream_->CanSeek());
     74   EXPECT_FALSE(stream_->CanGetSize());
     75   EXPECT_EQ(0, stream_->GetSize());
     76   EXPECT_EQ(0, stream_->GetRemainingSize());
     77   EXPECT_EQ(0, stream_->GetPosition());
     78 }
     79 
     80 TEST_F(FakeStreamTest, InitWriteOnly) {
     81   CreateStream(Stream::AccessMode::WRITE);
     82   EXPECT_TRUE(stream_->IsOpen());
     83   EXPECT_FALSE(stream_->CanRead());
     84   EXPECT_TRUE(stream_->CanWrite());
     85   EXPECT_FALSE(stream_->CanSeek());
     86   EXPECT_FALSE(stream_->CanGetSize());
     87   EXPECT_EQ(0, stream_->GetSize());
     88   EXPECT_EQ(0, stream_->GetRemainingSize());
     89   EXPECT_EQ(0, stream_->GetPosition());
     90 }
     91 
     92 TEST_F(FakeStreamTest, InitReadWrite) {
     93   CreateStream(Stream::AccessMode::READ_WRITE);
     94   EXPECT_TRUE(stream_->IsOpen());
     95   EXPECT_TRUE(stream_->CanRead());
     96   EXPECT_TRUE(stream_->CanWrite());
     97   EXPECT_FALSE(stream_->CanSeek());
     98   EXPECT_FALSE(stream_->CanGetSize());
     99   EXPECT_EQ(0, stream_->GetSize());
    100   EXPECT_EQ(0, stream_->GetRemainingSize());
    101   EXPECT_EQ(0, stream_->GetPosition());
    102 }
    103 
    104 TEST_F(FakeStreamTest, ReadEmpty) {
    105   CreateStream(Stream::AccessMode::READ);
    106   std::string data;
    107   bool eos = false;
    108   EXPECT_TRUE(ReadString(100, &data, &eos));
    109   EXPECT_TRUE(eos);
    110   EXPECT_TRUE(data.empty());
    111 }
    112 
    113 TEST_F(FakeStreamTest, ReadFullPacket) {
    114   CreateStream(Stream::AccessMode::READ);
    115   stream_->AddReadPacketString({}, "foo");
    116   std::string data;
    117   bool eos = false;
    118   EXPECT_TRUE(ReadString(100, &data, &eos));
    119   EXPECT_FALSE(eos);
    120   EXPECT_EQ("foo", data);
    121 
    122   EXPECT_TRUE(ReadString(100, &data, &eos));
    123   EXPECT_TRUE(eos);
    124   EXPECT_TRUE(data.empty());
    125 }
    126 
    127 TEST_F(FakeStreamTest, ReadPartialPacket) {
    128   CreateStream(Stream::AccessMode::READ);
    129   stream_->AddReadPacketString({}, "foobar");
    130   std::string data;
    131   bool eos = false;
    132   EXPECT_TRUE(ReadString(3, &data, &eos));
    133   EXPECT_FALSE(eos);
    134   EXPECT_EQ("foo", data);
    135 
    136   EXPECT_TRUE(ReadString(100, &data, &eos));
    137   EXPECT_FALSE(eos);
    138   EXPECT_EQ("bar", data);
    139 
    140   EXPECT_TRUE(ReadString(100, &data, &eos));
    141   EXPECT_TRUE(eos);
    142   EXPECT_TRUE(data.empty());
    143 }
    144 
    145 TEST_F(FakeStreamTest, ReadMultiplePackets) {
    146   CreateStream(Stream::AccessMode::READ);
    147   stream_->AddReadPacketString({}, "foobar");
    148   stream_->AddReadPacketString({}, "baz");
    149   stream_->AddReadPacketString({}, "quux");
    150   std::string data;
    151   bool eos = false;
    152   EXPECT_TRUE(ReadString(100, &data, &eos));
    153   EXPECT_FALSE(eos);
    154   EXPECT_EQ("foobar", data);
    155 
    156   EXPECT_TRUE(ReadString(2, &data, &eos));
    157   EXPECT_FALSE(eos);
    158   EXPECT_EQ("ba", data);
    159 
    160   EXPECT_TRUE(ReadString(100, &data, &eos));
    161   EXPECT_FALSE(eos);
    162   EXPECT_EQ("z", data);
    163 
    164   EXPECT_TRUE(ReadString(100, &data, &eos));
    165   EXPECT_FALSE(eos);
    166   EXPECT_EQ("quux", data);
    167 
    168   EXPECT_TRUE(ReadString(100, &data, &eos));
    169   EXPECT_TRUE(eos);
    170   EXPECT_TRUE(data.empty());
    171 
    172   stream_->AddReadPacketString({}, "foo-bar");
    173   EXPECT_TRUE(ReadString(100, &data, &eos));
    174   EXPECT_FALSE(eos);
    175   EXPECT_EQ("foo-bar", data);
    176 }
    177 
    178 TEST_F(FakeStreamTest, ReadPacketsWithDelay) {
    179   CreateStream(Stream::AccessMode::READ);
    180   stream_->AddReadPacketString({}, "foobar");
    181   stream_->AddReadPacketString(base::TimeDelta::FromSeconds(1), "baz");
    182   std::string data;
    183   bool eos = false;
    184   EXPECT_TRUE(ReadString(100, &data, &eos));
    185   EXPECT_FALSE(eos);
    186   EXPECT_EQ("foobar", data);
    187 
    188   EXPECT_TRUE(ReadString(100, &data, &eos));
    189   EXPECT_FALSE(eos);
    190   EXPECT_TRUE(data.empty());
    191 
    192   EXPECT_TRUE(ReadString(100, &data, &eos));
    193   EXPECT_FALSE(eos);
    194   EXPECT_TRUE(data.empty());
    195 
    196   clock_.Advance(base::TimeDelta::FromSeconds(1));
    197 
    198   EXPECT_TRUE(ReadString(100, &data, &eos));
    199   EXPECT_FALSE(eos);
    200   EXPECT_EQ("baz", data);
    201 }
    202 
    203 TEST_F(FakeStreamTest, ReadPacketsWithError) {
    204   CreateStream(Stream::AccessMode::READ);
    205   stream_->AddReadPacketString({}, "foobar");
    206   stream_->QueueReadErrorWithMessage(base::TimeDelta::FromSeconds(1),
    207                                      "Dummy error");
    208   stream_->AddReadPacketString({}, "baz");
    209 
    210   std::string data;
    211   bool eos = false;
    212   EXPECT_TRUE(ReadString(100, &data, &eos));
    213   EXPECT_FALSE(eos);
    214   EXPECT_EQ("foobar", data);
    215 
    216   EXPECT_TRUE(ReadString(100, &data, &eos));
    217   EXPECT_FALSE(eos);
    218   EXPECT_TRUE(data.empty());
    219 
    220   EXPECT_TRUE(ReadString(100, &data, &eos));
    221   EXPECT_FALSE(eos);
    222   EXPECT_TRUE(data.empty());
    223 
    224   clock_.Advance(base::TimeDelta::FromSeconds(1));
    225 
    226   EXPECT_FALSE(ReadString(100, &data, &eos));
    227 
    228   EXPECT_TRUE(ReadString(100, &data, &eos));
    229   EXPECT_FALSE(eos);
    230   EXPECT_EQ("baz", data);
    231 }
    232 
    233 TEST_F(FakeStreamTest, WaitForDataRead) {
    234   CreateStream(Stream::AccessMode::READ);
    235 
    236   EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(2);
    237 
    238   int call_count = 0;
    239   auto callback = [&call_count](Stream::AccessMode mode) {
    240     call_count++;
    241     EXPECT_EQ(Stream::AccessMode::READ, mode);
    242   };
    243 
    244   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ,
    245                                    base::Bind(callback), nullptr));
    246   mock_loop_.Run();
    247   EXPECT_EQ(1, call_count);
    248 
    249   stream_->AddReadPacketString({}, "foobar");
    250   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ,
    251                                    base::Bind(callback), nullptr));
    252   mock_loop_.Run();
    253   EXPECT_EQ(2, call_count);
    254 
    255   stream_->ClearReadQueue();
    256 
    257   auto one_sec_delay = base::TimeDelta::FromSeconds(1);
    258   stream_->AddReadPacketString(one_sec_delay, "baz");
    259   EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
    260   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ,
    261                                    base::Bind(callback), nullptr));
    262   mock_loop_.Run();
    263   EXPECT_EQ(3, call_count);
    264 }
    265 
    266 TEST_F(FakeStreamTest, ReadAsync) {
    267   CreateStream(Stream::AccessMode::READ);
    268   std::string input_data = "foobar-baz";
    269   size_t split_pos = input_data.find('-');
    270 
    271   auto one_sec_delay = base::TimeDelta::FromSeconds(1);
    272   stream_->AddReadPacketString({}, input_data.substr(0, split_pos));
    273   stream_->AddReadPacketString(one_sec_delay, input_data.substr(split_pos));
    274 
    275   {
    276     InSequence seq;
    277     EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(1);
    278     EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
    279   }
    280 
    281   std::vector<char> buffer;
    282   buffer.resize(input_data.size());
    283 
    284   int success_count = 0;
    285   int error_count = 0;
    286   auto on_success = [&success_count] { success_count++; };
    287   auto on_failure = [&error_count](const Error* /* error */) { error_count++; };
    288 
    289   EXPECT_TRUE(stream_->ReadAllAsync(buffer.data(), buffer.size(),
    290                                     base::Bind(on_success),
    291                                     base::Bind(on_failure),
    292                                     nullptr));
    293   mock_loop_.Run();
    294   EXPECT_EQ(1, success_count);
    295   EXPECT_EQ(0, error_count);
    296   EXPECT_EQ(input_data, (std::string{buffer.begin(), buffer.end()}));
    297 }
    298 
    299 TEST_F(FakeStreamTest, WriteEmpty) {
    300   CreateStream(Stream::AccessMode::WRITE);
    301   EXPECT_EQ(-1, WriteString("foo"));
    302 }
    303 
    304 TEST_F(FakeStreamTest, WritePartial) {
    305   CreateStream(Stream::AccessMode::WRITE);
    306   stream_->ExpectWritePacketSize({}, 6);
    307   EXPECT_EQ(3, WriteString("foo"));
    308   EXPECT_EQ(3, WriteString("bar"));
    309   EXPECT_EQ(-1, WriteString("baz"));
    310 
    311   EXPECT_EQ("foobar", stream_->GetFlushedOutputDataAsString());
    312 }
    313 
    314 TEST_F(FakeStreamTest, WriteFullPackets) {
    315   CreateStream(Stream::AccessMode::WRITE);
    316 
    317   stream_->ExpectWritePacketSize({}, 3);
    318   EXPECT_EQ(3, WriteString("foo"));
    319   EXPECT_EQ(-1, WriteString("bar"));
    320 
    321   stream_->ExpectWritePacketSize({}, 3);
    322   EXPECT_EQ(3, WriteString("bar"));
    323 
    324   stream_->ExpectWritePacketSize({}, 3);
    325   EXPECT_EQ(3, WriteString("quux"));
    326 
    327   EXPECT_EQ("foobarquu", stream_->GetFlushedOutputDataAsString());
    328 }
    329 
    330 TEST_F(FakeStreamTest, WriteAndVerifyData) {
    331   CreateStream(Stream::AccessMode::WRITE);
    332 
    333   stream_->ExpectWritePacketString({}, "foo");
    334   stream_->ExpectWritePacketString({}, "bar");
    335   EXPECT_EQ(3, WriteString("foobar"));
    336   EXPECT_EQ(3, WriteString("bar"));
    337 
    338   stream_->ExpectWritePacketString({}, "foo");
    339   stream_->ExpectWritePacketString({}, "baz");
    340   EXPECT_EQ(3, WriteString("foobar"));
    341   EXPECT_EQ(-1, WriteString("bar"));
    342 
    343   stream_->ExpectWritePacketString({}, "foobar");
    344   EXPECT_EQ(3, WriteString("foo"));
    345   EXPECT_EQ(2, WriteString("ba"));
    346   EXPECT_EQ(-1, WriteString("z"));
    347 }
    348 
    349 TEST_F(FakeStreamTest, WriteWithDelay) {
    350   CreateStream(Stream::AccessMode::WRITE);
    351 
    352   const auto delay = base::TimeDelta::FromMilliseconds(500);
    353 
    354   stream_->ExpectWritePacketSize({}, 3);
    355   stream_->ExpectWritePacketSize(delay, 3);
    356   EXPECT_EQ(3, WriteString("foobar"));
    357 
    358   EXPECT_EQ(0, WriteString("bar"));
    359   EXPECT_EQ(0, WriteString("bar"));
    360   clock_.Advance(delay);
    361   EXPECT_EQ(3, WriteString("bar"));
    362 
    363   EXPECT_EQ("foobar", stream_->GetFlushedOutputDataAsString());
    364 }
    365 
    366 TEST_F(FakeStreamTest, WriteWithError) {
    367   CreateStream(Stream::AccessMode::WRITE);
    368 
    369   const auto delay = base::TimeDelta::FromMilliseconds(500);
    370 
    371   stream_->ExpectWritePacketSize({}, 3);
    372   stream_->QueueWriteError({});
    373   stream_->ExpectWritePacketSize({}, 3);
    374   stream_->QueueWriteErrorWithMessage(delay, "Dummy message");
    375   stream_->ExpectWritePacketString({}, "foobar");
    376 
    377   const std::string data = "foobarbaz";
    378   EXPECT_EQ(3, WriteString(data));
    379   EXPECT_EQ(-1, WriteString(data));  // Simulated error #1.
    380   EXPECT_EQ(3, WriteString(data));
    381   EXPECT_EQ(0, WriteString(data));  // Waiting for data...
    382   clock_.Advance(delay);
    383   EXPECT_EQ(-1, WriteString(data));  // Simulated error #2.
    384   EXPECT_EQ(6, WriteString(data));
    385   EXPECT_EQ(-1, WriteString(data));  // No more data expected.
    386 }
    387 
    388 TEST_F(FakeStreamTest, WaitForDataWrite) {
    389   CreateStream(Stream::AccessMode::WRITE);
    390 
    391   EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(2);
    392 
    393   int call_count = 0;
    394   auto callback = [&call_count](Stream::AccessMode mode) {
    395     call_count++;
    396     EXPECT_EQ(Stream::AccessMode::WRITE, mode);
    397   };
    398 
    399   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::WRITE,
    400                                    base::Bind(callback), nullptr));
    401   mock_loop_.Run();
    402   EXPECT_EQ(1, call_count);
    403 
    404   stream_->ExpectWritePacketString({}, "foobar");
    405   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::WRITE,
    406                                    base::Bind(callback), nullptr));
    407   mock_loop_.Run();
    408   EXPECT_EQ(2, call_count);
    409 
    410   stream_->ClearWriteQueue();
    411 
    412   auto one_sec_delay = base::TimeDelta::FromSeconds(1);
    413   stream_->ExpectWritePacketString(one_sec_delay, "baz");
    414   EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
    415   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::WRITE,
    416                                    base::Bind(callback), nullptr));
    417   mock_loop_.Run();
    418   EXPECT_EQ(3, call_count);
    419 }
    420 
    421 TEST_F(FakeStreamTest, WriteAsync) {
    422   CreateStream(Stream::AccessMode::WRITE);
    423   std::string output_data = "foobar-baz";
    424   size_t split_pos = output_data.find('-');
    425 
    426   auto one_sec_delay = base::TimeDelta::FromSeconds(1);
    427   stream_->ExpectWritePacketString({}, output_data.substr(0, split_pos));
    428   stream_->ExpectWritePacketString(one_sec_delay,
    429                                    output_data.substr(split_pos));
    430 
    431   {
    432     InSequence seq;
    433     EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(1);
    434     EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
    435   }
    436 
    437   int success_count = 0;
    438   int error_count = 0;
    439   auto on_success = [&success_count] { success_count++; };
    440   auto on_failure = [&error_count](const Error* /* error */) { error_count++; };
    441 
    442   EXPECT_TRUE(stream_->WriteAllAsync(output_data.data(), output_data.size(),
    443                                      base::Bind(on_success),
    444                                      base::Bind(on_failure),
    445                                      nullptr));
    446   mock_loop_.Run();
    447   EXPECT_EQ(1, success_count);
    448   EXPECT_EQ(0, error_count);
    449   EXPECT_EQ(output_data, stream_->GetFlushedOutputDataAsString());
    450 }
    451 
    452 TEST_F(FakeStreamTest, WaitForDataReadWrite) {
    453   CreateStream(Stream::AccessMode::READ_WRITE);
    454   auto one_sec_delay = base::TimeDelta::FromSeconds(1);
    455   auto two_sec_delay = base::TimeDelta::FromSeconds(2);
    456 
    457   int call_count = 0;
    458   auto callback = [&call_count](Stream::AccessMode mode,
    459                                 Stream::AccessMode expected_mode) {
    460     call_count++;
    461     EXPECT_EQ(static_cast<int>(expected_mode), static_cast<int>(mode));
    462   };
    463 
    464   stream_->AddReadPacketString(one_sec_delay, "foo");
    465   stream_->ExpectWritePacketString(two_sec_delay, "bar");
    466 
    467   EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
    468   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE,
    469                                    base::Bind(callback,
    470                                               Stream::AccessMode::READ),
    471                                    nullptr));
    472   mock_loop_.Run();
    473   EXPECT_EQ(1, call_count);
    474 
    475   // The above step has adjusted the clock by 1 second already.
    476   stream_->ClearReadQueue();
    477   stream_->AddReadPacketString(two_sec_delay, "foo");
    478   EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
    479   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE,
    480                                    base::Bind(callback,
    481                                               Stream::AccessMode::WRITE),
    482                                    nullptr));
    483   mock_loop_.Run();
    484   EXPECT_EQ(2, call_count);
    485 
    486   clock_.Advance(one_sec_delay);
    487 
    488   EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(1);
    489   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE,
    490                                    base::Bind(callback,
    491                                               Stream::AccessMode::READ_WRITE),
    492                                    nullptr));
    493   mock_loop_.Run();
    494   EXPECT_EQ(3, call_count);
    495 
    496   stream_->ClearReadQueue();
    497   stream_->ClearWriteQueue();
    498   stream_->AddReadPacketString(one_sec_delay, "foo");
    499   stream_->ExpectWritePacketString(one_sec_delay, "bar");
    500 
    501   EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1);
    502   EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE,
    503                                    base::Bind(callback,
    504                                               Stream::AccessMode::READ_WRITE),
    505                                    nullptr));
    506   mock_loop_.Run();
    507   EXPECT_EQ(4, call_count);
    508 }
    509 
    510 }  // namespace brillo
    511