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 13using testing::An; 14using testing::DoAll; 15using testing::InSequence; 16using testing::Return; 17using testing::SetArgPointee; 18using testing::StrictMock; 19using testing::_; 20 21namespace brillo { 22 23class 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 46TEST_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 67TEST_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 82TEST_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 95TEST_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 101TEST_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 134TEST_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