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