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