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