]> CyberLeo.Net >> Repos - FreeBSD/releng/10.0.git/blob - contrib/atf/atf-run/misc_helpers.cpp
- Copy stable/10 (r259064) to releng/10.0 as part of the
[FreeBSD/releng/10.0.git] / contrib / atf / atf-run / misc_helpers.cpp
1 //
2 // Automated Testing Framework (atf)
3 //
4 // Copyright (c) 2007 The NetBSD Foundation, Inc.
5 // All rights reserved.
6 //
7 // Redistribution and use in source and binary forms, with or without
8 // modification, are permitted provided that the following conditions
9 // are met:
10 // 1. Redistributions of source code must retain the above copyright
11 //    notice, this list of conditions and the following disclaimer.
12 // 2. Redistributions in binary form must reproduce the above copyright
13 //    notice, this list of conditions and the following disclaimer in the
14 //    documentation and/or other materials provided with the distribution.
15 //
16 // THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND
17 // CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
18 // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
19 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 // IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS BE LIABLE FOR ANY
21 // DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
23 // GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
24 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
25 // IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
27 // IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29
30 extern "C" {
31 #include <sys/stat.h>
32
33 #include <signal.h>
34 #include <unistd.h>
35 }
36
37 #include <cstdlib>
38 #include <fstream>
39 #include <iomanip>
40 #include <ios>
41 #include <iostream>
42 #include <string>
43
44 #include "atf-c++/macros.hpp"
45
46 #include "atf-c++/detail/env.hpp"
47 #include "atf-c++/detail/fs.hpp"
48 #include "atf-c++/detail/process.hpp"
49 #include "atf-c++/detail/sanity.hpp"
50
51 // ------------------------------------------------------------------------
52 // Auxiliary functions.
53 // ------------------------------------------------------------------------
54
55 static
56 void
57 touch(const std::string& path)
58 {
59     std::ofstream os(path.c_str());
60     if (!os)
61         ATF_FAIL("Could not create file " + path);
62     os.close();
63 }
64
65 // ------------------------------------------------------------------------
66 // Helper tests for "t_integration".
67 // ------------------------------------------------------------------------
68
69 ATF_TEST_CASE(pass);
70 ATF_TEST_CASE_HEAD(pass)
71 {
72     set_md_var("descr", "Helper test case for the t_integration test program");
73 }
74 ATF_TEST_CASE_BODY(pass)
75 {
76 }
77
78 ATF_TEST_CASE(config);
79 ATF_TEST_CASE_HEAD(config)
80 {
81     set_md_var("descr", "Helper test case for the t_integration test program");
82 }
83 ATF_TEST_CASE_BODY(config)
84 {
85     std::cout << "1st: " << get_config_var("1st") << "\n";
86     std::cout << "2nd: " << get_config_var("2nd") << "\n";
87     std::cout << "3rd: " << get_config_var("3rd") << "\n";
88     std::cout << "4th: " << get_config_var("4th") << "\n";
89 }
90
91 ATF_TEST_CASE(fds);
92 ATF_TEST_CASE_HEAD(fds)
93 {
94     set_md_var("descr", "Helper test case for the t_integration test program");
95 }
96 ATF_TEST_CASE_BODY(fds)
97 {
98     std::cout << "msg1 to stdout" << "\n";
99     std::cout << "msg2 to stdout" << "\n";
100     std::cerr << "msg1 to stderr" << "\n";
101     std::cerr << "msg2 to stderr" << "\n";
102 }
103
104 ATF_TEST_CASE_WITHOUT_HEAD(mux_streams);
105 ATF_TEST_CASE_BODY(mux_streams)
106 {
107     for (size_t i = 0; i < 10000; i++) {
108         switch (i % 5) {
109         case 0:
110             std::cout << "stdout " << i << "\n";
111             break;
112         case 1:
113             std::cerr << "stderr " << i << "\n";
114             break;
115         case 2:
116             std::cout << "stdout " << i << "\n";
117             std::cerr << "stderr " << i << "\n";
118             break;
119         case 3:
120             std::cout << "stdout " << i << "\n";
121             std::cout << "stdout " << i << "\n";
122             std::cerr << "stderr " << i << "\n";
123             break;
124         case 4:
125             std::cout << "stdout " << i << "\n";
126             std::cerr << "stderr " << i << "\n";
127             std::cerr << "stderr " << i << "\n";
128             break;
129         default:
130             UNREACHABLE;
131         }
132     }
133 }
134
135 ATF_TEST_CASE(testvar);
136 ATF_TEST_CASE_HEAD(testvar)
137 {
138     set_md_var("descr", "Helper test case for the t_integration test program");
139 }
140 ATF_TEST_CASE_BODY(testvar)
141 {
142     if (!has_config_var("testvar"))
143         fail("testvar variable not defined");
144     std::cout << "testvar: " << get_config_var("testvar") << "\n";
145 }
146
147 ATF_TEST_CASE(env_list);
148 ATF_TEST_CASE_HEAD(env_list)
149 {
150     set_md_var("descr", "Helper test case for the t_integration test program");
151 }
152 ATF_TEST_CASE_BODY(env_list)
153 {
154     const atf::process::status s =
155         atf::process::exec(atf::fs::path("env"),
156                            atf::process::argv_array("env", NULL),
157                            atf::process::stream_inherit(),
158                            atf::process::stream_inherit());
159     ATF_REQUIRE(s.exited());
160     ATF_REQUIRE(s.exitstatus() == EXIT_SUCCESS);
161 }
162
163 ATF_TEST_CASE(env_home);
164 ATF_TEST_CASE_HEAD(env_home)
165 {
166     set_md_var("descr", "Helper test case for the t_integration test program");
167 }
168 ATF_TEST_CASE_BODY(env_home)
169 {
170     ATF_REQUIRE(atf::env::has("HOME"));
171     atf::fs::path p(atf::env::get("HOME"));
172     atf::fs::file_info fi1(p);
173     atf::fs::file_info fi2(atf::fs::path("."));
174     ATF_REQUIRE_EQ(fi1.get_device(), fi2.get_device());
175     ATF_REQUIRE_EQ(fi1.get_inode(), fi2.get_inode());
176 }
177
178 ATF_TEST_CASE(read_stdin);
179 ATF_TEST_CASE_HEAD(read_stdin)
180 {
181     set_md_var("descr", "Helper test case for the t_integration test program");
182 }
183 ATF_TEST_CASE_BODY(read_stdin)
184 {
185     char buf[100];
186     ssize_t len = ::read(STDIN_FILENO, buf, sizeof(buf) - 1);
187     ATF_REQUIRE(len != -1);
188
189     buf[len + 1] = '\0';
190     for (ssize_t i = 0; i < len; i++) {
191         if (buf[i] != '\0') {
192             fail("The stdin of the test case does not seem to be /dev/zero; "
193                  "got '" + std::string(buf) + "'");
194         }
195     }
196 }
197
198 ATF_TEST_CASE(umask);
199 ATF_TEST_CASE_HEAD(umask)
200 {
201     set_md_var("descr", "Helper test case for the t_integration test program");
202 }
203 ATF_TEST_CASE_BODY(umask)
204 {
205     mode_t m = ::umask(0);
206     std::cout << "umask: " << std::setw(4) << std::setfill('0')
207               << std::oct << m << "\n";
208     (void)::umask(m);
209 }
210
211 ATF_TEST_CASE_WITH_CLEANUP(cleanup_states);
212 ATF_TEST_CASE_HEAD(cleanup_states)
213 {
214     set_md_var("descr", "Helper test case for the t_integration test program");
215 }
216 ATF_TEST_CASE_BODY(cleanup_states)
217 {
218     touch(get_config_var("statedir") + "/to-delete");
219     touch(get_config_var("statedir") + "/to-stay");
220
221     if (get_config_var("state") == "fail")
222         ATF_FAIL("On purpose");
223     else if (get_config_var("state") == "skip")
224         ATF_SKIP("On purpose");
225 }
226 ATF_TEST_CASE_CLEANUP(cleanup_states)
227 {
228     atf::fs::remove(atf::fs::path(get_config_var("statedir") + "/to-delete"));
229 }
230
231 ATF_TEST_CASE_WITH_CLEANUP(cleanup_curdir);
232 ATF_TEST_CASE_HEAD(cleanup_curdir)
233 {
234     set_md_var("descr", "Helper test case for the t_integration test program");
235 }
236 ATF_TEST_CASE_BODY(cleanup_curdir)
237 {
238     std::ofstream os("oldvalue");
239     if (!os)
240         ATF_FAIL("Failed to create oldvalue file");
241     os << 1234;
242     os.close();
243 }
244 ATF_TEST_CASE_CLEANUP(cleanup_curdir)
245 {
246     std::ifstream is("oldvalue");
247     if (is) {
248         int i;
249         is >> i;
250         std::cout << "Old value: " << i << "\n";
251         is.close();
252     }
253 }
254
255 ATF_TEST_CASE(require_arch);
256 ATF_TEST_CASE_HEAD(require_arch)
257 {
258     set_md_var("descr", "Helper test case for the t_integration test program");
259     set_md_var("require.arch", get_config_var("arch", "not-set"));
260 }
261 ATF_TEST_CASE_BODY(require_arch)
262 {
263 }
264
265 ATF_TEST_CASE(require_config);
266 ATF_TEST_CASE_HEAD(require_config)
267 {
268     set_md_var("descr", "Helper test case for the t_integration test program");
269     set_md_var("require.config", "var1 var2");
270 }
271 ATF_TEST_CASE_BODY(require_config)
272 {
273     std::cout << "var1: " << get_config_var("var1") << "\n";
274     std::cout << "var2: " << get_config_var("var2") << "\n";
275 }
276
277 ATF_TEST_CASE(require_files);
278 ATF_TEST_CASE_HEAD(require_files)
279 {
280     set_md_var("descr", "Helper test case for the t_integration test program");
281     set_md_var("require.files", get_config_var("files", "not-set"));
282 }
283 ATF_TEST_CASE_BODY(require_files)
284 {
285 }
286
287 ATF_TEST_CASE(require_machine);
288 ATF_TEST_CASE_HEAD(require_machine)
289 {
290     set_md_var("descr", "Helper test case for the t_integration test program");
291     set_md_var("require.machine", get_config_var("machine", "not-set"));
292 }
293 ATF_TEST_CASE_BODY(require_machine)
294 {
295 }
296
297 ATF_TEST_CASE(require_progs);
298 ATF_TEST_CASE_HEAD(require_progs)
299 {
300     set_md_var("descr", "Helper test case for the t_integration test program");
301     set_md_var("require.progs", get_config_var("progs", "not-set"));
302 }
303 ATF_TEST_CASE_BODY(require_progs)
304 {
305 }
306
307 ATF_TEST_CASE(require_user);
308 ATF_TEST_CASE_HEAD(require_user)
309 {
310     set_md_var("descr", "Helper test case for the t_integration test program");
311     set_md_var("require.user", get_config_var("user", "not-set"));
312 }
313 ATF_TEST_CASE_BODY(require_user)
314 {
315 }
316
317 ATF_TEST_CASE(timeout);
318 ATF_TEST_CASE_HEAD(timeout)
319 {
320     set_md_var("descr", "Helper test case for the t_integration test program");
321     set_md_var("timeout", "1");
322 }
323 ATF_TEST_CASE_BODY(timeout)
324 {
325     sleep(10);
326     touch(get_config_var("statedir") + "/finished");
327 }
328
329 ATF_TEST_CASE(timeout_forkexit);
330 ATF_TEST_CASE_HEAD(timeout_forkexit)
331 {
332     set_md_var("descr", "Helper test case for the t_integration test program");
333 }
334 ATF_TEST_CASE_BODY(timeout_forkexit)
335 {
336     pid_t pid = fork();
337     ATF_REQUIRE(pid != -1);
338
339     if (pid == 0) {
340         sigset_t mask;
341         sigemptyset(&mask);
342
343         std::cout << "Waiting in subprocess\n";
344         std::cout.flush();
345         ::sigsuspend(&mask);
346
347         touch(get_config_var("statedir") + "/child-finished");
348         std::cout << "Subprocess exiting\n";
349         std::cout.flush();
350         exit(EXIT_SUCCESS);
351     } else {
352         // Don't wait for the child process and let atf-run deal with it.
353         touch(get_config_var("statedir") + "/parent-finished");
354         std::cout << "Parent process exiting\n";
355         ATF_PASS();
356     }
357 }
358
359 ATF_TEST_CASE(use_fs);
360 ATF_TEST_CASE_HEAD(use_fs)
361 {
362     set_md_var("descr", "Helper test case for the t_integration test program");
363     set_md_var("use.fs", "this-is-deprecated");
364 }
365 ATF_TEST_CASE_BODY(use_fs)
366 {
367     touch("test-file");
368 }
369
370 // ------------------------------------------------------------------------
371 // Main.
372 // ------------------------------------------------------------------------
373
374 ATF_INIT_TEST_CASES(tcs)
375 {
376     std::string which = atf::env::get("TESTCASE");
377
378     // Add helper tests for t_integration.
379     if (which == "pass")
380         ATF_ADD_TEST_CASE(tcs, pass);
381     if (which == "config")
382         ATF_ADD_TEST_CASE(tcs, config);
383     if (which == "fds")
384         ATF_ADD_TEST_CASE(tcs, fds);
385     if (which == "mux_streams")
386         ATF_ADD_TEST_CASE(tcs, mux_streams);
387     if (which == "testvar")
388         ATF_ADD_TEST_CASE(tcs, testvar);
389     if (which == "env_list")
390         ATF_ADD_TEST_CASE(tcs, env_list);
391     if (which == "env_home")
392         ATF_ADD_TEST_CASE(tcs, env_home);
393     if (which == "read_stdin")
394         ATF_ADD_TEST_CASE(tcs, read_stdin);
395     if (which == "umask")
396         ATF_ADD_TEST_CASE(tcs, umask);
397     if (which == "cleanup_states")
398         ATF_ADD_TEST_CASE(tcs, cleanup_states);
399     if (which == "cleanup_curdir")
400         ATF_ADD_TEST_CASE(tcs, cleanup_curdir);
401     if (which == "require_arch")
402         ATF_ADD_TEST_CASE(tcs, require_arch);
403     if (which == "require_config")
404         ATF_ADD_TEST_CASE(tcs, require_config);
405     if (which == "require_files")
406         ATF_ADD_TEST_CASE(tcs, require_files);
407     if (which == "require_machine")
408         ATF_ADD_TEST_CASE(tcs, require_machine);
409     if (which == "require_progs")
410         ATF_ADD_TEST_CASE(tcs, require_progs);
411     if (which == "require_user")
412         ATF_ADD_TEST_CASE(tcs, require_user);
413     if (which == "timeout")
414         ATF_ADD_TEST_CASE(tcs, timeout);
415     if (which == "timeout_forkexit")
416         ATF_ADD_TEST_CASE(tcs, timeout_forkexit);
417     if (which == "use_fs")
418         ATF_ADD_TEST_CASE(tcs, use_fs);
419 }