• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
SetUp()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 
TearDown()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 
IntToPtr(int addr)41   inline static void* IntToPtr(int addr) {
42     return reinterpret_cast<void*>(addr);
43   }
44 };
45 
TEST_F(InputStreamSetTest,InitialFalseAssumptions)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 
TEST_F(InputStreamSetTest,InitialTrueAssumptions)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 
TEST_F(InputStreamSetTest,CanGetSize)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 
TEST_F(InputStreamSetTest,GetRemainingSize)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 
TEST_F(InputStreamSetTest,ReadNonBlocking)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 
TEST_F(InputStreamSetTest,ReadBlocking)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