xref: /aosp_15_r20/external/libbrillo/brillo/streams/stream_test.cc (revision 1a96fba65179ea7d3f56207137718607415c5953)
1*1a96fba6SXin Li // Copyright 2015 The Chromium OS Authors. All rights reserved.
2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be
3*1a96fba6SXin Li // found in the LICENSE file.
4*1a96fba6SXin Li 
5*1a96fba6SXin Li #include <brillo/streams/stream.h>
6*1a96fba6SXin Li 
7*1a96fba6SXin Li #include <limits>
8*1a96fba6SXin Li 
9*1a96fba6SXin Li #include <base/bind.h>
10*1a96fba6SXin Li #include <base/callback.h>
11*1a96fba6SXin Li #include <gmock/gmock.h>
12*1a96fba6SXin Li #include <gtest/gtest.h>
13*1a96fba6SXin Li 
14*1a96fba6SXin Li #include <brillo/message_loops/fake_message_loop.h>
15*1a96fba6SXin Li #include <brillo/streams/stream_errors.h>
16*1a96fba6SXin Li 
17*1a96fba6SXin Li using testing::DoAll;
18*1a96fba6SXin Li using testing::InSequence;
19*1a96fba6SXin Li using testing::Return;
20*1a96fba6SXin Li using testing::SaveArg;
21*1a96fba6SXin Li using testing::SetArgPointee;
22*1a96fba6SXin Li using testing::_;
23*1a96fba6SXin Li 
24*1a96fba6SXin Li namespace {
25*1a96fba6SXin Li 
26*1a96fba6SXin Li // Helper function for base::Bind.
SetToTrue(bool * target,const brillo::Error *)27*1a96fba6SXin Li void SetToTrue(bool* target, const brillo::Error* /* error */) {
28*1a96fba6SXin Li   *target = true;
29*1a96fba6SXin Li }
30*1a96fba6SXin Li 
31*1a96fba6SXin Li }  // namespace
32*1a96fba6SXin Li 
33*1a96fba6SXin Li namespace brillo {
34*1a96fba6SXin Li 
35*1a96fba6SXin Li using AccessMode = Stream::AccessMode;
36*1a96fba6SXin Li using Whence = Stream::Whence;
37*1a96fba6SXin Li 
38*1a96fba6SXin Li // To verify "non-trivial" methods implemented in Stream, mock out the
39*1a96fba6SXin Li // "trivial" methods to make sure the ones we are interested in testing
40*1a96fba6SXin Li // actually end up calling the expected methods with right parameters.
41*1a96fba6SXin Li class MockStreamImpl : public Stream {
42*1a96fba6SXin Li  public:
43*1a96fba6SXin Li   MockStreamImpl() = default;
44*1a96fba6SXin Li 
45*1a96fba6SXin Li   MOCK_METHOD(bool, IsOpen, (), (const, override));
46*1a96fba6SXin Li   MOCK_METHOD(bool, CanRead, (), (const, override));
47*1a96fba6SXin Li   MOCK_METHOD(bool, CanWrite, (), (const, override));
48*1a96fba6SXin Li   MOCK_METHOD(bool, CanSeek, (), (const, override));
49*1a96fba6SXin Li   MOCK_METHOD(bool, CanGetSize, (), (const, override));
50*1a96fba6SXin Li 
51*1a96fba6SXin Li   MOCK_METHOD(uint64_t, GetSize, (), (const, override));
52*1a96fba6SXin Li   MOCK_METHOD(bool, SetSizeBlocking, (uint64_t, ErrorPtr*), (override));
53*1a96fba6SXin Li   MOCK_METHOD(uint64_t, GetRemainingSize, (), (const, override));
54*1a96fba6SXin Li 
55*1a96fba6SXin Li   MOCK_METHOD(uint64_t, GetPosition, (), (const, override));
56*1a96fba6SXin Li   MOCK_METHOD(bool, Seek, (int64_t, Whence, uint64_t*, ErrorPtr*), (override));
57*1a96fba6SXin Li 
58*1a96fba6SXin Li   // Omitted: ReadAsync
59*1a96fba6SXin Li   // Omitted: ReadAllAsync
60*1a96fba6SXin Li   MOCK_METHOD(bool,
61*1a96fba6SXin Li               ReadNonBlocking,
62*1a96fba6SXin Li               (void*, size_t, size_t*, bool*, ErrorPtr*),
63*1a96fba6SXin Li               (override));
64*1a96fba6SXin Li   // Omitted: ReadBlocking
65*1a96fba6SXin Li   // Omitted: ReadAllBlocking
66*1a96fba6SXin Li 
67*1a96fba6SXin Li   // Omitted: WriteAsync
68*1a96fba6SXin Li   // Omitted: WriteAllAsync
69*1a96fba6SXin Li   MOCK_METHOD(bool,
70*1a96fba6SXin Li               WriteNonBlocking,
71*1a96fba6SXin Li               (const void*, size_t, size_t*, ErrorPtr*),
72*1a96fba6SXin Li               (override));
73*1a96fba6SXin Li   // Omitted: WriteBlocking
74*1a96fba6SXin Li   // Omitted: WriteAllBlocking
75*1a96fba6SXin Li 
76*1a96fba6SXin Li   MOCK_METHOD(bool, FlushBlocking, (ErrorPtr*), (override));
77*1a96fba6SXin Li   MOCK_METHOD(bool, CloseBlocking, (ErrorPtr*), (override));
78*1a96fba6SXin Li 
79*1a96fba6SXin Li   MOCK_METHOD(bool,
80*1a96fba6SXin Li               WaitForData,
81*1a96fba6SXin Li               (AccessMode, const base::Callback<void(AccessMode)>&, ErrorPtr*),
82*1a96fba6SXin Li               (override));
83*1a96fba6SXin Li   MOCK_METHOD(bool,
84*1a96fba6SXin Li               WaitForDataBlocking,
85*1a96fba6SXin Li               (AccessMode, base::TimeDelta, AccessMode*, ErrorPtr*),
86*1a96fba6SXin Li               (override));
87*1a96fba6SXin Li 
88*1a96fba6SXin Li  private:
89*1a96fba6SXin Li   DISALLOW_COPY_AND_ASSIGN(MockStreamImpl);
90*1a96fba6SXin Li };
91*1a96fba6SXin Li 
TEST(Stream,TruncateBlocking)92*1a96fba6SXin Li TEST(Stream, TruncateBlocking) {
93*1a96fba6SXin Li   MockStreamImpl stream_mock;
94*1a96fba6SXin Li   EXPECT_CALL(stream_mock, GetPosition()).WillOnce(Return(123));
95*1a96fba6SXin Li   EXPECT_CALL(stream_mock, SetSizeBlocking(123, _)).WillOnce(Return(true));
96*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.TruncateBlocking(nullptr));
97*1a96fba6SXin Li }
98*1a96fba6SXin Li 
TEST(Stream,SetPosition)99*1a96fba6SXin Li TEST(Stream, SetPosition) {
100*1a96fba6SXin Li   MockStreamImpl stream_mock;
101*1a96fba6SXin Li   EXPECT_CALL(stream_mock, Seek(12345, Whence::FROM_BEGIN, _, _))
102*1a96fba6SXin Li       .WillOnce(Return(true));
103*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.SetPosition(12345, nullptr));
104*1a96fba6SXin Li 
105*1a96fba6SXin Li   // Test too large an offset (that doesn't fit in signed 64 bit value).
106*1a96fba6SXin Li   ErrorPtr error;
107*1a96fba6SXin Li   uint64_t max_offset = std::numeric_limits<int64_t>::max();
108*1a96fba6SXin Li   EXPECT_CALL(stream_mock, Seek(max_offset, _, _, _))
109*1a96fba6SXin Li       .WillOnce(Return(true));
110*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.SetPosition(max_offset, nullptr));
111*1a96fba6SXin Li 
112*1a96fba6SXin Li   EXPECT_FALSE(stream_mock.SetPosition(max_offset + 1, &error));
113*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
114*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kInvalidParameter, error->GetCode());
115*1a96fba6SXin Li }
116*1a96fba6SXin Li 
TEST(Stream,ReadAsync)117*1a96fba6SXin Li TEST(Stream, ReadAsync) {
118*1a96fba6SXin Li   size_t read_size = 0;
119*1a96fba6SXin Li   bool succeeded = false;
120*1a96fba6SXin Li   bool failed = false;
121*1a96fba6SXin Li   auto success_callback = base::Bind(
122*1a96fba6SXin Li       [](size_t* read_size, bool* succeeded, size_t size) {
123*1a96fba6SXin Li     *read_size = size;
124*1a96fba6SXin Li     *succeeded = true;
125*1a96fba6SXin Li   }, &read_size, &succeeded);
126*1a96fba6SXin Li   auto error_callback = base::Bind(&SetToTrue, &failed);
127*1a96fba6SXin Li 
128*1a96fba6SXin Li   MockStreamImpl stream_mock;
129*1a96fba6SXin Li   base::Callback<void(AccessMode)> data_callback;
130*1a96fba6SXin Li   char buf[10];
131*1a96fba6SXin Li 
132*1a96fba6SXin Li   // This sets up an initial non blocking read that would block, so ReadAsync()
133*1a96fba6SXin Li   // should wait for more data.
134*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 10, _, _, _))
135*1a96fba6SXin Li       .WillOnce(
136*1a96fba6SXin Li           DoAll(SetArgPointee<2>(0), SetArgPointee<3>(false), Return(true)));
137*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WaitForData(AccessMode::READ, _, _))
138*1a96fba6SXin Li       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
139*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.ReadAsync(buf, sizeof(buf), success_callback,
140*1a96fba6SXin Li                                     error_callback, nullptr));
141*1a96fba6SXin Li   EXPECT_EQ(0u, read_size);
142*1a96fba6SXin Li   EXPECT_FALSE(succeeded);
143*1a96fba6SXin Li   EXPECT_FALSE(failed);
144*1a96fba6SXin Li 
145*1a96fba6SXin Li   // Since the previous call is waiting for the data to be available, we can't
146*1a96fba6SXin Li   // schedule another read.
147*1a96fba6SXin Li   ErrorPtr error;
148*1a96fba6SXin Li   EXPECT_FALSE(stream_mock.ReadAsync(buf, sizeof(buf), success_callback,
149*1a96fba6SXin Li                                      error_callback, &error));
150*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
151*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kOperationNotSupported, error->GetCode());
152*1a96fba6SXin Li   EXPECT_EQ("Another asynchronous operation is still pending",
153*1a96fba6SXin Li             error->GetMessage());
154*1a96fba6SXin Li 
155*1a96fba6SXin Li   // Making the data available via data_callback should not schedule the
156*1a96fba6SXin Li   // success callback from the main loop and run it directly instead.
157*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 10, _, _, _))
158*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(7),
159*1a96fba6SXin Li                       SetArgPointee<3>(false),
160*1a96fba6SXin Li                       Return(true)));
161*1a96fba6SXin Li   data_callback.Run(AccessMode::READ);
162*1a96fba6SXin Li   EXPECT_EQ(7u, read_size);
163*1a96fba6SXin Li   EXPECT_FALSE(failed);
164*1a96fba6SXin Li }
165*1a96fba6SXin Li 
TEST(Stream,ReadAsync_DontWaitForData)166*1a96fba6SXin Li TEST(Stream, ReadAsync_DontWaitForData) {
167*1a96fba6SXin Li   bool succeeded = false;
168*1a96fba6SXin Li   bool failed = false;
169*1a96fba6SXin Li   auto success_callback = base::Bind([](bool* succeeded, size_t /* size */) {
170*1a96fba6SXin Li     *succeeded = true;
171*1a96fba6SXin Li   }, &succeeded);
172*1a96fba6SXin Li   auto error_callback = base::Bind(&SetToTrue, &failed);
173*1a96fba6SXin Li 
174*1a96fba6SXin Li   MockStreamImpl stream_mock;
175*1a96fba6SXin Li   char buf[10];
176*1a96fba6SXin Li   FakeMessageLoop fake_loop_{nullptr};
177*1a96fba6SXin Li   fake_loop_.SetAsCurrent();
178*1a96fba6SXin Li 
179*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 10, _, _, _))
180*1a96fba6SXin Li       .WillOnce(
181*1a96fba6SXin Li           DoAll(SetArgPointee<2>(5), SetArgPointee<3>(false), Return(true)));
182*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WaitForData(_, _, _)).Times(0);
183*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.ReadAsync(buf, sizeof(buf), success_callback,
184*1a96fba6SXin Li                                     error_callback, nullptr));
185*1a96fba6SXin Li   // Even if ReadNonBlocking() returned some data without waiting, the
186*1a96fba6SXin Li   // |success_callback| should not run yet.
187*1a96fba6SXin Li   EXPECT_TRUE(fake_loop_.PendingTasks());
188*1a96fba6SXin Li   EXPECT_FALSE(succeeded);
189*1a96fba6SXin Li   EXPECT_FALSE(failed);
190*1a96fba6SXin Li 
191*1a96fba6SXin Li   // Since the previous callback is still waiting in the main loop, we can't
192*1a96fba6SXin Li   // schedule another read yet.
193*1a96fba6SXin Li   ErrorPtr error;
194*1a96fba6SXin Li   EXPECT_FALSE(stream_mock.ReadAsync(buf, sizeof(buf), success_callback,
195*1a96fba6SXin Li                                      error_callback, &error));
196*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
197*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kOperationNotSupported, error->GetCode());
198*1a96fba6SXin Li   EXPECT_EQ("Another asynchronous operation is still pending",
199*1a96fba6SXin Li             error->GetMessage());
200*1a96fba6SXin Li 
201*1a96fba6SXin Li   fake_loop_.Run();
202*1a96fba6SXin Li   EXPECT_TRUE(succeeded);
203*1a96fba6SXin Li   EXPECT_FALSE(failed);
204*1a96fba6SXin Li }
205*1a96fba6SXin Li 
TEST(Stream,ReadAllAsync)206*1a96fba6SXin Li TEST(Stream, ReadAllAsync) {
207*1a96fba6SXin Li   bool succeeded = false;
208*1a96fba6SXin Li   bool failed = false;
209*1a96fba6SXin Li   auto success_callback = base::Bind([](bool* succeeded) { *succeeded = true; },
210*1a96fba6SXin Li                                      &succeeded);
211*1a96fba6SXin Li   auto error_callback = base::Bind(&SetToTrue, &failed);
212*1a96fba6SXin Li 
213*1a96fba6SXin Li   MockStreamImpl stream_mock;
214*1a96fba6SXin Li   base::Callback<void(AccessMode)> data_callback;
215*1a96fba6SXin Li   char buf[10];
216*1a96fba6SXin Li 
217*1a96fba6SXin Li   // This sets up an initial non blocking read that would block, so
218*1a96fba6SXin Li   // ReadAllAsync() should wait for more data.
219*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 10, _, _, _))
220*1a96fba6SXin Li       .WillOnce(
221*1a96fba6SXin Li           DoAll(SetArgPointee<2>(0), SetArgPointee<3>(false), Return(true)));
222*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WaitForData(AccessMode::READ, _, _))
223*1a96fba6SXin Li       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
224*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.ReadAllAsync(buf, sizeof(buf), success_callback,
225*1a96fba6SXin Li                                        error_callback, nullptr));
226*1a96fba6SXin Li   EXPECT_FALSE(succeeded);
227*1a96fba6SXin Li   EXPECT_FALSE(failed);
228*1a96fba6SXin Li   testing::Mock::VerifyAndClearExpectations(&stream_mock);
229*1a96fba6SXin Li 
230*1a96fba6SXin Li   // ReadAllAsync() will try to read non blocking until the read would block
231*1a96fba6SXin Li   // before it waits for the data to be available again.
232*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 10, _, _, _))
233*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(7),
234*1a96fba6SXin Li                       SetArgPointee<3>(false),
235*1a96fba6SXin Li                       Return(true)));
236*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf + 7, 3, _, _, _))
237*1a96fba6SXin Li       .WillOnce(
238*1a96fba6SXin Li           DoAll(SetArgPointee<2>(0), SetArgPointee<3>(false), Return(true)));
239*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WaitForData(AccessMode::READ, _, _))
240*1a96fba6SXin Li       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
241*1a96fba6SXin Li   data_callback.Run(AccessMode::READ);
242*1a96fba6SXin Li   EXPECT_FALSE(succeeded);
243*1a96fba6SXin Li   EXPECT_FALSE(failed);
244*1a96fba6SXin Li   testing::Mock::VerifyAndClearExpectations(&stream_mock);
245*1a96fba6SXin Li 
246*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf + 7, 3, _, _, _))
247*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(3),
248*1a96fba6SXin Li                       SetArgPointee<3>(true),
249*1a96fba6SXin Li                       Return(true)));
250*1a96fba6SXin Li   data_callback.Run(AccessMode::READ);
251*1a96fba6SXin Li   EXPECT_TRUE(succeeded);
252*1a96fba6SXin Li   EXPECT_FALSE(failed);
253*1a96fba6SXin Li }
254*1a96fba6SXin Li 
TEST(Stream,ReadAllAsync_EOS)255*1a96fba6SXin Li TEST(Stream, ReadAllAsync_EOS) {
256*1a96fba6SXin Li   bool succeeded = false;
257*1a96fba6SXin Li   bool failed = false;
258*1a96fba6SXin Li   auto success_callback = base::Bind([](bool* succeeded) { *succeeded = true; },
259*1a96fba6SXin Li                                      &succeeded);
260*1a96fba6SXin Li   auto error_callback = base::Bind([](bool* failed, const Error* error) {
261*1a96fba6SXin Li     ASSERT_EQ(errors::stream::kDomain, error->GetDomain());
262*1a96fba6SXin Li     ASSERT_EQ(errors::stream::kPartialData, error->GetCode());
263*1a96fba6SXin Li     *failed = true;
264*1a96fba6SXin Li   }, &failed);
265*1a96fba6SXin Li 
266*1a96fba6SXin Li   MockStreamImpl stream_mock;
267*1a96fba6SXin Li   base::Callback<void(AccessMode)> data_callback;
268*1a96fba6SXin Li   char buf[10];
269*1a96fba6SXin Li 
270*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 10, _, _, _))
271*1a96fba6SXin Li       .WillOnce(
272*1a96fba6SXin Li           DoAll(SetArgPointee<2>(0), SetArgPointee<3>(false), Return(true)));
273*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WaitForData(AccessMode::READ, _, _))
274*1a96fba6SXin Li       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
275*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.ReadAllAsync(buf, sizeof(buf), success_callback,
276*1a96fba6SXin Li                                        error_callback, nullptr));
277*1a96fba6SXin Li 
278*1a96fba6SXin Li   // ReadAsyncAll() should finish and fail once ReadNonBlocking() returns an
279*1a96fba6SXin Li   // end-of-stream condition.
280*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 10, _, _, _))
281*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(7),
282*1a96fba6SXin Li                       SetArgPointee<3>(true),
283*1a96fba6SXin Li                       Return(true)));
284*1a96fba6SXin Li   data_callback.Run(AccessMode::READ);
285*1a96fba6SXin Li   EXPECT_FALSE(succeeded);
286*1a96fba6SXin Li   EXPECT_TRUE(failed);
287*1a96fba6SXin Li }
288*1a96fba6SXin Li 
TEST(Stream,ReadBlocking)289*1a96fba6SXin Li TEST(Stream, ReadBlocking) {
290*1a96fba6SXin Li   MockStreamImpl stream_mock;
291*1a96fba6SXin Li   char buf[1024];
292*1a96fba6SXin Li   size_t read = 0;
293*1a96fba6SXin Li 
294*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 1024, _, _, _))
295*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(24),
296*1a96fba6SXin Li                       SetArgPointee<3>(false),
297*1a96fba6SXin Li                       Return(true)));
298*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.ReadBlocking(buf, sizeof(buf), &read, nullptr));
299*1a96fba6SXin Li   EXPECT_EQ(24, read);
300*1a96fba6SXin Li 
301*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 1024, _, _, _))
302*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(0),
303*1a96fba6SXin Li                       SetArgPointee<3>(true),
304*1a96fba6SXin Li                       Return(true)));
305*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.ReadBlocking(buf, sizeof(buf), &read, nullptr));
306*1a96fba6SXin Li   EXPECT_EQ(0, read);
307*1a96fba6SXin Li 
308*1a96fba6SXin Li   {
309*1a96fba6SXin Li     InSequence seq;
310*1a96fba6SXin Li     EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 1024, _, _, _))
311*1a96fba6SXin Li         .WillOnce(DoAll(SetArgPointee<2>(0),
312*1a96fba6SXin Li                         SetArgPointee<3>(false),
313*1a96fba6SXin Li                         Return(true)));
314*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WaitForDataBlocking(AccessMode::READ, _, _, _))
315*1a96fba6SXin Li         .WillOnce(Return(true));
316*1a96fba6SXin Li     EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 1024, _, _, _))
317*1a96fba6SXin Li         .WillOnce(DoAll(SetArgPointee<2>(0),
318*1a96fba6SXin Li                         SetArgPointee<3>(false),
319*1a96fba6SXin Li                         Return(true)));
320*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WaitForDataBlocking(AccessMode::READ, _, _, _))
321*1a96fba6SXin Li         .WillOnce(Return(true));
322*1a96fba6SXin Li     EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 1024, _, _, _))
323*1a96fba6SXin Li         .WillOnce(DoAll(SetArgPointee<2>(124),
324*1a96fba6SXin Li                         SetArgPointee<3>(false),
325*1a96fba6SXin Li                         Return(true)));
326*1a96fba6SXin Li   }
327*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.ReadBlocking(buf, sizeof(buf), &read, nullptr));
328*1a96fba6SXin Li   EXPECT_EQ(124, read);
329*1a96fba6SXin Li 
330*1a96fba6SXin Li   {
331*1a96fba6SXin Li     InSequence seq;
332*1a96fba6SXin Li     EXPECT_CALL(stream_mock, ReadNonBlocking(buf, 1024, _, _, _))
333*1a96fba6SXin Li         .WillOnce(DoAll(SetArgPointee<2>(0),
334*1a96fba6SXin Li                         SetArgPointee<3>(false),
335*1a96fba6SXin Li                         Return(true)));
336*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WaitForDataBlocking(AccessMode::READ, _, _, _))
337*1a96fba6SXin Li         .WillOnce(Return(false));
338*1a96fba6SXin Li   }
339*1a96fba6SXin Li   EXPECT_FALSE(stream_mock.ReadBlocking(buf, sizeof(buf), &read, nullptr));
340*1a96fba6SXin Li }
341*1a96fba6SXin Li 
TEST(Stream,ReadAllBlocking)342*1a96fba6SXin Li TEST(Stream, ReadAllBlocking) {
343*1a96fba6SXin Li   class MockReadBlocking : public MockStreamImpl {
344*1a96fba6SXin Li    public:
345*1a96fba6SXin Li     MOCK_METHOD(bool,
346*1a96fba6SXin Li                 ReadBlocking,
347*1a96fba6SXin Li                 (void*, size_t, size_t*, ErrorPtr*),
348*1a96fba6SXin Li                 (override));
349*1a96fba6SXin Li   } stream_mock;
350*1a96fba6SXin Li 
351*1a96fba6SXin Li   char buf[1024];
352*1a96fba6SXin Li 
353*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadBlocking(buf, 1024, _, _))
354*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(24), Return(true)));
355*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadBlocking(buf + 24, 1000, _, _))
356*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(1000), Return(true)));
357*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.ReadAllBlocking(buf, sizeof(buf), nullptr));
358*1a96fba6SXin Li 
359*1a96fba6SXin Li   ErrorPtr error;
360*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadBlocking(buf, 1024, _, _))
361*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(24), Return(true)));
362*1a96fba6SXin Li   EXPECT_CALL(stream_mock, ReadBlocking(buf + 24, 1000, _, _))
363*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));
364*1a96fba6SXin Li   EXPECT_FALSE(stream_mock.ReadAllBlocking(buf, sizeof(buf), &error));
365*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
366*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kPartialData, error->GetCode());
367*1a96fba6SXin Li }
368*1a96fba6SXin Li 
TEST(Stream,WriteAsync)369*1a96fba6SXin Li TEST(Stream, WriteAsync) {
370*1a96fba6SXin Li   size_t write_size = 0;
371*1a96fba6SXin Li   bool failed = false;
372*1a96fba6SXin Li   auto success_callback = base::Bind([](size_t* write_size, size_t size) {
373*1a96fba6SXin Li     *write_size = size;
374*1a96fba6SXin Li   }, &write_size);
375*1a96fba6SXin Li   auto error_callback = base::Bind(&SetToTrue, &failed);
376*1a96fba6SXin Li 
377*1a96fba6SXin Li   MockStreamImpl stream_mock;
378*1a96fba6SXin Li   InSequence s;
379*1a96fba6SXin Li   base::Callback<void(AccessMode)> data_callback;
380*1a96fba6SXin Li   char buf[10] = {};
381*1a96fba6SXin Li 
382*1a96fba6SXin Li   // WriteNonBlocking returns a blocking situation (size_written = 0) so the
383*1a96fba6SXin Li   // WaitForData() is run.
384*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 10, _, _))
385*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));
386*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WaitForData(AccessMode::WRITE, _, _))
387*1a96fba6SXin Li       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
388*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.WriteAsync(buf, sizeof(buf), success_callback,
389*1a96fba6SXin Li                                      error_callback, nullptr));
390*1a96fba6SXin Li   EXPECT_EQ(0u, write_size);
391*1a96fba6SXin Li   EXPECT_FALSE(failed);
392*1a96fba6SXin Li 
393*1a96fba6SXin Li   ErrorPtr error;
394*1a96fba6SXin Li   EXPECT_FALSE(stream_mock.WriteAsync(buf, sizeof(buf), success_callback,
395*1a96fba6SXin Li                                       error_callback, &error));
396*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
397*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kOperationNotSupported, error->GetCode());
398*1a96fba6SXin Li   EXPECT_EQ("Another asynchronous operation is still pending",
399*1a96fba6SXin Li             error->GetMessage());
400*1a96fba6SXin Li 
401*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 10, _, _))
402*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(7), Return(true)));
403*1a96fba6SXin Li   data_callback.Run(AccessMode::WRITE);
404*1a96fba6SXin Li   EXPECT_EQ(7u, write_size);
405*1a96fba6SXin Li   EXPECT_FALSE(failed);
406*1a96fba6SXin Li }
407*1a96fba6SXin Li 
TEST(Stream,WriteAllAsync)408*1a96fba6SXin Li TEST(Stream, WriteAllAsync) {
409*1a96fba6SXin Li   bool succeeded = false;
410*1a96fba6SXin Li   bool failed = false;
411*1a96fba6SXin Li   auto success_callback = base::Bind([](bool* succeeded) { *succeeded = true; },
412*1a96fba6SXin Li                                      &succeeded);
413*1a96fba6SXin Li   auto error_callback = base::Bind(&SetToTrue, &failed);
414*1a96fba6SXin Li 
415*1a96fba6SXin Li   MockStreamImpl stream_mock;
416*1a96fba6SXin Li   base::Callback<void(AccessMode)> data_callback;
417*1a96fba6SXin Li   char buf[10] = {};
418*1a96fba6SXin Li 
419*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 10, _, _))
420*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));
421*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WaitForData(AccessMode::WRITE, _, _))
422*1a96fba6SXin Li       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
423*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.WriteAllAsync(buf, sizeof(buf), success_callback,
424*1a96fba6SXin Li                                         error_callback, nullptr));
425*1a96fba6SXin Li   testing::Mock::VerifyAndClearExpectations(&stream_mock);
426*1a96fba6SXin Li   EXPECT_FALSE(succeeded);
427*1a96fba6SXin Li   EXPECT_FALSE(failed);
428*1a96fba6SXin Li 
429*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 10, _, _))
430*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(7), Return(true)));
431*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteNonBlocking(buf + 7, 3, _, _))
432*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));
433*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WaitForData(AccessMode::WRITE, _, _))
434*1a96fba6SXin Li       .WillOnce(DoAll(SaveArg<1>(&data_callback), Return(true)));
435*1a96fba6SXin Li   data_callback.Run(AccessMode::WRITE);
436*1a96fba6SXin Li   testing::Mock::VerifyAndClearExpectations(&stream_mock);
437*1a96fba6SXin Li   EXPECT_FALSE(succeeded);
438*1a96fba6SXin Li   EXPECT_FALSE(failed);
439*1a96fba6SXin Li 
440*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteNonBlocking(buf + 7, 3, _, _))
441*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(3), Return(true)));
442*1a96fba6SXin Li   data_callback.Run(AccessMode::WRITE);
443*1a96fba6SXin Li   EXPECT_TRUE(succeeded);
444*1a96fba6SXin Li   EXPECT_FALSE(failed);
445*1a96fba6SXin Li }
446*1a96fba6SXin Li 
TEST(Stream,WriteBlocking)447*1a96fba6SXin Li TEST(Stream, WriteBlocking) {
448*1a96fba6SXin Li   MockStreamImpl stream_mock;
449*1a96fba6SXin Li   char buf[1024];
450*1a96fba6SXin Li   size_t written = 0;
451*1a96fba6SXin Li 
452*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 1024, _, _))
453*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(24), Return(true)));
454*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.WriteBlocking(buf, sizeof(buf), &written, nullptr));
455*1a96fba6SXin Li   EXPECT_EQ(24, written);
456*1a96fba6SXin Li 
457*1a96fba6SXin Li   {
458*1a96fba6SXin Li     InSequence seq;
459*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 1024, _, _))
460*1a96fba6SXin Li           .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));
461*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WaitForDataBlocking(AccessMode::WRITE, _, _, _))
462*1a96fba6SXin Li         .WillOnce(Return(true));
463*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 1024, _, _))
464*1a96fba6SXin Li           .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));
465*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WaitForDataBlocking(AccessMode::WRITE, _, _, _))
466*1a96fba6SXin Li         .WillOnce(Return(true));
467*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 1024, _, _))
468*1a96fba6SXin Li           .WillOnce(DoAll(SetArgPointee<2>(124), Return(true)));
469*1a96fba6SXin Li   }
470*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.WriteBlocking(buf, sizeof(buf), &written, nullptr));
471*1a96fba6SXin Li   EXPECT_EQ(124, written);
472*1a96fba6SXin Li 
473*1a96fba6SXin Li   {
474*1a96fba6SXin Li     InSequence seq;
475*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WriteNonBlocking(buf, 1024, _, _))
476*1a96fba6SXin Li           .WillOnce(DoAll(SetArgPointee<2>(0), Return(true)));
477*1a96fba6SXin Li     EXPECT_CALL(stream_mock, WaitForDataBlocking(AccessMode::WRITE, _, _, _))
478*1a96fba6SXin Li         .WillOnce(Return(false));
479*1a96fba6SXin Li   }
480*1a96fba6SXin Li   EXPECT_FALSE(stream_mock.WriteBlocking(buf, sizeof(buf), &written, nullptr));
481*1a96fba6SXin Li }
482*1a96fba6SXin Li 
TEST(Stream,WriteAllBlocking)483*1a96fba6SXin Li TEST(Stream, WriteAllBlocking) {
484*1a96fba6SXin Li   class MockWritelocking : public MockStreamImpl {
485*1a96fba6SXin Li    public:
486*1a96fba6SXin Li     MOCK_METHOD(bool,
487*1a96fba6SXin Li                 WriteBlocking,
488*1a96fba6SXin Li                 (const void*, size_t, size_t*, ErrorPtr*),
489*1a96fba6SXin Li                 (override));
490*1a96fba6SXin Li   } stream_mock;
491*1a96fba6SXin Li 
492*1a96fba6SXin Li   char buf[1024];
493*1a96fba6SXin Li 
494*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteBlocking(buf, 1024, _, _))
495*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(24), Return(true)));
496*1a96fba6SXin Li   EXPECT_CALL(stream_mock, WriteBlocking(buf + 24, 1000, _, _))
497*1a96fba6SXin Li       .WillOnce(DoAll(SetArgPointee<2>(1000), Return(true)));
498*1a96fba6SXin Li   EXPECT_TRUE(stream_mock.WriteAllBlocking(buf, sizeof(buf), nullptr));
499*1a96fba6SXin Li }
500*1a96fba6SXin Li 
501*1a96fba6SXin Li }  // namespace brillo
502