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