xref: /aosp_15_r20/external/libbrillo/brillo/streams/stream_utils_test.cc (revision 1a96fba65179ea7d3f56207137718607415c5953)
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_utils.h>
6*1a96fba6SXin Li 
7*1a96fba6SXin Li #include <limits>
8*1a96fba6SXin Li #include <memory>
9*1a96fba6SXin Li #include <string>
10*1a96fba6SXin Li #include <utility>
11*1a96fba6SXin Li 
12*1a96fba6SXin Li #include <base/bind.h>
13*1a96fba6SXin Li #include <brillo/message_loops/fake_message_loop.h>
14*1a96fba6SXin Li #include <brillo/message_loops/message_loop.h>
15*1a96fba6SXin Li #include <brillo/streams/mock_stream.h>
16*1a96fba6SXin Li #include <brillo/streams/stream_errors.h>
17*1a96fba6SXin Li #include <gmock/gmock.h>
18*1a96fba6SXin Li #include <gtest/gtest.h>
19*1a96fba6SXin Li 
20*1a96fba6SXin Li using testing::InSequence;
21*1a96fba6SXin Li using testing::StrictMock;
22*1a96fba6SXin Li using testing::_;
23*1a96fba6SXin Li 
ACTION_TEMPLATE(InvokeAsyncCallback,HAS_1_TEMPLATE_PARAMS (int,k),AND_1_VALUE_PARAMS (size))24*1a96fba6SXin Li ACTION_TEMPLATE(InvokeAsyncCallback,
25*1a96fba6SXin Li                 HAS_1_TEMPLATE_PARAMS(int, k),
26*1a96fba6SXin Li                 AND_1_VALUE_PARAMS(size)) {
27*1a96fba6SXin Li   brillo::MessageLoop::current()->PostTask(
28*1a96fba6SXin Li       FROM_HERE, base::BindOnce(std::get<k>(args), size));
29*1a96fba6SXin Li   return true;
30*1a96fba6SXin Li }
31*1a96fba6SXin Li 
ACTION_TEMPLATE(InvokeAsyncCallback,HAS_1_TEMPLATE_PARAMS (int,k),AND_0_VALUE_PARAMS ())32*1a96fba6SXin Li ACTION_TEMPLATE(InvokeAsyncCallback,
33*1a96fba6SXin Li                 HAS_1_TEMPLATE_PARAMS(int, k),
34*1a96fba6SXin Li                 AND_0_VALUE_PARAMS()) {
35*1a96fba6SXin Li   brillo::MessageLoop::current()->PostTask(FROM_HERE, std::get<k>(args));
36*1a96fba6SXin Li   return true;
37*1a96fba6SXin Li }
38*1a96fba6SXin Li 
ACTION_TEMPLATE(InvokeAsyncErrorCallback,HAS_1_TEMPLATE_PARAMS (int,k),AND_1_VALUE_PARAMS (code))39*1a96fba6SXin Li ACTION_TEMPLATE(InvokeAsyncErrorCallback,
40*1a96fba6SXin Li                 HAS_1_TEMPLATE_PARAMS(int, k),
41*1a96fba6SXin Li                 AND_1_VALUE_PARAMS(code)) {
42*1a96fba6SXin Li   brillo::ErrorPtr error;
43*1a96fba6SXin Li   brillo::Error::AddTo(&error, FROM_HERE, "test", code, "message");
44*1a96fba6SXin Li   brillo::MessageLoop::current()->PostTask(
45*1a96fba6SXin Li       FROM_HERE, base::BindOnce(std::get<k>(args),
46*1a96fba6SXin Li                                 base::Owned(error.release())));
47*1a96fba6SXin Li   return true;
48*1a96fba6SXin Li }
49*1a96fba6SXin Li 
50*1a96fba6SXin Li namespace brillo {
51*1a96fba6SXin Li 
TEST(StreamUtils,ErrorStreamClosed)52*1a96fba6SXin Li TEST(StreamUtils, ErrorStreamClosed) {
53*1a96fba6SXin Li   ErrorPtr error;
54*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::ErrorStreamClosed(FROM_HERE, &error));
55*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
56*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kStreamClosed, error->GetCode());
57*1a96fba6SXin Li   EXPECT_EQ("Stream is closed", error->GetMessage());
58*1a96fba6SXin Li }
59*1a96fba6SXin Li 
TEST(StreamUtils,ErrorOperationNotSupported)60*1a96fba6SXin Li TEST(StreamUtils, ErrorOperationNotSupported) {
61*1a96fba6SXin Li   ErrorPtr error;
62*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::ErrorOperationNotSupported(FROM_HERE, &error));
63*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
64*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kOperationNotSupported, error->GetCode());
65*1a96fba6SXin Li   EXPECT_EQ("Stream operation not supported", error->GetMessage());
66*1a96fba6SXin Li }
67*1a96fba6SXin Li 
TEST(StreamUtils,ErrorReadPastEndOfStream)68*1a96fba6SXin Li TEST(StreamUtils, ErrorReadPastEndOfStream) {
69*1a96fba6SXin Li   ErrorPtr error;
70*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::ErrorReadPastEndOfStream(FROM_HERE, &error));
71*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
72*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kPartialData, error->GetCode());
73*1a96fba6SXin Li   EXPECT_EQ("Reading past the end of stream", error->GetMessage());
74*1a96fba6SXin Li }
75*1a96fba6SXin Li 
TEST(StreamUtils,CheckInt64Overflow)76*1a96fba6SXin Li TEST(StreamUtils, CheckInt64Overflow) {
77*1a96fba6SXin Li   const int64_t max_int64 = std::numeric_limits<int64_t>::max();
78*1a96fba6SXin Li   const uint64_t max_uint64 = std::numeric_limits<uint64_t>::max();
79*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CheckInt64Overflow(FROM_HERE, 0, 0, nullptr));
80*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CheckInt64Overflow(
81*1a96fba6SXin Li       FROM_HERE, 0, max_int64, nullptr));
82*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CheckInt64Overflow(
83*1a96fba6SXin Li       FROM_HERE, max_int64, 0, nullptr));
84*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CheckInt64Overflow(FROM_HERE, 100, -90, nullptr));
85*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CheckInt64Overflow(
86*1a96fba6SXin Li       FROM_HERE, 1000, -1000, nullptr));
87*1a96fba6SXin Li 
88*1a96fba6SXin Li   ErrorPtr error;
89*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::CheckInt64Overflow(FROM_HERE, 100, -101, &error));
90*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kDomain, error->GetDomain());
91*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kInvalidParameter, error->GetCode());
92*1a96fba6SXin Li   EXPECT_EQ("The stream offset value is out of range", error->GetMessage());
93*1a96fba6SXin Li 
94*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::CheckInt64Overflow(
95*1a96fba6SXin Li       FROM_HERE, max_int64, 1, nullptr));
96*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::CheckInt64Overflow(
97*1a96fba6SXin Li       FROM_HERE, max_uint64, 0, nullptr));
98*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::CheckInt64Overflow(
99*1a96fba6SXin Li       FROM_HERE, max_uint64, max_int64, nullptr));
100*1a96fba6SXin Li }
101*1a96fba6SXin Li 
TEST(StreamUtils,CalculateStreamPosition)102*1a96fba6SXin Li TEST(StreamUtils, CalculateStreamPosition) {
103*1a96fba6SXin Li   using Whence = Stream::Whence;
104*1a96fba6SXin Li   const uint64_t current_pos = 1234;
105*1a96fba6SXin Li   const uint64_t end_pos = 2000;
106*1a96fba6SXin Li   uint64_t pos = 0;
107*1a96fba6SXin Li 
108*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CalculateStreamPosition(
109*1a96fba6SXin Li       FROM_HERE, 0, Whence::FROM_BEGIN, current_pos, end_pos, &pos, nullptr));
110*1a96fba6SXin Li   EXPECT_EQ(0u, pos);
111*1a96fba6SXin Li 
112*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CalculateStreamPosition(
113*1a96fba6SXin Li       FROM_HERE, 0, Whence::FROM_CURRENT, current_pos, end_pos, &pos, nullptr));
114*1a96fba6SXin Li   EXPECT_EQ(current_pos, pos);
115*1a96fba6SXin Li 
116*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CalculateStreamPosition(
117*1a96fba6SXin Li       FROM_HERE, 0, Whence::FROM_END, current_pos, end_pos, &pos, nullptr));
118*1a96fba6SXin Li   EXPECT_EQ(end_pos, pos);
119*1a96fba6SXin Li 
120*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CalculateStreamPosition(
121*1a96fba6SXin Li       FROM_HERE, 10, Whence::FROM_BEGIN, current_pos, end_pos, &pos, nullptr));
122*1a96fba6SXin Li   EXPECT_EQ(10u, pos);
123*1a96fba6SXin Li 
124*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CalculateStreamPosition(
125*1a96fba6SXin Li       FROM_HERE, 10, Whence::FROM_CURRENT, current_pos, end_pos, &pos,
126*1a96fba6SXin Li       nullptr));
127*1a96fba6SXin Li   EXPECT_EQ(current_pos + 10, pos);
128*1a96fba6SXin Li 
129*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CalculateStreamPosition(
130*1a96fba6SXin Li       FROM_HERE, 10, Whence::FROM_END, current_pos, end_pos, &pos, nullptr));
131*1a96fba6SXin Li   EXPECT_EQ(end_pos + 10, pos);
132*1a96fba6SXin Li 
133*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CalculateStreamPosition(
134*1a96fba6SXin Li       FROM_HERE, -10, Whence::FROM_CURRENT, current_pos, end_pos, &pos,
135*1a96fba6SXin Li       nullptr));
136*1a96fba6SXin Li   EXPECT_EQ(current_pos - 10, pos);
137*1a96fba6SXin Li 
138*1a96fba6SXin Li   EXPECT_TRUE(stream_utils::CalculateStreamPosition(
139*1a96fba6SXin Li       FROM_HERE, -10, Whence::FROM_END, current_pos, end_pos, &pos, nullptr));
140*1a96fba6SXin Li   EXPECT_EQ(end_pos - 10, pos);
141*1a96fba6SXin Li 
142*1a96fba6SXin Li   ErrorPtr error;
143*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::CalculateStreamPosition(
144*1a96fba6SXin Li       FROM_HERE, -1, Whence::FROM_BEGIN, current_pos, end_pos, &pos, &error));
145*1a96fba6SXin Li   EXPECT_EQ(errors::stream::kInvalidParameter, error->GetCode());
146*1a96fba6SXin Li   EXPECT_EQ("The stream offset value is out of range", error->GetMessage());
147*1a96fba6SXin Li 
148*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::CalculateStreamPosition(
149*1a96fba6SXin Li       FROM_HERE, -1001, Whence::FROM_CURRENT, 1000, end_pos, &pos, nullptr));
150*1a96fba6SXin Li 
151*1a96fba6SXin Li   const uint64_t max_int64 = std::numeric_limits<int64_t>::max();
152*1a96fba6SXin Li   EXPECT_FALSE(stream_utils::CalculateStreamPosition(
153*1a96fba6SXin Li       FROM_HERE, 1, Whence::FROM_CURRENT, max_int64, end_pos, &pos, nullptr));
154*1a96fba6SXin Li }
155*1a96fba6SXin Li 
156*1a96fba6SXin Li class CopyStreamDataTest : public testing::Test {
157*1a96fba6SXin Li  public:
SetUp()158*1a96fba6SXin Li   void SetUp() override {
159*1a96fba6SXin Li     fake_loop_.SetAsCurrent();
160*1a96fba6SXin Li     in_stream_.reset(new StrictMock<MockStream>{});
161*1a96fba6SXin Li     out_stream_.reset(new StrictMock<MockStream>{});
162*1a96fba6SXin Li   }
163*1a96fba6SXin Li 
164*1a96fba6SXin Li   FakeMessageLoop fake_loop_{nullptr};
165*1a96fba6SXin Li   std::unique_ptr<StrictMock<MockStream>> in_stream_;
166*1a96fba6SXin Li   std::unique_ptr<StrictMock<MockStream>> out_stream_;
167*1a96fba6SXin Li   bool succeeded_{false};
168*1a96fba6SXin Li   bool failed_{false};
169*1a96fba6SXin Li 
OnSuccess(uint64_t expected,StreamPtr,StreamPtr,uint64_t copied)170*1a96fba6SXin Li   void OnSuccess(uint64_t expected,
171*1a96fba6SXin Li                  StreamPtr /* in_stream */,
172*1a96fba6SXin Li                  StreamPtr /* out_stream */,
173*1a96fba6SXin Li                  uint64_t copied) {
174*1a96fba6SXin Li     EXPECT_EQ(expected, copied);
175*1a96fba6SXin Li     succeeded_ = true;
176*1a96fba6SXin Li   }
177*1a96fba6SXin Li 
OnError(const std::string & expected_error,StreamPtr,StreamPtr,const Error * error)178*1a96fba6SXin Li   void OnError(const std::string& expected_error,
179*1a96fba6SXin Li                StreamPtr /* in_stream */,
180*1a96fba6SXin Li                StreamPtr /* out_stream */,
181*1a96fba6SXin Li                const Error* error) {
182*1a96fba6SXin Li     EXPECT_EQ(expected_error, error->GetCode());
183*1a96fba6SXin Li     failed_ = true;
184*1a96fba6SXin Li   }
185*1a96fba6SXin Li 
ExpectSuccess()186*1a96fba6SXin Li   void ExpectSuccess() {
187*1a96fba6SXin Li     EXPECT_TRUE(succeeded_);
188*1a96fba6SXin Li     EXPECT_FALSE(failed_);
189*1a96fba6SXin Li   }
190*1a96fba6SXin Li 
ExpectFailure()191*1a96fba6SXin Li   void ExpectFailure() {
192*1a96fba6SXin Li     EXPECT_FALSE(succeeded_);
193*1a96fba6SXin Li     EXPECT_TRUE(failed_);
194*1a96fba6SXin Li   }
195*1a96fba6SXin Li };
196*1a96fba6SXin Li 
TEST_F(CopyStreamDataTest,CopyAllAtOnce)197*1a96fba6SXin Li TEST_F(CopyStreamDataTest, CopyAllAtOnce) {
198*1a96fba6SXin Li   {
199*1a96fba6SXin Li     InSequence seq;
200*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 100, _, _, _))
201*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>(100));
202*1a96fba6SXin Li     EXPECT_CALL(*out_stream_, WriteAllAsync(_, 100, _, _, _))
203*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>());
204*1a96fba6SXin Li   }
205*1a96fba6SXin Li   stream_utils::CopyData(
206*1a96fba6SXin Li       std::move(in_stream_), std::move(out_stream_), 100, 4096,
207*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 100),
208*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), ""));
209*1a96fba6SXin Li   fake_loop_.Run();
210*1a96fba6SXin Li   ExpectSuccess();
211*1a96fba6SXin Li }
212*1a96fba6SXin Li 
TEST_F(CopyStreamDataTest,CopyInBlocks)213*1a96fba6SXin Li TEST_F(CopyStreamDataTest, CopyInBlocks) {
214*1a96fba6SXin Li   {
215*1a96fba6SXin Li     InSequence seq;
216*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 100, _, _, _))
217*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>(60));
218*1a96fba6SXin Li     EXPECT_CALL(*out_stream_, WriteAllAsync(_, 60, _, _, _))
219*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>());
220*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 40, _, _, _))
221*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>(40));
222*1a96fba6SXin Li     EXPECT_CALL(*out_stream_, WriteAllAsync(_, 40, _, _, _))
223*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>());
224*1a96fba6SXin Li   }
225*1a96fba6SXin Li   stream_utils::CopyData(
226*1a96fba6SXin Li       std::move(in_stream_), std::move(out_stream_), 100, 4096,
227*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 100),
228*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), ""));
229*1a96fba6SXin Li   fake_loop_.Run();
230*1a96fba6SXin Li   ExpectSuccess();
231*1a96fba6SXin Li }
232*1a96fba6SXin Li 
TEST_F(CopyStreamDataTest,CopyTillEndOfStream)233*1a96fba6SXin Li TEST_F(CopyStreamDataTest, CopyTillEndOfStream) {
234*1a96fba6SXin Li   {
235*1a96fba6SXin Li     InSequence seq;
236*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 100, _, _, _))
237*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>(60));
238*1a96fba6SXin Li     EXPECT_CALL(*out_stream_, WriteAllAsync(_, 60, _, _, _))
239*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>());
240*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 40, _, _, _))
241*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>(0));
242*1a96fba6SXin Li   }
243*1a96fba6SXin Li   stream_utils::CopyData(
244*1a96fba6SXin Li       std::move(in_stream_), std::move(out_stream_), 100, 4096,
245*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 60),
246*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), ""));
247*1a96fba6SXin Li   fake_loop_.Run();
248*1a96fba6SXin Li   ExpectSuccess();
249*1a96fba6SXin Li }
250*1a96fba6SXin Li 
TEST_F(CopyStreamDataTest,CopyInSmallBlocks)251*1a96fba6SXin Li TEST_F(CopyStreamDataTest, CopyInSmallBlocks) {
252*1a96fba6SXin Li   {
253*1a96fba6SXin Li     InSequence seq;
254*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 60, _, _, _))
255*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>(60));
256*1a96fba6SXin Li     EXPECT_CALL(*out_stream_, WriteAllAsync(_, 60, _, _, _))
257*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>());
258*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 40, _, _, _))
259*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>(40));
260*1a96fba6SXin Li     EXPECT_CALL(*out_stream_, WriteAllAsync(_, 40, _, _, _))
261*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>());
262*1a96fba6SXin Li   }
263*1a96fba6SXin Li   stream_utils::CopyData(
264*1a96fba6SXin Li       std::move(in_stream_), std::move(out_stream_), 100, 60,
265*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 100),
266*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), ""));
267*1a96fba6SXin Li   fake_loop_.Run();
268*1a96fba6SXin Li   ExpectSuccess();
269*1a96fba6SXin Li }
270*1a96fba6SXin Li 
TEST_F(CopyStreamDataTest,ErrorRead)271*1a96fba6SXin Li TEST_F(CopyStreamDataTest, ErrorRead) {
272*1a96fba6SXin Li   {
273*1a96fba6SXin Li     InSequence seq;
274*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 60, _, _, _))
275*1a96fba6SXin Li         .WillOnce(InvokeAsyncErrorCallback<3>("read"));
276*1a96fba6SXin Li   }
277*1a96fba6SXin Li   stream_utils::CopyData(
278*1a96fba6SXin Li       std::move(in_stream_), std::move(out_stream_), 100, 60,
279*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 0),
280*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this), "read"));
281*1a96fba6SXin Li   fake_loop_.Run();
282*1a96fba6SXin Li   ExpectFailure();
283*1a96fba6SXin Li }
284*1a96fba6SXin Li 
TEST_F(CopyStreamDataTest,ErrorWrite)285*1a96fba6SXin Li TEST_F(CopyStreamDataTest, ErrorWrite) {
286*1a96fba6SXin Li   {
287*1a96fba6SXin Li     InSequence seq;
288*1a96fba6SXin Li     EXPECT_CALL(*in_stream_, ReadAsync(_, 60, _, _, _))
289*1a96fba6SXin Li         .WillOnce(InvokeAsyncCallback<2>(60));
290*1a96fba6SXin Li     EXPECT_CALL(*out_stream_, WriteAllAsync(_, 60, _, _, _))
291*1a96fba6SXin Li         .WillOnce(InvokeAsyncErrorCallback<3>("write"));
292*1a96fba6SXin Li   }
293*1a96fba6SXin Li   stream_utils::CopyData(
294*1a96fba6SXin Li       std::move(in_stream_), std::move(out_stream_), 100, 60,
295*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnSuccess, base::Unretained(this), 0),
296*1a96fba6SXin Li       base::Bind(&CopyStreamDataTest::OnError, base::Unretained(this),
297*1a96fba6SXin Li                  "write"));
298*1a96fba6SXin Li   fake_loop_.Run();
299*1a96fba6SXin Li   ExpectFailure();
300*1a96fba6SXin Li }
301*1a96fba6SXin Li 
302*1a96fba6SXin Li }  // namespace brillo
303