status_test.cc (19360B)
1 // Copyright 2019 The Abseil Authors. 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 // https://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 #include "absl/status/status.h" 16 17 #include <errno.h> 18 19 #include <array> 20 #include <cstddef> 21 #include <sstream> 22 #include <utility> 23 24 #include "gmock/gmock.h" 25 #include "gtest/gtest.h" 26 #include "absl/strings/cord.h" 27 #include "absl/strings/str_cat.h" 28 #include "absl/strings/str_format.h" 29 30 namespace { 31 32 using ::testing::Eq; 33 using ::testing::HasSubstr; 34 using ::testing::Optional; 35 using ::testing::UnorderedElementsAreArray; 36 37 TEST(StatusCode, InsertionOperator) { 38 const absl::StatusCode code = absl::StatusCode::kUnknown; 39 std::ostringstream oss; 40 oss << code; 41 EXPECT_EQ(oss.str(), absl::StatusCodeToString(code)); 42 } 43 44 // This structure holds the details for testing a single error code, 45 // its creator, and its classifier. 46 struct ErrorTest { 47 absl::StatusCode code; 48 using Creator = absl::Status (*)( 49 absl::string_view 50 ); 51 using Classifier = bool (*)(const absl::Status&); 52 Creator creator; 53 Classifier classifier; 54 }; 55 56 constexpr ErrorTest kErrorTests[]{ 57 {absl::StatusCode::kCancelled, absl::CancelledError, absl::IsCancelled}, 58 {absl::StatusCode::kUnknown, absl::UnknownError, absl::IsUnknown}, 59 {absl::StatusCode::kInvalidArgument, absl::InvalidArgumentError, 60 absl::IsInvalidArgument}, 61 {absl::StatusCode::kDeadlineExceeded, absl::DeadlineExceededError, 62 absl::IsDeadlineExceeded}, 63 {absl::StatusCode::kNotFound, absl::NotFoundError, absl::IsNotFound}, 64 {absl::StatusCode::kAlreadyExists, absl::AlreadyExistsError, 65 absl::IsAlreadyExists}, 66 {absl::StatusCode::kPermissionDenied, absl::PermissionDeniedError, 67 absl::IsPermissionDenied}, 68 {absl::StatusCode::kResourceExhausted, absl::ResourceExhaustedError, 69 absl::IsResourceExhausted}, 70 {absl::StatusCode::kFailedPrecondition, absl::FailedPreconditionError, 71 absl::IsFailedPrecondition}, 72 {absl::StatusCode::kAborted, absl::AbortedError, absl::IsAborted}, 73 {absl::StatusCode::kOutOfRange, absl::OutOfRangeError, absl::IsOutOfRange}, 74 {absl::StatusCode::kUnimplemented, absl::UnimplementedError, 75 absl::IsUnimplemented}, 76 {absl::StatusCode::kInternal, absl::InternalError, absl::IsInternal}, 77 {absl::StatusCode::kUnavailable, absl::UnavailableError, 78 absl::IsUnavailable}, 79 {absl::StatusCode::kDataLoss, absl::DataLossError, absl::IsDataLoss}, 80 {absl::StatusCode::kUnauthenticated, absl::UnauthenticatedError, 81 absl::IsUnauthenticated}, 82 }; 83 84 TEST(Status, CreateAndClassify) { 85 for (const auto& test : kErrorTests) { 86 SCOPED_TRACE(absl::StatusCodeToString(test.code)); 87 88 // Ensure that the creator does, in fact, create status objects with the 89 // expected error code and message. 90 std::string message = 91 absl::StrCat("error code ", test.code, " test message"); 92 absl::Status status = test.creator( 93 message 94 ); 95 EXPECT_EQ(test.code, status.code()); 96 EXPECT_EQ(message, status.message()); 97 98 // Ensure that the classifier returns true for a status produced by the 99 // creator. 100 EXPECT_TRUE(test.classifier(status)); 101 102 // Ensure that the classifier returns false for status with a different 103 // code. 104 for (const auto& other : kErrorTests) { 105 if (other.code != test.code) { 106 EXPECT_FALSE(test.classifier(absl::Status(other.code, ""))) 107 << " other.code = " << other.code; 108 } 109 } 110 } 111 } 112 113 TEST(Status, DefaultConstructor) { 114 absl::Status status; 115 EXPECT_TRUE(status.ok()); 116 EXPECT_EQ(absl::StatusCode::kOk, status.code()); 117 EXPECT_EQ("", status.message()); 118 } 119 120 TEST(Status, OkStatus) { 121 absl::Status status = absl::OkStatus(); 122 EXPECT_TRUE(status.ok()); 123 EXPECT_EQ(absl::StatusCode::kOk, status.code()); 124 EXPECT_EQ("", status.message()); 125 } 126 127 TEST(Status, ConstructorWithCodeMessage) { 128 { 129 absl::Status status(absl::StatusCode::kCancelled, ""); 130 EXPECT_FALSE(status.ok()); 131 EXPECT_EQ(absl::StatusCode::kCancelled, status.code()); 132 EXPECT_EQ("", status.message()); 133 } 134 { 135 absl::Status status(absl::StatusCode::kInternal, "message"); 136 EXPECT_FALSE(status.ok()); 137 EXPECT_EQ(absl::StatusCode::kInternal, status.code()); 138 EXPECT_EQ("message", status.message()); 139 } 140 } 141 142 TEST(Status, StatusMessageCStringTest) { 143 { 144 absl::Status status = absl::OkStatus(); 145 EXPECT_EQ(status.message(), ""); 146 EXPECT_STREQ(absl::StatusMessageAsCStr(status), ""); 147 EXPECT_EQ(status.message(), absl::StatusMessageAsCStr(status)); 148 EXPECT_NE(absl::StatusMessageAsCStr(status), nullptr); 149 } 150 { 151 absl::Status status; 152 EXPECT_EQ(status.message(), ""); 153 EXPECT_NE(absl::StatusMessageAsCStr(status), nullptr); 154 EXPECT_STREQ(absl::StatusMessageAsCStr(status), ""); 155 } 156 { 157 absl::Status status(absl::StatusCode::kInternal, "message"); 158 EXPECT_FALSE(status.ok()); 159 EXPECT_EQ(absl::StatusCode::kInternal, status.code()); 160 EXPECT_EQ("message", status.message()); 161 EXPECT_STREQ("message", absl::StatusMessageAsCStr(status)); 162 } 163 } 164 165 TEST(Status, ConstructOutOfRangeCode) { 166 const int kRawCode = 9999; 167 absl::Status status(static_cast<absl::StatusCode>(kRawCode), ""); 168 EXPECT_EQ(absl::StatusCode::kUnknown, status.code()); 169 EXPECT_EQ(kRawCode, status.raw_code()); 170 } 171 172 constexpr char kUrl1[] = "url.payload.1"; 173 constexpr char kUrl2[] = "url.payload.2"; 174 constexpr char kUrl3[] = "url.payload.3"; 175 constexpr char kUrl4[] = "url.payload.xx"; 176 177 constexpr char kPayload1[] = "aaaaa"; 178 constexpr char kPayload2[] = "bbbbb"; 179 constexpr char kPayload3[] = "ccccc"; 180 181 using PayloadsVec = std::vector<std::pair<std::string, absl::Cord>>; 182 183 TEST(Status, TestGetSetPayload) { 184 absl::Status ok_status = absl::OkStatus(); 185 ok_status.SetPayload(kUrl1, absl::Cord(kPayload1)); 186 ok_status.SetPayload(kUrl2, absl::Cord(kPayload2)); 187 188 EXPECT_FALSE(ok_status.GetPayload(kUrl1)); 189 EXPECT_FALSE(ok_status.GetPayload(kUrl2)); 190 191 absl::Status bad_status(absl::StatusCode::kInternal, "fail"); 192 bad_status.SetPayload(kUrl1, absl::Cord(kPayload1)); 193 bad_status.SetPayload(kUrl2, absl::Cord(kPayload2)); 194 195 EXPECT_THAT(bad_status.GetPayload(kUrl1), Optional(Eq(kPayload1))); 196 EXPECT_THAT(bad_status.GetPayload(kUrl2), Optional(Eq(kPayload2))); 197 198 EXPECT_FALSE(bad_status.GetPayload(kUrl3)); 199 200 bad_status.SetPayload(kUrl1, absl::Cord(kPayload3)); 201 EXPECT_THAT(bad_status.GetPayload(kUrl1), Optional(Eq(kPayload3))); 202 203 // Testing dynamically generated type_url 204 bad_status.SetPayload(absl::StrCat(kUrl1, ".1"), absl::Cord(kPayload1)); 205 EXPECT_THAT(bad_status.GetPayload(absl::StrCat(kUrl1, ".1")), 206 Optional(Eq(kPayload1))); 207 } 208 209 TEST(Status, TestErasePayload) { 210 absl::Status bad_status(absl::StatusCode::kInternal, "fail"); 211 bad_status.SetPayload(kUrl1, absl::Cord(kPayload1)); 212 bad_status.SetPayload(kUrl2, absl::Cord(kPayload2)); 213 bad_status.SetPayload(kUrl3, absl::Cord(kPayload3)); 214 215 EXPECT_FALSE(bad_status.ErasePayload(kUrl4)); 216 217 EXPECT_TRUE(bad_status.GetPayload(kUrl2)); 218 EXPECT_TRUE(bad_status.ErasePayload(kUrl2)); 219 EXPECT_FALSE(bad_status.GetPayload(kUrl2)); 220 EXPECT_FALSE(bad_status.ErasePayload(kUrl2)); 221 222 EXPECT_TRUE(bad_status.ErasePayload(kUrl1)); 223 EXPECT_TRUE(bad_status.ErasePayload(kUrl3)); 224 225 bad_status.SetPayload(kUrl1, absl::Cord(kPayload1)); 226 EXPECT_TRUE(bad_status.ErasePayload(kUrl1)); 227 } 228 229 TEST(Status, TestComparePayloads) { 230 absl::Status bad_status1(absl::StatusCode::kInternal, "fail"); 231 bad_status1.SetPayload(kUrl1, absl::Cord(kPayload1)); 232 bad_status1.SetPayload(kUrl2, absl::Cord(kPayload2)); 233 bad_status1.SetPayload(kUrl3, absl::Cord(kPayload3)); 234 235 absl::Status bad_status2(absl::StatusCode::kInternal, "fail"); 236 bad_status2.SetPayload(kUrl2, absl::Cord(kPayload2)); 237 bad_status2.SetPayload(kUrl3, absl::Cord(kPayload3)); 238 bad_status2.SetPayload(kUrl1, absl::Cord(kPayload1)); 239 240 EXPECT_EQ(bad_status1, bad_status2); 241 } 242 243 TEST(Status, TestComparePayloadsAfterErase) { 244 absl::Status payload_status(absl::StatusCode::kInternal, ""); 245 payload_status.SetPayload(kUrl1, absl::Cord(kPayload1)); 246 payload_status.SetPayload(kUrl2, absl::Cord(kPayload2)); 247 248 absl::Status empty_status(absl::StatusCode::kInternal, ""); 249 250 // Different payloads, not equal 251 EXPECT_NE(payload_status, empty_status); 252 EXPECT_TRUE(payload_status.ErasePayload(kUrl1)); 253 254 // Still Different payloads, still not equal. 255 EXPECT_NE(payload_status, empty_status); 256 EXPECT_TRUE(payload_status.ErasePayload(kUrl2)); 257 258 // Both empty payloads, should be equal 259 EXPECT_EQ(payload_status, empty_status); 260 } 261 262 PayloadsVec AllVisitedPayloads(const absl::Status& s) { 263 PayloadsVec result; 264 265 s.ForEachPayload([&](absl::string_view type_url, const absl::Cord& payload) { 266 result.push_back(std::make_pair(std::string(type_url), payload)); 267 }); 268 269 return result; 270 } 271 272 TEST(Status, TestForEachPayload) { 273 absl::Status bad_status(absl::StatusCode::kInternal, "fail"); 274 bad_status.SetPayload(kUrl1, absl::Cord(kPayload1)); 275 bad_status.SetPayload(kUrl2, absl::Cord(kPayload2)); 276 bad_status.SetPayload(kUrl3, absl::Cord(kPayload3)); 277 278 int count = 0; 279 280 bad_status.ForEachPayload( 281 [&count](absl::string_view, const absl::Cord&) { ++count; }); 282 283 EXPECT_EQ(count, 3); 284 285 PayloadsVec expected_payloads = {{kUrl1, absl::Cord(kPayload1)}, 286 {kUrl2, absl::Cord(kPayload2)}, 287 {kUrl3, absl::Cord(kPayload3)}}; 288 289 // Test that we visit all the payloads in the status. 290 PayloadsVec visited_payloads = AllVisitedPayloads(bad_status); 291 EXPECT_THAT(visited_payloads, UnorderedElementsAreArray(expected_payloads)); 292 293 // Test that visitation order is not consistent between run. 294 std::vector<absl::Status> scratch; 295 while (true) { 296 scratch.emplace_back(absl::StatusCode::kInternal, "fail"); 297 298 scratch.back().SetPayload(kUrl1, absl::Cord(kPayload1)); 299 scratch.back().SetPayload(kUrl2, absl::Cord(kPayload2)); 300 scratch.back().SetPayload(kUrl3, absl::Cord(kPayload3)); 301 302 if (AllVisitedPayloads(scratch.back()) != visited_payloads) { 303 break; 304 } 305 } 306 } 307 308 TEST(Status, ToString) { 309 absl::Status status(absl::StatusCode::kInternal, "fail"); 310 EXPECT_EQ("INTERNAL: fail", status.ToString()); 311 status.SetPayload("foo", absl::Cord("bar")); 312 EXPECT_EQ("INTERNAL: fail [foo='bar']", status.ToString()); 313 status.SetPayload("bar", absl::Cord("\377")); 314 EXPECT_THAT(status.ToString(), 315 AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), 316 HasSubstr("[bar='\\xff']"))); 317 } 318 319 TEST(Status, ToStringMode) { 320 absl::Status status(absl::StatusCode::kInternal, "fail"); 321 status.SetPayload("foo", absl::Cord("bar")); 322 status.SetPayload("bar", absl::Cord("\377")); 323 324 EXPECT_EQ("INTERNAL: fail", 325 status.ToString(absl::StatusToStringMode::kWithNoExtraData)); 326 327 EXPECT_THAT(status.ToString(absl::StatusToStringMode::kWithPayload), 328 AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), 329 HasSubstr("[bar='\\xff']"))); 330 331 EXPECT_THAT(status.ToString(absl::StatusToStringMode::kWithEverything), 332 AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), 333 HasSubstr("[bar='\\xff']"))); 334 335 EXPECT_THAT(status.ToString(~absl::StatusToStringMode::kWithPayload), 336 AllOf(HasSubstr("INTERNAL: fail"), Not(HasSubstr("[foo='bar']")), 337 Not(HasSubstr("[bar='\\xff']")))); 338 } 339 340 TEST(Status, OstreamOperator) { 341 absl::Status status(absl::StatusCode::kInternal, "fail"); 342 { std::stringstream stream; 343 stream << status; 344 EXPECT_EQ("INTERNAL: fail", stream.str()); 345 } 346 status.SetPayload("foo", absl::Cord("bar")); 347 { std::stringstream stream; 348 stream << status; 349 EXPECT_EQ("INTERNAL: fail [foo='bar']", stream.str()); 350 } 351 status.SetPayload("bar", absl::Cord("\377")); 352 { std::stringstream stream; 353 stream << status; 354 EXPECT_THAT(stream.str(), 355 AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), 356 HasSubstr("[bar='\\xff']"))); 357 } 358 } 359 360 TEST(Status, AbslStringify) { 361 absl::Status status(absl::StatusCode::kInternal, "fail"); 362 EXPECT_EQ("INTERNAL: fail", absl::StrCat(status)); 363 EXPECT_EQ("INTERNAL: fail", absl::StrFormat("%v", status)); 364 status.SetPayload("foo", absl::Cord("bar")); 365 EXPECT_EQ("INTERNAL: fail [foo='bar']", absl::StrCat(status)); 366 status.SetPayload("bar", absl::Cord("\377")); 367 EXPECT_THAT(absl::StrCat(status), 368 AllOf(HasSubstr("INTERNAL: fail"), HasSubstr("[foo='bar']"), 369 HasSubstr("[bar='\\xff']"))); 370 } 371 372 TEST(Status, OstreamEqStringify) { 373 absl::Status status(absl::StatusCode::kUnknown, "fail"); 374 status.SetPayload("foo", absl::Cord("bar")); 375 std::stringstream stream; 376 stream << status; 377 EXPECT_EQ(stream.str(), absl::StrCat(status)); 378 } 379 380 absl::Status EraseAndReturn(const absl::Status& base) { 381 absl::Status copy = base; 382 EXPECT_TRUE(copy.ErasePayload(kUrl1)); 383 return copy; 384 } 385 386 TEST(Status, CopyOnWriteForErasePayload) { 387 { 388 absl::Status base(absl::StatusCode::kInvalidArgument, "fail"); 389 base.SetPayload(kUrl1, absl::Cord(kPayload1)); 390 EXPECT_TRUE(base.GetPayload(kUrl1).has_value()); 391 absl::Status copy = EraseAndReturn(base); 392 EXPECT_TRUE(base.GetPayload(kUrl1).has_value()); 393 EXPECT_FALSE(copy.GetPayload(kUrl1).has_value()); 394 } 395 { 396 absl::Status base(absl::StatusCode::kInvalidArgument, "fail"); 397 base.SetPayload(kUrl1, absl::Cord(kPayload1)); 398 absl::Status copy = base; 399 400 EXPECT_TRUE(base.GetPayload(kUrl1).has_value()); 401 EXPECT_TRUE(copy.GetPayload(kUrl1).has_value()); 402 403 EXPECT_TRUE(base.ErasePayload(kUrl1)); 404 405 EXPECT_FALSE(base.GetPayload(kUrl1).has_value()); 406 EXPECT_TRUE(copy.GetPayload(kUrl1).has_value()); 407 } 408 } 409 410 TEST(Status, CopyConstructor) { 411 { 412 absl::Status status; 413 absl::Status copy(status); 414 EXPECT_EQ(copy, status); 415 } 416 { 417 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 418 absl::Status copy(status); 419 EXPECT_EQ(copy, status); 420 } 421 { 422 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 423 status.SetPayload(kUrl1, absl::Cord(kPayload1)); 424 absl::Status copy(status); 425 EXPECT_EQ(copy, status); 426 } 427 } 428 429 TEST(Status, CopyAssignment) { 430 absl::Status assignee; 431 { 432 absl::Status status; 433 assignee = status; 434 EXPECT_EQ(assignee, status); 435 } 436 { 437 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 438 assignee = status; 439 EXPECT_EQ(assignee, status); 440 } 441 { 442 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 443 status.SetPayload(kUrl1, absl::Cord(kPayload1)); 444 assignee = status; 445 EXPECT_EQ(assignee, status); 446 } 447 } 448 449 TEST(Status, CopyAssignmentIsNotRef) { 450 const absl::Status status_orig(absl::StatusCode::kInvalidArgument, "message"); 451 absl::Status status_copy = status_orig; 452 EXPECT_EQ(status_orig, status_copy); 453 status_copy.SetPayload(kUrl1, absl::Cord(kPayload1)); 454 EXPECT_NE(status_orig, status_copy); 455 } 456 457 TEST(Status, MoveConstructor) { 458 { 459 absl::Status status; 460 absl::Status copy(absl::Status{}); 461 EXPECT_EQ(copy, status); 462 } 463 { 464 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 465 absl::Status copy( 466 absl::Status(absl::StatusCode::kInvalidArgument, "message")); 467 EXPECT_EQ(copy, status); 468 } 469 { 470 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 471 status.SetPayload(kUrl1, absl::Cord(kPayload1)); 472 absl::Status copy1(status); 473 absl::Status copy2(std::move(status)); 474 EXPECT_EQ(copy1, copy2); 475 } 476 } 477 478 TEST(Status, MoveAssignment) { 479 absl::Status assignee; 480 { 481 absl::Status status; 482 assignee = absl::Status(); 483 EXPECT_EQ(assignee, status); 484 } 485 { 486 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 487 assignee = absl::Status(absl::StatusCode::kInvalidArgument, "message"); 488 EXPECT_EQ(assignee, status); 489 } 490 { 491 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 492 status.SetPayload(kUrl1, absl::Cord(kPayload1)); 493 absl::Status copy(status); 494 assignee = std::move(status); 495 EXPECT_EQ(assignee, copy); 496 } 497 { 498 absl::Status status(absl::StatusCode::kInvalidArgument, "message"); 499 absl::Status copy(status); 500 assignee = static_cast<absl::Status&&>(status); 501 EXPECT_EQ(assignee, copy); 502 } 503 } 504 505 TEST(Status, Update) { 506 absl::Status s; 507 s.Update(absl::OkStatus()); 508 EXPECT_TRUE(s.ok()); 509 const absl::Status a(absl::StatusCode::kCancelled, "message"); 510 s.Update(a); 511 EXPECT_EQ(s, a); 512 const absl::Status b(absl::StatusCode::kInternal, "other message"); 513 s.Update(b); 514 EXPECT_EQ(s, a); 515 s.Update(absl::OkStatus()); 516 EXPECT_EQ(s, a); 517 EXPECT_FALSE(s.ok()); 518 } 519 520 TEST(Status, Equality) { 521 absl::Status ok; 522 absl::Status no_payload = absl::CancelledError("no payload"); 523 absl::Status one_payload = absl::InvalidArgumentError("one payload"); 524 one_payload.SetPayload(kUrl1, absl::Cord(kPayload1)); 525 absl::Status two_payloads = one_payload; 526 two_payloads.SetPayload(kUrl2, absl::Cord(kPayload2)); 527 const std::array<absl::Status, 4> status_arr = {ok, no_payload, one_payload, 528 two_payloads}; 529 for (int i = 0; i < status_arr.size(); i++) { 530 for (int j = 0; j < status_arr.size(); j++) { 531 if (i == j) { 532 EXPECT_TRUE(status_arr[i] == status_arr[j]); 533 EXPECT_FALSE(status_arr[i] != status_arr[j]); 534 } else { 535 EXPECT_TRUE(status_arr[i] != status_arr[j]); 536 EXPECT_FALSE(status_arr[i] == status_arr[j]); 537 } 538 } 539 } 540 } 541 542 TEST(Status, Swap) { 543 auto test_swap = [](const absl::Status& s1, const absl::Status& s2) { 544 absl::Status copy1 = s1, copy2 = s2; 545 swap(copy1, copy2); 546 EXPECT_EQ(copy1, s2); 547 EXPECT_EQ(copy2, s1); 548 }; 549 const absl::Status ok; 550 const absl::Status no_payload(absl::StatusCode::kAlreadyExists, "no payload"); 551 absl::Status with_payload(absl::StatusCode::kInternal, "with payload"); 552 with_payload.SetPayload(kUrl1, absl::Cord(kPayload1)); 553 test_swap(ok, no_payload); 554 test_swap(no_payload, ok); 555 test_swap(ok, with_payload); 556 test_swap(with_payload, ok); 557 test_swap(no_payload, with_payload); 558 test_swap(with_payload, no_payload); 559 } 560 561 TEST(StatusErrno, ErrnoToStatusCode) { 562 EXPECT_EQ(absl::ErrnoToStatusCode(0), absl::StatusCode::kOk); 563 564 // Spot-check a few errno values. 565 EXPECT_EQ(absl::ErrnoToStatusCode(EINVAL), 566 absl::StatusCode::kInvalidArgument); 567 EXPECT_EQ(absl::ErrnoToStatusCode(ENOENT), absl::StatusCode::kNotFound); 568 569 // We'll pick a very large number so it hopefully doesn't collide to errno. 570 EXPECT_EQ(absl::ErrnoToStatusCode(19980927), absl::StatusCode::kUnknown); 571 } 572 573 TEST(StatusErrno, ErrnoToStatus) { 574 absl::Status status = absl::ErrnoToStatus(ENOENT, "Cannot open 'path'"); 575 EXPECT_EQ(status.code(), absl::StatusCode::kNotFound); 576 EXPECT_EQ(status.message(), "Cannot open 'path': No such file or directory"); 577 } 578 579 } // namespace