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