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