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