blob: f5b7a5e94c6835b0eb267dab4a4ef5bbc0d62717 [file] [log] [blame]
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -08001#include <gtest/gtest.h>
2#include <stdplus/util/cexec.hpp>
3#include <string_view>
4#include <system_error>
5
6namespace stdplus
7{
8namespace util
9{
10namespace
11{
12
13int sample1()
14{
15 return 1;
16}
17
18int sample2(int val)
19{
20 return val;
21}
22
23ssize_t sample3(int val, ssize_t* val2)
24{
25 return *val2 + val;
26}
27
28const char* ptr(const char* p)
29{
30 return p;
31}
32
33struct sample
34{
35 int count = 3;
36
37 int one()
38 {
39 return count++;
40 }
41
42 int two(int val) const
43 {
44 return val;
45 }
46
47 int* ptr()
48 {
49 return &count;
50 }
51
52 int* ptr2()
53 {
54 return nullptr;
55 }
56
57 static int s(int val)
58 {
59 return val;
60 }
61};
62
63int makeTrivialError(int error, const char* msg)
64{
65 (void)msg;
66 return error;
67}
68
69TEST(Cexec, CallCheckErrnoInt)
70{
William A. Kennington III80c988f2020-08-02 02:54:22 -070071 EXPECT_EQ(1, CHECK_ERRNO(sample1(), [](int) { throw 0; }));
72 EXPECT_EQ(1, CHECK_ERRNO(sample1(), "sample1"));
73 EXPECT_EQ(1, CHECK_ERRNO(sample1(), std::string("sample1")));
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -080074 EXPECT_EQ(1, callCheckErrno("sample1", sample1));
William A. Kennington III1f1681e2020-06-10 02:28:01 -070075 EXPECT_EQ(2, callCheckErrno(std::string("sample2"), &sample2, 2));
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -080076 EXPECT_EQ(4, callCheckErrno("sample::s", sample::s, 4));
77 ssize_t v = 10;
78 EXPECT_EQ(12, callCheckErrno("sample3", sample3, 2, &v));
79
80 constexpr auto error = "sample2 error";
81 try
82 {
83 errno = EBADF;
84 callCheckErrno(error, sample2, -1);
85 EXPECT_TRUE(false);
86 }
87 catch (const std::system_error& e)
88 {
89 EXPECT_EQ(std::string_view(error),
90 std::string_view(e.what(), strlen(error)));
91 EXPECT_EQ(EBADF, e.code().value());
92 }
William A. Kennington III80c988f2020-08-02 02:54:22 -070093
94 try
95 {
96 errno = EBADF;
97 CHECK_ERRNO(sample2(-1), error);
98 EXPECT_TRUE(false);
99 }
100 catch (const std::system_error& e)
101 {
102 EXPECT_EQ(std::string_view(error),
103 std::string_view(e.what(), strlen(error)));
104 EXPECT_EQ(EBADF, e.code().value());
105 }
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -0800106}
107
108TEST(Cexec, CallCheckErrnoIntMem)
109{
110 sample s;
111 const sample* sp = &s;
112 EXPECT_EQ(3, callCheckErrno("sample::one", &sample::one, s));
113 EXPECT_EQ(4, callCheckErrno("sample::one", &sample::one, &s));
114 EXPECT_EQ(5, callCheckErrno("sample::two", &sample::two, sp, 5));
115
116 constexpr auto error = "sample error";
117 try
118 {
119 errno = EBADF;
120 callCheckErrno(error, &sample::two, sp, -1);
121 EXPECT_TRUE(false);
122 }
123 catch (const std::system_error& e)
124 {
125 EXPECT_EQ(std::string_view(error),
126 std::string_view(e.what(), strlen(error)));
127 EXPECT_EQ(EBADF, e.code().value());
128 }
129}
130
131TEST(Cexec, CallCheckErrnoPtr)
132{
133 constexpr auto sample = "sample";
134 EXPECT_EQ(sample, callCheckErrno("sample1", ptr, sample));
135
136 constexpr auto error = "sample error";
137 try
138 {
139 errno = EBADF;
140 callCheckErrno(error, &ptr, nullptr);
141 EXPECT_TRUE(false);
142 }
143 catch (const std::system_error& e)
144 {
145 EXPECT_EQ(std::string_view(error),
146 std::string_view(e.what(), strlen(error)));
147 EXPECT_EQ(EBADF, e.code().value());
148 }
149}
150
151TEST(Cexec, CallCheckErrnoPtrMem)
152{
153 sample s;
154 EXPECT_EQ(&s.count, callCheckErrno("sample1", &sample::ptr, &s));
155
156 constexpr auto error = "sample error";
157 try
158 {
159 errno = EBADF;
160 callCheckErrno(error, &sample::ptr2, s);
161 EXPECT_TRUE(false);
162 }
163 catch (const std::system_error& e)
164 {
165 EXPECT_EQ(std::string_view(error),
166 std::string_view(e.what(), strlen(error)));
167 EXPECT_EQ(EBADF, e.code().value());
168 }
169}
170
171TEST(Cexec, CallCheckErrnoErrorFunc)
172{
173 errno = EBADF;
174 try
175 {
176 callCheckErrno<makeTrivialError>("sample2", sample2, -1);
177 EXPECT_TRUE(false);
178 }
179 catch (int error)
180 {
181 EXPECT_EQ(errno, error);
182 }
William A. Kennington III80c988f2020-08-02 02:54:22 -0700183
184 try
185 {
186 errno = EBADF;
187 CHECK_ERRNO(sample2(-1), [](int r) { throw r; });
188 EXPECT_TRUE(false);
189 }
190 catch (int i)
191 {
192 EXPECT_EQ(EBADF, i);
193 }
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -0800194}
195
196TEST(Cexec, CallCheckRetInt)
197{
198 EXPECT_EQ(1, callCheckRet("sample1", sample1));
William A. Kennington III80c988f2020-08-02 02:54:22 -0700199 EXPECT_EQ(1, CHECK_RET(sample1(), "sample1"));
William A. Kennington III1f1681e2020-06-10 02:28:01 -0700200 EXPECT_EQ(2, callCheckRet(std::string("sample2"), &sample2, 2));
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -0800201 EXPECT_EQ(4, callCheckRet("sample::s", sample::s, 4));
202 ssize_t v = 10;
203 EXPECT_EQ(12, callCheckRet("sample3", sample3, 2, &v));
204
205 constexpr auto error = "sample2 error";
206 try
207 {
208 errno = EBADF;
209 callCheckRet(error, sample2, -EINTR);
210 EXPECT_TRUE(false);
211 }
212 catch (const std::system_error& e)
213 {
214 EXPECT_EQ(std::string_view(error),
215 std::string_view(e.what(), strlen(error)));
216 EXPECT_EQ(EINTR, e.code().value());
217 }
William A. Kennington III80c988f2020-08-02 02:54:22 -0700218
219 try
220 {
221 errno = EBADF;
222 CHECK_RET(sample2(-EINTR), error);
223 EXPECT_TRUE(false);
224 }
225 catch (const std::system_error& e)
226 {
227 EXPECT_EQ(std::string_view(error),
228 std::string_view(e.what(), strlen(error)));
229 EXPECT_EQ(EINTR, e.code().value());
230 }
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -0800231}
232
233TEST(Cexec, CallCheckRetIntMem)
234{
235 sample s;
236 const sample* sp = &s;
237 EXPECT_EQ(3, callCheckRet("sample::one", &sample::one, s));
238 EXPECT_EQ(4, callCheckRet("sample::one", &sample::one, &s));
239 EXPECT_EQ(5, callCheckRet("sample::two", &sample::two, sp, 5));
240
241 constexpr auto error = "sample error";
242 try
243 {
244 errno = EBADF;
245 callCheckRet(error, &sample::two, s, -EINTR);
246 EXPECT_TRUE(false);
247 }
248 catch (const std::system_error& e)
249 {
250 EXPECT_EQ(std::string_view(error),
251 std::string_view(e.what(), strlen(error)));
252 EXPECT_EQ(EINTR, e.code().value());
253 }
254}
255
256TEST(Cexec, CallCheckRetErrorFunc)
257{
258 try
259 {
260 callCheckRet<makeTrivialError>("sample2", sample2, -EBADF);
261 EXPECT_TRUE(false);
262 }
263 catch (int error)
264 {
265 EXPECT_EQ(EBADF, error);
266 }
267}
268
269} // namespace
270} // namespace util
271} // namespace stdplus