xref: /netbsd-src/external/bsd/kyua-testers/dist/atf_list_test.c (revision 8faee98977258cf9a6a22d27c0e1864a8fa6e38b)
1754f425fSjmmv // Copyright 2012 Google Inc.
2754f425fSjmmv // All rights reserved.
3754f425fSjmmv //
4754f425fSjmmv // Redistribution and use in source and binary forms, with or without
5754f425fSjmmv // modification, are permitted provided that the following conditions are
6754f425fSjmmv // met:
7754f425fSjmmv //
8754f425fSjmmv // * Redistributions of source code must retain the above copyright
9754f425fSjmmv //   notice, this list of conditions and the following disclaimer.
10754f425fSjmmv // * Redistributions in binary form must reproduce the above copyright
11754f425fSjmmv //   notice, this list of conditions and the following disclaimer in the
12754f425fSjmmv //   documentation and/or other materials provided with the distribution.
13754f425fSjmmv // * Neither the name of Google Inc. nor the names of its contributors
14754f425fSjmmv //   may be used to endorse or promote products derived from this software
15754f425fSjmmv //   without specific prior written permission.
16754f425fSjmmv //
17754f425fSjmmv // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
18754f425fSjmmv // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
19754f425fSjmmv // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
20754f425fSjmmv // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
21754f425fSjmmv // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22754f425fSjmmv // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
23754f425fSjmmv // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
24754f425fSjmmv // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
25754f425fSjmmv // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
26754f425fSjmmv // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27754f425fSjmmv // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28754f425fSjmmv 
29754f425fSjmmv #include "atf_list.h"
30754f425fSjmmv 
31754f425fSjmmv #include <fcntl.h>
32754f425fSjmmv 
33754f425fSjmmv #include <atf-c.h>
34754f425fSjmmv 
35754f425fSjmmv #include "error.h"
36754f425fSjmmv 
37754f425fSjmmv 
38754f425fSjmmv /// Opens a file for reading and fails the test case if the open fails.
39754f425fSjmmv ///
40754f425fSjmmv /// \param name The file to open.
41754f425fSjmmv ///
42754f425fSjmmv /// \return A valid file descriptor.
43754f425fSjmmv static int
safe_open(const char * name)44754f425fSjmmv safe_open(const char* name)
45754f425fSjmmv {
46754f425fSjmmv     const int fd = open(name, O_RDONLY);
47754f425fSjmmv     ATF_REQUIRE(fd != -1);
48754f425fSjmmv     return fd;
49754f425fSjmmv }
50754f425fSjmmv 
51754f425fSjmmv 
52754f425fSjmmv /// Test atf_list_parse for a valid case.
53754f425fSjmmv ///
54754f425fSjmmv /// \param input_name Result file to parse.
55754f425fSjmmv /// \param exp_output Expected output of the parsing.
56754f425fSjmmv static void
do_ok_test(const char * input_name,const char * exp_output)57754f425fSjmmv do_ok_test(const char* input_name, const char* exp_output)
58754f425fSjmmv {
59754f425fSjmmv     FILE* output = fopen("output.txt", "w");
60754f425fSjmmv     kyua_error_t error = atf_list_parse(safe_open(input_name), output);
61754f425fSjmmv     fclose(output);
62754f425fSjmmv 
63754f425fSjmmv     if (!atf_utils_compare_file("output.txt", exp_output)) {
64754f425fSjmmv         atf_utils_create_file("expout.txt", "%s", exp_output);
65754f425fSjmmv         atf_utils_cat_file("expout.txt", "EXPECTED: ");
66754f425fSjmmv         atf_utils_cat_file("output.txt", "ACTUAL:   ");
67754f425fSjmmv         atf_tc_fail_nonfatal("Output of atf_list_parse does not match expected "
68754f425fSjmmv                              "results");
69754f425fSjmmv     }
70754f425fSjmmv 
71754f425fSjmmv     if (kyua_error_is_set(error)) {
72754f425fSjmmv         char message[1024];
73754f425fSjmmv         kyua_error_format(error, message, sizeof(message));
74754f425fSjmmv         kyua_error_free(error);
75754f425fSjmmv         atf_tc_fail("%s", message);
76754f425fSjmmv     }
77754f425fSjmmv }
78754f425fSjmmv 
79754f425fSjmmv 
80754f425fSjmmv /// Test atf_list_parse for an error case.
81754f425fSjmmv ///
82754f425fSjmmv /// \param input_name Invalid result file to parse.
83754f425fSjmmv /// \param exp_type Expected error type.
84754f425fSjmmv /// \param exp_message Expected error message.
85754f425fSjmmv static void
do_fail_test(const char * input_name,const char * exp_type,const char * exp_message)86754f425fSjmmv do_fail_test(const char* input_name, const char* exp_type,
87754f425fSjmmv              const char* exp_message)
88754f425fSjmmv {
89754f425fSjmmv     FILE* output = fopen("output.txt", "w");
90754f425fSjmmv     kyua_error_t error = atf_list_parse(safe_open(input_name), output);
91754f425fSjmmv     fclose(output);
92754f425fSjmmv 
93754f425fSjmmv     ATF_REQUIRE(kyua_error_is_set(error));
94754f425fSjmmv     ATF_REQUIRE(kyua_error_is_type(error, exp_type));
95754f425fSjmmv 
96754f425fSjmmv     char message[1024];
97754f425fSjmmv     kyua_error_format(error, message, sizeof(message));
98754f425fSjmmv     kyua_error_free(error);
99754f425fSjmmv     ATF_REQUIRE_MATCH(exp_message, message);
100754f425fSjmmv }
101754f425fSjmmv 
102754f425fSjmmv 
103754f425fSjmmv ATF_TC_WITHOUT_HEAD(parse__ok__one);
ATF_TC_BODY(parse__ok__one,tc)104754f425fSjmmv ATF_TC_BODY(parse__ok__one, tc)
105754f425fSjmmv {
106754f425fSjmmv     atf_utils_create_file(
107754f425fSjmmv         "input.txt",
108754f425fSjmmv         "Content-Type: application/X-atf-tp; version=\"1\"\n"
109754f425fSjmmv         "\n"
110754f425fSjmmv         "ident: first\n");
111754f425fSjmmv     do_ok_test(
112754f425fSjmmv         "input.txt",
113754f425fSjmmv         "test_case{name='first'}\n");
114754f425fSjmmv }
115754f425fSjmmv 
116754f425fSjmmv 
117754f425fSjmmv ATF_TC_WITHOUT_HEAD(parse__ok__several);
ATF_TC_BODY(parse__ok__several,tc)118754f425fSjmmv ATF_TC_BODY(parse__ok__several, tc)
119754f425fSjmmv {
120754f425fSjmmv     atf_utils_create_file(
121754f425fSjmmv         "input.txt",
122754f425fSjmmv         "Content-Type: application/X-atf-tp; version=\"1\"\n"
123754f425fSjmmv         "\n"
124754f425fSjmmv         "ident: first\n"
125754f425fSjmmv         "require.user: root\n"
126754f425fSjmmv         "\n"
127754f425fSjmmv         "ident: second\n"
128754f425fSjmmv         "\n"
129754f425fSjmmv         "ident: third\n"
130*8faee989Sjmmv         "descr: A string with an embedded ' and \\' in it\n"
131754f425fSjmmv         "has.cleanup: true\n"
132754f425fSjmmv         "X-custom: foo\n"
133754f425fSjmmv         "X-a'b: bar\n");
134754f425fSjmmv     do_ok_test(
135754f425fSjmmv         "input.txt",
136754f425fSjmmv         "test_case{name='first', required_user='root'}\n"
137754f425fSjmmv         "test_case{name='second'}\n"
138*8faee989Sjmmv         "test_case{name='third', description='A string with an embedded \\' "
139*8faee989Sjmmv         "and \\\\\\' in it', has_cleanup='true', ['custom.X-custom']='foo', "
140754f425fSjmmv         "['custom.X-a\\'b']='bar'}\n");
141754f425fSjmmv }
142754f425fSjmmv 
143754f425fSjmmv 
144754f425fSjmmv ATF_TC_WITHOUT_HEAD(parse__error__bad_fd);
ATF_TC_BODY(parse__error__bad_fd,tc)145754f425fSjmmv ATF_TC_BODY(parse__error__bad_fd, tc)
146754f425fSjmmv {
147754f425fSjmmv     (void)close(10);
148754f425fSjmmv     kyua_error_t error = atf_list_parse(10, stdout);
149754f425fSjmmv 
150754f425fSjmmv     ATF_REQUIRE(kyua_error_is_set(error));
151754f425fSjmmv     ATF_REQUIRE(kyua_error_is_type(error, "libc"));
152754f425fSjmmv 
153754f425fSjmmv     char message[1024];
154754f425fSjmmv     kyua_error_format(error, message, sizeof(message));
155754f425fSjmmv     kyua_error_free(error);
156754f425fSjmmv     ATF_REQUIRE_MATCH("fdopen\\(10\\) failed", message);
157754f425fSjmmv }
158754f425fSjmmv 
159754f425fSjmmv 
160754f425fSjmmv ATF_TC_WITHOUT_HEAD(parse__error__bad_header);
ATF_TC_BODY(parse__error__bad_header,tc)161754f425fSjmmv ATF_TC_BODY(parse__error__bad_header, tc)
162754f425fSjmmv {
163754f425fSjmmv     atf_utils_create_file("input.txt", "%s", "");
164754f425fSjmmv     do_fail_test("input.txt", "generic",
165754f425fSjmmv                  "fgets failed to read test cases list header");
166754f425fSjmmv 
167754f425fSjmmv     atf_utils_create_file(
168754f425fSjmmv         "input.txt",
169754f425fSjmmv         "Content-Type: application/X-atf-tp; version=\"1234\"");
170754f425fSjmmv     do_fail_test("input.txt", "generic",
171754f425fSjmmv                  "Invalid test cases list header '.*X-atf-tp.*1234.*'");
172754f425fSjmmv 
173754f425fSjmmv     atf_utils_create_file(
174754f425fSjmmv         "input.txt",
175754f425fSjmmv         "Content-Type: application/X-atf-tp; version=\"1\"\n");
176754f425fSjmmv     do_fail_test("input.txt", "generic",
177754f425fSjmmv                  "fgets failed to read test cases list header");
178754f425fSjmmv 
179754f425fSjmmv     atf_utils_create_file(
180754f425fSjmmv         "input.txt",
181754f425fSjmmv         "Content-Type: application/X-atf-tp; version=\"1\"\n"
182754f425fSjmmv         "some garbage\n"
183754f425fSjmmv         "\n");
184754f425fSjmmv     do_fail_test("input.txt", "generic",
185754f425fSjmmv                  "Incomplete test cases list header");
186754f425fSjmmv }
187754f425fSjmmv 
188754f425fSjmmv 
189754f425fSjmmv ATF_TC_WITHOUT_HEAD(parse__error__empty);
ATF_TC_BODY(parse__error__empty,tc)190754f425fSjmmv ATF_TC_BODY(parse__error__empty, tc)
191754f425fSjmmv {
192754f425fSjmmv     atf_utils_create_file(
193754f425fSjmmv         "input.txt",
194754f425fSjmmv         "Content-Type: application/X-atf-tp; version=\"1\"\n"
195754f425fSjmmv         "\n");
196754f425fSjmmv     do_fail_test("input.txt", "generic",
197754f425fSjmmv                  "Empty test cases list: unexpected EOF");
198754f425fSjmmv }
199754f425fSjmmv 
200754f425fSjmmv 
201754f425fSjmmv ATF_TC_WITHOUT_HEAD(parse__error__bad_property);
ATF_TC_BODY(parse__error__bad_property,tc)202754f425fSjmmv ATF_TC_BODY(parse__error__bad_property, tc)
203754f425fSjmmv {
204754f425fSjmmv     atf_utils_create_file(
205754f425fSjmmv         "input.txt",
206754f425fSjmmv         "Content-Type: application/X-atf-tp; version=\"1\"\n"
207754f425fSjmmv         "\n"
208754f425fSjmmv         "oh noes; 2\n");
209754f425fSjmmv     do_fail_test("input.txt", "generic", "Invalid property 'oh noes; 2'");
210754f425fSjmmv }
211754f425fSjmmv 
212754f425fSjmmv 
213754f425fSjmmv ATF_TC_WITHOUT_HEAD(parse__error__bad_order);
ATF_TC_BODY(parse__error__bad_order,tc)214754f425fSjmmv ATF_TC_BODY(parse__error__bad_order, tc)
215754f425fSjmmv {
216754f425fSjmmv     atf_utils_create_file(
217754f425fSjmmv         "input.txt",
218754f425fSjmmv         "Content-Type: application/X-atf-tp; version=\"1\"\n"
219754f425fSjmmv         "\n"
220754f425fSjmmv         "descr: Some text\n"
221754f425fSjmmv         "ident: first\n");
222754f425fSjmmv     do_fail_test("input.txt", "generic", "Expected ident property, got descr");
223754f425fSjmmv }
224754f425fSjmmv 
225754f425fSjmmv 
ATF_TP_ADD_TCS(tp)226754f425fSjmmv ATF_TP_ADD_TCS(tp)
227754f425fSjmmv {
228754f425fSjmmv     ATF_TP_ADD_TC(tp, parse__ok__one);
229754f425fSjmmv     ATF_TP_ADD_TC(tp, parse__ok__several);
230754f425fSjmmv     ATF_TP_ADD_TC(tp, parse__error__bad_fd);
231754f425fSjmmv     ATF_TP_ADD_TC(tp, parse__error__bad_header);
232754f425fSjmmv     ATF_TP_ADD_TC(tp, parse__error__empty);
233754f425fSjmmv     ATF_TP_ADD_TC(tp, parse__error__bad_property);
234754f425fSjmmv     ATF_TP_ADD_TC(tp, parse__error__bad_order);
235754f425fSjmmv 
236754f425fSjmmv     return atf_no_error();
237754f425fSjmmv }
238