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/input_stream_set.h>
      6 
      7 #include <brillo/errors/error_codes.h>
      8 #include <brillo/streams/mock_stream.h>
      9 #include <brillo/streams/stream_errors.h>
     10 #include <gmock/gmock.h>
     11 #include <gtest/gtest.h>
     12 
     13 using testing::An;
     14 using testing::DoAll;
     15 using testing::InSequence;
     16 using testing::Return;
     17 using testing::SetArgPointee;
     18 using testing::StrictMock;
     19 using testing::_;
     20 
     21 namespace brillo {
     22 
     23 class InputStreamSetTest : public testing::Test {
     24  public:
     25   void SetUp() override {
     26     itf1_.reset(new StrictMock<MockStream>{});
     27     itf2_.reset(new StrictMock<MockStream>{});
     28     stream_.reset(new InputStreamSet({itf1_.get(), itf2_.get()}, {}, 100));
     29   }
     30 
     31   void TearDown() override {
     32     stream_.reset();
     33     itf2_.reset();
     34     itf1_.reset();
     35   }
     36 
     37   std::unique_ptr<StrictMock<MockStream>> itf1_;
     38   std::unique_ptr<StrictMock<MockStream>> itf2_;
     39   std::unique_ptr<InputStreamSet> stream_;
     40 
     41   inline static void* IntToPtr(int addr) {
     42     return reinterpret_cast<void*>(addr);
     43   }
     44 };
     45 
     46 TEST_F(InputStreamSetTest, InitialFalseAssumptions) {
     47   // Methods that should just succeed/fail without calling underlying streams.
     48   EXPECT_TRUE(stream_->CanRead());
     49   EXPECT_FALSE(stream_->CanWrite());
     50   EXPECT_FALSE(stream_->CanSeek());
     51   EXPECT_EQ(100, stream_->GetSize());
     52   EXPECT_FALSE(stream_->SetSizeBlocking(0, nullptr));
     53   EXPECT_FALSE(stream_->GetPosition());
     54   EXPECT_FALSE(stream_->Seek(0, Stream::Whence::FROM_BEGIN, nullptr, nullptr));
     55   char buffer[100];
     56   size_t size = 0;
     57   EXPECT_FALSE(stream_->WriteAsync(buffer, sizeof(buffer), {}, {}, nullptr));
     58   EXPECT_FALSE(stream_->WriteAllAsync(buffer, sizeof(buffer), {}, {}, nullptr));
     59   EXPECT_FALSE(stream_->WriteNonBlocking(buffer, sizeof(buffer), &size,
     60                                          nullptr));
     61   EXPECT_FALSE(stream_->WriteBlocking(buffer, sizeof(buffer), &size, nullptr));
     62   EXPECT_FALSE(stream_->WriteAllBlocking(buffer, sizeof(buffer), nullptr));
     63   EXPECT_TRUE(stream_->FlushBlocking(nullptr));
     64   EXPECT_TRUE(stream_->CloseBlocking(nullptr));
     65 }
     66 
     67 TEST_F(InputStreamSetTest, InitialTrueAssumptions) {
     68   // Methods that redirect calls to underlying streams.
     69   EXPECT_CALL(*itf1_, CanGetSize()).WillOnce(Return(true));
     70   EXPECT_CALL(*itf2_, CanGetSize()).WillOnce(Return(true));
     71   EXPECT_TRUE(stream_->CanGetSize());
     72 
     73   // Reading from the first stream fails, so the second one shouldn't be used.
     74   EXPECT_CALL(*itf1_, ReadNonBlocking(_, _, _, _, _))
     75       .WillOnce(Return(false));
     76   EXPECT_CALL(*itf2_, ReadNonBlocking(_, _, _, _, _)).Times(0);
     77   char buffer[100];
     78   size_t size = 0;
     79   EXPECT_FALSE(stream_->ReadBlocking(buffer, sizeof(buffer), &size, nullptr));
     80 }
     81 
     82 TEST_F(InputStreamSetTest, CanGetSize) {
     83   EXPECT_CALL(*itf1_, CanGetSize()).WillOnce(Return(true));
     84   EXPECT_CALL(*itf2_, CanGetSize()).WillOnce(Return(true));
     85   EXPECT_TRUE(stream_->CanGetSize());
     86 
     87   EXPECT_CALL(*itf1_, CanGetSize()).WillOnce(Return(false));
     88   EXPECT_FALSE(stream_->CanGetSize());
     89 
     90   EXPECT_CALL(*itf1_, CanGetSize()).WillOnce(Return(true));
     91   EXPECT_CALL(*itf2_, CanGetSize()).WillOnce(Return(false));
     92   EXPECT_FALSE(stream_->CanGetSize());
     93 }
     94 
     95 TEST_F(InputStreamSetTest, GetRemainingSize) {
     96   EXPECT_CALL(*itf1_, GetRemainingSize()).WillOnce(Return(10));
     97   EXPECT_CALL(*itf2_, GetRemainingSize()).WillOnce(Return(32));
     98   EXPECT_EQ(42, stream_->GetRemainingSize());
     99 }
    100 
    101 TEST_F(InputStreamSetTest, ReadNonBlocking) {
    102   size_t read = 0;
    103   bool eos = false;
    104 
    105   InSequence s;
    106   EXPECT_CALL(*itf1_, ReadNonBlocking(IntToPtr(1000), 100, _, _, _))
    107     .WillOnce(DoAll(SetArgPointee<2>(10),
    108                     SetArgPointee<3>(false),
    109                     Return(true)));
    110   EXPECT_TRUE(stream_->ReadNonBlocking(IntToPtr(1000), 100, &read, &eos,
    111                                        nullptr));
    112   EXPECT_EQ(10, read);
    113   EXPECT_FALSE(eos);
    114 
    115   EXPECT_CALL(*itf1_, ReadNonBlocking(IntToPtr(1000), 100, _, _, _))
    116     .WillOnce(DoAll(SetArgPointee<2>(0), SetArgPointee<3>(true), Return(true)));
    117   EXPECT_CALL(*itf2_, ReadNonBlocking(IntToPtr(1000), 100 , _, _, _))
    118     .WillOnce(DoAll(SetArgPointee<2>(100),
    119                     SetArgPointee<3>(false),
    120                     Return(true)));
    121   EXPECT_TRUE(stream_->ReadNonBlocking(IntToPtr(1000), 100, &read, &eos,
    122                                        nullptr));
    123   EXPECT_EQ(100, read);
    124   EXPECT_FALSE(eos);
    125 
    126   EXPECT_CALL(*itf2_, ReadNonBlocking(IntToPtr(1000), 100, _, _, _))
    127     .WillOnce(DoAll(SetArgPointee<2>(0), SetArgPointee<3>(true), Return(true)));
    128   EXPECT_TRUE(stream_->ReadNonBlocking(IntToPtr(1000), 100, &read, &eos,
    129                                        nullptr));
    130   EXPECT_EQ(0, read);
    131   EXPECT_TRUE(eos);
    132 }
    133 
    134 TEST_F(InputStreamSetTest, ReadBlocking) {
    135   size_t read = 0;
    136 
    137   InSequence s;
    138   EXPECT_CALL(*itf1_, ReadNonBlocking(IntToPtr(1000), 100, _, _, _))
    139       .WillOnce(DoAll(SetArgPointee<2>(10),
    140                       SetArgPointee<3>(false),
    141                       Return(true)));
    142   EXPECT_TRUE(stream_->ReadBlocking(IntToPtr(1000), 100, &read, nullptr));
    143   EXPECT_EQ(10, read);
    144 
    145   EXPECT_CALL(*itf1_, ReadNonBlocking(IntToPtr(1000), 100, _, _, _))
    146       .WillOnce(DoAll(SetArgPointee<2>(0),
    147                       SetArgPointee<3>(true),
    148                       Return(true)));
    149   EXPECT_CALL(*itf2_, ReadNonBlocking(IntToPtr(1000), 100, _, _, _))
    150       .WillOnce(DoAll(SetArgPointee<2>(0),
    151                       SetArgPointee<3>(false),
    152                       Return(true)));
    153   EXPECT_CALL(*itf2_, WaitForDataBlocking(Stream::AccessMode::READ, _, _, _))
    154       .WillOnce(Return(true));
    155   EXPECT_CALL(*itf2_, ReadNonBlocking(IntToPtr(1000), 100, _, _, _))
    156       .WillOnce(DoAll(SetArgPointee<2>(100),
    157                       SetArgPointee<3>(false),
    158                       Return(true)));
    159   EXPECT_TRUE(stream_->ReadBlocking(IntToPtr(1000), 100, &read, nullptr));
    160   EXPECT_EQ(100, read);
    161 
    162   EXPECT_CALL(*itf2_, ReadNonBlocking(IntToPtr(1000), 100, _, _, _))
    163       .WillOnce(DoAll(SetArgPointee<2>(0),
    164                       SetArgPointee<3>(true),
    165                       Return(true)));
    166   EXPECT_TRUE(stream_->ReadBlocking(IntToPtr(1000), 100, &read, nullptr));
    167   EXPECT_EQ(0, read);
    168 }
    169 
    170 }  // namespace brillo
    171