1 /* Copyright 2015 The TensorFlow Authors. All Rights Reserved.
2
3 Licensed under the Apache License, Version 2.0 (the "License");
4 you may not use this file except in compliance with the License.
5 You may obtain a copy of the License at
6
7 http://www.apache.org/licenses/LICENSE-2.0
8
9 Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14 ==============================================================================*/
15
16 #include "tensorflow/core/lib/core/status.h"
17
18 #include "absl/strings/match.h"
19 #include "tensorflow/core/lib/core/errors.h"
20 #include "tensorflow/core/lib/core/status_test_util.h"
21 #include "tensorflow/core/platform/test.h"
22 #include "tensorflow/core/platform/test_benchmark.h"
23
24 namespace tensorflow {
25
TEST(Status,OK)26 TEST(Status, OK) {
27 EXPECT_EQ(OkStatus().code(), error::OK);
28 EXPECT_EQ(OkStatus().error_message(), "");
29 TF_EXPECT_OK(OkStatus());
30 TF_ASSERT_OK(OkStatus());
31 EXPECT_EQ(OkStatus(), Status());
32 Status s;
33 EXPECT_TRUE(s.ok());
34 }
35
TEST(DeathStatus,CheckOK)36 TEST(DeathStatus, CheckOK) {
37 Status status(errors::InvalidArgument("Invalid"));
38 ASSERT_DEATH(TF_CHECK_OK(status), "Invalid");
39 }
40
TEST(Status,Set)41 TEST(Status, Set) {
42 Status status;
43 status = Status(error::CANCELLED, "Error message");
44 EXPECT_EQ(status.code(), error::CANCELLED);
45 EXPECT_EQ(status.error_message(), "Error message");
46 }
47
TEST(Status,Copy)48 TEST(Status, Copy) {
49 Status a(errors::InvalidArgument("Invalid"));
50 Status b(a);
51 ASSERT_EQ(a.ToString(), b.ToString());
52 }
53
TEST(Status,Assign)54 TEST(Status, Assign) {
55 Status a(errors::InvalidArgument("Invalid"));
56 Status b;
57 b = a;
58 ASSERT_EQ(a.ToString(), b.ToString());
59 }
60
TEST(Status,Move)61 TEST(Status, Move) {
62 Status a(errors::InvalidArgument("Invalid"));
63 Status b(std::move(a));
64 ASSERT_EQ("INVALID_ARGUMENT: Invalid", b.ToString());
65 }
66
TEST(Status,MoveAssign)67 TEST(Status, MoveAssign) {
68 Status a(errors::InvalidArgument("Invalid"));
69 Status b;
70 b = std::move(a);
71 ASSERT_EQ("INVALID_ARGUMENT: Invalid", b.ToString());
72 }
73
TEST(Status,Update)74 TEST(Status, Update) {
75 Status s;
76 s.Update(OkStatus());
77 ASSERT_TRUE(s.ok());
78 Status a(errors::InvalidArgument("Invalid"));
79 s.Update(a);
80 ASSERT_EQ(s.ToString(), a.ToString());
81 Status b(errors::Internal("Internal"));
82 s.Update(b);
83 ASSERT_EQ(s.ToString(), a.ToString());
84 s.Update(OkStatus());
85 ASSERT_EQ(s.ToString(), a.ToString());
86 ASSERT_FALSE(s.ok());
87 }
88
TEST(Status,EqualsOK)89 TEST(Status, EqualsOK) { ASSERT_EQ(OkStatus(), Status()); }
90
TEST(Status,EqualsSame)91 TEST(Status, EqualsSame) {
92 Status a(errors::InvalidArgument("Invalid"));
93 Status b(errors::InvalidArgument("Invalid"));
94 ASSERT_EQ(a, b);
95 }
96
TEST(Status,EqualsCopy)97 TEST(Status, EqualsCopy) {
98 const Status a(errors::InvalidArgument("Invalid"));
99 const Status b = a;
100 ASSERT_EQ(a, b);
101 }
102
TEST(Status,EqualsDifferentCode)103 TEST(Status, EqualsDifferentCode) {
104 const Status a(errors::InvalidArgument("message"));
105 const Status b(errors::Internal("message"));
106 ASSERT_NE(a, b);
107 }
108
TEST(Status,EqualsDifferentMessage)109 TEST(Status, EqualsDifferentMessage) {
110 const Status a(errors::InvalidArgument("message"));
111 const Status b(errors::InvalidArgument("another"));
112 ASSERT_NE(a, b);
113 }
114
TEST(StatusGroup,OKStatusGroup)115 TEST(StatusGroup, OKStatusGroup) {
116 StatusGroup c;
117 c.Update(OkStatus());
118 c.Update(OkStatus());
119 ASSERT_EQ(c.as_summary_status(), OkStatus());
120 ASSERT_EQ(c.as_concatenated_status(), OkStatus());
121 }
122
TEST(StatusGroup,AggregateWithSingleErrorStatus)123 TEST(StatusGroup, AggregateWithSingleErrorStatus) {
124 StatusGroup c;
125 const Status internal(errors::Internal("Original error."));
126
127 c.Update(internal);
128 ASSERT_EQ(c.as_summary_status(), internal);
129
130 Status concat_status = c.as_concatenated_status();
131 ASSERT_EQ(concat_status.code(), internal.code());
132 ASSERT_TRUE(absl::StrContains(concat_status.error_message(),
133 internal.error_message()));
134
135 // Add derived error status
136 const Status derived =
137 StatusGroup::MakeDerived(errors::Internal("Derived error."));
138 c.Update(derived);
139
140 ASSERT_EQ(c.as_summary_status(), internal);
141
142 concat_status = c.as_concatenated_status();
143 ASSERT_EQ(concat_status.code(), internal.code());
144 ASSERT_TRUE(absl::StrContains(concat_status.error_message(),
145 internal.error_message()));
146 }
147
TEST(StatusGroup,AggregateWithMultipleErrorStatus)148 TEST(StatusGroup, AggregateWithMultipleErrorStatus) {
149 StatusGroup c;
150 const Status internal(errors::Internal("Original error."));
151 const Status cancelled(errors::Cancelled("Cancelled after 10 steps."));
152 const Status aborted(errors::Aborted("Aborted after 10 steps."));
153
154 c.Update(internal);
155 c.Update(cancelled);
156 c.Update(aborted);
157
158 Status summary = c.as_summary_status();
159
160 ASSERT_EQ(summary.code(), internal.code());
161 ASSERT_TRUE(
162 absl::StrContains(summary.error_message(), internal.error_message()));
163 ASSERT_TRUE(
164 absl::StrContains(summary.error_message(), cancelled.error_message()));
165 ASSERT_TRUE(
166 absl::StrContains(summary.error_message(), aborted.error_message()));
167
168 Status concat_status = c.as_concatenated_status();
169 ASSERT_EQ(concat_status.code(), internal.code());
170 ASSERT_TRUE(absl::StrContains(concat_status.error_message(),
171 internal.error_message()));
172 ASSERT_TRUE(absl::StrContains(concat_status.error_message(),
173 cancelled.error_message()));
174 ASSERT_TRUE(absl::StrContains(concat_status.error_message(),
175 aborted.error_message()));
176 }
177
TEST(Status,InvalidPayloadGetsIgnored)178 TEST(Status, InvalidPayloadGetsIgnored) {
179 Status s = Status();
180 s.SetPayload("Invalid", "Invalid Val");
181 ASSERT_FALSE(s.GetPayload("Invalid").has_value());
182 bool is_err_erased = s.ErasePayload("Invalid");
183 ASSERT_EQ(is_err_erased, false);
184 }
185
TEST(Status,SetPayloadSetsOrUpdatesIt)186 TEST(Status, SetPayloadSetsOrUpdatesIt) {
187 Status s(error::INTERNAL, "Error message");
188 s.SetPayload("Error key", "Original");
189 ASSERT_EQ(s.GetPayload("Error key"), absl::Cord("Original"));
190 s.SetPayload("Error key", "Updated");
191 ASSERT_EQ(s.GetPayload("Error key"), absl::Cord("Updated"));
192 }
193
TEST(Status,ErasePayloadRemovesIt)194 TEST(Status, ErasePayloadRemovesIt) {
195 Status s(error::INTERNAL, "Error message");
196 s.SetPayload("Error key", "Original");
197
198 bool is_err_erased = s.ErasePayload("Error key");
199 ASSERT_EQ(is_err_erased, true);
200 is_err_erased = s.ErasePayload("Error key");
201 ASSERT_EQ(is_err_erased, false);
202 ASSERT_FALSE(s.GetPayload("Error key").has_value());
203 }
204
TEST(Status,GetAllPayloads)205 TEST(Status, GetAllPayloads) {
206 Status s_error(error::INTERNAL, "Error message");
207 s_error.SetPayload("Error key", "foo");
208 auto payloads_error_status = s_error.GetAllPayloads();
209 ASSERT_EQ(payloads_error_status.size(), 1);
210 ASSERT_EQ(payloads_error_status["Error key"], "foo");
211
212 Status s_ok = Status();
213 auto payloads_ok_status = s_ok.GetAllPayloads();
214 ASSERT_TRUE(payloads_ok_status.empty());
215 }
216
TEST(Status,OKStatusReplaceAllPayloadsFromErrorStatus)217 TEST(Status, OKStatusReplaceAllPayloadsFromErrorStatus) {
218 // An OK status will should not change after ReplaceAllPayloads() calls.
219 Status s_error(error::INTERNAL, "Error message");
220 s_error.SetPayload("Error key", "foo");
221 Status s_ok = Status();
222
223 s_ok.ReplaceAllPayloads(s_error.GetAllPayloads());
224 auto payloads_ok_status = s_ok.GetAllPayloads();
225 ASSERT_TRUE(payloads_ok_status.empty());
226 }
227
TEST(Status,ErrorStatusReplaceAllPayloadsFromOKStatus)228 TEST(Status, ErrorStatusReplaceAllPayloadsFromOKStatus) {
229 // An ReplaceAllPayloads() call should not take effect from empty inputs.
230 Status s_error(error::INTERNAL, "Error message");
231 s_error.SetPayload("Error key", "foo");
232 Status s_ok = Status();
233
234 s_error.ReplaceAllPayloads(s_ok.GetAllPayloads());
235 ASSERT_EQ(s_error.GetPayload("Error key"), "foo");
236 }
237
TEST(Status,ErrorStatusReplaceAllPayloadsFromErrorStatus)238 TEST(Status, ErrorStatusReplaceAllPayloadsFromErrorStatus) {
239 Status s_error1(error::INTERNAL, "Error message");
240 s_error1.SetPayload("Error key 1", "foo");
241 s_error1.SetPayload("Error key 2", "bar");
242 Status s_error2(error::INTERNAL, "Error message");
243 s_error2.SetPayload("Error key", "bar");
244 ASSERT_EQ(s_error2.GetPayload("Error key"), "bar");
245
246 s_error2.ReplaceAllPayloads(s_error1.GetAllPayloads());
247 ASSERT_EQ(s_error2.GetPayload("Error key 1"), "foo");
248 ASSERT_EQ(s_error2.GetPayload("Error key 2"), "bar");
249 auto payloads_error_status = s_error2.GetAllPayloads();
250 ASSERT_EQ(payloads_error_status.size(), 2);
251 }
252
BM_TF_CHECK_OK(::testing::benchmark::State & state)253 static void BM_TF_CHECK_OK(::testing::benchmark::State& state) {
254 tensorflow::Status s = (state.max_iterations < 0)
255 ? errors::InvalidArgument("Invalid")
256 : OkStatus();
257 for (auto i : state) {
258 TF_CHECK_OK(s);
259 }
260 }
261 BENCHMARK(BM_TF_CHECK_OK);
262
263 } // namespace tensorflow
264