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/fake_stream.h> 6 7 #include <vector> 8 9 #include <base/callback.h> 10 #include <base/test/simple_test_clock.h> 11 #include <brillo/bind_lambda.h> 12 #include <brillo/message_loops/mock_message_loop.h> 13 #include <gmock/gmock.h> 14 #include <gtest/gtest.h> 15 16 using testing::AnyNumber; 17 using testing::InSequence; 18 using testing::_; 19 20 namespace brillo { 21 22 class FakeStreamTest : public testing::Test { 23 public: 24 void SetUp() override { 25 mock_loop_.SetAsCurrent(); 26 // Ignore calls to RunOnce(). 27 EXPECT_CALL(mock_loop_, RunOnce(true)).Times(AnyNumber()); 28 } 29 30 void CreateStream(Stream::AccessMode mode) { 31 stream_.reset(new FakeStream{mode, &clock_}); 32 } 33 34 // Performs non-blocking read on the stream and returns the read data 35 // as a string in |out_buffer|. Returns true if the read was successful or 36 // false when an error occurs. |*eos| is set to true when end of stream is 37 // reached. 38 bool ReadString(size_t size_to_read, std::string* out_buffer, bool* eos) { 39 std::vector<char> data; 40 data.resize(size_to_read); 41 size_t size_read = 0; 42 bool ok = stream_->ReadNonBlocking(data.data(), data.size(), &size_read, 43 eos, nullptr); 44 if (ok) { 45 out_buffer->assign(data.data(), data.data() + size_read); 46 } else { 47 out_buffer->clear(); 48 } 49 return ok; 50 } 51 52 // Writes a string to a stream. Returns the number of bytes written or -1 53 // in case an error occurred. 54 int WriteString(const std::string& data) { 55 size_t written = 0; 56 if (!stream_->WriteNonBlocking(data.data(), data.size(), &written, nullptr)) 57 return -1; 58 return static_cast<int>(written); 59 } 60 61 protected: 62 base::SimpleTestClock clock_; 63 MockMessageLoop mock_loop_{&clock_}; 64 std::unique_ptr<FakeStream> stream_; 65 const base::TimeDelta zero_delay; 66 }; 67 68 TEST_F(FakeStreamTest, InitReadOnly) { 69 CreateStream(Stream::AccessMode::READ); 70 EXPECT_TRUE(stream_->IsOpen()); 71 EXPECT_TRUE(stream_->CanRead()); 72 EXPECT_FALSE(stream_->CanWrite()); 73 EXPECT_FALSE(stream_->CanSeek()); 74 EXPECT_FALSE(stream_->CanGetSize()); 75 EXPECT_EQ(0, stream_->GetSize()); 76 EXPECT_EQ(0, stream_->GetRemainingSize()); 77 EXPECT_EQ(0, stream_->GetPosition()); 78 } 79 80 TEST_F(FakeStreamTest, InitWriteOnly) { 81 CreateStream(Stream::AccessMode::WRITE); 82 EXPECT_TRUE(stream_->IsOpen()); 83 EXPECT_FALSE(stream_->CanRead()); 84 EXPECT_TRUE(stream_->CanWrite()); 85 EXPECT_FALSE(stream_->CanSeek()); 86 EXPECT_FALSE(stream_->CanGetSize()); 87 EXPECT_EQ(0, stream_->GetSize()); 88 EXPECT_EQ(0, stream_->GetRemainingSize()); 89 EXPECT_EQ(0, stream_->GetPosition()); 90 } 91 92 TEST_F(FakeStreamTest, InitReadWrite) { 93 CreateStream(Stream::AccessMode::READ_WRITE); 94 EXPECT_TRUE(stream_->IsOpen()); 95 EXPECT_TRUE(stream_->CanRead()); 96 EXPECT_TRUE(stream_->CanWrite()); 97 EXPECT_FALSE(stream_->CanSeek()); 98 EXPECT_FALSE(stream_->CanGetSize()); 99 EXPECT_EQ(0, stream_->GetSize()); 100 EXPECT_EQ(0, stream_->GetRemainingSize()); 101 EXPECT_EQ(0, stream_->GetPosition()); 102 } 103 104 TEST_F(FakeStreamTest, ReadEmpty) { 105 CreateStream(Stream::AccessMode::READ); 106 std::string data; 107 bool eos = false; 108 EXPECT_TRUE(ReadString(100, &data, &eos)); 109 EXPECT_TRUE(eos); 110 EXPECT_TRUE(data.empty()); 111 } 112 113 TEST_F(FakeStreamTest, ReadFullPacket) { 114 CreateStream(Stream::AccessMode::READ); 115 stream_->AddReadPacketString({}, "foo"); 116 std::string data; 117 bool eos = false; 118 EXPECT_TRUE(ReadString(100, &data, &eos)); 119 EXPECT_FALSE(eos); 120 EXPECT_EQ("foo", data); 121 122 EXPECT_TRUE(ReadString(100, &data, &eos)); 123 EXPECT_TRUE(eos); 124 EXPECT_TRUE(data.empty()); 125 } 126 127 TEST_F(FakeStreamTest, ReadPartialPacket) { 128 CreateStream(Stream::AccessMode::READ); 129 stream_->AddReadPacketString({}, "foobar"); 130 std::string data; 131 bool eos = false; 132 EXPECT_TRUE(ReadString(3, &data, &eos)); 133 EXPECT_FALSE(eos); 134 EXPECT_EQ("foo", data); 135 136 EXPECT_TRUE(ReadString(100, &data, &eos)); 137 EXPECT_FALSE(eos); 138 EXPECT_EQ("bar", data); 139 140 EXPECT_TRUE(ReadString(100, &data, &eos)); 141 EXPECT_TRUE(eos); 142 EXPECT_TRUE(data.empty()); 143 } 144 145 TEST_F(FakeStreamTest, ReadMultiplePackets) { 146 CreateStream(Stream::AccessMode::READ); 147 stream_->AddReadPacketString({}, "foobar"); 148 stream_->AddReadPacketString({}, "baz"); 149 stream_->AddReadPacketString({}, "quux"); 150 std::string data; 151 bool eos = false; 152 EXPECT_TRUE(ReadString(100, &data, &eos)); 153 EXPECT_FALSE(eos); 154 EXPECT_EQ("foobar", data); 155 156 EXPECT_TRUE(ReadString(2, &data, &eos)); 157 EXPECT_FALSE(eos); 158 EXPECT_EQ("ba", data); 159 160 EXPECT_TRUE(ReadString(100, &data, &eos)); 161 EXPECT_FALSE(eos); 162 EXPECT_EQ("z", data); 163 164 EXPECT_TRUE(ReadString(100, &data, &eos)); 165 EXPECT_FALSE(eos); 166 EXPECT_EQ("quux", data); 167 168 EXPECT_TRUE(ReadString(100, &data, &eos)); 169 EXPECT_TRUE(eos); 170 EXPECT_TRUE(data.empty()); 171 172 stream_->AddReadPacketString({}, "foo-bar"); 173 EXPECT_TRUE(ReadString(100, &data, &eos)); 174 EXPECT_FALSE(eos); 175 EXPECT_EQ("foo-bar", data); 176 } 177 178 TEST_F(FakeStreamTest, ReadPacketsWithDelay) { 179 CreateStream(Stream::AccessMode::READ); 180 stream_->AddReadPacketString({}, "foobar"); 181 stream_->AddReadPacketString(base::TimeDelta::FromSeconds(1), "baz"); 182 std::string data; 183 bool eos = false; 184 EXPECT_TRUE(ReadString(100, &data, &eos)); 185 EXPECT_FALSE(eos); 186 EXPECT_EQ("foobar", data); 187 188 EXPECT_TRUE(ReadString(100, &data, &eos)); 189 EXPECT_FALSE(eos); 190 EXPECT_TRUE(data.empty()); 191 192 EXPECT_TRUE(ReadString(100, &data, &eos)); 193 EXPECT_FALSE(eos); 194 EXPECT_TRUE(data.empty()); 195 196 clock_.Advance(base::TimeDelta::FromSeconds(1)); 197 198 EXPECT_TRUE(ReadString(100, &data, &eos)); 199 EXPECT_FALSE(eos); 200 EXPECT_EQ("baz", data); 201 } 202 203 TEST_F(FakeStreamTest, ReadPacketsWithError) { 204 CreateStream(Stream::AccessMode::READ); 205 stream_->AddReadPacketString({}, "foobar"); 206 stream_->QueueReadErrorWithMessage(base::TimeDelta::FromSeconds(1), 207 "Dummy error"); 208 stream_->AddReadPacketString({}, "baz"); 209 210 std::string data; 211 bool eos = false; 212 EXPECT_TRUE(ReadString(100, &data, &eos)); 213 EXPECT_FALSE(eos); 214 EXPECT_EQ("foobar", data); 215 216 EXPECT_TRUE(ReadString(100, &data, &eos)); 217 EXPECT_FALSE(eos); 218 EXPECT_TRUE(data.empty()); 219 220 EXPECT_TRUE(ReadString(100, &data, &eos)); 221 EXPECT_FALSE(eos); 222 EXPECT_TRUE(data.empty()); 223 224 clock_.Advance(base::TimeDelta::FromSeconds(1)); 225 226 EXPECT_FALSE(ReadString(100, &data, &eos)); 227 228 EXPECT_TRUE(ReadString(100, &data, &eos)); 229 EXPECT_FALSE(eos); 230 EXPECT_EQ("baz", data); 231 } 232 233 TEST_F(FakeStreamTest, WaitForDataRead) { 234 CreateStream(Stream::AccessMode::READ); 235 236 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(2); 237 238 int call_count = 0; 239 auto callback = [&call_count](Stream::AccessMode mode) { 240 call_count++; 241 EXPECT_EQ(Stream::AccessMode::READ, mode); 242 }; 243 244 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ, 245 base::Bind(callback), nullptr)); 246 mock_loop_.Run(); 247 EXPECT_EQ(1, call_count); 248 249 stream_->AddReadPacketString({}, "foobar"); 250 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ, 251 base::Bind(callback), nullptr)); 252 mock_loop_.Run(); 253 EXPECT_EQ(2, call_count); 254 255 stream_->ClearReadQueue(); 256 257 auto one_sec_delay = base::TimeDelta::FromSeconds(1); 258 stream_->AddReadPacketString(one_sec_delay, "baz"); 259 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1); 260 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ, 261 base::Bind(callback), nullptr)); 262 mock_loop_.Run(); 263 EXPECT_EQ(3, call_count); 264 } 265 266 TEST_F(FakeStreamTest, ReadAsync) { 267 CreateStream(Stream::AccessMode::READ); 268 std::string input_data = "foobar-baz"; 269 size_t split_pos = input_data.find('-'); 270 271 auto one_sec_delay = base::TimeDelta::FromSeconds(1); 272 stream_->AddReadPacketString({}, input_data.substr(0, split_pos)); 273 stream_->AddReadPacketString(one_sec_delay, input_data.substr(split_pos)); 274 275 { 276 InSequence seq; 277 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(1); 278 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1); 279 } 280 281 std::vector<char> buffer; 282 buffer.resize(input_data.size()); 283 284 int success_count = 0; 285 int error_count = 0; 286 auto on_success = [&success_count] { success_count++; }; 287 auto on_failure = [&error_count](const Error* /* error */) { error_count++; }; 288 289 EXPECT_TRUE(stream_->ReadAllAsync(buffer.data(), buffer.size(), 290 base::Bind(on_success), 291 base::Bind(on_failure), 292 nullptr)); 293 mock_loop_.Run(); 294 EXPECT_EQ(1, success_count); 295 EXPECT_EQ(0, error_count); 296 EXPECT_EQ(input_data, (std::string{buffer.begin(), buffer.end()})); 297 } 298 299 TEST_F(FakeStreamTest, WriteEmpty) { 300 CreateStream(Stream::AccessMode::WRITE); 301 EXPECT_EQ(-1, WriteString("foo")); 302 } 303 304 TEST_F(FakeStreamTest, WritePartial) { 305 CreateStream(Stream::AccessMode::WRITE); 306 stream_->ExpectWritePacketSize({}, 6); 307 EXPECT_EQ(3, WriteString("foo")); 308 EXPECT_EQ(3, WriteString("bar")); 309 EXPECT_EQ(-1, WriteString("baz")); 310 311 EXPECT_EQ("foobar", stream_->GetFlushedOutputDataAsString()); 312 } 313 314 TEST_F(FakeStreamTest, WriteFullPackets) { 315 CreateStream(Stream::AccessMode::WRITE); 316 317 stream_->ExpectWritePacketSize({}, 3); 318 EXPECT_EQ(3, WriteString("foo")); 319 EXPECT_EQ(-1, WriteString("bar")); 320 321 stream_->ExpectWritePacketSize({}, 3); 322 EXPECT_EQ(3, WriteString("bar")); 323 324 stream_->ExpectWritePacketSize({}, 3); 325 EXPECT_EQ(3, WriteString("quux")); 326 327 EXPECT_EQ("foobarquu", stream_->GetFlushedOutputDataAsString()); 328 } 329 330 TEST_F(FakeStreamTest, WriteAndVerifyData) { 331 CreateStream(Stream::AccessMode::WRITE); 332 333 stream_->ExpectWritePacketString({}, "foo"); 334 stream_->ExpectWritePacketString({}, "bar"); 335 EXPECT_EQ(3, WriteString("foobar")); 336 EXPECT_EQ(3, WriteString("bar")); 337 338 stream_->ExpectWritePacketString({}, "foo"); 339 stream_->ExpectWritePacketString({}, "baz"); 340 EXPECT_EQ(3, WriteString("foobar")); 341 EXPECT_EQ(-1, WriteString("bar")); 342 343 stream_->ExpectWritePacketString({}, "foobar"); 344 EXPECT_EQ(3, WriteString("foo")); 345 EXPECT_EQ(2, WriteString("ba")); 346 EXPECT_EQ(-1, WriteString("z")); 347 } 348 349 TEST_F(FakeStreamTest, WriteWithDelay) { 350 CreateStream(Stream::AccessMode::WRITE); 351 352 const auto delay = base::TimeDelta::FromMilliseconds(500); 353 354 stream_->ExpectWritePacketSize({}, 3); 355 stream_->ExpectWritePacketSize(delay, 3); 356 EXPECT_EQ(3, WriteString("foobar")); 357 358 EXPECT_EQ(0, WriteString("bar")); 359 EXPECT_EQ(0, WriteString("bar")); 360 clock_.Advance(delay); 361 EXPECT_EQ(3, WriteString("bar")); 362 363 EXPECT_EQ("foobar", stream_->GetFlushedOutputDataAsString()); 364 } 365 366 TEST_F(FakeStreamTest, WriteWithError) { 367 CreateStream(Stream::AccessMode::WRITE); 368 369 const auto delay = base::TimeDelta::FromMilliseconds(500); 370 371 stream_->ExpectWritePacketSize({}, 3); 372 stream_->QueueWriteError({}); 373 stream_->ExpectWritePacketSize({}, 3); 374 stream_->QueueWriteErrorWithMessage(delay, "Dummy message"); 375 stream_->ExpectWritePacketString({}, "foobar"); 376 377 const std::string data = "foobarbaz"; 378 EXPECT_EQ(3, WriteString(data)); 379 EXPECT_EQ(-1, WriteString(data)); // Simulated error #1. 380 EXPECT_EQ(3, WriteString(data)); 381 EXPECT_EQ(0, WriteString(data)); // Waiting for data... 382 clock_.Advance(delay); 383 EXPECT_EQ(-1, WriteString(data)); // Simulated error #2. 384 EXPECT_EQ(6, WriteString(data)); 385 EXPECT_EQ(-1, WriteString(data)); // No more data expected. 386 } 387 388 TEST_F(FakeStreamTest, WaitForDataWrite) { 389 CreateStream(Stream::AccessMode::WRITE); 390 391 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(2); 392 393 int call_count = 0; 394 auto callback = [&call_count](Stream::AccessMode mode) { 395 call_count++; 396 EXPECT_EQ(Stream::AccessMode::WRITE, mode); 397 }; 398 399 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::WRITE, 400 base::Bind(callback), nullptr)); 401 mock_loop_.Run(); 402 EXPECT_EQ(1, call_count); 403 404 stream_->ExpectWritePacketString({}, "foobar"); 405 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::WRITE, 406 base::Bind(callback), nullptr)); 407 mock_loop_.Run(); 408 EXPECT_EQ(2, call_count); 409 410 stream_->ClearWriteQueue(); 411 412 auto one_sec_delay = base::TimeDelta::FromSeconds(1); 413 stream_->ExpectWritePacketString(one_sec_delay, "baz"); 414 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1); 415 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::WRITE, 416 base::Bind(callback), nullptr)); 417 mock_loop_.Run(); 418 EXPECT_EQ(3, call_count); 419 } 420 421 TEST_F(FakeStreamTest, WriteAsync) { 422 CreateStream(Stream::AccessMode::WRITE); 423 std::string output_data = "foobar-baz"; 424 size_t split_pos = output_data.find('-'); 425 426 auto one_sec_delay = base::TimeDelta::FromSeconds(1); 427 stream_->ExpectWritePacketString({}, output_data.substr(0, split_pos)); 428 stream_->ExpectWritePacketString(one_sec_delay, 429 output_data.substr(split_pos)); 430 431 { 432 InSequence seq; 433 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(1); 434 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1); 435 } 436 437 int success_count = 0; 438 int error_count = 0; 439 auto on_success = [&success_count] { success_count++; }; 440 auto on_failure = [&error_count](const Error* /* error */) { error_count++; }; 441 442 EXPECT_TRUE(stream_->WriteAllAsync(output_data.data(), output_data.size(), 443 base::Bind(on_success), 444 base::Bind(on_failure), 445 nullptr)); 446 mock_loop_.Run(); 447 EXPECT_EQ(1, success_count); 448 EXPECT_EQ(0, error_count); 449 EXPECT_EQ(output_data, stream_->GetFlushedOutputDataAsString()); 450 } 451 452 TEST_F(FakeStreamTest, WaitForDataReadWrite) { 453 CreateStream(Stream::AccessMode::READ_WRITE); 454 auto one_sec_delay = base::TimeDelta::FromSeconds(1); 455 auto two_sec_delay = base::TimeDelta::FromSeconds(2); 456 457 int call_count = 0; 458 auto callback = [&call_count](Stream::AccessMode mode, 459 Stream::AccessMode expected_mode) { 460 call_count++; 461 EXPECT_EQ(static_cast<int>(expected_mode), static_cast<int>(mode)); 462 }; 463 464 stream_->AddReadPacketString(one_sec_delay, "foo"); 465 stream_->ExpectWritePacketString(two_sec_delay, "bar"); 466 467 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1); 468 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE, 469 base::Bind(callback, 470 Stream::AccessMode::READ), 471 nullptr)); 472 mock_loop_.Run(); 473 EXPECT_EQ(1, call_count); 474 475 // The above step has adjusted the clock by 1 second already. 476 stream_->ClearReadQueue(); 477 stream_->AddReadPacketString(two_sec_delay, "foo"); 478 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1); 479 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE, 480 base::Bind(callback, 481 Stream::AccessMode::WRITE), 482 nullptr)); 483 mock_loop_.Run(); 484 EXPECT_EQ(2, call_count); 485 486 clock_.Advance(one_sec_delay); 487 488 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, zero_delay)).Times(1); 489 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE, 490 base::Bind(callback, 491 Stream::AccessMode::READ_WRITE), 492 nullptr)); 493 mock_loop_.Run(); 494 EXPECT_EQ(3, call_count); 495 496 stream_->ClearReadQueue(); 497 stream_->ClearWriteQueue(); 498 stream_->AddReadPacketString(one_sec_delay, "foo"); 499 stream_->ExpectWritePacketString(one_sec_delay, "bar"); 500 501 EXPECT_CALL(mock_loop_, PostDelayedTask(_, _, one_sec_delay)).Times(1); 502 EXPECT_TRUE(stream_->WaitForData(Stream::AccessMode::READ_WRITE, 503 base::Bind(callback, 504 Stream::AccessMode::READ_WRITE), 505 nullptr)); 506 mock_loop_.Run(); 507 EXPECT_EQ(4, call_count); 508 } 509 510 } // namespace brillo 511