1 /*
2 * Copyright © 2019 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
21 * IN THE SOFTWARE.
22 */
23
24 #include <sys/wait.h>
25 #include <string.h>
26 #include <stdlib.h>
27
28 #include "drmtest.h"
29 #include "igt_tests_common.h"
30
31 IGT_TEST_DESCRIPTION("the top level description");
fake_main(int argc,char ** argv)32 static void fake_main(int argc, char **argv) {
33 igt_subtest_init(argc, argv);
34
35 igt_describe("Basic A");
36 igt_subtest("A")
37 ;
38
39 igt_fixture
40 printf("should not be executed!\n");
41
42 igt_describe("Group with B, C & D");
43 igt_subtest_group {
44 igt_describe("Basic B");
45 igt_subtest("B")
46 ;
47
48 if (!igt_only_list_subtests())
49 printf("should not be executed!\n");
50
51 igt_describe("Group with C & D");
52 igt_subtest_group {
53 igt_describe("Basic C");
54 igt_subtest("C")
55 printf("should not be executed!\n");
56
57 // NO DOC
58 igt_subtest("D")
59 ;
60 }
61 }
62
63 // NO DOC
64 igt_subtest_group {
65 // NO DOC
66 igt_subtest("E")
67 ;
68 }
69
70 // NO DOC
71 igt_subtest("F")
72 ;
73
74 igt_describe("this description should be so long that it wraps itself nicely in the terminal "
75 "this description should be so long that it wraps itself nicely in the terminal "
76 "this description should be so long that it wraps itself nicely in the terminal "
77 "this description should be so long that it wraps itself nicely in the terminal "
78 "this description should be so long that it wraps itself nicely in the terminal "
79 "this description should be so long that it wraps itself nicely in the terminal");
80 igt_subtest("G")
81 ;
82
83 igt_describe("verylongwordthatshoudlbeprintedeventhoughitspastthewrppinglimit"
84 "verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit "
85 "verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit"
86 "verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit");
87 igt_subtest("F")
88 ;
89
90 igt_exit();
91 }
92
93 static const char DESCRIBE_ALL_OUTPUT[] = \
94 "the top level description\n"
95 "\n"
96 "SUB A ../lib/tests/igt_describe.c:36:\n"
97 " Basic A\n"
98 "\n"
99 "SUB B ../lib/tests/igt_describe.c:45:\n"
100 " Group with B, C & D\n"
101 "\n"
102 " Basic B\n"
103 "\n"
104 "SUB C ../lib/tests/igt_describe.c:54:\n"
105 " Group with B, C & D\n"
106 "\n"
107 " Group with C & D\n"
108 "\n"
109 " Basic C\n"
110 "\n"
111 "SUB D ../lib/tests/igt_describe.c:58:\n"
112 " Group with B, C & D\n"
113 "\n"
114 " Group with C & D\n"
115 "\n"
116 "SUB E ../lib/tests/igt_describe.c:66:\n"
117 " NO DOCUMENTATION!\n"
118 "\n"
119 "SUB F ../lib/tests/igt_describe.c:71:\n"
120 " NO DOCUMENTATION!\n"
121 "\n"
122 "SUB G ../lib/tests/igt_describe.c:80:\n"
123 " this description should be so long that it wraps itself nicely in the terminal this\n"
124 " description should be so long that it wraps itself nicely in the terminal this description\n"
125 " should be so long that it wraps itself nicely in the terminal this description should be so\n"
126 " long that it wraps itself nicely in the terminal this description should be so long that it\n"
127 " wraps itself nicely in the terminal this description should be so long that it wraps itself\n"
128 " nicely in the terminal\n"
129 "\n"
130 "SUB F ../lib/tests/igt_describe.c:87:\n"
131 " verylongwordthatshoudlbeprintedeventhoughitspastthewrppinglimitverylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit\n"
132 " verylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimitverylongwordthatshoudlbeprintedeventhoughitspastthewrappinglimit\n\n";
133
134 static const char JUST_C_OUTPUT[] = \
135 "the top level description\n"
136 "\n"
137 "SUB C ../lib/tests/igt_describe.c:54:\n"
138 " Group with B, C & D\n"
139 "\n"
140 " Group with C & D\n"
141 "\n"
142 " Basic C\n"
143 "\n";
144
assert_pipe_empty(int fd)145 static void assert_pipe_empty(int fd)
146 {
147 char buf[5];
148 internal_assert(0 == read(fd, buf, sizeof(buf)));
149 }
150
read_whole_pipe(int fd,char * buf,size_t buflen)151 static void read_whole_pipe(int fd, char *buf, size_t buflen)
152 {
153 ssize_t readlen;
154 off_t offset;
155
156 offset = 0;
157 while ((readlen = read(fd, buf+offset, buflen-offset))) {
158 if (readlen == -1) {
159 if (errno == EINTR) {
160 continue;
161 } else {
162 printf("read failed with %s\n", strerror(errno));
163 exit(1);
164 }
165 }
166 internal_assert(readlen != -1);
167 offset += readlen;
168 }
169 }
170
do_fork(int argc,char ** argv,int * out,int * err)171 static pid_t do_fork(int argc, char **argv, int *out, int *err)
172 {
173 int outfd[2], errfd[2];
174 pid_t pid;
175
176 internal_assert(pipe(outfd) != -1);
177 internal_assert(pipe(errfd) != -1);
178
179 pid = fork();
180 internal_assert(pid != -1);
181
182 if (pid == 0) {
183 while (dup2(outfd[1], STDOUT_FILENO) == -1 && errno == EINTR) {}
184 while (dup2(errfd[1], STDERR_FILENO) == -1 && errno == EINTR) {}
185
186 close(outfd[0]);
187 close(outfd[1]);
188 close(errfd[0]);
189 close(errfd[1]);
190
191 fake_main(argc, argv);
192
193 exit(-1);
194 } else {
195 /* close the writing ends */
196 close(outfd[1]);
197 close(errfd[1]);
198
199 *out = outfd[0];
200 *err = errfd[0];
201
202 return pid;
203 }
204 }
205
_wait(pid_t pid,int * status)206 static int _wait(pid_t pid, int *status) {
207 int ret;
208
209 do {
210 ret = waitpid(pid, status, 0);
211 } while (ret == -1 && errno == EINTR);
212
213 return ret;
214 }
215
main(int argc,char ** argv)216 int main(int argc, char **argv)
217 {
218 char prog[] = "igt_describe";
219 int status;
220 int outfd, errfd;
221
222 /* describe all subtest */ {
223 static char out[4096];
224 char arg[] = "--describe";
225 char *fake_argv[] = {prog, arg};
226 int fake_argc = ARRAY_SIZE(fake_argv);
227
228 pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
229
230 read_whole_pipe(outfd, out, sizeof(out));
231 assert_pipe_empty(errfd);
232
233 internal_assert(_wait(pid, &status) != -1);
234 internal_assert(WIFEXITED(status));
235 internal_assert(WEXITSTATUS(status) == IGT_EXIT_SUCCESS);
236 internal_assert(0 == strcmp(DESCRIBE_ALL_OUTPUT, out));
237
238 close(outfd);
239 close(errfd);
240 }
241
242 /* describe C using a pattern */ {
243 static char out[4096];
244 char arg[] = "--describe=C";
245 char *fake_argv[] = {prog, arg};
246 int fake_argc = ARRAY_SIZE(fake_argv);
247
248 pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
249
250 read_whole_pipe(outfd, out, sizeof(out));
251 assert_pipe_empty(errfd);
252
253 internal_assert(_wait(pid, &status) != -1);
254 internal_assert(WIFEXITED(status));
255 internal_assert(WEXITSTATUS(status) == IGT_EXIT_SUCCESS);
256 internal_assert(0 == strcmp(JUST_C_OUTPUT, out));
257
258 close(outfd);
259 close(errfd);
260 }
261
262 /* fail describing with a bad pattern */ {
263 static char err[4096];
264 char arg[] = "--describe=Z";
265 char *fake_argv[] = {prog, arg};
266 int fake_argc = ARRAY_SIZE(fake_argv);
267
268 pid_t pid = do_fork(fake_argc, fake_argv, &outfd, &errfd);
269
270 read_whole_pipe(errfd, err, sizeof(err));
271
272 internal_assert(_wait(pid, &status) != -1);
273 internal_assert(WIFEXITED(status));
274 internal_assert(WEXITSTATUS(status) == IGT_EXIT_INVALID);
275 internal_assert(strstr(err, "Unknown subtest: Z"));
276
277 close(outfd);
278 close(errfd);
279 }
280
281 return 0;
282 }
283