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