blob: c41c2d43709eb6f5188800d4afb880edba035f70 [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{
71 EXPECT_EQ(1, callCheckErrno("sample1", sample1));
William A. Kennington III1f1681e2020-06-10 02:28:01 -070072 EXPECT_EQ(2, callCheckErrno(std::string("sample2"), &sample2, 2));
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -080073 EXPECT_EQ(4, callCheckErrno("sample::s", sample::s, 4));
74 ssize_t v = 10;
75 EXPECT_EQ(12, callCheckErrno("sample3", sample3, 2, &v));
76
77 constexpr auto error = "sample2 error";
78 try
79 {
80 errno = EBADF;
81 callCheckErrno(error, sample2, -1);
82 EXPECT_TRUE(false);
83 }
84 catch (const std::system_error& e)
85 {
86 EXPECT_EQ(std::string_view(error),
87 std::string_view(e.what(), strlen(error)));
88 EXPECT_EQ(EBADF, e.code().value());
89 }
90}
91
92TEST(Cexec, CallCheckErrnoIntMem)
93{
94 sample s;
95 const sample* sp = &s;
96 EXPECT_EQ(3, callCheckErrno("sample::one", &sample::one, s));
97 EXPECT_EQ(4, callCheckErrno("sample::one", &sample::one, &s));
98 EXPECT_EQ(5, callCheckErrno("sample::two", &sample::two, sp, 5));
99
100 constexpr auto error = "sample error";
101 try
102 {
103 errno = EBADF;
104 callCheckErrno(error, &sample::two, sp, -1);
105 EXPECT_TRUE(false);
106 }
107 catch (const std::system_error& e)
108 {
109 EXPECT_EQ(std::string_view(error),
110 std::string_view(e.what(), strlen(error)));
111 EXPECT_EQ(EBADF, e.code().value());
112 }
113}
114
115TEST(Cexec, CallCheckErrnoPtr)
116{
117 constexpr auto sample = "sample";
118 EXPECT_EQ(sample, callCheckErrno("sample1", ptr, sample));
119
120 constexpr auto error = "sample error";
121 try
122 {
123 errno = EBADF;
124 callCheckErrno(error, &ptr, nullptr);
125 EXPECT_TRUE(false);
126 }
127 catch (const std::system_error& e)
128 {
129 EXPECT_EQ(std::string_view(error),
130 std::string_view(e.what(), strlen(error)));
131 EXPECT_EQ(EBADF, e.code().value());
132 }
133}
134
135TEST(Cexec, CallCheckErrnoPtrMem)
136{
137 sample s;
138 EXPECT_EQ(&s.count, callCheckErrno("sample1", &sample::ptr, &s));
139
140 constexpr auto error = "sample error";
141 try
142 {
143 errno = EBADF;
144 callCheckErrno(error, &sample::ptr2, s);
145 EXPECT_TRUE(false);
146 }
147 catch (const std::system_error& e)
148 {
149 EXPECT_EQ(std::string_view(error),
150 std::string_view(e.what(), strlen(error)));
151 EXPECT_EQ(EBADF, e.code().value());
152 }
153}
154
155TEST(Cexec, CallCheckErrnoErrorFunc)
156{
157 errno = EBADF;
158 try
159 {
160 callCheckErrno<makeTrivialError>("sample2", sample2, -1);
161 EXPECT_TRUE(false);
162 }
163 catch (int error)
164 {
165 EXPECT_EQ(errno, error);
166 }
167}
168
169TEST(Cexec, CallCheckRetInt)
170{
171 EXPECT_EQ(1, callCheckRet("sample1", sample1));
William A. Kennington III1f1681e2020-06-10 02:28:01 -0700172 EXPECT_EQ(2, callCheckRet(std::string("sample2"), &sample2, 2));
William A. Kennington IIIbff0b0f2018-11-16 19:56:10 -0800173 EXPECT_EQ(4, callCheckRet("sample::s", sample::s, 4));
174 ssize_t v = 10;
175 EXPECT_EQ(12, callCheckRet("sample3", sample3, 2, &v));
176
177 constexpr auto error = "sample2 error";
178 try
179 {
180 errno = EBADF;
181 callCheckRet(error, sample2, -EINTR);
182 EXPECT_TRUE(false);
183 }
184 catch (const std::system_error& e)
185 {
186 EXPECT_EQ(std::string_view(error),
187 std::string_view(e.what(), strlen(error)));
188 EXPECT_EQ(EINTR, e.code().value());
189 }
190}
191
192TEST(Cexec, CallCheckRetIntMem)
193{
194 sample s;
195 const sample* sp = &s;
196 EXPECT_EQ(3, callCheckRet("sample::one", &sample::one, s));
197 EXPECT_EQ(4, callCheckRet("sample::one", &sample::one, &s));
198 EXPECT_EQ(5, callCheckRet("sample::two", &sample::two, sp, 5));
199
200 constexpr auto error = "sample error";
201 try
202 {
203 errno = EBADF;
204 callCheckRet(error, &sample::two, s, -EINTR);
205 EXPECT_TRUE(false);
206 }
207 catch (const std::system_error& e)
208 {
209 EXPECT_EQ(std::string_view(error),
210 std::string_view(e.what(), strlen(error)));
211 EXPECT_EQ(EINTR, e.code().value());
212 }
213}
214
215TEST(Cexec, CallCheckRetErrorFunc)
216{
217 try
218 {
219 callCheckRet<makeTrivialError>("sample2", sample2, -EBADF);
220 EXPECT_TRUE(false);
221 }
222 catch (int error)
223 {
224 EXPECT_EQ(EBADF, error);
225 }
226}
227
228} // namespace
229} // namespace util
230} // namespace stdplus