2021-12-14 13:55:34 +00:00
|
|
|
/*
|
|
|
|
* Copyright (C) 2021 The Android Open Source Project
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include "utils/ErrorsMacros.h"
|
|
|
|
|
|
|
|
#include <android-base/result.h>
|
|
|
|
|
|
|
|
#include <gtest/gtest.h>
|
|
|
|
|
|
|
|
using namespace android;
|
|
|
|
|
|
|
|
using android::base::Error;
|
|
|
|
using android::base::Result;
|
|
|
|
|
|
|
|
status_t success_or_fail(bool success) {
|
|
|
|
if (success)
|
|
|
|
return OK;
|
|
|
|
else
|
|
|
|
return PERMISSION_DENIED;
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(errors, unwrap_or_return) {
|
|
|
|
auto f = [](bool success, int* val) -> status_t {
|
|
|
|
OR_RETURN(success_or_fail(success));
|
|
|
|
*val = 10;
|
|
|
|
return OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
int val;
|
|
|
|
status_t s = f(true, &val);
|
|
|
|
EXPECT_EQ(OK, s);
|
|
|
|
EXPECT_EQ(10, val);
|
|
|
|
|
|
|
|
val = 0; // reset
|
|
|
|
status_t q = f(false, &val);
|
|
|
|
EXPECT_EQ(PERMISSION_DENIED, q);
|
|
|
|
EXPECT_EQ(0, val);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(errors, unwrap_or_return_result) {
|
|
|
|
auto f = [](bool success) -> Result<std::string, StatusT> {
|
|
|
|
OR_RETURN(success_or_fail(success));
|
|
|
|
return "hello";
|
|
|
|
};
|
|
|
|
|
|
|
|
auto r = f(true);
|
|
|
|
EXPECT_TRUE(r.ok());
|
|
|
|
EXPECT_EQ("hello", *r);
|
|
|
|
|
|
|
|
auto s = f(false);
|
|
|
|
EXPECT_FALSE(s.ok());
|
|
|
|
EXPECT_EQ(PERMISSION_DENIED, s.error().code());
|
|
|
|
EXPECT_EQ("PERMISSION_DENIED", s.error().message());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(errors, unwrap_or_return_result_int) {
|
|
|
|
auto f = [](bool success) -> Result<int, StatusT> {
|
|
|
|
OR_RETURN(success_or_fail(success));
|
|
|
|
return 10;
|
|
|
|
};
|
|
|
|
|
|
|
|
auto r = f(true);
|
|
|
|
EXPECT_TRUE(r.ok());
|
|
|
|
EXPECT_EQ(10, *r);
|
|
|
|
|
|
|
|
auto s = f(false);
|
|
|
|
EXPECT_FALSE(s.ok());
|
|
|
|
EXPECT_EQ(PERMISSION_DENIED, s.error().code());
|
|
|
|
EXPECT_EQ("PERMISSION_DENIED", s.error().message());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(errors, unwrap_or_fatal) {
|
|
|
|
OR_FATAL(success_or_fail(true));
|
|
|
|
|
|
|
|
EXPECT_DEATH(OR_FATAL(success_or_fail(false)), "PERMISSION_DENIED");
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(errors, result_in_status) {
|
|
|
|
auto f = [](bool success) -> Result<std::string, StatusT> {
|
|
|
|
if (success)
|
|
|
|
return "OK";
|
|
|
|
else
|
|
|
|
return Error<StatusT>(PERMISSION_DENIED) << "custom error message";
|
|
|
|
};
|
|
|
|
|
|
|
|
auto g = [&](bool success) -> status_t {
|
|
|
|
std::string val = OR_RETURN(f(success));
|
|
|
|
EXPECT_EQ("OK", val);
|
|
|
|
return OK;
|
|
|
|
};
|
|
|
|
|
|
|
|
status_t a = g(true);
|
|
|
|
EXPECT_EQ(OK, a);
|
|
|
|
|
|
|
|
status_t b = g(false);
|
|
|
|
EXPECT_EQ(PERMISSION_DENIED, b);
|
|
|
|
}
|
2022-02-11 22:26:28 +00:00
|
|
|
|
|
|
|
TEST(errors, conversion_promotion) {
|
|
|
|
constexpr size_t successVal = 10ull;
|
|
|
|
auto f = [&](bool success) -> Result<size_t, StatusT> {
|
|
|
|
OR_RETURN(success_or_fail(success));
|
|
|
|
return successVal;
|
|
|
|
};
|
|
|
|
auto s = f(true);
|
|
|
|
ASSERT_TRUE(s.ok());
|
|
|
|
EXPECT_EQ(s.value(), successVal);
|
|
|
|
auto r = f(false);
|
|
|
|
EXPECT_TRUE(!r.ok());
|
|
|
|
EXPECT_EQ(PERMISSION_DENIED, r.error().code());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(errors, conversion_promotion_bool) {
|
|
|
|
constexpr size_t successVal = true;
|
|
|
|
auto f = [&](bool success) -> Result<bool, StatusT> {
|
|
|
|
OR_RETURN(success_or_fail(success));
|
|
|
|
return successVal;
|
|
|
|
};
|
|
|
|
auto s = f(true);
|
|
|
|
ASSERT_TRUE(s.ok());
|
|
|
|
EXPECT_EQ(s.value(), successVal);
|
|
|
|
auto r = f(false);
|
|
|
|
EXPECT_TRUE(!r.ok());
|
|
|
|
EXPECT_EQ(PERMISSION_DENIED, r.error().code());
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(errors, conversion_promotion_char) {
|
|
|
|
constexpr char successVal = 'a';
|
|
|
|
auto f = [&](bool success) -> Result<unsigned char, StatusT> {
|
|
|
|
OR_RETURN(success_or_fail(success));
|
|
|
|
return successVal;
|
|
|
|
};
|
|
|
|
auto s = f(true);
|
|
|
|
ASSERT_TRUE(s.ok());
|
|
|
|
EXPECT_EQ(s.value(), successVal);
|
|
|
|
auto r = f(false);
|
|
|
|
EXPECT_TRUE(!r.ok());
|
|
|
|
EXPECT_EQ(PERMISSION_DENIED, r.error().code());
|
|
|
|
}
|
|
|
|
|
|
|
|
struct IntContainer {
|
|
|
|
// Implicit conversion from int is desired
|
|
|
|
IntContainer(int val) : val_(val) {}
|
|
|
|
int val_;
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST(errors, conversion_construct) {
|
|
|
|
constexpr int successVal = 10;
|
|
|
|
auto f = [&](bool success) -> Result<IntContainer, StatusT> {
|
|
|
|
OR_RETURN(success_or_fail(success));
|
|
|
|
return successVal;
|
|
|
|
};
|
|
|
|
auto s = f(true);
|
|
|
|
ASSERT_TRUE(s.ok());
|
|
|
|
EXPECT_EQ(s.value().val_, successVal);
|
|
|
|
auto r = f(false);
|
|
|
|
EXPECT_TRUE(!r.ok());
|
|
|
|
EXPECT_EQ(PERMISSION_DENIED, r.error().code());
|
|
|
|
}
|