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 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 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 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 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 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 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 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 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 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 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 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 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