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