1 /* 2 * Automated Testing Framework (atf) 3 * 4 * Copyright (c) 2008 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 #include <sys/types.h> 31 #include <sys/wait.h> 32 33 #include <errno.h> 34 #include <fcntl.h> 35 #include <stdarg.h> 36 #include <stdbool.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <string.h> 40 #include <unistd.h> 41 42 #include <atf-c.h> 43 44 #include "detail/fs.h" 45 #include "detail/process.h" 46 #include "detail/test_helpers.h" 47 #include "detail/text.h" 48 49 /* --------------------------------------------------------------------- 50 * Auxiliary functions. 51 * --------------------------------------------------------------------- */ 52 53 static 54 void 55 create_ctl_file(const char *name) 56 { 57 atf_fs_path_t p; 58 59 RE(atf_fs_path_init_fmt(&p, "%s", name)); 60 ATF_REQUIRE(open(atf_fs_path_cstring(&p), 61 O_CREAT | O_WRONLY | O_TRUNC, 0644) != -1); 62 atf_fs_path_fini(&p); 63 } 64 65 static 66 bool 67 exists(const char *p) 68 { 69 bool b; 70 atf_fs_path_t pp; 71 72 RE(atf_fs_path_init_fmt(&pp, "%s", p)); 73 RE(atf_fs_exists(&pp, &b)); 74 atf_fs_path_fini(&pp); 75 76 return b; 77 } 78 79 static 80 void 81 init_and_run_h_tc(const char *name, void (*head)(atf_tc_t *), 82 void (*body)(const atf_tc_t *)) 83 { 84 atf_tc_t tc; 85 const char *const config[] = { NULL }; 86 87 RE(atf_tc_init(&tc, name, head, body, NULL, config)); 88 run_h_tc(&tc, "output", "error", "result"); 89 atf_tc_fini(&tc); 90 } 91 92 /* --------------------------------------------------------------------- 93 * Helper test cases. 94 * --------------------------------------------------------------------- */ 95 96 #define H_DEF(id, macro) \ 97 ATF_TC_HEAD(h_ ## id, tc) \ 98 { \ 99 atf_tc_set_md_var(tc, "descr", "Helper test case"); \ 100 } \ 101 ATF_TC_BODY(h_ ## id, tc) \ 102 { \ 103 create_ctl_file("before"); \ 104 macro; \ 105 create_ctl_file("after"); \ 106 } 107 108 #define H_CHECK_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_ ## id) 109 #define H_CHECK_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_ ## id) 110 #define H_CHECK(id, condition) \ 111 H_DEF(check_ ## id, ATF_CHECK(condition)) 112 113 #define H_CHECK_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_msg_ ## id) 114 #define H_CHECK_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_msg_ ## id) 115 #define H_CHECK_MSG(id, condition, msg) \ 116 H_DEF(check_msg_ ## id, ATF_CHECK_MSG(condition, msg)) 117 118 #define H_CHECK_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_eq_ ## id) 119 #define H_CHECK_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_eq_ ## id) 120 #define H_CHECK_EQ(id, v1, v2) \ 121 H_DEF(check_eq_ ## id, ATF_CHECK_EQ(v1, v2)) 122 123 #define H_CHECK_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_streq_ ## id) 124 #define H_CHECK_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_streq_ ## id) 125 #define H_CHECK_STREQ(id, v1, v2) \ 126 H_DEF(check_streq_ ## id, ATF_CHECK_STREQ(v1, v2)) 127 128 #define H_CHECK_EQ_MSG_HEAD_NAME(id) \ 129 ATF_TC_HEAD_NAME(h_check_eq_msg_ ## id) 130 #define H_CHECK_EQ_MSG_BODY_NAME(id) \ 131 ATF_TC_BODY_NAME(h_check_eq_msg_ ## id) 132 #define H_CHECK_EQ_MSG(id, v1, v2, msg) \ 133 H_DEF(check_eq_msg_ ## id, ATF_CHECK_EQ_MSG(v1, v2, msg)) 134 135 #define H_CHECK_STREQ_MSG_HEAD_NAME(id) \ 136 ATF_TC_HEAD_NAME(h_check_streq_msg_ ## id) 137 #define H_CHECK_STREQ_MSG_BODY_NAME(id) \ 138 ATF_TC_BODY_NAME(h_check_streq_msg_ ## id) 139 #define H_CHECK_STREQ_MSG(id, v1, v2, msg) \ 140 H_DEF(check_streq_msg_ ## id, ATF_CHECK_STREQ_MSG(v1, v2, msg)) 141 142 #define H_CHECK_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_check_errno_ ## id) 143 #define H_CHECK_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_check_errno_ ## id) 144 #define H_CHECK_ERRNO(id, exp_errno, bool_expr) \ 145 H_DEF(check_errno_ ## id, ATF_CHECK_ERRNO(exp_errno, bool_expr)) 146 147 #define H_REQUIRE_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_ ## id) 148 #define H_REQUIRE_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_ ## id) 149 #define H_REQUIRE(id, condition) \ 150 H_DEF(require_ ## id, ATF_REQUIRE(condition)) 151 152 #define H_REQUIRE_MSG_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_msg_ ## id) 153 #define H_REQUIRE_MSG_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_msg_ ## id) 154 #define H_REQUIRE_MSG(id, condition, msg) \ 155 H_DEF(require_msg_ ## id, ATF_REQUIRE_MSG(condition, msg)) 156 157 #define H_REQUIRE_EQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_eq_ ## id) 158 #define H_REQUIRE_EQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_eq_ ## id) 159 #define H_REQUIRE_EQ(id, v1, v2) \ 160 H_DEF(require_eq_ ## id, ATF_REQUIRE_EQ(v1, v2)) 161 162 #define H_REQUIRE_STREQ_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_streq_ ## id) 163 #define H_REQUIRE_STREQ_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_streq_ ## id) 164 #define H_REQUIRE_STREQ(id, v1, v2) \ 165 H_DEF(require_streq_ ## id, ATF_REQUIRE_STREQ(v1, v2)) 166 167 #define H_REQUIRE_EQ_MSG_HEAD_NAME(id) \ 168 ATF_TC_HEAD_NAME(h_require_eq_msg_ ## id) 169 #define H_REQUIRE_EQ_MSG_BODY_NAME(id) \ 170 ATF_TC_BODY_NAME(h_require_eq_msg_ ## id) 171 #define H_REQUIRE_EQ_MSG(id, v1, v2, msg) \ 172 H_DEF(require_eq_msg_ ## id, ATF_REQUIRE_EQ_MSG(v1, v2, msg)) 173 174 #define H_REQUIRE_STREQ_MSG_HEAD_NAME(id) \ 175 ATF_TC_HEAD_NAME(h_require_streq_msg_ ## id) 176 #define H_REQUIRE_STREQ_MSG_BODY_NAME(id) \ 177 ATF_TC_BODY_NAME(h_require_streq_msg_ ## id) 178 #define H_REQUIRE_STREQ_MSG(id, v1, v2, msg) \ 179 H_DEF(require_streq_msg_ ## id, ATF_REQUIRE_STREQ_MSG(v1, v2, msg)) 180 181 #define H_REQUIRE_ERRNO_HEAD_NAME(id) ATF_TC_HEAD_NAME(h_require_errno_ ## id) 182 #define H_REQUIRE_ERRNO_BODY_NAME(id) ATF_TC_BODY_NAME(h_require_errno_ ## id) 183 #define H_REQUIRE_ERRNO(id, exp_errno, bool_expr) \ 184 H_DEF(require_errno_ ## id, ATF_REQUIRE_ERRNO(exp_errno, bool_expr)) 185 186 /* --------------------------------------------------------------------- 187 * Test cases for the ATF_{CHECK,REQUIRE}_ERRNO macros. 188 * --------------------------------------------------------------------- */ 189 190 static int 191 errno_fail_stub(const int raised_errno) 192 { 193 errno = raised_errno; 194 return -1; 195 } 196 197 static int 198 errno_ok_stub(void) 199 { 200 return 0; 201 } 202 203 H_CHECK_ERRNO(no_error, -1, errno_ok_stub() == -1); 204 H_CHECK_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1); 205 H_CHECK_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1); 206 207 H_REQUIRE_ERRNO(no_error, -1, errno_ok_stub() == -1); 208 H_REQUIRE_ERRNO(errno_ok, 2, errno_fail_stub(2) == -1); 209 H_REQUIRE_ERRNO(errno_fail, 3, errno_fail_stub(4) == -1); 210 211 ATF_TC(check_errno); 212 ATF_TC_HEAD(check_errno, tc) 213 { 214 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_ERRNO macro"); 215 } 216 ATF_TC_BODY(check_errno, tc) 217 { 218 struct test { 219 void (*head)(atf_tc_t *); 220 void (*body)(const atf_tc_t *); 221 bool ok; 222 const char *exp_regex; 223 } *t, tests[] = { 224 { H_CHECK_ERRNO_HEAD_NAME(no_error), 225 H_CHECK_ERRNO_BODY_NAME(no_error), 226 false, "Expected true value in errno_ok_stub\\(\\) == -1" }, 227 { H_CHECK_ERRNO_HEAD_NAME(errno_ok), 228 H_CHECK_ERRNO_BODY_NAME(errno_ok), 229 true, NULL }, 230 { H_CHECK_ERRNO_HEAD_NAME(errno_fail), 231 H_CHECK_ERRNO_BODY_NAME(errno_fail), 232 false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" }, 233 { NULL, NULL, false, NULL } 234 }; 235 236 for (t = &tests[0]; t->head != NULL; t++) { 237 init_and_run_h_tc("h_check_errno", t->head, t->body); 238 239 ATF_REQUIRE(exists("before")); 240 ATF_REQUIRE(exists("after")); 241 242 if (t->ok) { 243 ATF_REQUIRE(grep_file("result", "^passed")); 244 } else { 245 ATF_REQUIRE(grep_file("result", "^failed")); 246 ATF_REQUIRE(grep_file("error", "macros_test.c:[0-9]+: %s$", 247 t->exp_regex)); 248 } 249 250 ATF_REQUIRE(unlink("before") != -1); 251 ATF_REQUIRE(unlink("after") != -1); 252 } 253 } 254 255 ATF_TC(require_errno); 256 ATF_TC_HEAD(require_errno, tc) 257 { 258 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_ERRNO macro"); 259 } 260 ATF_TC_BODY(require_errno, tc) 261 { 262 struct test { 263 void (*head)(atf_tc_t *); 264 void (*body)(const atf_tc_t *); 265 bool ok; 266 const char *exp_regex; 267 } *t, tests[] = { 268 { H_REQUIRE_ERRNO_HEAD_NAME(no_error), 269 H_REQUIRE_ERRNO_BODY_NAME(no_error), 270 false, "Expected true value in errno_ok_stub\\(\\) == -1" }, 271 { H_REQUIRE_ERRNO_HEAD_NAME(errno_ok), 272 H_REQUIRE_ERRNO_BODY_NAME(errno_ok), 273 true, NULL }, 274 { H_REQUIRE_ERRNO_HEAD_NAME(errno_fail), 275 H_REQUIRE_ERRNO_BODY_NAME(errno_fail), 276 false, "Expected errno 3, got 4, in errno_fail_stub\\(4\\) == -1" }, 277 { NULL, NULL, false, NULL } 278 }; 279 280 for (t = &tests[0]; t->head != NULL; t++) { 281 init_and_run_h_tc("h_require_errno", t->head, t->body); 282 283 ATF_REQUIRE(exists("before")); 284 if (t->ok) { 285 ATF_REQUIRE(grep_file("result", "^passed")); 286 ATF_REQUIRE(exists("after")); 287 } else { 288 ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c:[0-9]+: " 289 "%s$", t->exp_regex)); 290 ATF_REQUIRE(!exists("after")); 291 } 292 293 ATF_REQUIRE(unlink("before") != -1); 294 if (t->ok) 295 ATF_REQUIRE(unlink("after") != -1); 296 } 297 } 298 299 /* --------------------------------------------------------------------- 300 * Test cases for the ATF_CHECK and ATF_CHECK_MSG macros. 301 * --------------------------------------------------------------------- */ 302 303 H_CHECK(0, 0); 304 H_CHECK(1, 1); 305 H_CHECK_MSG(0, 0, "expected a false value"); 306 H_CHECK_MSG(1, 1, "expected a true value"); 307 308 ATF_TC(check); 309 ATF_TC_HEAD(check, tc) 310 { 311 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK and " 312 "ATF_CHECK_MSG macros"); 313 } 314 ATF_TC_BODY(check, tc) 315 { 316 struct test { 317 void (*head)(atf_tc_t *); 318 void (*body)(const atf_tc_t *); 319 bool value; 320 const char *msg; 321 bool ok; 322 } *t, tests[] = { 323 { H_CHECK_HEAD_NAME(0), H_CHECK_BODY_NAME(0), 0, 324 "0 not met", false }, 325 { H_CHECK_HEAD_NAME(1), H_CHECK_BODY_NAME(1), 1, 326 "1 not met", true }, 327 { H_CHECK_MSG_HEAD_NAME(0), H_CHECK_MSG_BODY_NAME(0), 0, 328 "expected a false value", false }, 329 { H_CHECK_MSG_HEAD_NAME(1), H_CHECK_MSG_BODY_NAME(1), 1, 330 "expected a true value", true }, 331 { NULL, NULL, false, NULL, false } 332 }; 333 334 for (t = &tests[0]; t->head != NULL; t++) { 335 printf("Checking with a %d value\n", t->value); 336 337 init_and_run_h_tc("h_check", t->head, t->body); 338 339 ATF_REQUIRE(exists("before")); 340 ATF_REQUIRE(exists("after")); 341 342 if (t->ok) { 343 ATF_REQUIRE(grep_file("result", "^passed")); 344 } else { 345 ATF_REQUIRE(grep_file("result", "^failed")); 346 ATF_REQUIRE(grep_file("error", "Check failed: .*" 347 "macros_test.c:[0-9]+: %s$", t->msg)); 348 } 349 350 ATF_REQUIRE(unlink("before") != -1); 351 ATF_REQUIRE(unlink("after") != -1); 352 } 353 } 354 355 /* --------------------------------------------------------------------- 356 * Test cases for the ATF_CHECK_*EQ_ macros. 357 * --------------------------------------------------------------------- */ 358 359 struct check_eq_test { 360 void (*head)(atf_tc_t *); 361 void (*body)(const atf_tc_t *); 362 const char *v1; 363 const char *v2; 364 const char *msg; 365 bool ok; 366 }; 367 368 static 369 void 370 do_check_eq_tests(const struct check_eq_test *tests) 371 { 372 const struct check_eq_test *t; 373 374 for (t = &tests[0]; t->head != NULL; t++) { 375 printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2, 376 t->ok ? "true" : "false"); 377 378 init_and_run_h_tc("h_check", t->head, t->body); 379 380 ATF_CHECK(exists("before")); 381 ATF_CHECK(exists("after")); 382 383 if (t->ok) { 384 ATF_REQUIRE(grep_file("result", "^passed")); 385 } else { 386 ATF_REQUIRE(grep_file("result", "^failed")); 387 ATF_CHECK(grep_file("error", "Check failed: .*" 388 "macros_test.c:[0-9]+: %s$", t->msg)); 389 } 390 391 ATF_CHECK(unlink("before") != -1); 392 ATF_CHECK(unlink("after") != -1); 393 } 394 } 395 396 H_CHECK_EQ(1_1, 1, 1); 397 H_CHECK_EQ(1_2, 1, 2); 398 H_CHECK_EQ(2_1, 2, 1); 399 H_CHECK_EQ(2_2, 2, 2); 400 H_CHECK_EQ_MSG(1_1, 1, 1, "1 does not match 1"); 401 H_CHECK_EQ_MSG(1_2, 1, 2, "1 does not match 2"); 402 H_CHECK_EQ_MSG(2_1, 2, 1, "2 does not match 1"); 403 H_CHECK_EQ_MSG(2_2, 2, 2, "2 does not match 2"); 404 405 ATF_TC(check_eq); 406 ATF_TC_HEAD(check_eq, tc) 407 { 408 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_EQ and " 409 "ATF_CHECK_EQ_MSG macros"); 410 } 411 ATF_TC_BODY(check_eq, tc) 412 { 413 struct check_eq_test tests[] = { 414 { H_CHECK_EQ_HEAD_NAME(1_1), H_CHECK_EQ_BODY_NAME(1_1), 415 "1", "1", "1 != 1", true }, 416 { H_CHECK_EQ_HEAD_NAME(1_2), H_CHECK_EQ_BODY_NAME(1_2), 417 "1", "2", "1 != 2", false }, 418 { H_CHECK_EQ_HEAD_NAME(2_1), H_CHECK_EQ_BODY_NAME(2_1), 419 "2", "1", "2 != 1", false }, 420 { H_CHECK_EQ_HEAD_NAME(2_2), H_CHECK_EQ_BODY_NAME(2_2), 421 "2", "2", "2 != 2", true }, 422 { H_CHECK_EQ_MSG_HEAD_NAME(1_1), H_CHECK_EQ_MSG_BODY_NAME(1_1), 423 "1", "1", "1 != 1: 1 does not match 1", true }, 424 { H_CHECK_EQ_MSG_HEAD_NAME(1_2), H_CHECK_EQ_MSG_BODY_NAME(1_2), 425 "1", "2", "1 != 2: 1 does not match 2", false }, 426 { H_CHECK_EQ_MSG_HEAD_NAME(2_1), H_CHECK_EQ_MSG_BODY_NAME(2_1), 427 "2", "1", "2 != 1: 2 does not match 1", false }, 428 { H_CHECK_EQ_MSG_HEAD_NAME(2_2), H_CHECK_EQ_MSG_BODY_NAME(2_2), 429 "2", "2", "2 != 2: 2 does not match 2", true }, 430 { NULL, NULL, 0, 0, "", false } 431 }; 432 do_check_eq_tests(tests); 433 } 434 435 H_CHECK_STREQ(1_1, "1", "1"); 436 H_CHECK_STREQ(1_2, "1", "2"); 437 H_CHECK_STREQ(2_1, "2", "1"); 438 H_CHECK_STREQ(2_2, "2", "2"); 439 H_CHECK_STREQ_MSG(1_1, "1", "1", "1 does not match 1"); 440 H_CHECK_STREQ_MSG(1_2, "1", "2", "1 does not match 2"); 441 H_CHECK_STREQ_MSG(2_1, "2", "1", "2 does not match 1"); 442 H_CHECK_STREQ_MSG(2_2, "2", "2", "2 does not match 2"); 443 #define CHECK_STREQ_VAR1 "5" 444 #define CHECK_STREQ_VAR2 "9" 445 const const char *check_streq_var1 = CHECK_STREQ_VAR1; 446 const const char *check_streq_var2 = CHECK_STREQ_VAR2; 447 H_CHECK_STREQ(vars, check_streq_var1, check_streq_var2); 448 449 ATF_TC(check_streq); 450 ATF_TC_HEAD(check_streq, tc) 451 { 452 atf_tc_set_md_var(tc, "descr", "Tests the ATF_CHECK_STREQ and " 453 "ATF_CHECK_STREQ_MSG macros"); 454 } 455 ATF_TC_BODY(check_streq, tc) 456 { 457 struct check_eq_test tests[] = { 458 { H_CHECK_STREQ_HEAD_NAME(1_1), H_CHECK_STREQ_BODY_NAME(1_1), 459 "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true }, 460 { H_CHECK_STREQ_HEAD_NAME(1_2), H_CHECK_STREQ_BODY_NAME(1_2), 461 "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false }, 462 { H_CHECK_STREQ_HEAD_NAME(2_1), H_CHECK_STREQ_BODY_NAME(2_1), 463 "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false }, 464 { H_CHECK_STREQ_HEAD_NAME(2_2), H_CHECK_STREQ_BODY_NAME(2_2), 465 "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true }, 466 { H_CHECK_STREQ_MSG_HEAD_NAME(1_1), 467 H_CHECK_STREQ_MSG_BODY_NAME(1_1), 468 "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true }, 469 { H_CHECK_STREQ_MSG_HEAD_NAME(1_2), 470 H_CHECK_STREQ_MSG_BODY_NAME(1_2), 471 "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false }, 472 { H_CHECK_STREQ_MSG_HEAD_NAME(2_1), 473 H_CHECK_STREQ_MSG_BODY_NAME(2_1), 474 "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false }, 475 { H_CHECK_STREQ_MSG_HEAD_NAME(2_2), 476 H_CHECK_STREQ_MSG_BODY_NAME(2_2), 477 "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true }, 478 { H_CHECK_STREQ_HEAD_NAME(vars), H_CHECK_STREQ_BODY_NAME(vars), 479 check_streq_var1, check_streq_var2, 480 "check_streq_var1 != check_streq_var2 \\(" 481 CHECK_STREQ_VAR1 " != " CHECK_STREQ_VAR2 "\\)", false }, 482 { NULL, NULL, 0, 0, "", false } 483 }; 484 do_check_eq_tests(tests); 485 } 486 487 /* --------------------------------------------------------------------- 488 * Test cases for the ATF_REQUIRE and ATF_REQUIRE_MSG macros. 489 * --------------------------------------------------------------------- */ 490 491 H_REQUIRE(0, 0); 492 H_REQUIRE(1, 1); 493 H_REQUIRE_MSG(0, 0, "expected a false value"); 494 H_REQUIRE_MSG(1, 1, "expected a true value"); 495 496 ATF_TC(require); 497 ATF_TC_HEAD(require, tc) 498 { 499 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE and " 500 "ATF_REQUIRE_MSG macros"); 501 } 502 ATF_TC_BODY(require, tc) 503 { 504 struct test { 505 void (*head)(atf_tc_t *); 506 void (*body)(const atf_tc_t *); 507 bool value; 508 const char *msg; 509 bool ok; 510 } *t, tests[] = { 511 { H_REQUIRE_HEAD_NAME(0), H_REQUIRE_BODY_NAME(0), 0, 512 "0 not met", false }, 513 { H_REQUIRE_HEAD_NAME(1), H_REQUIRE_BODY_NAME(1), 1, 514 "1 not met", true }, 515 { H_REQUIRE_MSG_HEAD_NAME(0), H_REQUIRE_MSG_BODY_NAME(0), 0, 516 "expected a false value", false }, 517 { H_REQUIRE_MSG_HEAD_NAME(1), H_REQUIRE_MSG_BODY_NAME(1), 1, 518 "expected a true value", true }, 519 { NULL, NULL, false, NULL, false } 520 }; 521 522 for (t = &tests[0]; t->head != NULL; t++) { 523 printf("Checking with a %d value\n", t->value); 524 525 init_and_run_h_tc("h_require", t->head, t->body); 526 527 ATF_REQUIRE(exists("before")); 528 if (t->ok) { 529 ATF_REQUIRE(grep_file("result", "^passed")); 530 ATF_REQUIRE(exists("after")); 531 } else { 532 ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c:[0-9]+: " 533 "%s$", t->msg)); 534 ATF_REQUIRE(!exists("after")); 535 } 536 537 ATF_REQUIRE(unlink("before") != -1); 538 if (t->ok) 539 ATF_REQUIRE(unlink("after") != -1); 540 } 541 } 542 543 /* --------------------------------------------------------------------- 544 * Test cases for the ATF_REQUIRE_*EQ_ macros. 545 * --------------------------------------------------------------------- */ 546 547 struct require_eq_test { 548 void (*head)(atf_tc_t *); 549 void (*body)(const atf_tc_t *); 550 const char *v1; 551 const char *v2; 552 const char *msg; 553 bool ok; 554 }; 555 556 static 557 void 558 do_require_eq_tests(const struct require_eq_test *tests) 559 { 560 const struct require_eq_test *t; 561 562 for (t = &tests[0]; t->head != NULL; t++) { 563 printf("Checking with %s, %s and expecting %s\n", t->v1, t->v2, 564 t->ok ? "true" : "false"); 565 566 init_and_run_h_tc("h_require", t->head, t->body); 567 568 ATF_REQUIRE(exists("before")); 569 if (t->ok) { 570 ATF_REQUIRE(grep_file("result", "^passed")); 571 ATF_REQUIRE(exists("after")); 572 } else { 573 ATF_REQUIRE(grep_file("result", "^failed: .*macros_test.c" 574 ":[0-9]+: %s$", t->msg)); 575 ATF_REQUIRE(!exists("after")); 576 } 577 578 ATF_REQUIRE(unlink("before") != -1); 579 if (t->ok) 580 ATF_REQUIRE(unlink("after") != -1); 581 } 582 } 583 584 H_REQUIRE_EQ(1_1, 1, 1); 585 H_REQUIRE_EQ(1_2, 1, 2); 586 H_REQUIRE_EQ(2_1, 2, 1); 587 H_REQUIRE_EQ(2_2, 2, 2); 588 H_REQUIRE_EQ_MSG(1_1, 1, 1, "1 does not match 1"); 589 H_REQUIRE_EQ_MSG(1_2, 1, 2, "1 does not match 2"); 590 H_REQUIRE_EQ_MSG(2_1, 2, 1, "2 does not match 1"); 591 H_REQUIRE_EQ_MSG(2_2, 2, 2, "2 does not match 2"); 592 593 ATF_TC(require_eq); 594 ATF_TC_HEAD(require_eq, tc) 595 { 596 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_EQ and " 597 "ATF_REQUIRE_EQ_MSG macros"); 598 } 599 ATF_TC_BODY(require_eq, tc) 600 { 601 struct require_eq_test tests[] = { 602 { H_REQUIRE_EQ_HEAD_NAME(1_1), H_REQUIRE_EQ_BODY_NAME(1_1), 603 "1", "1", "1 != 1", true }, 604 { H_REQUIRE_EQ_HEAD_NAME(1_2), H_REQUIRE_EQ_BODY_NAME(1_2), 605 "1", "2", "1 != 2", false }, 606 { H_REQUIRE_EQ_HEAD_NAME(2_1), H_REQUIRE_EQ_BODY_NAME(2_1), 607 "2", "1", "2 != 1", false }, 608 { H_REQUIRE_EQ_HEAD_NAME(2_2), H_REQUIRE_EQ_BODY_NAME(2_2), 609 "2", "2", "2 != 2", true }, 610 { H_REQUIRE_EQ_MSG_HEAD_NAME(1_1), H_REQUIRE_EQ_MSG_BODY_NAME(1_1), 611 "1", "1", "1 != 1: 1 does not match 1", true }, 612 { H_REQUIRE_EQ_MSG_HEAD_NAME(1_2), H_REQUIRE_EQ_MSG_BODY_NAME(1_2), 613 "1", "2", "1 != 2: 1 does not match 2", false }, 614 { H_REQUIRE_EQ_MSG_HEAD_NAME(2_1), H_REQUIRE_EQ_MSG_BODY_NAME(2_1), 615 "2", "1", "2 != 1: 2 does not match 1", false }, 616 { H_REQUIRE_EQ_MSG_HEAD_NAME(2_2), H_REQUIRE_EQ_MSG_BODY_NAME(2_2), 617 "2", "2", "2 != 2: 2 does not match 2", true }, 618 { NULL, NULL, 0, 0, "", false } 619 }; 620 do_require_eq_tests(tests); 621 } 622 623 H_REQUIRE_STREQ(1_1, "1", "1"); 624 H_REQUIRE_STREQ(1_2, "1", "2"); 625 H_REQUIRE_STREQ(2_1, "2", "1"); 626 H_REQUIRE_STREQ(2_2, "2", "2"); 627 H_REQUIRE_STREQ_MSG(1_1, "1", "1", "1 does not match 1"); 628 H_REQUIRE_STREQ_MSG(1_2, "1", "2", "1 does not match 2"); 629 H_REQUIRE_STREQ_MSG(2_1, "2", "1", "2 does not match 1"); 630 H_REQUIRE_STREQ_MSG(2_2, "2", "2", "2 does not match 2"); 631 #define REQUIRE_STREQ_VAR1 "5" 632 #define REQUIRE_STREQ_VAR2 "9" 633 const const char *require_streq_var1 = REQUIRE_STREQ_VAR1; 634 const const char *require_streq_var2 = REQUIRE_STREQ_VAR2; 635 H_REQUIRE_STREQ(vars, require_streq_var1, require_streq_var2); 636 637 ATF_TC(require_streq); 638 ATF_TC_HEAD(require_streq, tc) 639 { 640 atf_tc_set_md_var(tc, "descr", "Tests the ATF_REQUIRE_STREQ and " 641 "ATF_REQUIRE_STREQ_MSG macros"); 642 } 643 ATF_TC_BODY(require_streq, tc) 644 { 645 struct require_eq_test tests[] = { 646 { H_REQUIRE_STREQ_HEAD_NAME(1_1), H_REQUIRE_STREQ_BODY_NAME(1_1), 647 "1", "1", "\"1\" != \"1\" \\(1 != 1\\)", true }, 648 { H_REQUIRE_STREQ_HEAD_NAME(1_2), H_REQUIRE_STREQ_BODY_NAME(1_2), 649 "1", "2", "\"1\" != \"2\" \\(1 != 2\\)", false }, 650 { H_REQUIRE_STREQ_HEAD_NAME(2_1), H_REQUIRE_STREQ_BODY_NAME(2_1), 651 "2", "1", "\"2\" != \"1\" \\(2 != 1\\)", false }, 652 { H_REQUIRE_STREQ_HEAD_NAME(2_2), H_REQUIRE_STREQ_BODY_NAME(2_2), 653 "2", "2", "\"2\" != \"2\" \\(2 != 2\\)", true }, 654 { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_1), 655 H_REQUIRE_STREQ_MSG_BODY_NAME(1_1), 656 "1", "1", "\"1\" != \"1\" \\(1 != 1\\): 1 does not match 1", true }, 657 { H_REQUIRE_STREQ_MSG_HEAD_NAME(1_2), 658 H_REQUIRE_STREQ_MSG_BODY_NAME(1_2), 659 "1", "2", "\"1\" != \"2\" \\(1 != 2\\): 1 does not match 2", false }, 660 { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_1), 661 H_REQUIRE_STREQ_MSG_BODY_NAME(2_1), 662 "2", "1", "\"2\" != \"1\" \\(2 != 1\\): 2 does not match 1", false }, 663 { H_REQUIRE_STREQ_MSG_HEAD_NAME(2_2), 664 H_REQUIRE_STREQ_MSG_BODY_NAME(2_2), 665 "2", "2", "\"2\" != \"2\" \\(2 != 2\\): 2 does not match 2", true }, 666 { H_REQUIRE_STREQ_HEAD_NAME(vars), H_REQUIRE_STREQ_BODY_NAME(vars), 667 require_streq_var1, require_streq_var2, 668 "require_streq_var1 != require_streq_var2 \\(" 669 REQUIRE_STREQ_VAR1 " != " REQUIRE_STREQ_VAR2 "\\)", false }, 670 { NULL, NULL, 0, 0, "", false } 671 }; 672 do_require_eq_tests(tests); 673 } 674 675 /* --------------------------------------------------------------------- 676 * Miscellaneous test cases covering several macros. 677 * --------------------------------------------------------------------- */ 678 679 static 680 bool 681 aux_bool(const char *fmt ATF_DEFS_ATTRIBUTE_UNUSED) 682 { 683 return false; 684 } 685 686 static 687 const char * 688 aux_str(const char *fmt ATF_DEFS_ATTRIBUTE_UNUSED) 689 { 690 return "foo"; 691 } 692 693 H_CHECK(msg, aux_bool("%d")); 694 H_REQUIRE(msg, aux_bool("%d")); 695 H_CHECK_STREQ(msg, aux_str("%d"), ""); 696 H_REQUIRE_STREQ(msg, aux_str("%d"), ""); 697 698 ATF_TC(msg_embedded_fmt); 699 ATF_TC_HEAD(msg_embedded_fmt, tc) 700 { 701 atf_tc_set_md_var(tc, "descr", "Tests that format strings passed " 702 "as part of the automatically-generated messages " 703 "do not get expanded"); 704 } 705 ATF_TC_BODY(msg_embedded_fmt, tc) 706 { 707 struct test { 708 void (*head)(atf_tc_t *); 709 void (*body)(const atf_tc_t *); 710 bool fatal; 711 const char *msg; 712 } *t, tests[] = { 713 { H_CHECK_HEAD_NAME(msg), H_CHECK_BODY_NAME(msg), false, 714 "aux_bool\\(\"%d\"\\) not met" }, 715 { H_REQUIRE_HEAD_NAME(msg), H_REQUIRE_BODY_NAME(msg), true, 716 "aux_bool\\(\"%d\"\\) not met" }, 717 { H_CHECK_STREQ_HEAD_NAME(msg), H_CHECK_STREQ_BODY_NAME(msg), false, 718 "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" }, 719 { H_REQUIRE_STREQ_HEAD_NAME(msg), H_REQUIRE_STREQ_BODY_NAME(msg), true, 720 "aux_str\\(\"%d\"\\) != \"\" \\(foo != \\)" }, 721 { NULL, NULL, false, NULL } 722 }; 723 724 for (t = &tests[0]; t->head != NULL; t++) { 725 printf("Checking with an expected '%s' message\n", t->msg); 726 727 init_and_run_h_tc("h_check", t->head, t->body); 728 729 if (t->fatal) { 730 bool matched = 731 grep_file("result", "^failed: .*macros_test.c:[0-9]+: " 732 "%s$", t->msg); 733 ATF_CHECK_MSG(matched, "couldn't find error string in result"); 734 } else { 735 bool matched = grep_file("error", "Check failed: .*" 736 "macros_test.c:[0-9]+: %s$", t->msg); 737 ATF_CHECK_MSG(matched, "couldn't find error string in output"); 738 } 739 } 740 } 741 742 /* --------------------------------------------------------------------- 743 * Tests cases for the header file. 744 * --------------------------------------------------------------------- */ 745 746 HEADER_TC(include, "atf-c/macros.h"); 747 BUILD_TC(use, "macros_h_test.c", 748 "Tests that the macros provided by the atf-c/macros.h file " 749 "do not cause syntax errors when used", 750 "Build of macros_h_test.c failed; some macros in atf-c/macros.h " 751 "are broken"); 752 BUILD_TC_FAIL(detect_unused_tests, "unused_test.c", 753 "Tests that defining an unused test case raises a warning (and thus " 754 "an error)", 755 "Build of unused_test.c passed; unused test cases are not properly " 756 "detected"); 757 758 /* --------------------------------------------------------------------- 759 * Main. 760 * --------------------------------------------------------------------- */ 761 762 ATF_TP_ADD_TCS(tp) 763 { 764 ATF_TP_ADD_TC(tp, check); 765 ATF_TP_ADD_TC(tp, check_eq); 766 ATF_TP_ADD_TC(tp, check_streq); 767 ATF_TP_ADD_TC(tp, check_errno); 768 769 ATF_TP_ADD_TC(tp, require); 770 ATF_TP_ADD_TC(tp, require_eq); 771 ATF_TP_ADD_TC(tp, require_streq); 772 ATF_TP_ADD_TC(tp, require_errno); 773 774 ATF_TP_ADD_TC(tp, msg_embedded_fmt); 775 776 /* Add the test cases for the header file. */ 777 ATF_TP_ADD_TC(tp, include); 778 ATF_TP_ADD_TC(tp, use); 779 ATF_TP_ADD_TC(tp, detect_unused_tests); 780 781 return atf_no_error(); 782 } 783