xref: /aosp_15_r20/external/abseil-cpp/absl/status/status_test.cc (revision 9356374a3709195abf420251b3e825997ff56c0f)
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 
TEST(StatusCode,InsertionOperator)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 
TEST(Status,CreateAndClassify)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 
TEST(Status,DefaultConstructor)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 
TEST(Status,OkStatus)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 
TEST(Status,ConstructorWithCodeMessage)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 
TEST(Status,StatusMessageCStringTest)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 
TEST(Status,ConstructOutOfRangeCode)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 
TEST(Status,TestGetSetPayload)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 
TEST(Status,TestErasePayload)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 
TEST(Status,TestComparePayloads)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 
TEST(Status,TestComparePayloadsAfterErase)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 
AllVisitedPayloads(const absl::Status & s)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 
TEST(Status,TestForEachPayload)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 
TEST(Status,ToString)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 
TEST(Status,ToStringMode)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 
TEST(Status,OstreamOperator)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 
TEST(Status,AbslStringify)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 
TEST(Status,OstreamEqStringify)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 
EraseAndReturn(const absl::Status & base)380 absl::Status EraseAndReturn(const absl::Status& base) {
381   absl::Status copy = base;
382   EXPECT_TRUE(copy.ErasePayload(kUrl1));
383   return copy;
384 }
385 
TEST(Status,CopyOnWriteForErasePayload)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 
TEST(Status,CopyConstructor)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 
TEST(Status,CopyAssignment)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 
TEST(Status,CopyAssignmentIsNotRef)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 
TEST(Status,MoveConstructor)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 
TEST(Status,MoveAssignment)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 
TEST(Status,Update)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 
TEST(Status,Equality)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 
TEST(Status,Swap)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 
TEST(StatusErrno,ErrnoToStatusCode)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 
TEST(StatusErrno,ErrnoToStatus)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
580