1 // Copyright 2012 Google Inc.
2 // All rights reserved.
3 //
4 // Redistribution and use in source and binary forms, with or without
5 // modification, are permitted provided that the following conditions are
6 // met:
7 //
8 // * Redistributions of source code must retain the above copyright
9 //   notice, this list of conditions and the following disclaimer.
10 // * Redistributions in binary form must reproduce the above copyright
11 //   notice, this list of conditions and the following disclaimer in the
12 //   documentation and/or other materials provided with the distribution.
13 // * Neither the name of Google Inc. nor the names of its contributors
14 //   may be used to endorse or promote products derived from this software
15 //   without specific prior written permission.
16 //
17 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #include "error.h"
30 
31 #include <errno.h>
32 #include <stdint.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
36 
37 #include <atf-c.h>
38 
39 
40 ATF_TC_WITHOUT_HEAD(error_new__oom);
41 ATF_TC_BODY(error_new__oom, tc)
42 {
43     void* invalid = (void*)1;
44     kyua_error_t error = kyua_error_new("test_error", invalid, SIZE_MAX, NULL);
45     ATF_REQUIRE(kyua_error_is_type(error, kyua_oom_error_type));
46     ATF_REQUIRE(kyua_error_data(error) == NULL);
47     kyua_error_free(error);
48 }
49 
50 
51 ATF_TC_WITHOUT_HEAD(error_subsume__none);
52 ATF_TC_BODY(error_subsume__none, tc)
53 {
54     kyua_error_t primary = kyua_error_ok();
55     kyua_error_t secondary = kyua_error_ok();
56     ATF_REQUIRE(!kyua_error_is_set(kyua_error_subsume(primary, secondary)));
57 }
58 
59 
60 ATF_TC_WITHOUT_HEAD(error_subsume__primary);
61 ATF_TC_BODY(error_subsume__primary, tc)
62 {
63     kyua_error_t primary = kyua_error_new("primary_error", NULL, 0, NULL);
64     kyua_error_t secondary = kyua_error_new("secondary_error", NULL, 0, NULL);
65     kyua_error_t error = kyua_error_subsume(primary, secondary);
66     ATF_REQUIRE(kyua_error_is_type(error, "primary_error"));
67     kyua_error_free(error);
68 }
69 
70 
71 ATF_TC_WITHOUT_HEAD(error_subsume__secondary);
72 ATF_TC_BODY(error_subsume__secondary, tc)
73 {
74     kyua_error_t primary = kyua_error_ok();
75     kyua_error_t secondary = kyua_error_new("secondary_error", NULL, 0, NULL);
76     kyua_error_t error = kyua_error_subsume(primary, secondary);
77     ATF_REQUIRE(kyua_error_is_type(error, "secondary_error"));
78     kyua_error_free(error);
79 }
80 
81 
82 ATF_TC_WITHOUT_HEAD(error_is_type__match);
83 ATF_TC_BODY(error_is_type__match, tc)
84 {
85     kyua_error_t error = kyua_error_new("test_error", NULL, 0, NULL);
86     ATF_REQUIRE(kyua_error_is_type(error, "test_error"));
87     kyua_error_free(error);
88 }
89 
90 
91 ATF_TC_WITHOUT_HEAD(error_is_type__not_match);
92 ATF_TC_BODY(error_is_type__not_match, tc)
93 {
94     kyua_error_t error = kyua_error_new("test_error", NULL, 0, NULL);
95     ATF_REQUIRE(!kyua_error_is_type(error, "test_erro"));
96     ATF_REQUIRE(!kyua_error_is_type(error, "test_error2"));
97     ATF_REQUIRE(!kyua_error_is_type(error, "foo"));
98     kyua_error_free(error);
99 }
100 
101 
102 ATF_TC_WITHOUT_HEAD(error_data__none);
103 ATF_TC_BODY(error_data__none, tc)
104 {
105     kyua_error_t error = kyua_error_new("test_error", NULL, 0, NULL);
106     ATF_REQUIRE(kyua_error_data(error) == NULL);
107     kyua_error_free(error);
108 }
109 
110 
111 ATF_TC_WITHOUT_HEAD(error_data__some);
112 ATF_TC_BODY(error_data__some, tc)
113 {
114     int data = 5;
115     kyua_error_t error = kyua_error_new("test_data_error", &data, sizeof(data),
116                                         NULL);
117     ATF_REQUIRE(kyua_error_data(error) != NULL);
118     ATF_REQUIRE_EQ(*((const int*)kyua_error_data(error)), 5);
119     kyua_error_free(error);
120 }
121 
122 
123 ATF_TC_WITHOUT_HEAD(error_is_set__no);
124 ATF_TC_BODY(error_is_set__no, tc)
125 {
126     kyua_error_t error = kyua_error_ok();
127     ATF_REQUIRE(!kyua_error_is_set(error));
128 }
129 
130 
131 ATF_TC_WITHOUT_HEAD(error_is_set__yes);
132 ATF_TC_BODY(error_is_set__yes, tc)
133 {
134     kyua_error_t error = kyua_error_new("test_error", NULL, 0, NULL);
135     ATF_REQUIRE(kyua_error_is_set(error));
136     kyua_error_free(error);
137 }
138 
139 
140 ATF_TC_WITHOUT_HEAD(error_format__default);
141 ATF_TC_BODY(error_format__default, tc)
142 {
143     kyua_error_t error = kyua_error_new("test_error", NULL, 0, NULL);
144     char buffer[1024];
145     kyua_error_format(error, buffer, sizeof(buffer));
146     ATF_REQUIRE_STREQ("Error 'test_error'", buffer);
147     kyua_error_free(error);
148 }
149 
150 
151 /// Error-specific formatting function for testing purposes.
152 static int
153 test_format(const kyua_error_t error, char* const output_buffer,
154             const size_t output_size)
155 {
156     ATF_REQUIRE(kyua_error_is_type(error, "test_error"));
157     return snprintf(output_buffer, output_size, "Test formatting function");
158 }
159 
160 
161 ATF_TC_WITHOUT_HEAD(error_format__custom__ok);
162 ATF_TC_BODY(error_format__custom__ok, tc)
163 {
164     kyua_error_t error = kyua_error_new("test_error", NULL, 0, test_format);
165     const char* exp_message = "Test formatting function";
166     char buffer[1024];
167     ATF_REQUIRE_EQ((int)strlen(exp_message),
168                    kyua_error_format(error, buffer, sizeof(buffer)));
169     ATF_REQUIRE_STREQ(exp_message, buffer);
170     kyua_error_free(error);
171 }
172 
173 
174 ATF_TC_WITHOUT_HEAD(error_format__custom__error);
175 ATF_TC_BODY(error_format__custom__error, tc)
176 {
177     kyua_error_t error = kyua_error_new("test_error", NULL, 0, test_format);
178     char buffer[5];
179     ATF_REQUIRE(kyua_error_format(error, buffer, sizeof(buffer))
180                 >= (int)sizeof(buffer));
181     kyua_error_free(error);
182 }
183 
184 
185 ATF_TC_WITHOUT_HEAD(err);
186 ATF_TC_BODY(err, tc)
187 {
188     const pid_t pid = atf_utils_fork();
189     if (pid == 0) {
190         kyua_error_t error = kyua_usage_error_new("A usage error");
191         kyua_error_err(15, error, "The %s message", "1st");
192     }
193     atf_utils_wait(pid, 15, "", "error_test: The 1st message: A usage error\n");
194 }
195 
196 
197 ATF_TC_WITHOUT_HEAD(fprintf);
198 ATF_TC_BODY(fprintf, tc)
199 {
200     FILE* output = fopen("output", "w");
201     const kyua_error_t error = kyua_usage_error_new("A usage error");
202     kyua_error_fprintf(output, error, "The %s message", "1st");
203     kyua_error_free(error);
204     fclose(output);
205 
206     ATF_REQUIRE(atf_utils_grep_file("The 1st message: A usage error",
207                                     "output"));
208 }
209 
210 
211 ATF_TC_WITHOUT_HEAD(warn);
212 ATF_TC_BODY(warn, tc)
213 {
214     const pid_t pid = atf_utils_fork();
215     if (pid == 0) {
216         kyua_error_t error = kyua_usage_error_new("A usage error");
217         kyua_error_warn(error, "The %s message", "1st");
218         kyua_error_free(error);
219         exit(51);
220     }
221     atf_utils_wait(pid, 51, "", "error_test: The 1st message: A usage error\n");
222 }
223 
224 
225 ATF_TC_WITHOUT_HEAD(generic_error_type);
226 ATF_TC_BODY(generic_error_type, tc)
227 {
228     kyua_error_t error = kyua_generic_error_new("Nothing");
229     ATF_REQUIRE(kyua_error_is_type(error, kyua_generic_error_type));
230     kyua_error_free(error);
231 }
232 
233 
234 ATF_TC_WITHOUT_HEAD(generic_error_format__plain);
235 ATF_TC_BODY(generic_error_format__plain, tc)
236 {
237     kyua_error_t error = kyua_generic_error_new("Test message");
238     char buffer[1024];
239     kyua_error_format(error, buffer, sizeof(buffer));
240     ATF_REQUIRE_STREQ("Test message", buffer);
241     kyua_error_free(error);
242 }
243 
244 
245 ATF_TC_WITHOUT_HEAD(generic_error_format__args);
246 ATF_TC_BODY(generic_error_format__args, tc)
247 {
248     kyua_error_t error = kyua_generic_error_new("%s message %d", "A", 123);
249     char buffer[1024];
250     kyua_error_format(error, buffer, sizeof(buffer));
251     ATF_REQUIRE_STREQ("A message 123", buffer);
252     kyua_error_free(error);
253 }
254 
255 
256 ATF_TC_WITHOUT_HEAD(libc_error_type);
257 ATF_TC_BODY(libc_error_type, tc)
258 {
259     kyua_error_t error = kyua_libc_error_new(ENOMEM, "Nothing");
260     ATF_REQUIRE(kyua_error_is_type(error, kyua_libc_error_type));
261     kyua_error_free(error);
262 }
263 
264 
265 ATF_TC_WITHOUT_HEAD(libc_error_errno);
266 ATF_TC_BODY(libc_error_errno, tc)
267 {
268     kyua_error_t error = kyua_libc_error_new(EPERM, "Doesn't matter");
269     ATF_REQUIRE_EQ(EPERM, kyua_libc_error_errno(error));
270     kyua_error_free(error);
271 }
272 
273 
274 ATF_TC_WITHOUT_HEAD(libc_error_format__plain);
275 ATF_TC_BODY(libc_error_format__plain, tc)
276 {
277     kyua_error_t error = kyua_libc_error_new(ENOMEM, "Test message");
278     char buffer[1024];
279     kyua_error_format(error, buffer, sizeof(buffer));
280     ATF_REQUIRE(strstr(buffer, strerror(ENOMEM)) != NULL);
281     ATF_REQUIRE(strstr(buffer, "Test message") != NULL);
282     kyua_error_free(error);
283 }
284 
285 
286 ATF_TC_WITHOUT_HEAD(libc_error_format__args);
287 ATF_TC_BODY(libc_error_format__args, tc)
288 {
289     kyua_error_t error = kyua_libc_error_new(EPERM, "%s message %d", "A", 123);
290     char buffer[1024];
291     kyua_error_format(error, buffer, sizeof(buffer));
292     ATF_REQUIRE(strstr(buffer, strerror(EPERM)) != NULL);
293     ATF_REQUIRE(strstr(buffer, "A message 123") != NULL);
294     kyua_error_free(error);
295 }
296 
297 
298 ATF_TC_WITHOUT_HEAD(oom_error_type);
299 ATF_TC_BODY(oom_error_type, tc)
300 {
301     kyua_error_t error = kyua_oom_error_new();
302     ATF_REQUIRE(kyua_error_is_type(error, kyua_oom_error_type));
303     kyua_error_free(error);
304 }
305 
306 
307 ATF_TC_WITHOUT_HEAD(oom_error_data);
308 ATF_TC_BODY(oom_error_data, tc)
309 {
310     kyua_error_t error = kyua_oom_error_new();
311     ATF_REQUIRE(kyua_error_data(error) == NULL);
312     kyua_error_free(error);
313 }
314 
315 
316 ATF_TC_WITHOUT_HEAD(oom_error_format);
317 ATF_TC_BODY(oom_error_format, tc)
318 {
319     kyua_error_t error = kyua_oom_error_new();
320     char buffer[1024];
321     kyua_error_format(error, buffer, sizeof(buffer));
322     ATF_REQUIRE_STREQ("Not enough memory", buffer);
323     kyua_error_free(error);
324 }
325 
326 
327 ATF_TC_WITHOUT_HEAD(oom_error_reuse);
328 ATF_TC_BODY(oom_error_reuse, tc)
329 {
330     {
331         kyua_error_t error = kyua_oom_error_new();
332         ATF_REQUIRE(kyua_error_is_type(error, kyua_oom_error_type));
333         ATF_REQUIRE(kyua_error_data(error) == NULL);
334         kyua_error_free(error);
335     }
336 
337     {
338         kyua_error_t error = kyua_oom_error_new();
339         ATF_REQUIRE(kyua_error_is_type(error, kyua_oom_error_type));
340         ATF_REQUIRE(kyua_error_data(error) == NULL);
341         kyua_error_free(error);
342     }
343 }
344 
345 
346 ATF_TC_WITHOUT_HEAD(usage_error_type);
347 ATF_TC_BODY(usage_error_type, tc)
348 {
349     kyua_error_t error = kyua_usage_error_new("Nothing");
350     ATF_REQUIRE(kyua_error_is_type(error, kyua_usage_error_type));
351     kyua_error_free(error);
352 }
353 
354 
355 ATF_TC_WITHOUT_HEAD(usage_error_format__plain);
356 ATF_TC_BODY(usage_error_format__plain, tc)
357 {
358     kyua_error_t error = kyua_usage_error_new("Test message");
359     char buffer[1024];
360     kyua_error_format(error, buffer, sizeof(buffer));
361     ATF_REQUIRE_STREQ("Test message", buffer);
362     kyua_error_free(error);
363 }
364 
365 
366 ATF_TC_WITHOUT_HEAD(usage_error_format__args);
367 ATF_TC_BODY(usage_error_format__args, tc)
368 {
369     kyua_error_t error = kyua_usage_error_new("%s message %d", "A", 123);
370     char buffer[1024];
371     kyua_error_format(error, buffer, sizeof(buffer));
372     ATF_REQUIRE_STREQ("A message 123", buffer);
373     kyua_error_free(error);
374 }
375 
376 
377 ATF_TP_ADD_TCS(tp)
378 {
379     ATF_TP_ADD_TC(tp, error_new__oom);
380     ATF_TP_ADD_TC(tp, error_subsume__none);
381     ATF_TP_ADD_TC(tp, error_subsume__primary);
382     ATF_TP_ADD_TC(tp, error_subsume__secondary);
383     ATF_TP_ADD_TC(tp, error_is_type__match);
384     ATF_TP_ADD_TC(tp, error_is_type__not_match);
385     ATF_TP_ADD_TC(tp, error_data__none);
386     ATF_TP_ADD_TC(tp, error_data__some);
387     ATF_TP_ADD_TC(tp, error_is_set__no);
388     ATF_TP_ADD_TC(tp, error_is_set__yes);
389     ATF_TP_ADD_TC(tp, error_format__default);
390     ATF_TP_ADD_TC(tp, error_format__custom__ok);
391     ATF_TP_ADD_TC(tp, error_format__custom__error);
392 
393     ATF_TP_ADD_TC(tp, err);
394     ATF_TP_ADD_TC(tp, fprintf);
395     ATF_TP_ADD_TC(tp, warn);
396 
397     ATF_TP_ADD_TC(tp, generic_error_type);
398     ATF_TP_ADD_TC(tp, generic_error_format__plain);
399     ATF_TP_ADD_TC(tp, generic_error_format__args);
400 
401     ATF_TP_ADD_TC(tp, libc_error_type);
402     ATF_TP_ADD_TC(tp, libc_error_errno);
403     ATF_TP_ADD_TC(tp, libc_error_format__plain);
404     ATF_TP_ADD_TC(tp, libc_error_format__args);
405 
406     ATF_TP_ADD_TC(tp, oom_error_type);
407     ATF_TP_ADD_TC(tp, oom_error_data);
408     ATF_TP_ADD_TC(tp, oom_error_format);
409     ATF_TP_ADD_TC(tp, oom_error_reuse);
410 
411     ATF_TP_ADD_TC(tp, usage_error_type);
412     ATF_TP_ADD_TC(tp, usage_error_format__plain);
413     ATF_TP_ADD_TC(tp, usage_error_format__args);
414 
415     return atf_no_error();
416 }
417