1*754f425fSjmmv // Copyright 2012 Google Inc.
2*754f425fSjmmv // All rights reserved.
3*754f425fSjmmv //
4*754f425fSjmmv // Redistribution and use in source and binary forms, with or without
5*754f425fSjmmv // modification, are permitted provided that the following conditions are
6*754f425fSjmmv // met:
7*754f425fSjmmv //
8*754f425fSjmmv // * Redistributions of source code must retain the above copyright
9*754f425fSjmmv // notice, this list of conditions and the following disclaimer.
10*754f425fSjmmv // * Redistributions in binary form must reproduce the above copyright
11*754f425fSjmmv // notice, this list of conditions and the following disclaimer in the
12*754f425fSjmmv // documentation and/or other materials provided with the distribution.
13*754f425fSjmmv // * Neither the name of Google Inc. nor the names of its contributors
14*754f425fSjmmv // may be used to endorse or promote products derived from this software
15*754f425fSjmmv // without specific prior written permission.
16*754f425fSjmmv //
17*754f425fSjmmv // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18*754f425fSjmmv // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19*754f425fSjmmv // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20*754f425fSjmmv // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21*754f425fSjmmv // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22*754f425fSjmmv // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23*754f425fSjmmv // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24*754f425fSjmmv // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25*754f425fSjmmv // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26*754f425fSjmmv // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27*754f425fSjmmv // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28*754f425fSjmmv
29*754f425fSjmmv #include "atf_result.h"
30*754f425fSjmmv
31*754f425fSjmmv #include <sys/resource.h>
32*754f425fSjmmv #include <sys/wait.h>
33*754f425fSjmmv
34*754f425fSjmmv #include <signal.h>
35*754f425fSjmmv #include <stdlib.h>
36*754f425fSjmmv #include <unistd.h>
37*754f425fSjmmv
38*754f425fSjmmv #include <atf-c.h>
39*754f425fSjmmv
40*754f425fSjmmv #include "error.h"
41*754f425fSjmmv
42*754f425fSjmmv
43*754f425fSjmmv /// Evalutes an expression and ensures it does not return an error.
44*754f425fSjmmv ///
45*754f425fSjmmv /// \param expr A expression that must evaluate to kyua_error_t.
46*754f425fSjmmv #define RE(expr) ATF_REQUIRE(!kyua_error_is_set(expr))
47*754f425fSjmmv
48*754f425fSjmmv
49*754f425fSjmmv /// Generates a wait(2) status for a successful exit code.
50*754f425fSjmmv ///
51*754f425fSjmmv /// \param exitstatus The exit status to encode in the status.
52*754f425fSjmmv ///
53*754f425fSjmmv /// \return The wait(2) status.
54*754f425fSjmmv static int
generate_wait_exitstatus(const int exitstatus)55*754f425fSjmmv generate_wait_exitstatus(const int exitstatus)
56*754f425fSjmmv {
57*754f425fSjmmv const pid_t pid = fork();
58*754f425fSjmmv ATF_REQUIRE(pid != -1);
59*754f425fSjmmv if (pid == 0) {
60*754f425fSjmmv exit(exitstatus);
61*754f425fSjmmv } else {
62*754f425fSjmmv int status;
63*754f425fSjmmv ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
64*754f425fSjmmv return status;
65*754f425fSjmmv }
66*754f425fSjmmv }
67*754f425fSjmmv
68*754f425fSjmmv
69*754f425fSjmmv /// Generates a wait(2) status for a termination due to a signal.
70*754f425fSjmmv ///
71*754f425fSjmmv /// \param signo The signal number to encode in the status.
72*754f425fSjmmv ///
73*754f425fSjmmv /// \return The wait(2) status.
74*754f425fSjmmv static int
generate_wait_termsig(const int signo)75*754f425fSjmmv generate_wait_termsig(const int signo)
76*754f425fSjmmv {
77*754f425fSjmmv // Explicitly disable core files to avoid inconsistent behaviors across
78*754f425fSjmmv // operating systems. Some of the signal numbers passed to this function
79*754f425fSjmmv // may have a meaning or not depending on the system, and this might mean
80*754f425fSjmmv // that a core gets generated arbitrarily. As a result of this, our string
81*754f425fSjmmv // comparisons below fail.
82*754f425fSjmmv struct rlimit rl;
83*754f425fSjmmv rl.rlim_cur = 0;
84*754f425fSjmmv rl.rlim_max = RLIM_INFINITY;
85*754f425fSjmmv if (setrlimit(RLIMIT_CORE, &rl) == -1)
86*754f425fSjmmv atf_tc_skip("Failed to lower the core size limit");
87*754f425fSjmmv
88*754f425fSjmmv const pid_t pid = fork();
89*754f425fSjmmv ATF_REQUIRE(pid != -1);
90*754f425fSjmmv if (pid == 0) {
91*754f425fSjmmv kill(getpid(), signo);
92*754f425fSjmmv abort();
93*754f425fSjmmv } else {
94*754f425fSjmmv int status;
95*754f425fSjmmv ATF_REQUIRE(waitpid(pid, &status, 0) != -1);
96*754f425fSjmmv return status;
97*754f425fSjmmv }
98*754f425fSjmmv }
99*754f425fSjmmv
100*754f425fSjmmv
101*754f425fSjmmv /// Validates an execution of kyua_atf_result_rewrite().
102*754f425fSjmmv ///
103*754f425fSjmmv /// The code of this check is all within the macro instead of in a separate
104*754f425fSjmmv /// function so that we get meaningful line numbers in test failure messages.
105*754f425fSjmmv ///
106*754f425fSjmmv /// \param name Name of the test case.
107*754f425fSjmmv /// \param input Text of the ATF result.
108*754f425fSjmmv /// \param wait_status Exit status of the ATF test case, as returned by wait(2).
109*754f425fSjmmv /// \param timed_out Whether the test case timed out or not.
110*754f425fSjmmv /// \param exp_output Text of the expected generic result.
111*754f425fSjmmv /// \param exp_success Expected value of the success result.
112*754f425fSjmmv #define CHECK(name, input, wait_status, timed_out, exp_output, exp_success) \
113*754f425fSjmmv ATF_TC_WITHOUT_HEAD(name); \
114*754f425fSjmmv ATF_TC_BODY(name, tc) \
115*754f425fSjmmv { \
116*754f425fSjmmv bool success; \
117*754f425fSjmmv atf_utils_create_file("in.txt", "%s", input); \
118*754f425fSjmmv RE(kyua_atf_result_rewrite("in.txt", "out.txt", wait_status, \
119*754f425fSjmmv timed_out, &success)); \
120*754f425fSjmmv atf_utils_cat_file("out.txt", "OUTPUT: "); \
121*754f425fSjmmv ATF_REQUIRE(atf_utils_compare_file("out.txt", exp_output)); \
122*754f425fSjmmv ATF_REQUIRE_EQ(exp_success, success); \
123*754f425fSjmmv }
124*754f425fSjmmv
125*754f425fSjmmv
126*754f425fSjmmv CHECK(rewrite__expected_death__exit_failure,
127*754f425fSjmmv "expected_death: Some text\n",
128*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
129*754f425fSjmmv "expected_failure: Some text\n",
130*754f425fSjmmv true);
131*754f425fSjmmv CHECK(rewrite__expected_death__signaled,
132*754f425fSjmmv "expected_death: Foo bar\n",
133*754f425fSjmmv generate_wait_termsig(1), false,
134*754f425fSjmmv "expected_failure: Foo bar\n",
135*754f425fSjmmv true);
136*754f425fSjmmv CHECK(rewrite__expected_death__exit_success,
137*754f425fSjmmv "expected_death: Some text\n",
138*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
139*754f425fSjmmv "failed: Test case expected to die but exited successfully\n",
140*754f425fSjmmv false);
141*754f425fSjmmv CHECK(rewrite__expected_death__no_reason,
142*754f425fSjmmv "expected_death\n",
143*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
144*754f425fSjmmv "broken: Test case should have reported a failure reason but didn't; "
145*754f425fSjmmv "test case exited with code 1\n",
146*754f425fSjmmv false);
147*754f425fSjmmv CHECK(rewrite__expected_death__unexpected_arg,
148*754f425fSjmmv "expected_death(23): Some text\n",
149*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
150*754f425fSjmmv "broken: Unknown test case result status expected_death(23); "
151*754f425fSjmmv "test case exited with code 1\n",
152*754f425fSjmmv false);
153*754f425fSjmmv
154*754f425fSjmmv
155*754f425fSjmmv CHECK(rewrite__expected_exit__exit_success,
156*754f425fSjmmv "expected_exit: Some text\n",
157*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
158*754f425fSjmmv "expected_failure: Some text\n",
159*754f425fSjmmv true);
160*754f425fSjmmv CHECK(rewrite__expected_exit__exit_failure,
161*754f425fSjmmv "expected_exit: Some other text\n",
162*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
163*754f425fSjmmv "expected_failure: Some other text\n",
164*754f425fSjmmv true);
165*754f425fSjmmv CHECK(rewrite__expected_exit__arg_match,
166*754f425fSjmmv "expected_exit(15): Some text\n",
167*754f425fSjmmv generate_wait_exitstatus(15), false,
168*754f425fSjmmv "expected_failure: Some text\n",
169*754f425fSjmmv true);
170*754f425fSjmmv CHECK(rewrite__expected_exit__arg_not_match,
171*754f425fSjmmv "expected_exit(18): Some text\n",
172*754f425fSjmmv generate_wait_exitstatus(15), false,
173*754f425fSjmmv "failed: Test case expected to exit with code 18 but got code 15\n",
174*754f425fSjmmv false);
175*754f425fSjmmv CHECK(rewrite__expected_exit__signaled,
176*754f425fSjmmv "expected_exit: Foo bar\n",
177*754f425fSjmmv generate_wait_termsig(1), false,
178*754f425fSjmmv "failed: Test case expected to exit normally but received signal 1\n",
179*754f425fSjmmv false);
180*754f425fSjmmv CHECK(rewrite__expected_exit__no_reason,
181*754f425fSjmmv "expected_exit\n",
182*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
183*754f425fSjmmv "broken: Test case should have reported a failure reason but didn't; "
184*754f425fSjmmv "test case exited with code 1\n",
185*754f425fSjmmv false);
186*754f425fSjmmv CHECK(rewrite__expected_exit__bad_arg,
187*754f425fSjmmv "expected_exit(abc): Some text\n",
188*754f425fSjmmv generate_wait_exitstatus(25), false,
189*754f425fSjmmv "broken: Invalid status argument (abc): not a number; test case exited "
190*754f425fSjmmv "with code 25\n",
191*754f425fSjmmv false);
192*754f425fSjmmv
193*754f425fSjmmv
194*754f425fSjmmv CHECK(rewrite__expected_failure__ok,
195*754f425fSjmmv "expected_failure: Some text\n",
196*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
197*754f425fSjmmv "expected_failure: Some text\n",
198*754f425fSjmmv true);
199*754f425fSjmmv CHECK(rewrite__expected_failure__failed,
200*754f425fSjmmv "expected_failure: Some text\n",
201*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
202*754f425fSjmmv "failed: Test case expected a failure but exited with error code 1\n",
203*754f425fSjmmv false);
204*754f425fSjmmv CHECK(rewrite__expected_failure__signaled,
205*754f425fSjmmv "expected_failure: Foo bar\n",
206*754f425fSjmmv generate_wait_termsig(1), false,
207*754f425fSjmmv "failed: Test case expected a failure but received signal 1\n",
208*754f425fSjmmv false);
209*754f425fSjmmv CHECK(rewrite__expected_failure__no_reason,
210*754f425fSjmmv "expected_failure\n",
211*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
212*754f425fSjmmv "broken: Test case should have reported a failure reason but didn't; "
213*754f425fSjmmv "test case exited with code 1\n",
214*754f425fSjmmv false);
215*754f425fSjmmv CHECK(rewrite__expected_failure__unexpected_arg,
216*754f425fSjmmv "expected_failure(23): Some text\n",
217*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
218*754f425fSjmmv "broken: Unknown test case result status expected_failure(23); "
219*754f425fSjmmv "test case exited with code 1\n",
220*754f425fSjmmv false);
221*754f425fSjmmv
222*754f425fSjmmv
223*754f425fSjmmv CHECK(rewrite__expected_signal__ok,
224*754f425fSjmmv "expected_signal: Some text\n",
225*754f425fSjmmv generate_wait_termsig(6), false,
226*754f425fSjmmv "expected_failure: Some text\n",
227*754f425fSjmmv true);
228*754f425fSjmmv CHECK(rewrite__expected_signal__arg_match,
229*754f425fSjmmv "expected_signal(15): Some text\n",
230*754f425fSjmmv generate_wait_termsig(15), false,
231*754f425fSjmmv "expected_failure: Some text\n",
232*754f425fSjmmv true);
233*754f425fSjmmv CHECK(rewrite__expected_signal__arg_not_match,
234*754f425fSjmmv "expected_signal(18): Some text\n",
235*754f425fSjmmv generate_wait_termsig(15), false,
236*754f425fSjmmv "failed: Test case expected to receive signal 18 but got 15\n",
237*754f425fSjmmv false);
238*754f425fSjmmv CHECK(rewrite__expected_signal__exited,
239*754f425fSjmmv "expected_signal: Foo bar\n",
240*754f425fSjmmv generate_wait_exitstatus(12), false,
241*754f425fSjmmv "failed: Test case expected to receive a signal but exited with code 12\n",
242*754f425fSjmmv false);
243*754f425fSjmmv CHECK(rewrite__expected_signal__no_reason,
244*754f425fSjmmv "expected_signal\n",
245*754f425fSjmmv generate_wait_termsig(15), false,
246*754f425fSjmmv "broken: Test case should have reported a failure reason but didn't; "
247*754f425fSjmmv "test case received signal 15\n",
248*754f425fSjmmv false);
249*754f425fSjmmv CHECK(rewrite__expected_signal__bad_arg,
250*754f425fSjmmv "expected_signal(abc): Some text\n",
251*754f425fSjmmv generate_wait_termsig(25), false,
252*754f425fSjmmv "broken: Invalid status argument (abc): not a number; test case received "
253*754f425fSjmmv "signal 25\n",
254*754f425fSjmmv false);
255*754f425fSjmmv
256*754f425fSjmmv
257*754f425fSjmmv CHECK(rewrite__expected_timeout__ok,
258*754f425fSjmmv "expected_timeout: Some text\n",
259*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), true,
260*754f425fSjmmv "expected_failure: Some text\n",
261*754f425fSjmmv true);
262*754f425fSjmmv CHECK(rewrite__expected_timeout__exited,
263*754f425fSjmmv "expected_timeout: Foo bar\n",
264*754f425fSjmmv generate_wait_exitstatus(12), false,
265*754f425fSjmmv "failed: Test case expected to time out but exited with code 12\n",
266*754f425fSjmmv false);
267*754f425fSjmmv CHECK(rewrite__expected_timeout__signaled,
268*754f425fSjmmv "expected_timeout: Foo bar\n",
269*754f425fSjmmv generate_wait_termsig(15), false,
270*754f425fSjmmv "failed: Test case expected to time out but received signal 15\n",
271*754f425fSjmmv false);
272*754f425fSjmmv CHECK(rewrite__expected_timeout__no_reason,
273*754f425fSjmmv "expected_timeout\n",
274*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
275*754f425fSjmmv "broken: Test case should have reported a failure reason but didn't; "
276*754f425fSjmmv "test case exited with code 1\n",
277*754f425fSjmmv false);
278*754f425fSjmmv CHECK(rewrite__expected_timeout__unexpected_arg,
279*754f425fSjmmv "expected_timeout(23): Some text\n",
280*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
281*754f425fSjmmv "broken: Unknown test case result status expected_timeout(23); "
282*754f425fSjmmv "test case exited with code 1\n",
283*754f425fSjmmv false);
284*754f425fSjmmv
285*754f425fSjmmv
286*754f425fSjmmv CHECK(rewrite__failed__ok,
287*754f425fSjmmv "failed: Some text\n",
288*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
289*754f425fSjmmv "failed: Some text\n",
290*754f425fSjmmv false);
291*754f425fSjmmv CHECK(rewrite__failed__exit_success,
292*754f425fSjmmv "failed: Some text\n",
293*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
294*754f425fSjmmv "broken: Test case reported a failed result but exited with a successful "
295*754f425fSjmmv "exit code\n",
296*754f425fSjmmv false);
297*754f425fSjmmv CHECK(rewrite__failed__signaled,
298*754f425fSjmmv "failed: Not used\n",
299*754f425fSjmmv generate_wait_termsig(1), false,
300*754f425fSjmmv "broken: Test case reported a failed result but received signal 1\n",
301*754f425fSjmmv false);
302*754f425fSjmmv CHECK(rewrite__failed__no_reason,
303*754f425fSjmmv "failed\n",
304*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
305*754f425fSjmmv "broken: Test case should have reported a failure reason but didn't; "
306*754f425fSjmmv "test case exited with code 1\n",
307*754f425fSjmmv false);
308*754f425fSjmmv CHECK(rewrite__failed__unexpected_arg,
309*754f425fSjmmv "failed(23): Some text\n",
310*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
311*754f425fSjmmv "broken: Unknown test case result status failed(23); "
312*754f425fSjmmv "test case exited with code 1\n",
313*754f425fSjmmv false);
314*754f425fSjmmv
315*754f425fSjmmv
316*754f425fSjmmv CHECK(rewrite__passed__ok,
317*754f425fSjmmv "passed\n",
318*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
319*754f425fSjmmv "passed\n",
320*754f425fSjmmv true);
321*754f425fSjmmv CHECK(rewrite__passed__exit_failure,
322*754f425fSjmmv "passed\n",
323*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
324*754f425fSjmmv "broken: Test case reported a passed result but returned a non-zero "
325*754f425fSjmmv "exit code 1\n",
326*754f425fSjmmv false);
327*754f425fSjmmv CHECK(rewrite__passed__signaled,
328*754f425fSjmmv "passed\n",
329*754f425fSjmmv generate_wait_termsig(1), false,
330*754f425fSjmmv "broken: Test case reported a passed result but received signal 1\n",
331*754f425fSjmmv false);
332*754f425fSjmmv CHECK(rewrite__passed__unexpected_reason,
333*754f425fSjmmv "passed: This should not be here\n",
334*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
335*754f425fSjmmv "broken: Found unexpected reason in passed test result; test case exited "
336*754f425fSjmmv "with code 0\n",
337*754f425fSjmmv false);
338*754f425fSjmmv CHECK(rewrite__passed__unexpected_arg,
339*754f425fSjmmv "passed(0)\n",
340*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
341*754f425fSjmmv "broken: Unknown test case result status passed(0); "
342*754f425fSjmmv "test case exited with code 0\n",
343*754f425fSjmmv false);
344*754f425fSjmmv
345*754f425fSjmmv
346*754f425fSjmmv CHECK(rewrite__skipped__ok,
347*754f425fSjmmv "skipped: Does not apply\n",
348*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
349*754f425fSjmmv "skipped: Does not apply\n",
350*754f425fSjmmv true);
351*754f425fSjmmv CHECK(rewrite__skipped__exit_failure,
352*754f425fSjmmv "skipped: Some reason\n",
353*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
354*754f425fSjmmv "broken: Test case reported a skipped result but returned a non-zero "
355*754f425fSjmmv "exit code 1\n",
356*754f425fSjmmv false);
357*754f425fSjmmv CHECK(rewrite__skipped__signaled,
358*754f425fSjmmv "skipped: Not used\n",
359*754f425fSjmmv generate_wait_termsig(1), false,
360*754f425fSjmmv "broken: Test case reported a skipped result but received signal 1\n",
361*754f425fSjmmv false);
362*754f425fSjmmv CHECK(rewrite__skipped__no_reason,
363*754f425fSjmmv "skipped\n",
364*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
365*754f425fSjmmv "broken: Test case should have reported a failure reason but didn't; "
366*754f425fSjmmv "test case exited with code 0\n",
367*754f425fSjmmv false);
368*754f425fSjmmv CHECK(rewrite__skipped__unexpected_arg,
369*754f425fSjmmv "skipped(1): Some text\n",
370*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
371*754f425fSjmmv "broken: Unknown test case result status skipped(1); "
372*754f425fSjmmv "test case exited with code 0\n",
373*754f425fSjmmv false);
374*754f425fSjmmv
375*754f425fSjmmv
376*754f425fSjmmv CHECK(rewrite__timed_out,
377*754f425fSjmmv "this invalid result file should not be parsed\n",
378*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), true,
379*754f425fSjmmv "broken: Test case body timed out\n",
380*754f425fSjmmv false);
381*754f425fSjmmv
382*754f425fSjmmv
383*754f425fSjmmv ATF_TC_WITHOUT_HEAD(rewrite__missing_file);
ATF_TC_BODY(rewrite__missing_file,tc)384*754f425fSjmmv ATF_TC_BODY(rewrite__missing_file, tc)
385*754f425fSjmmv {
386*754f425fSjmmv bool success;
387*754f425fSjmmv RE(kyua_atf_result_rewrite("in.txt", "out.txt",
388*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS),
389*754f425fSjmmv false, &success));
390*754f425fSjmmv atf_utils_cat_file("out.txt", "OUTPUT: ");
391*754f425fSjmmv ATF_REQUIRE(atf_utils_compare_file("out.txt",
392*754f425fSjmmv "broken: Premature exit; test case exited with code 0\n"));
393*754f425fSjmmv ATF_REQUIRE(!success);
394*754f425fSjmmv }
395*754f425fSjmmv CHECK(rewrite__empty,
396*754f425fSjmmv "",
397*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
398*754f425fSjmmv "broken: Empty result file in.txt; test case exited with code 1\n",
399*754f425fSjmmv false);
400*754f425fSjmmv CHECK(rewrite__unknown_status,
401*754f425fSjmmv "foo\n",
402*754f425fSjmmv generate_wait_exitstatus(123), false,
403*754f425fSjmmv "broken: Unknown test case result status foo; test case exited with "
404*754f425fSjmmv "code 123\n",
405*754f425fSjmmv false);
406*754f425fSjmmv CHECK(rewrite__status_without_newline,
407*754f425fSjmmv "failed",
408*754f425fSjmmv generate_wait_termsig(1), false,
409*754f425fSjmmv "broken: Missing newline in result file; test case received signal 1\n",
410*754f425fSjmmv false);
411*754f425fSjmmv CHECK(rewrite__status_multiline,
412*754f425fSjmmv "failed: First line\nSecond line\nThird line",
413*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
414*754f425fSjmmv "failed: First line<<NEWLINE>>Second line<<NEWLINE>>Third line\n",
415*754f425fSjmmv false);
416*754f425fSjmmv CHECK(rewrite__status_multiline_2,
417*754f425fSjmmv "failed: First line\nSecond line\nThird line\n",
418*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
419*754f425fSjmmv "failed: First line<<NEWLINE>>Second line<<NEWLINE>>Third line\n",
420*754f425fSjmmv false);
421*754f425fSjmmv
422*754f425fSjmmv
423*754f425fSjmmv /// Validates an execution of kyua_atf_result_cleanup_rewrite().
424*754f425fSjmmv ///
425*754f425fSjmmv /// The code of this check is all within the macro instead of in a separate
426*754f425fSjmmv /// function so that we get meaningful line numbers in test failure messages.
427*754f425fSjmmv ///
428*754f425fSjmmv /// \param name Name of the test case.
429*754f425fSjmmv /// \param wait_status Exit status of the ATF test case, as returned by wait(2).
430*754f425fSjmmv /// \param timed_out Whether the test case timed out or not.
431*754f425fSjmmv /// \param exp_output Text of the expected generic result.
432*754f425fSjmmv /// \param exp_success Expected value of the success result.
433*754f425fSjmmv #define CHECK_CLEANUP(name, wait_status, timed_out, exp_output, exp_success) \
434*754f425fSjmmv ATF_TC_WITHOUT_HEAD(name); \
435*754f425fSjmmv ATF_TC_BODY(name, tc) \
436*754f425fSjmmv { \
437*754f425fSjmmv bool success; \
438*754f425fSjmmv atf_utils_create_file("out.txt", "skipped: Preexistent file\n"); \
439*754f425fSjmmv RE(kyua_atf_result_cleanup_rewrite("out.txt", wait_status, \
440*754f425fSjmmv timed_out, &success)); \
441*754f425fSjmmv atf_utils_cat_file("out.txt", "OUTPUT: "); \
442*754f425fSjmmv ATF_REQUIRE(atf_utils_compare_file("out.txt", exp_output)); \
443*754f425fSjmmv ATF_REQUIRE_EQ(exp_success, success); \
444*754f425fSjmmv }
445*754f425fSjmmv
446*754f425fSjmmv
447*754f425fSjmmv CHECK_CLEANUP(cleanup_rewrite__ok,
448*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), false,
449*754f425fSjmmv "skipped: Preexistent file\n", // Previous file not overwritten.
450*754f425fSjmmv true);
451*754f425fSjmmv CHECK_CLEANUP(cleanup_rewrite__exit_failure,
452*754f425fSjmmv generate_wait_exitstatus(EXIT_FAILURE), false,
453*754f425fSjmmv "broken: Test case cleanup exited with code 1\n",
454*754f425fSjmmv false);
455*754f425fSjmmv CHECK_CLEANUP(cleanup_rewrite__signaled,
456*754f425fSjmmv generate_wait_termsig(1), false,
457*754f425fSjmmv "broken: Test case cleanup received signal 1\n",
458*754f425fSjmmv false);
459*754f425fSjmmv CHECK_CLEANUP(cleanup_rewrite__timed_out,
460*754f425fSjmmv generate_wait_exitstatus(EXIT_SUCCESS), true,
461*754f425fSjmmv "broken: Test case cleanup timed out\n",
462*754f425fSjmmv false);
463*754f425fSjmmv
464*754f425fSjmmv
ATF_TP_ADD_TCS(tp)465*754f425fSjmmv ATF_TP_ADD_TCS(tp)
466*754f425fSjmmv {
467*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_death__exit_failure);
468*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_death__signaled);
469*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_death__exit_success);
470*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_death__no_reason);
471*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_death__unexpected_arg);
472*754f425fSjmmv
473*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_exit__exit_success);
474*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_exit__exit_failure);
475*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_exit__arg_match);
476*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_exit__arg_not_match);
477*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_exit__signaled);
478*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_exit__no_reason);
479*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_exit__bad_arg);
480*754f425fSjmmv
481*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_failure__ok);
482*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_failure__failed);
483*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_failure__signaled);
484*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_failure__no_reason);
485*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_failure__unexpected_arg);
486*754f425fSjmmv
487*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_signal__ok);
488*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_signal__arg_match);
489*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_signal__arg_not_match);
490*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_signal__exited);
491*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_signal__no_reason);
492*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_signal__bad_arg);
493*754f425fSjmmv
494*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_timeout__ok);
495*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_timeout__exited);
496*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_timeout__signaled);
497*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_timeout__no_reason);
498*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__expected_timeout__unexpected_arg);
499*754f425fSjmmv
500*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__failed__ok);
501*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__failed__exit_success);
502*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__failed__signaled);
503*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__failed__no_reason);
504*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__failed__unexpected_arg);
505*754f425fSjmmv
506*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__passed__ok);
507*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__passed__exit_failure);
508*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__passed__signaled);
509*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__passed__unexpected_reason);
510*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__passed__unexpected_arg);
511*754f425fSjmmv
512*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__skipped__ok);
513*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__skipped__exit_failure);
514*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__skipped__signaled);
515*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__skipped__no_reason);
516*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__skipped__unexpected_arg);
517*754f425fSjmmv
518*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__timed_out);
519*754f425fSjmmv
520*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__missing_file);
521*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__empty);
522*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__unknown_status);
523*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__status_without_newline);
524*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__status_multiline);
525*754f425fSjmmv ATF_TP_ADD_TC(tp, rewrite__status_multiline_2);
526*754f425fSjmmv
527*754f425fSjmmv ATF_TP_ADD_TC(tp, cleanup_rewrite__ok);
528*754f425fSjmmv ATF_TP_ADD_TC(tp, cleanup_rewrite__exit_failure);
529*754f425fSjmmv ATF_TP_ADD_TC(tp, cleanup_rewrite__signaled);
530*754f425fSjmmv ATF_TP_ADD_TC(tp, cleanup_rewrite__timed_out);
531*754f425fSjmmv
532*754f425fSjmmv return atf_no_error();
533*754f425fSjmmv }
534