1 /* 2 * Copyright (C) 2021 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 "utils/ErrorsMacros.h" 18 19 #include <android-base/result.h> 20 21 #include <gtest/gtest.h> 22 23 using namespace android; 24 25 using android::base::Error; 26 using android::base::Result; 27 success_or_fail(bool success)28 status_t success_or_fail(bool success) { 29 if (success) 30 return OK; 31 else 32 return PERMISSION_DENIED; 33 } 34 TEST(errors,unwrap_or_return)35 TEST(errors, unwrap_or_return) { 36 auto f = [](bool success, int* val) -> status_t { 37 OR_RETURN(success_or_fail(success)); 38 *val = 10; 39 return OK; 40 }; 41 42 int val; 43 status_t s = f(true, &val); 44 EXPECT_EQ(OK, s); 45 EXPECT_EQ(10, val); 46 47 val = 0; // reset 48 status_t q = f(false, &val); 49 EXPECT_EQ(PERMISSION_DENIED, q); 50 EXPECT_EQ(0, val); 51 } 52 TEST(errors,unwrap_or_return_result)53 TEST(errors, unwrap_or_return_result) { 54 auto f = [](bool success) -> Result<std::string, StatusT> { 55 OR_RETURN(success_or_fail(success)); 56 return "hello"; 57 }; 58 59 auto r = f(true); 60 EXPECT_TRUE(r.ok()); 61 EXPECT_EQ("hello", *r); 62 63 auto s = f(false); 64 EXPECT_FALSE(s.ok()); 65 EXPECT_EQ(PERMISSION_DENIED, s.error().code()); 66 EXPECT_EQ("PERMISSION_DENIED", s.error().message()); 67 } 68 TEST(errors,unwrap_or_return_result_int)69 TEST(errors, unwrap_or_return_result_int) { 70 auto f = [](bool success) -> Result<int, StatusT> { 71 OR_RETURN(success_or_fail(success)); 72 return 10; 73 }; 74 75 auto r = f(true); 76 EXPECT_TRUE(r.ok()); 77 EXPECT_EQ(10, *r); 78 79 auto s = f(false); 80 EXPECT_FALSE(s.ok()); 81 EXPECT_EQ(PERMISSION_DENIED, s.error().code()); 82 EXPECT_EQ("PERMISSION_DENIED", s.error().message()); 83 } 84 TEST(errors,unwrap_or_fatal)85 TEST(errors, unwrap_or_fatal) { 86 OR_FATAL(success_or_fail(true)); 87 88 EXPECT_DEATH(OR_FATAL(success_or_fail(false)), "PERMISSION_DENIED"); 89 } 90 TEST(errors,result_in_status)91 TEST(errors, result_in_status) { 92 auto f = [](bool success) -> Result<std::string, StatusT> { 93 if (success) 94 return "OK"; 95 else 96 return Error<StatusT>(PERMISSION_DENIED) << "custom error message"; 97 }; 98 99 auto g = [&](bool success) -> status_t { 100 std::string val = OR_RETURN(f(success)); 101 EXPECT_EQ("OK", val); 102 return OK; 103 }; 104 105 status_t a = g(true); 106 EXPECT_EQ(OK, a); 107 108 status_t b = g(false); 109 EXPECT_EQ(PERMISSION_DENIED, b); 110 } 111 TEST(errors,conversion_promotion)112 TEST(errors, conversion_promotion) { 113 constexpr size_t successVal = 10ull; 114 auto f = [&](bool success) -> Result<size_t, StatusT> { 115 OR_RETURN(success_or_fail(success)); 116 return successVal; 117 }; 118 auto s = f(true); 119 ASSERT_TRUE(s.ok()); 120 EXPECT_EQ(s.value(), successVal); 121 auto r = f(false); 122 EXPECT_TRUE(!r.ok()); 123 EXPECT_EQ(PERMISSION_DENIED, r.error().code()); 124 } 125 TEST(errors,conversion_promotion_bool)126 TEST(errors, conversion_promotion_bool) { 127 constexpr size_t successVal = true; 128 auto f = [&](bool success) -> Result<bool, StatusT> { 129 OR_RETURN(success_or_fail(success)); 130 return successVal; 131 }; 132 auto s = f(true); 133 ASSERT_TRUE(s.ok()); 134 EXPECT_EQ(s.value(), successVal); 135 auto r = f(false); 136 EXPECT_TRUE(!r.ok()); 137 EXPECT_EQ(PERMISSION_DENIED, r.error().code()); 138 } 139 TEST(errors,conversion_promotion_char)140 TEST(errors, conversion_promotion_char) { 141 constexpr char successVal = 'a'; 142 auto f = [&](bool success) -> Result<unsigned char, StatusT> { 143 OR_RETURN(success_or_fail(success)); 144 return successVal; 145 }; 146 auto s = f(true); 147 ASSERT_TRUE(s.ok()); 148 EXPECT_EQ(s.value(), successVal); 149 auto r = f(false); 150 EXPECT_TRUE(!r.ok()); 151 EXPECT_EQ(PERMISSION_DENIED, r.error().code()); 152 } 153 154 struct IntContainer { 155 // Implicit conversion from int is desired IntContainerIntContainer156 IntContainer(int val) : val_(val) {} 157 int val_; 158 }; 159 TEST(errors,conversion_construct)160 TEST(errors, conversion_construct) { 161 constexpr int successVal = 10; 162 auto f = [&](bool success) -> Result<IntContainer, StatusT> { 163 OR_RETURN(success_or_fail(success)); 164 return successVal; 165 }; 166 auto s = f(true); 167 ASSERT_TRUE(s.ok()); 168 EXPECT_EQ(s.value().val_, successVal); 169 auto r = f(false); 170 EXPECT_TRUE(!r.ok()); 171 EXPECT_EQ(PERMISSION_DENIED, r.error().code()); 172 } 173