tools/llvm: Do not build with symbols
[minix3.git] / external / bsd / kyua-testers / dist / plain_main.c
blobd532df8f776f8a6dc544be3b5a5399e8491e7244
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.
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.
29 #include <sys/wait.h>
31 #include <assert.h>
32 #include <err.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <string.h>
37 #include "cli.h"
38 #include "defs.h"
39 #include "error.h"
40 #include "result.h"
41 #include "run.h"
42 #include "stacktrace.h"
45 /// Template for the creation of the temporary work directories.
46 #define WORKDIR_TEMPLATE "kyua.plain-tester.XXXXXX"
49 /// Name of the fake test case exposed by the program.
50 const char* const fake_test_case_name = "main";
53 /// Converts the exit status of a program to a result.
54 ///
55 /// \param status Exit status of the test program, as returned by waitpid().
56 /// \param timed_out Whether the test program timed out or not.
57 /// \param result_file Path to the result file to create.
58 /// \param [out] success Set to true if the test program returned with a
59 /// successful condition.
60 ///
61 /// \return An error if something went wrong.
62 static kyua_error_t
63 status_to_result(int status, const bool timed_out, const char* result_file,
64 bool* success)
66 if (timed_out) {
67 *success = false;
68 return kyua_result_write(result_file, KYUA_RESULT_BROKEN,
69 "Test case timed out");
72 if (WIFEXITED(status)) {
73 if (WEXITSTATUS(status) == EXIT_SUCCESS) {
74 *success = true;
75 return kyua_result_write(result_file, KYUA_RESULT_PASSED, NULL);
76 } else {
77 *success = false;
78 return kyua_result_write(result_file, KYUA_RESULT_FAILED,
79 "Returned non-success exit status %d",
80 WEXITSTATUS(status));
82 } else {
83 assert(WIFSIGNALED(status));
84 *success = false;
85 return kyua_result_write(result_file, KYUA_RESULT_BROKEN,
86 "Received signal %d", WTERMSIG(status));
91 /// Lists the test cases in a test program.
92 ///
93 /// \param unused_test_program Path to the test program for which to list the
94 /// test cases. Should be absolute.
95 /// \param unused_run_params Execution parameters to configure the test process.
96 ///
97 /// \return An error if the listing fails; OK otherwise.
98 static kyua_error_t
99 list_test_cases(const char* KYUA_DEFS_UNUSED_PARAM(test_program),
100 const kyua_run_params_t* KYUA_DEFS_UNUSED_PARAM(run_params))
102 printf("test_case{name='%s'}\n", fake_test_case_name);
103 return kyua_error_ok();
107 /// Runs a single test cases of a test program.
109 /// \param test_program Path to the test program for which to list the test
110 /// cases. Should be absolute.
111 /// \param test_case Name of the test case to run.
112 /// \param result_file Path to the file to which to write the result of the
113 /// test. Should be absolute.
114 /// \param user_variables Array of name=value pairs that describe the user
115 /// configuration variables for the test case.
116 /// \param run_params Execution parameters to configure the test process.
117 /// \param [out] success Set to true if the test case reported a valid exit
118 /// condition (like "passed" or "skipped"); false otherwise. This is
119 /// only updated if the method returns OK.
121 /// \return An error if the listing fails; OK otherwise.
122 static kyua_error_t
123 run_test_case(const char* test_program, const char* test_case,
124 const char* result_file, const char* const user_variables[],
125 const kyua_run_params_t* run_params,
126 bool* success)
128 kyua_error_t error;
130 if (strcmp(test_case, fake_test_case_name) != 0) {
131 error = kyua_generic_error_new("Unknown test case '%s'", test_case);
132 goto out;
135 const char* const* iter;
136 for (iter = user_variables; *iter != NULL; ++iter) {
137 warnx("Configuration variables not supported; ignoring '%s'", *iter);
140 char *work_directory;
141 error = kyua_run_work_directory_enter(WORKDIR_TEMPLATE,
142 run_params->unprivileged_user,
143 run_params->unprivileged_group,
144 &work_directory);
145 if (kyua_error_is_set(error))
146 goto out;
147 kyua_run_params_t real_run_params = *run_params;
148 real_run_params.work_directory = work_directory;
150 pid_t pid;
151 error = kyua_run_fork(&real_run_params, &pid);
152 if (!kyua_error_is_set(error) && pid == 0) {
153 const char* const program_args[] = { test_program, NULL };
154 kyua_run_exec(test_program, program_args);
156 assert(pid != -1 && pid != 0);
157 if (kyua_error_is_set(error))
158 goto out_work_directory;
160 int status; bool timed_out;
161 error = kyua_run_wait(pid, &status, &timed_out);
162 if (kyua_error_is_set(error))
163 goto out_work_directory;
165 if (WIFSIGNALED(status) && WCOREDUMP(status)) {
166 kyua_stacktrace_dump(test_program, pid, run_params, stderr);
169 error = status_to_result(status, timed_out, result_file, success);
171 out_work_directory:
172 error = kyua_error_subsume(error,
173 kyua_run_work_directory_leave(&work_directory));
174 out:
175 return error;
179 /// Definition of the tester.
180 static kyua_cli_tester_t plain_tester = {
181 .list_test_cases = list_test_cases,
182 .run_test_case = run_test_case,
186 /// Tester entry point.
188 /// \param argc Number of command line arguments.
189 /// \param argv NULL-terminated array of command line arguments.
191 /// \return An exit code.
193 main(const int argc, char* const* const argv)
195 return kyua_cli_main(argc, argv, &plain_tester);