1 /*
2 * Copyright (C) 2017 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
16
17 #include "android-base/result.h"
18 #include <utils/ErrorsMacros.h>
19 #include "errno.h"
20
21 #include <istream>
22 #include <memory>
23 #include <string>
24 #include <type_traits>
25
26 #include <gmock/gmock.h>
27 #include <gtest/gtest.h>
28
29 #include "android-base/result-gmock.h"
30
31 using namespace std::string_literals;
32 using ::testing::Eq;
33 using ::testing::ExplainMatchResult;
34 using ::testing::HasSubstr;
35 using ::testing::Not;
36 using ::testing::StartsWith;
37
38 namespace android {
39 namespace base {
40
TEST(result,result_accessors)41 TEST(result, result_accessors) {
42 Result<std::string> result = "success";
43 ASSERT_RESULT_OK(result);
44 ASSERT_TRUE(result.has_value());
45
46 EXPECT_EQ("success", *result);
47 EXPECT_EQ("success", result.value());
48
49 EXPECT_EQ('s', result->data()[0]);
50 }
51
TEST(result,result_accessors_rvalue)52 TEST(result, result_accessors_rvalue) {
53 ASSERT_TRUE(Result<std::string>("success").ok());
54 ASSERT_TRUE(Result<std::string>("success").has_value());
55
56 EXPECT_EQ("success", *Result<std::string>("success"));
57 EXPECT_EQ("success", Result<std::string>("success").value());
58
59 EXPECT_EQ('s', Result<std::string>("success")->data()[0]);
60 }
61
TEST(result,result_void)62 TEST(result, result_void) {
63 Result<void> ok = {};
64 EXPECT_RESULT_OK(ok);
65 ok.value(); // should not crash
66 ASSERT_DEATH(ok.error(), "");
67
68 Result<void> fail = Error() << "failure" << 1;
69 EXPECT_FALSE(fail.ok());
70 EXPECT_EQ("failure1", fail.error().message());
71 EXPECT_EQ(0, fail.error().code());
72 EXPECT_TRUE(ok != fail);
73 ASSERT_DEATH(fail.value(), "");
74
75 auto test = [](bool ok) -> Result<void> {
76 if (ok) return {};
77 else return Error() << "failure" << 1;
78 };
79 EXPECT_TRUE(test(true).ok());
80 EXPECT_FALSE(test(false).ok());
81 test(true).value(); // should not crash
82 ASSERT_DEATH(test(true).error(), "");
83 ASSERT_DEATH(test(false).value(), "");
84 EXPECT_EQ("failure1", test(false).error().message());
85 }
86
TEST(result,result_error)87 TEST(result, result_error) {
88 Result<void> result = Error() << "failure" << 1;
89 ASSERT_FALSE(result.ok());
90 ASSERT_FALSE(result.has_value());
91
92 EXPECT_EQ(0, result.error().code());
93 EXPECT_EQ("failure1", result.error().message());
94 }
95
TEST(result,result_error_empty)96 TEST(result, result_error_empty) {
97 Result<void> result = Error();
98 ASSERT_FALSE(result.ok());
99 ASSERT_FALSE(result.has_value());
100
101 EXPECT_EQ(0, result.error().code());
102 EXPECT_EQ("", result.error().message());
103 }
104
TEST(result,result_error_rvalue)105 TEST(result, result_error_rvalue) {
106 // Error() and ErrnoError() aren't actually used to create a Result<T> object.
107 // Under the hood, they are an intermediate class that can be implicitly constructed into a
108 // Result<T>. This is needed both to create the ostream and because Error() itself, by
109 // definition will not know what the type, T, of the underlying Result<T> object that it would
110 // create is.
111
112 auto MakeRvalueErrorResult = []() -> Result<void> { return Error() << "failure" << 1; };
113 ASSERT_FALSE(MakeRvalueErrorResult().ok());
114 ASSERT_FALSE(MakeRvalueErrorResult().has_value());
115
116 EXPECT_EQ(0, MakeRvalueErrorResult().error().code());
117 EXPECT_EQ("failure1", MakeRvalueErrorResult().error().message());
118 }
119
TEST(result,result_errno_error)120 TEST(result, result_errno_error) {
121 constexpr int test_errno = 6;
122 errno = test_errno;
123 Result<void> result = ErrnoError() << "failure" << 1;
124
125 ASSERT_FALSE(result.ok());
126 ASSERT_FALSE(result.has_value());
127
128 EXPECT_EQ(test_errno, result.error().code());
129 EXPECT_EQ("failure1: "s + strerror(test_errno), result.error().message());
130 }
131
TEST(result,result_errno_error_no_text)132 TEST(result, result_errno_error_no_text) {
133 constexpr int test_errno = 6;
134 errno = test_errno;
135 Result<void> result = ErrnoError();
136
137 ASSERT_FALSE(result.ok());
138 ASSERT_FALSE(result.has_value());
139
140 EXPECT_EQ(test_errno, result.error().code());
141 EXPECT_EQ(strerror(test_errno), result.error().message());
142 }
143
TEST(result,result_error_from_other_result)144 TEST(result, result_error_from_other_result) {
145 auto error_text = "test error"s;
146 Result<void> result = Error() << error_text;
147
148 ASSERT_FALSE(result.ok());
149 ASSERT_FALSE(result.has_value());
150
151 Result<std::string> result2 = result.error();
152
153 ASSERT_FALSE(result2.ok());
154 ASSERT_FALSE(result2.has_value());
155
156 EXPECT_EQ(0, result2.error().code());
157 EXPECT_EQ(error_text, result2.error().message());
158 }
159
TEST(result,result_error_through_ostream)160 TEST(result, result_error_through_ostream) {
161 auto error_text = "test error"s;
162 Result<void> result = Error() << error_text;
163
164 ASSERT_FALSE(result.ok());
165 ASSERT_FALSE(result.has_value());
166
167 Result<std::string> result2 = Error() << result.error();
168
169 ASSERT_FALSE(result2.ok());
170 ASSERT_FALSE(result2.has_value());
171
172 EXPECT_EQ(0, result2.error().code());
173 EXPECT_EQ(error_text, result2.error().message());
174 }
175
TEST(result,result_errno_error_through_ostream)176 TEST(result, result_errno_error_through_ostream) {
177 auto error_text = "test error"s;
178 constexpr int test_errno = 6;
179 errno = 6;
180 Result<void> result = ErrnoError() << error_text;
181
182 errno = 0;
183
184 ASSERT_FALSE(result.ok());
185 ASSERT_FALSE(result.has_value());
186
187 Result<std::string> result2 = Error() << result.error();
188
189 ASSERT_FALSE(result2.ok());
190 ASSERT_FALSE(result2.has_value());
191
192 EXPECT_EQ(test_errno, result2.error().code());
193 EXPECT_EQ(error_text + ": " + strerror(test_errno), result2.error().message());
194 }
195
196 enum class CustomError { A, B };
197
198 struct CustomErrorWrapper {
CustomErrorWrapperandroid::base::CustomErrorWrapper199 CustomErrorWrapper() : val_(CustomError::A) {}
CustomErrorWrapperandroid::base::CustomErrorWrapper200 CustomErrorWrapper(const CustomError& e) : val_(e) {}
valueandroid::base::CustomErrorWrapper201 CustomError value() const { return val_; }
operator CustomErrorandroid::base::CustomErrorWrapper202 operator CustomError() const { return value(); }
printandroid::base::CustomErrorWrapper203 std::string print() const {
204 switch (val_) {
205 case CustomError::A:
206 return "A";
207 case CustomError::B:
208 return "B";
209 }
210 }
211 CustomError val_;
212 };
213
214 #define NewCustomError(e) Error<CustomErrorWrapper>(CustomError::e)
215
TEST(result,result_with_custom_errorcode)216 TEST(result, result_with_custom_errorcode) {
217 Result<void, CustomError> ok = {};
218 EXPECT_RESULT_OK(ok);
219 ok.value(); // should not crash
220 EXPECT_DEATH(ok.error(), "");
221
222 auto error_text = "test error"s;
223 Result<void, CustomError> err = NewCustomError(A) << error_text;
224
225 EXPECT_FALSE(err.ok());
226 EXPECT_FALSE(err.has_value());
227
228 EXPECT_EQ(CustomError::A, err.error().code());
229 EXPECT_EQ(error_text + ": A", err.error().message());
230 }
231
success_or_fail(bool success)232 Result<std::string, CustomError> success_or_fail(bool success) {
233 if (success)
234 return "success";
235 else
236 return NewCustomError(A) << "fail";
237 }
238
TEST(result,constructor_forwarding)239 TEST(result, constructor_forwarding) {
240 auto result = Result<std::string>(std::in_place, 5, 'a');
241
242 ASSERT_RESULT_OK(result);
243 ASSERT_TRUE(result.has_value());
244
245 EXPECT_EQ("aaaaa", *result);
246 }
247
TEST(result,unwrap_or_return)248 TEST(result, unwrap_or_return) {
249 auto f = [](bool success) -> Result<size_t, CustomError> {
250 return OR_RETURN(success_or_fail(success)).size();
251 };
252
253 auto r = f(true);
254 EXPECT_TRUE(r.ok());
255 EXPECT_EQ(strlen("success"), *r);
256
257 auto s = f(false);
258 EXPECT_FALSE(s.ok());
259 EXPECT_EQ(CustomError::A, s.error().code());
260 EXPECT_EQ("fail: A", s.error().message());
261 }
262
TEST(result,unwrap_or_return_errorcode)263 TEST(result, unwrap_or_return_errorcode) {
264 auto f = [](bool success) -> CustomError {
265 // Note that we use the same OR_RETURN macro for different return types: Result<U, CustomError>
266 // and CustomError.
267 std::string val = OR_RETURN(success_or_fail(success));
268 EXPECT_EQ("success", val);
269 return CustomError::B;
270 };
271
272 auto r = f(true);
273 EXPECT_EQ(CustomError::B, r);
274
275 auto s = f(false);
276 EXPECT_EQ(CustomError::A, s);
277 }
278
TEST(result,unwrap_or_fatal)279 TEST(result, unwrap_or_fatal) {
280 auto r = OR_FATAL(success_or_fail(true));
281 EXPECT_EQ("success", r);
282
283 EXPECT_DEATH(OR_FATAL(success_or_fail(false)), "fail: A");
284 }
285
TEST(result,unwrap_ambiguous_int)286 TEST(result, unwrap_ambiguous_int) {
287 const std::string firstSuccess{"a"};
288 constexpr int secondSuccess = 5;
289 auto enum_success_or_fail = [&](bool success) -> Result<std::string, StatusT> {
290 if (success) return firstSuccess;
291 return ResultError<StatusT>("Fail", 10);
292 };
293 auto f = [&](bool success) -> Result<int, StatusT> {
294 auto val = OR_RETURN(enum_success_or_fail(success));
295 EXPECT_EQ(firstSuccess, val);
296 return secondSuccess;
297 };
298
299 auto r = f(true);
300 ASSERT_TRUE(r.ok());
301 EXPECT_EQ(r.value(), secondSuccess);
302 auto s = f(false);
303 ASSERT_TRUE(!s.ok());
304 EXPECT_EQ(s.error().code(), 10);
305 }
306
TEST(result,unwrap_ambiguous_uint_conv)307 TEST(result, unwrap_ambiguous_uint_conv) {
308 const std::string firstSuccess{"a"};
309 constexpr size_t secondSuccess = 5ull;
310 auto enum_success_or_fail = [&](bool success) -> Result<std::string, StatusT> {
311 if (success) return firstSuccess;
312 return ResultError<StatusT>("Fail", 10);
313 };
314
315 auto f = [&](bool success) -> Result<size_t, StatusT> {
316 auto val = OR_RETURN(enum_success_or_fail(success));
317 EXPECT_EQ(firstSuccess, val);
318 return secondSuccess;
319 };
320
321 auto r = f(true);
322 ASSERT_TRUE(r.ok());
323 EXPECT_EQ(r.value(), secondSuccess);
324 auto s = f(false);
325 ASSERT_TRUE(!s.ok());
326 EXPECT_EQ(s.error().code(), 10);
327 }
328
329 struct IntConst {
330 int val_;
331 template <typename T, typename = std::enable_if_t<std::is_convertible_v<T, int>>>
IntConstandroid::base::IntConst332 IntConst(T&& val) : val_(val) {}
operator status_tandroid::base::IntConst333 operator status_t() {return val_;}
334 };
335
TEST(result,unwrap_ambiguous_constructible)336 TEST(result, unwrap_ambiguous_constructible) {
337 constexpr int firstSuccess = 5;
338 constexpr int secondSuccess = 7;
339 struct A {
340 A (int val) : val_(val) {}
341 operator status_t() { return 0; }
342 int val_;
343 };
344 // If this returns Result<A, ...> instead of Result<IntConst, ...>,
345 // compilation fails unless we compile with c++20
346 auto enum_success_or_fail = [&](bool success) -> Result<IntConst, StatusT, false> {
347 if (success) return firstSuccess;
348 return ResultError<StatusT, false>(10);
349 };
350 auto f = [&](bool success) -> Result<IntConst, StatusT, false> {
351 auto val = OR_RETURN(enum_success_or_fail(success));
352 EXPECT_EQ(firstSuccess, val.val_);
353 return secondSuccess;
354 };
355 auto r = f(true);
356 EXPECT_EQ(r.value().val_, secondSuccess);
357 auto s = f(false);
358 EXPECT_EQ(s.error().code(), 10);
359 }
360
361 struct Dangerous {};
362 struct ImplicitFromDangerous {
363 ImplicitFromDangerous(Dangerous);
364 };
365 template <typename U>
366 struct Templated {
367 U val_;
368 template <typename T, typename=std::enable_if_t<std::is_convertible_v<T, U>>>
Templatedandroid::base::Templated369 Templated(T val) : val_(val) {}
370 };
371
372
TEST(result,dangerous_result_conversion)373 TEST(result, dangerous_result_conversion) {
374 ResultError<Dangerous, false> error {Dangerous{}};
375 Result<Templated<Dangerous>, Dangerous, false> surprise {error};
376 EXPECT_TRUE(!surprise.ok());
377 Result<Templated<ImplicitFromDangerous>, Dangerous, false> surprise2 {error};
378 EXPECT_TRUE(!surprise2.ok());
379 }
380
TEST(result,generic_convertible)381 TEST(result, generic_convertible) {
382 const std::string firstSuccess{"a"};
383 struct A {};
384 struct B {
385 operator A() {return A{};}
386 };
387
388 auto enum_success_or_fail = [&](bool success) -> Result<std::string, B> {
389 if (success) return firstSuccess;
390 return ResultError<B>("Fail", B{});
391 };
392 auto f = [&](bool success) -> Result<A, B> {
393 auto val = OR_RETURN(enum_success_or_fail(success));
394 EXPECT_EQ(firstSuccess, val);
395 return A{};
396 };
397
398 auto r = f(true);
399 EXPECT_TRUE(r.ok());
400 auto s = f(false);
401 EXPECT_TRUE(!s.ok());
402 }
403
TEST(result,generic_exact)404 TEST(result, generic_exact) {
405 const std::string firstSuccess{"a"};
406 struct A {};
407 auto enum_success_or_fail = [&](bool success) -> Result<std::string, A> {
408 if (success) return firstSuccess;
409 return ResultError<A>("Fail", A{});
410 };
411 auto f = [&](bool success) -> Result<A, A> {
412 auto val = OR_RETURN(enum_success_or_fail(success));
413 EXPECT_EQ(firstSuccess, val);
414 return A{};
415 };
416
417 auto r = f(true);
418 EXPECT_TRUE(r.ok());
419 auto s = f(false);
420 EXPECT_TRUE(!s.ok());
421 }
422
423 struct MyData {
424 const int data;
425 static int copy_constructed;
426 static int move_constructed;
MyDataandroid::base::MyData427 explicit MyData(int d) : data(d) {}
MyDataandroid::base::MyData428 MyData(const MyData& other) : data(other.data) { copy_constructed++; }
MyDataandroid::base::MyData429 MyData(MyData&& other) : data(other.data) { move_constructed++; }
430 MyData& operator=(const MyData&) = delete;
431 MyData& operator=(MyData&&) = delete;
432 };
433
434 int MyData::copy_constructed = 0;
435 int MyData::move_constructed = 0;
436
TEST(result,unwrap_does_not_incur_additional_copying)437 TEST(result, unwrap_does_not_incur_additional_copying) {
438 MyData::copy_constructed = 0;
439 MyData::move_constructed = 0;
440 auto f = []() -> Result<MyData> { return MyData{10}; };
441
442 [&]() -> Result<void> {
443 int data = OR_RETURN(f()).data;
444 EXPECT_EQ(10, data);
445 EXPECT_EQ(0, MyData::copy_constructed);
446 // Moved once when MyData{10} is returned as Result<MyData> in the lambda f.
447 // Moved once again when the variable d is constructed from OR_RETURN.
448 EXPECT_EQ(2, MyData::move_constructed);
449 return {};
450 }();
451 }
452
TEST(result,supports_move_only_type)453 TEST(result, supports_move_only_type) {
454 auto f = [](bool success) -> Result<std::unique_ptr<std::string>> {
455 if (success) return std::make_unique<std::string>("hello");
456 return Error() << "error";
457 };
458
459 auto g = [&](bool success) -> Result<std::unique_ptr<std::string>> {
460 auto r = OR_RETURN(f(success));
461 EXPECT_EQ("hello", *(r.get()));
462 return std::make_unique<std::string>("world");
463 };
464
465 auto s = g(true);
466 EXPECT_RESULT_OK(s);
467 EXPECT_EQ("world", *(s->get()));
468
469 auto t = g(false);
470 EXPECT_FALSE(t.ok());
471 EXPECT_EQ("error", t.error().message());
472 }
473
TEST(result,unique_ptr)474 TEST(result, unique_ptr) {
475 using testing::Ok;
476
477 auto return_unique_ptr = [](bool success) -> Result<std::unique_ptr<int>> {
478 auto result = OR_RETURN(Result<std::unique_ptr<int>>(std::make_unique<int>(3)));
479 if (!success) {
480 return Error() << __func__ << " failed.";
481 }
482 return result;
483 };
484 Result<std::unique_ptr<int>> result1 = return_unique_ptr(false);
485 ASSERT_THAT(result1, Not(Ok()));
486 Result<std::unique_ptr<int>> result2 = return_unique_ptr(true);
487 ASSERT_THAT(result2, Ok());
488 EXPECT_EQ(**result2, 3);
489 }
490
491 struct ConstructorTracker {
492 static size_t constructor_called;
493 static size_t copy_constructor_called;
494 static size_t move_constructor_called;
495 static size_t copy_assignment_called;
496 static size_t move_assignment_called;
497
498 template <typename T>
ConstructorTrackerandroid::base::ConstructorTracker499 ConstructorTracker(T&& string) : string(string) {
500 ++constructor_called;
501 }
502
ConstructorTrackerandroid::base::ConstructorTracker503 ConstructorTracker(const ConstructorTracker& ct) {
504 ++copy_constructor_called;
505 string = ct.string;
506 }
ConstructorTrackerandroid::base::ConstructorTracker507 ConstructorTracker(ConstructorTracker&& ct) noexcept {
508 ++move_constructor_called;
509 string = std::move(ct.string);
510 }
operator =android::base::ConstructorTracker511 ConstructorTracker& operator=(const ConstructorTracker& ct) {
512 ++copy_assignment_called;
513 string = ct.string;
514 return *this;
515 }
operator =android::base::ConstructorTracker516 ConstructorTracker& operator=(ConstructorTracker&& ct) noexcept {
517 ++move_assignment_called;
518 string = std::move(ct.string);
519 return *this;
520 }
521
522 std::string string;
523 };
524
525 size_t ConstructorTracker::constructor_called = 0;
526 size_t ConstructorTracker::copy_constructor_called = 0;
527 size_t ConstructorTracker::move_constructor_called = 0;
528 size_t ConstructorTracker::copy_assignment_called = 0;
529 size_t ConstructorTracker::move_assignment_called = 0;
530
ReturnConstructorTracker(const std::string & in)531 Result<ConstructorTracker> ReturnConstructorTracker(const std::string& in) {
532 if (in.empty()) {
533 return "literal string";
534 }
535 if (in == "test2") {
536 return ConstructorTracker(in + in + "2");
537 }
538 ConstructorTracker result(in + " " + in);
539 return result;
540 };
541
TEST(result,no_copy_on_return)542 TEST(result, no_copy_on_return) {
543 // If returning parameters that may be used to implicitly construct the type T of Result<T>,
544 // then those parameters are forwarded to the construction of Result<T>.
545
546 // If returning an prvalue or xvalue, it will be move constructed during the construction of
547 // Result<T>.
548
549 // This check ensures that that is the case, and particularly that no copy constructors
550 // are called.
551
552 auto result1 = ReturnConstructorTracker("");
553 ASSERT_RESULT_OK(result1);
554 EXPECT_EQ("literal string", result1->string);
555 EXPECT_EQ(1U, ConstructorTracker::constructor_called);
556 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
557 EXPECT_EQ(0U, ConstructorTracker::move_constructor_called);
558 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
559 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
560
561 auto result2 = ReturnConstructorTracker("test2");
562 ASSERT_RESULT_OK(result2);
563 EXPECT_EQ("test2test22", result2->string);
564 EXPECT_EQ(2U, ConstructorTracker::constructor_called);
565 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
566 EXPECT_EQ(1U, ConstructorTracker::move_constructor_called);
567 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
568 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
569
570 auto result3 = ReturnConstructorTracker("test3");
571 ASSERT_RESULT_OK(result3);
572 EXPECT_EQ("test3 test3", result3->string);
573 EXPECT_EQ(3U, ConstructorTracker::constructor_called);
574 EXPECT_EQ(0U, ConstructorTracker::copy_constructor_called);
575 EXPECT_EQ(2U, ConstructorTracker::move_constructor_called);
576 EXPECT_EQ(0U, ConstructorTracker::copy_assignment_called);
577 EXPECT_EQ(0U, ConstructorTracker::move_assignment_called);
578 }
579
580 // Below two tests require that we do not hide the move constructor with our forwarding reference
581 // constructor. This is done with by disabling the forwarding reference constructor if its first
582 // and only type is Result<T>.
TEST(result,result_result_with_success)583 TEST(result, result_result_with_success) {
584 auto return_result_result_with_success = []() -> Result<Result<void>> { return Result<void>(); };
585 auto result = return_result_result_with_success();
586 ASSERT_RESULT_OK(result);
587 ASSERT_RESULT_OK(*result);
588
589 auto inner_result = result.value();
590 ASSERT_RESULT_OK(inner_result);
591 }
592
TEST(result,result_result_with_failure)593 TEST(result, result_result_with_failure) {
594 auto return_result_result_with_error = []() -> Result<Result<void>> {
595 return Result<void>(ResultError("failure string", 6));
596 };
597 auto result = return_result_result_with_error();
598 ASSERT_RESULT_OK(result);
599 ASSERT_FALSE(result->ok());
600 EXPECT_EQ("failure string", (*result).error().message());
601 EXPECT_EQ(6, (*result).error().code());
602 }
603
604 // This test requires that we disable the forwarding reference constructor if Result<T> is the
605 // *only* type that we are forwarding. In otherwords, if we are forwarding Result<T>, int to
606 // construct a Result<T>, then we still need the constructor.
TEST(result,result_two_parameter_constructor_same_type)607 TEST(result, result_two_parameter_constructor_same_type) {
608 struct TestStruct {
609 TestStruct(int value) : value_(value) {}
610 TestStruct(Result<TestStruct> result, int value) : value_(result->value_ * value) {}
611 int value_;
612 };
613
614 auto return_test_struct = []() -> Result<TestStruct> {
615 return Result<TestStruct>(std::in_place, Result<TestStruct>(std::in_place, 6), 6);
616 };
617
618 auto result = return_test_struct();
619 ASSERT_RESULT_OK(result);
620 EXPECT_EQ(36, result->value_);
621 }
622
TEST(result,die_on_access_failed_result)623 TEST(result, die_on_access_failed_result) {
624 Result<std::string> result = Error();
625 ASSERT_DEATH(*result, "");
626 }
627
TEST(result,die_on_get_error_succesful_result)628 TEST(result, die_on_get_error_succesful_result) {
629 Result<std::string> result = "success";
630 ASSERT_DEATH(result.error(), "");
631 }
632
633 template <class CharT>
SetErrnoToTwo(std::basic_ostream<CharT> & ss)634 std::basic_ostream<CharT>& SetErrnoToTwo(std::basic_ostream<CharT>& ss) {
635 errno = 2;
636 return ss;
637 }
638
TEST(result,preserve_errno)639 TEST(result, preserve_errno) {
640 errno = 1;
641 int old_errno = errno;
642 Result<int> result = Error() << "Failed" << SetErrnoToTwo<char>;
643 ASSERT_FALSE(result.ok());
644 EXPECT_EQ(old_errno, errno);
645
646 errno = 1;
647 old_errno = errno;
648 Result<int> result2 = ErrnoError() << "Failed" << SetErrnoToTwo<char>;
649 ASSERT_FALSE(result2.ok());
650 EXPECT_EQ(old_errno, errno);
651 EXPECT_EQ(old_errno, result2.error().code());
652 }
653
TEST(result,error_with_fmt)654 TEST(result, error_with_fmt) {
655 Result<int> result = Errorf("{} {}!", "hello", "world");
656 EXPECT_EQ("hello world!", result.error().message());
657
658 result = Errorf("{} {}!", std::string("hello"), std::string("world"));
659 EXPECT_EQ("hello world!", result.error().message());
660
661 result = Errorf("{1} {0}!", "world", "hello");
662 EXPECT_EQ("hello world!", result.error().message());
663
664 result = Errorf("hello world!");
665 EXPECT_EQ("hello world!", result.error().message());
666
667 Result<int> result2 = Errorf("error occurred with {}", result.error());
668 EXPECT_EQ("error occurred with hello world!", result2.error().message());
669
670 constexpr int test_errno = 6;
671 errno = test_errno;
672 result = ErrnoErrorf("{} {}!", "hello", "world");
673 EXPECT_EQ(test_errno, result.error().code());
674 EXPECT_EQ("hello world!: "s + strerror(test_errno), result.error().message());
675 }
676
TEST(result,error_with_fmt_carries_errno)677 TEST(result, error_with_fmt_carries_errno) {
678 constexpr int inner_errno = 6;
679 errno = inner_errno;
680 Result<int> inner_result = ErrnoErrorf("inner failure");
681 errno = 0;
682 EXPECT_EQ(inner_errno, inner_result.error().code());
683
684 // outer_result is created with Errorf, but its error code is got from inner_result.
685 Result<int> outer_result = Errorf("outer failure caused by {}", inner_result.error());
686 EXPECT_EQ(inner_errno, outer_result.error().code());
687 EXPECT_EQ("outer failure caused by inner failure: "s + strerror(inner_errno),
688 outer_result.error().message());
689
690 // now both result objects are created with ErrnoErrorf. errno from the inner_result
691 // is not passed to outer_result.
692 constexpr int outer_errno = 10;
693 errno = outer_errno;
694 outer_result = ErrnoErrorf("outer failure caused by {}", inner_result.error());
695 EXPECT_EQ(outer_errno, outer_result.error().code());
696 EXPECT_EQ("outer failure caused by inner failure: "s + strerror(inner_errno) + ": "s +
697 strerror(outer_errno),
698 outer_result.error().message());
699 }
700
TEST(result,errno_chaining_multiple)701 TEST(result, errno_chaining_multiple) {
702 constexpr int errno1 = 6;
703 errno = errno1;
704 Result<int> inner1 = ErrnoErrorf("error1");
705
706 constexpr int errno2 = 10;
707 errno = errno2;
708 Result<int> inner2 = ErrnoErrorf("error2");
709
710 // takes the error code of inner2 since its the last one.
711 Result<int> outer = Errorf("two errors: {}, {}", inner1.error(), inner2.error());
712 EXPECT_EQ(errno2, outer.error().code());
713 EXPECT_EQ("two errors: error1: "s + strerror(errno1) + ", error2: "s + strerror(errno2),
714 outer.error().message());
715 }
716
TEST(result,error_without_message)717 TEST(result, error_without_message) {
718 constexpr bool include_message = false;
719 Result<void, Errno, include_message> res = Error<Errno, include_message>(10);
720 EXPECT_FALSE(res.ok());
721 EXPECT_EQ(10, res.error().code());
722 EXPECT_EQ(sizeof(int), sizeof(res.error()));
723 }
724
725 namespace testing {
726
727 class Listener : public ::testing::MatchResultListener {
728 public:
Listener()729 Listener() : MatchResultListener(&ss_) {}
730 ~Listener() = default;
message() const731 std::string message() const { return ss_.str(); }
732
733 private:
734 std::stringstream ss_;
735 };
736
737 class ResultMatchers : public ::testing::Test {
738 public:
739 Result<int> result = 1;
740 Result<int> error = Error(EBADF) << "error message";
741 Listener listener;
742 };
743
TEST_F(ResultMatchers,ok_result)744 TEST_F(ResultMatchers, ok_result) {
745 EXPECT_TRUE(ExplainMatchResult(Ok(), result, &listener));
746 EXPECT_THAT(listener.message(), Eq("result is OK"));
747 }
748
TEST_F(ResultMatchers,ok_error)749 TEST_F(ResultMatchers, ok_error) {
750 EXPECT_FALSE(ExplainMatchResult(Ok(), error, &listener));
751 EXPECT_THAT(listener.message(), StartsWith("error is"));
752 EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
753 EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
754 }
755
TEST_F(ResultMatchers,not_ok_result)756 TEST_F(ResultMatchers, not_ok_result) {
757 EXPECT_FALSE(ExplainMatchResult(Not(Ok()), result, &listener));
758 EXPECT_THAT(listener.message(), Eq("result is OK"));
759 }
760
TEST_F(ResultMatchers,not_ok_error)761 TEST_F(ResultMatchers, not_ok_error) {
762 EXPECT_TRUE(ExplainMatchResult(Not(Ok()), error, &listener));
763 EXPECT_THAT(listener.message(), StartsWith("error is"));
764 EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
765 EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
766 }
767
TEST_F(ResultMatchers,has_value_result)768 TEST_F(ResultMatchers, has_value_result) {
769 EXPECT_TRUE(ExplainMatchResult(HasValue(*result), result, &listener));
770 }
771
TEST_F(ResultMatchers,has_value_wrong_result)772 TEST_F(ResultMatchers, has_value_wrong_result) {
773 EXPECT_FALSE(ExplainMatchResult(HasValue(*result + 1), result, &listener));
774 }
775
TEST_F(ResultMatchers,has_value_error)776 TEST_F(ResultMatchers, has_value_error) {
777 EXPECT_FALSE(ExplainMatchResult(HasValue(*result), error, &listener));
778 EXPECT_THAT(listener.message(), StartsWith("error is"));
779 EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
780 EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
781 }
782
TEST_F(ResultMatchers,has_error_code_result)783 TEST_F(ResultMatchers, has_error_code_result) {
784 EXPECT_FALSE(ExplainMatchResult(HasError(WithCode(error.error().code())), result, &listener));
785 EXPECT_THAT(listener.message(), Eq("result is OK"));
786 }
787
TEST_F(ResultMatchers,has_error_code_wrong_code)788 TEST_F(ResultMatchers, has_error_code_wrong_code) {
789 EXPECT_FALSE(ExplainMatchResult(HasError(WithCode(error.error().code() + 1)), error, &listener));
790 EXPECT_THAT(listener.message(), StartsWith("actual error is"));
791 EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
792 }
793
TEST_F(ResultMatchers,has_error_code_correct_code)794 TEST_F(ResultMatchers, has_error_code_correct_code) {
795 EXPECT_TRUE(ExplainMatchResult(HasError(WithCode(error.error().code())), error, &listener));
796 EXPECT_THAT(listener.message(), StartsWith("actual error is"));
797 EXPECT_THAT(listener.message(), HasSubstr(strerror(error.error().code())));
798 }
799
TEST_F(ResultMatchers,has_error_message_result)800 TEST_F(ResultMatchers, has_error_message_result) {
801 EXPECT_FALSE(
802 ExplainMatchResult(HasError(WithMessage(error.error().message())), result, &listener));
803 EXPECT_THAT(listener.message(), Eq("result is OK"));
804 }
805
TEST_F(ResultMatchers,has_error_message_wrong_message)806 TEST_F(ResultMatchers, has_error_message_wrong_message) {
807 EXPECT_FALSE(ExplainMatchResult(HasError(WithMessage("foo")), error, &listener));
808 EXPECT_THAT(listener.message(), StartsWith("actual error is"));
809 EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
810 }
811
TEST_F(ResultMatchers,has_error_message_correct_message)812 TEST_F(ResultMatchers, has_error_message_correct_message) {
813 EXPECT_TRUE(ExplainMatchResult(HasError(WithMessage(error.error().message())), error, &listener));
814 EXPECT_THAT(listener.message(), StartsWith("actual error is"));
815 EXPECT_THAT(listener.message(), HasSubstr(error.error().message()));
816 }
817
818 } // namespace testing
819 } // namespace base
820 } // namespace android
821