Split up progress tests.
[third_party/subunit] / c / tests / test_child.c
1 /**
2  *
3  *  subunit C bindings.
4  *  Copyright (C) 2006  Robert Collins <robertc@robertcollins.net>
5  *
6  *  Licensed under either the Apache License, Version 2.0 or the BSD 3-clause
7  *  license at the users choice. A copy of both licenses are available in the
8  *  project source as Apache-2.0 and BSD. You may not use this file except in
9  *  compliance with one of these two licences.
10  *  
11  *  Unless required by applicable law or agreed to in writing, software
12  *  distributed under these licenses is distributed on an "AS IS" BASIS,
13  *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  *  See the license you chose for the specific language governing permissions
15  *  and limitations under that license.
16  **/
17
18 #include <stdlib.h>
19 #include <unistd.h>
20 #include <string.h>
21 #include <check.h>
22
23 #include "subunit/child.h"
24
25 /**
26  * Helper function to capture stdout, run some call, and check what
27  * was written.
28  * @expected the expected stdout content
29  * @function the function to call.
30  **/
31 static void
32 test_stdout_function(char const * expected,
33                      void (*function)(void))
34 {
35     /* test that the start function emits a correct test: line. */
36     int bytecount;
37     int old_stdout;
38     int new_stdout[2];
39     char buffer[100];
40     /* we need a socketpair to capture stdout in */
41     fail_if(pipe(new_stdout), "Failed to create a socketpair.");
42     /* backup stdout so we can replace it */
43     old_stdout = dup(1);
44     if (old_stdout == -1) {
45       close(new_stdout[0]);
46       close(new_stdout[1]);
47       fail("Failed to backup stdout before replacing.");
48     }
49     /* redirect stdout so we can analyse it */
50     if (dup2(new_stdout[1], 1) != 1) {
51       close(old_stdout);
52       close(new_stdout[0]);
53       close(new_stdout[1]);
54       fail("Failed to redirect stdout");
55     }
56     /* yes this can block. Its a test case with < 100 bytes of output.
57      * DEAL.
58      */
59     function();
60     /* restore stdout now */
61     if (dup2(old_stdout, 1) != 1) {
62       close(old_stdout);
63       close(new_stdout[0]);
64       close(new_stdout[1]);
65       fail("Failed to restore stdout");
66     }
67     /* and we dont need the write side any more */
68     if (close(new_stdout[1])) {
69       close(new_stdout[0]);
70       fail("Failed to close write side of socketpair.");
71     }
72     /* get the output */
73     bytecount = read(new_stdout[0], buffer, 100);
74     if (0 > bytecount) {
75       close(new_stdout[0]);
76       fail("Failed to read captured output.");
77     }
78     buffer[bytecount]='\0';
79     /* and we dont need the read side any more */
80     fail_if(close(new_stdout[0]), "Failed to close write side of socketpair.");
81     /* compare with expected outcome */
82     fail_if(strcmp(expected, buffer), "Did not get expected output [%s], got [%s]", expected, buffer);
83 }
84
85
86 static void
87 call_test_start(void)
88 {
89     subunit_test_start("test case");
90 }
91
92
93 START_TEST (test_start)
94 {
95     test_stdout_function("test: test case\n", call_test_start);
96 }
97 END_TEST
98
99
100 static void
101 call_test_pass(void)
102 {
103     subunit_test_pass("test case");
104 }
105
106
107 START_TEST (test_pass)
108 {
109     test_stdout_function("success: test case\n", call_test_pass);
110 }
111 END_TEST
112
113
114 static void
115 call_test_fail(void)
116 {
117     subunit_test_fail("test case", "Multiple lines\n of error\n");
118 }
119
120
121 START_TEST (test_fail)
122 {
123     test_stdout_function("failure: test case [\n"
124                          "Multiple lines\n"
125                          " of error\n"
126                          "]\n",
127                          call_test_fail);
128 }
129 END_TEST
130
131
132 static void
133 call_test_error(void)
134 {
135     subunit_test_error("test case", "Multiple lines\n of output\n");
136 }
137
138
139 START_TEST (test_error)
140 {
141     test_stdout_function("error: test case [\n"
142                          "Multiple lines\n"
143                          " of output\n"
144                          "]\n",
145                          call_test_error);
146 }
147 END_TEST
148
149
150 static void
151 call_test_skip(void)
152 {
153     subunit_test_skip("test case", "Multiple lines\n of output\n");
154 }
155
156
157 START_TEST (test_skip)
158 {
159     test_stdout_function("skip: test case [\n"
160                          "Multiple lines\n"
161                          " of output\n"
162                          "]\n",
163                          call_test_skip);
164 }
165 END_TEST
166
167
168 static void
169 call_test_progress_pop(void)
170 {
171         subunit_progress(SUBUNIT_PROGRESS_POP, 0);
172 }
173
174 static void
175 call_test_progress_set(void)
176 {
177         subunit_progress(SUBUNIT_PROGRESS_SET, 5);
178 }
179
180 static void
181 call_test_progress_push(void)
182 {
183         subunit_progress(SUBUNIT_PROGRESS_PUSH, 0);
184 }
185
186 static void
187 call_test_progress_cur(void)
188 {
189         subunit_progress(SUBUNIT_PROGRESS_CUR, -6);
190 }
191
192 START_TEST (test_progress)
193 {
194         test_stdout_function("progress: pop\n",
195                          call_test_progress_pop);
196         test_stdout_function("progress: push\n",
197                          call_test_progress_push);
198         test_stdout_function("progress: 5\n",
199                          call_test_progress_set);
200         test_stdout_function("progress: -6\n",
201                          call_test_progress_cur);
202 }
203 END_TEST
204
205 static Suite *
206 child_suite(void)
207 {
208     Suite *s = suite_create("subunit_child");
209     TCase *tc_core = tcase_create("Core");
210     suite_add_tcase (s, tc_core);
211     tcase_add_test (tc_core, test_start);
212     tcase_add_test (tc_core, test_pass);
213     tcase_add_test (tc_core, test_fail);
214     tcase_add_test (tc_core, test_error);
215     tcase_add_test (tc_core, test_skip);
216     tcase_add_test (tc_core, test_progress);
217     return s;
218 }
219
220
221 int
222 main(void)
223 {
224   int nf;
225   Suite *s = child_suite();
226   SRunner *sr = srunner_create(s);
227   srunner_run_all(sr, CK_NORMAL);
228   nf = srunner_ntests_failed(sr);
229   srunner_free(sr);
230   return (nf == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
231 }