1*993b0882SAndroid Build Coastguard Worker /*
2*993b0882SAndroid Build Coastguard Worker * Copyright (C) 2018 The Android Open Source Project
3*993b0882SAndroid Build Coastguard Worker *
4*993b0882SAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License");
5*993b0882SAndroid Build Coastguard Worker * you may not use this file except in compliance with the License.
6*993b0882SAndroid Build Coastguard Worker * You may obtain a copy of the License at
7*993b0882SAndroid Build Coastguard Worker *
8*993b0882SAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0
9*993b0882SAndroid Build Coastguard Worker *
10*993b0882SAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software
11*993b0882SAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS,
12*993b0882SAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13*993b0882SAndroid Build Coastguard Worker * See the License for the specific language governing permissions and
14*993b0882SAndroid Build Coastguard Worker * limitations under the License.
15*993b0882SAndroid Build Coastguard Worker */
16*993b0882SAndroid Build Coastguard Worker
17*993b0882SAndroid Build Coastguard Worker #include "utils/base/status.h"
18*993b0882SAndroid Build Coastguard Worker
19*993b0882SAndroid Build Coastguard Worker #include "utils/base/logging.h"
20*993b0882SAndroid Build Coastguard Worker #include "utils/base/status_macros.h"
21*993b0882SAndroid Build Coastguard Worker #include "gtest/gtest.h"
22*993b0882SAndroid Build Coastguard Worker
23*993b0882SAndroid Build Coastguard Worker namespace libtextclassifier3 {
24*993b0882SAndroid Build Coastguard Worker namespace {
25*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,PrintsAbortedStatus)26*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, PrintsAbortedStatus) {
27*993b0882SAndroid Build Coastguard Worker logging::LoggingStringStream stream;
28*993b0882SAndroid Build Coastguard Worker stream << Status::UNKNOWN;
29*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::UNKNOWN.error_code(), 2);
30*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::UNKNOWN.CanonicalCode(), StatusCode::UNKNOWN);
31*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::UNKNOWN.error_message(), "");
32*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(stream.message, "2");
33*993b0882SAndroid Build Coastguard Worker }
34*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,PrintsOKStatus)35*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, PrintsOKStatus) {
36*993b0882SAndroid Build Coastguard Worker logging::LoggingStringStream stream;
37*993b0882SAndroid Build Coastguard Worker stream << Status::OK;
38*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::OK.error_code(), 0);
39*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::OK.CanonicalCode(), StatusCode::OK);
40*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::OK.error_message(), "");
41*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(stream.message, "0");
42*993b0882SAndroid Build Coastguard Worker }
43*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,UnknownStatusHasRightAttributes)44*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, UnknownStatusHasRightAttributes) {
45*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::UNKNOWN.error_code(), 2);
46*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::UNKNOWN.CanonicalCode(), StatusCode::UNKNOWN);
47*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::UNKNOWN.error_message(), "");
48*993b0882SAndroid Build Coastguard Worker }
49*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,OkStatusHasRightAttributes)50*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, OkStatusHasRightAttributes) {
51*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::OK.error_code(), 0);
52*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::OK.CanonicalCode(), StatusCode::OK);
53*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(Status::OK.error_message(), "");
54*993b0882SAndroid Build Coastguard Worker }
55*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,CustomStatusHasRightAttributes)56*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, CustomStatusHasRightAttributes) {
57*993b0882SAndroid Build Coastguard Worker Status status(StatusCode::INVALID_ARGUMENT, "You can't put this here!");
58*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.error_code(), 3);
59*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.CanonicalCode(), StatusCode::INVALID_ARGUMENT);
60*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.error_message(), "You can't put this here!");
61*993b0882SAndroid Build Coastguard Worker }
62*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,AssignmentPreservesMembers)63*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, AssignmentPreservesMembers) {
64*993b0882SAndroid Build Coastguard Worker Status status(StatusCode::INVALID_ARGUMENT, "You can't put this here!");
65*993b0882SAndroid Build Coastguard Worker
66*993b0882SAndroid Build Coastguard Worker Status status2 = status;
67*993b0882SAndroid Build Coastguard Worker
68*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status2.error_code(), 3);
69*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status2.CanonicalCode(), StatusCode::INVALID_ARGUMENT);
70*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status2.error_message(), "You can't put this here!");
71*993b0882SAndroid Build Coastguard Worker }
72*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,ReturnIfErrorOkStatus)73*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, ReturnIfErrorOkStatus) {
74*993b0882SAndroid Build Coastguard Worker bool returned_due_to_error = true;
75*993b0882SAndroid Build Coastguard Worker auto lambda = [&returned_due_to_error](const Status& s) {
76*993b0882SAndroid Build Coastguard Worker TC3_RETURN_IF_ERROR(s);
77*993b0882SAndroid Build Coastguard Worker returned_due_to_error = false;
78*993b0882SAndroid Build Coastguard Worker return Status::OK;
79*993b0882SAndroid Build Coastguard Worker };
80*993b0882SAndroid Build Coastguard Worker
81*993b0882SAndroid Build Coastguard Worker // OK should allow execution to continue and the returned status should also
82*993b0882SAndroid Build Coastguard Worker // be OK.
83*993b0882SAndroid Build Coastguard Worker Status status = lambda(Status());
84*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.error_code(), 0);
85*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.CanonicalCode(), StatusCode::OK);
86*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.error_message(), "");
87*993b0882SAndroid Build Coastguard Worker EXPECT_FALSE(returned_due_to_error);
88*993b0882SAndroid Build Coastguard Worker }
89*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,ReturnIfErrorInvalidArgumentStatus)90*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, ReturnIfErrorInvalidArgumentStatus) {
91*993b0882SAndroid Build Coastguard Worker bool returned_due_to_error = true;
92*993b0882SAndroid Build Coastguard Worker auto lambda = [&returned_due_to_error](const Status& s) {
93*993b0882SAndroid Build Coastguard Worker TC3_RETURN_IF_ERROR(s);
94*993b0882SAndroid Build Coastguard Worker returned_due_to_error = false;
95*993b0882SAndroid Build Coastguard Worker return Status::OK;
96*993b0882SAndroid Build Coastguard Worker };
97*993b0882SAndroid Build Coastguard Worker
98*993b0882SAndroid Build Coastguard Worker // INVALID_ARGUMENT should cause an early return.
99*993b0882SAndroid Build Coastguard Worker Status invalid_arg_status(StatusCode::INVALID_ARGUMENT, "You can't do that!");
100*993b0882SAndroid Build Coastguard Worker Status status = lambda(invalid_arg_status);
101*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.error_code(), 3);
102*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.CanonicalCode(), StatusCode::INVALID_ARGUMENT);
103*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.error_message(), "You can't do that!");
104*993b0882SAndroid Build Coastguard Worker EXPECT_TRUE(returned_due_to_error);
105*993b0882SAndroid Build Coastguard Worker }
106*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,ReturnIfErrorUnknownStatus)107*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, ReturnIfErrorUnknownStatus) {
108*993b0882SAndroid Build Coastguard Worker bool returned_due_to_error = true;
109*993b0882SAndroid Build Coastguard Worker auto lambda = [&returned_due_to_error](const Status& s) {
110*993b0882SAndroid Build Coastguard Worker TC3_RETURN_IF_ERROR(s);
111*993b0882SAndroid Build Coastguard Worker returned_due_to_error = false;
112*993b0882SAndroid Build Coastguard Worker return Status::OK;
113*993b0882SAndroid Build Coastguard Worker };
114*993b0882SAndroid Build Coastguard Worker
115*993b0882SAndroid Build Coastguard Worker // UNKNOWN should cause an early return.
116*993b0882SAndroid Build Coastguard Worker Status unknown_status(StatusCode::UNKNOWN,
117*993b0882SAndroid Build Coastguard Worker "We also know there are known unknowns.");
118*993b0882SAndroid Build Coastguard Worker libtextclassifier3::Status status = lambda(unknown_status);
119*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.error_code(), 2);
120*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.CanonicalCode(), StatusCode::UNKNOWN);
121*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.error_message(), "We also know there are known unknowns.");
122*993b0882SAndroid Build Coastguard Worker EXPECT_TRUE(returned_due_to_error);
123*993b0882SAndroid Build Coastguard Worker }
124*993b0882SAndroid Build Coastguard Worker
TEST(StatusTest,ReturnIfErrorOnlyInvokesExpressionOnce)125*993b0882SAndroid Build Coastguard Worker TEST(StatusTest, ReturnIfErrorOnlyInvokesExpressionOnce) {
126*993b0882SAndroid Build Coastguard Worker int num_invocations = 0;
127*993b0882SAndroid Build Coastguard Worker auto ok_internal_expr = [&num_invocations]() {
128*993b0882SAndroid Build Coastguard Worker ++num_invocations;
129*993b0882SAndroid Build Coastguard Worker return Status::OK;
130*993b0882SAndroid Build Coastguard Worker };
131*993b0882SAndroid Build Coastguard Worker auto ok_lambda = [&ok_internal_expr]() {
132*993b0882SAndroid Build Coastguard Worker TC3_RETURN_IF_ERROR(ok_internal_expr());
133*993b0882SAndroid Build Coastguard Worker return Status::OK;
134*993b0882SAndroid Build Coastguard Worker };
135*993b0882SAndroid Build Coastguard Worker
136*993b0882SAndroid Build Coastguard Worker libtextclassifier3::Status status = ok_lambda();
137*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.CanonicalCode(), StatusCode::OK);
138*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(num_invocations, 1);
139*993b0882SAndroid Build Coastguard Worker
140*993b0882SAndroid Build Coastguard Worker num_invocations = 0;
141*993b0882SAndroid Build Coastguard Worker auto error_internal_expr = [&num_invocations]() {
142*993b0882SAndroid Build Coastguard Worker ++num_invocations;
143*993b0882SAndroid Build Coastguard Worker return Status::UNKNOWN;
144*993b0882SAndroid Build Coastguard Worker };
145*993b0882SAndroid Build Coastguard Worker auto error_lambda = [&error_internal_expr]() {
146*993b0882SAndroid Build Coastguard Worker TC3_RETURN_IF_ERROR(error_internal_expr());
147*993b0882SAndroid Build Coastguard Worker return Status::OK;
148*993b0882SAndroid Build Coastguard Worker };
149*993b0882SAndroid Build Coastguard Worker
150*993b0882SAndroid Build Coastguard Worker status = error_lambda();
151*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(status.CanonicalCode(), StatusCode::UNKNOWN);
152*993b0882SAndroid Build Coastguard Worker EXPECT_EQ(num_invocations, 1);
153*993b0882SAndroid Build Coastguard Worker }
154*993b0882SAndroid Build Coastguard Worker
155*993b0882SAndroid Build Coastguard Worker } // namespace
156*993b0882SAndroid Build Coastguard Worker } // namespace libtextclassifier3
157