Baton::ready, a const variant of try_wait
[folly.git] / folly / test / ExceptionTest.cpp
1 /*
2  * Copyright 2017 Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *   http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <folly/Exception.h>
18
19 #include <folly/experimental/TestUtil.h>
20 #include <folly/portability/GTest.h>
21
22 #include <cstdio>
23 #include <memory>
24
25 namespace folly { namespace test {
26
27 #define EXPECT_SYSTEM_ERROR(statement, err, msg) \
28   try { \
29     statement; \
30     ADD_FAILURE() << "Didn't throw"; \
31   } catch (const std::system_error& e) { \
32     std::system_error expected(err, std::system_category(), msg); \
33     EXPECT_STREQ(expected.what(), e.what()); \
34   } catch (...) { \
35     ADD_FAILURE() << "Threw a different type"; \
36   }
37
38
39 TEST(ExceptionTest, Simple) {
40   // Make sure errno isn't used when we don't want it to, set it to something
41   // else than what we set when we call Explicit functions
42   errno = ERANGE;
43   EXPECT_SYSTEM_ERROR({throwSystemErrorExplicit(EIO, "hello");},
44                       EIO, "hello");
45   errno = ERANGE;
46   EXPECT_SYSTEM_ERROR({throwSystemErrorExplicit(EIO, "hello", " world");},
47                       EIO, "hello world");
48   errno = ERANGE;
49   EXPECT_SYSTEM_ERROR({throwSystemError("hello", " world");},
50                       ERANGE, "hello world");
51
52   EXPECT_NO_THROW({checkPosixError(0, "hello", " world");});
53   errno = ERANGE;
54   EXPECT_SYSTEM_ERROR({checkPosixError(EIO, "hello", " world");},
55                       EIO, "hello world");
56
57   EXPECT_NO_THROW({checkKernelError(0, "hello", " world");});
58   EXPECT_NO_THROW({checkKernelError(EIO, "hello", " world");});
59   errno = ERANGE;
60   EXPECT_SYSTEM_ERROR({checkKernelError(-EIO, "hello", " world");},
61                       EIO, "hello world");
62
63   EXPECT_NO_THROW({checkUnixError(0, "hello", " world");});
64   EXPECT_NO_THROW({checkUnixError(1, "hello", " world");});
65   errno = ERANGE;
66   EXPECT_SYSTEM_ERROR({checkUnixError(-1, "hello", " world");},
67                       ERANGE, "hello world");
68
69   EXPECT_NO_THROW({checkUnixErrorExplicit(0, EIO, "hello", " world");});
70   EXPECT_NO_THROW({checkUnixErrorExplicit(1, EIO, "hello", " world");});
71   errno = ERANGE;
72   EXPECT_SYSTEM_ERROR({checkUnixErrorExplicit(-1, EIO, "hello", " world");},
73                       EIO, "hello world");
74
75   TemporaryDirectory tmpdir;
76   auto exnpath = tmpdir.path() / "ExceptionTest";
77   auto fp = fopen(exnpath.string().c_str(), "w+b");
78   ASSERT_TRUE(fp != nullptr);
79   SCOPE_EXIT { fclose(fp); };
80
81   EXPECT_NO_THROW({ checkFopenError(fp, "hello", " world"); });
82   errno = ERANGE;
83   EXPECT_SYSTEM_ERROR({checkFopenError(nullptr, "hello", " world");},
84                       ERANGE, "hello world");
85
86   EXPECT_NO_THROW({ checkFopenErrorExplicit(fp, EIO, "hello", " world"); });
87   errno = ERANGE;
88   EXPECT_SYSTEM_ERROR({checkFopenErrorExplicit(nullptr, EIO,
89                                                "hello", " world");},
90                       EIO, "hello world");
91 }
92
93 TEST(ExceptionTest, makeSystemError) {
94   errno = ENOENT;
95   auto ex = makeSystemErrorExplicit(EDEADLK, "stuck");
96   EXPECT_EQ(EDEADLK, ex.code().value());
97   EXPECT_EQ(std::system_category(), ex.code().category());
98   EXPECT_TRUE(StringPiece{ex.what()}.contains("stuck"))
99       << "what() string missing input message: " << ex.what();
100
101   ex = makeSystemErrorExplicit(EDOM, 300, " is bigger than max=", 255);
102   EXPECT_EQ(EDOM, ex.code().value());
103   EXPECT_EQ(std::system_category(), ex.code().category());
104   EXPECT_TRUE(StringPiece{ex.what()}.contains("300 is bigger than max=255"))
105       << "what() string missing input message: " << ex.what();
106
107   errno = EINVAL;
108   ex = makeSystemError("bad argument ", 1234, ": bogus");
109   EXPECT_EQ(EINVAL, ex.code().value());
110   EXPECT_EQ(std::system_category(), ex.code().category());
111   EXPECT_TRUE(StringPiece{ex.what()}.contains("bad argument 1234: bogus"))
112       << "what() string missing input message: " << ex.what();
113
114   errno = 0;
115   ex = makeSystemError("unexpected success");
116   EXPECT_EQ(0, ex.code().value());
117   EXPECT_EQ(std::system_category(), ex.code().category());
118   EXPECT_TRUE(StringPiece{ex.what()}.contains("unexpected success"))
119       << "what() string missing input message: " << ex.what();
120 }
121
122 } // namespace test
123 } // namespace folly